micro/internal/buffer/backup.go

119 lines
2.8 KiB
Go
Raw Normal View History

2019-12-21 21:35:09 +00:00
package buffer
import (
2019-12-22 23:05:23 +00:00
"fmt"
2019-12-21 21:35:09 +00:00
"io"
2019-12-22 00:55:23 +00:00
"log"
"os"
"time"
2019-12-21 21:35:09 +00:00
"github.com/zyedidia/micro/internal/config"
2019-12-22 23:05:23 +00:00
"github.com/zyedidia/micro/internal/screen"
2019-12-21 21:35:09 +00:00
"github.com/zyedidia/micro/internal/util"
"golang.org/x/text/encoding"
)
2019-12-22 00:55:23 +00:00
const backupMsg = `A backup was detected for this file. This likely means that micro
crashed while editing this file, or another instance of micro is currently
editing this file.
2019-12-22 23:05:23 +00:00
The backup was created on %s.
2019-12-22 00:55:23 +00:00
* 'recover' will apply the backup as unsaved changes to the current buffer.
When the buffer is closed, the backup will be removed.
* 'ignore' will ignore the backup, discarding its changes. The backup file
will be removed.
Options: [r]ecover, [i]gnore: `
2019-12-21 21:35:09 +00:00
// Backup saves the current buffer to ConfigDir/backups
2019-12-22 04:26:53 +00:00
func (b *Buffer) Backup(checkTime bool) error {
2019-12-22 18:43:29 +00:00
if !b.Settings["backup"].(bool) || b.Path == "" {
2019-12-21 21:35:09 +00:00
return nil
}
2019-12-22 04:26:53 +00:00
if checkTime {
sub := time.Now().Sub(b.lastbackup)
if sub < time.Duration(backup_time)*time.Millisecond {
log.Println("Backup event but not enough time has passed", sub)
return nil
}
2019-12-22 00:55:23 +00:00
}
b.lastbackup = time.Now()
backupdir := config.ConfigDir + "/backups/"
if _, err := os.Stat(backupdir); os.IsNotExist(err) {
os.Mkdir(backupdir, os.ModePerm)
log.Println("Creating backup dir")
}
name := backupdir + util.EscapePath(b.AbsPath)
log.Println("Backing up to", name)
2019-12-21 21:35:09 +00:00
err := overwriteFile(name, encoding.Nop, func(file io.Writer) (e error) {
if len(b.lines) == 0 {
return
}
// end of line
eol := []byte{'\n'}
// write lines
if _, e = file.Write(b.lines[0].data); e != nil {
return
}
for _, l := range b.lines[1:] {
if _, e = file.Write(eol); e != nil {
return
}
if _, e = file.Write(l.data); e != nil {
return
}
}
return
})
return err
}
2019-12-22 00:55:23 +00:00
// RemoveBackup removes any backup file associated with this buffer
func (b *Buffer) RemoveBackup() {
2019-12-22 18:43:29 +00:00
if !b.Settings["backup"].(bool) || b.Path == "" {
2019-12-22 00:55:23 +00:00
return
}
f := config.ConfigDir + "/backups/" + util.EscapePath(b.AbsPath)
os.Remove(f)
}
2019-12-21 21:35:09 +00:00
// ApplyBackup applies the corresponding backup file to this buffer (if one exists)
2019-12-22 23:05:23 +00:00
// Returns true if a backup was applied
func (b *Buffer) ApplyBackup(fsize int64) bool {
if b.Settings["backup"].(bool) && len(b.Path) > 0 {
backupfile := config.ConfigDir + "/backups/" + util.EscapePath(b.AbsPath)
if info, err := os.Stat(backupfile); err == nil {
backup, err := os.Open(backupfile)
if err == nil {
defer backup.Close()
t := info.ModTime()
msg := fmt.Sprintf(backupMsg, t.Format("Mon Jan _2 at 15:04, 2006"))
choice := screen.TermPrompt(msg, []string{"r", "i", "recover", "ignore"}, true)
if choice%2 == 0 {
// recover
b.LineArray = NewLineArray(uint64(fsize), FFAuto, backup)
b.isModified = true
return true
} else if choice%2 == 1 {
// delete
os.Remove(backupfile)
}
}
}
}
return false
2019-12-21 21:35:09 +00:00
}