Documentation
¶
Overview ¶
Package backup keeps crash-recovery copies of edited files outside the directories being edited.
Emacs writes backups as file~ and autosaves as #file# beside the original. That clutters a working tree — every backup shows up as an untracked file in git status — so nem keeps everything in one state directory instead, with each file's absolute path mirrored beneath it:
/home/reza/p/main.go -> ~/.local/state/nem/backups/home/reza/p/main.go~ -> ~/.local/state/nem/autosave/home/reza/p/main.go#
On Windows the volume is mirrored as a directory of its own:
C:\Users\reza\p\main.go -> %LOCALAPPDATA%\nem\backups\C\Users\reza\p\main.go~
Mirroring the whole path rather than flattening it keeps the store browsable and means two files with the same base name in different projects cannot overwrite each other's backups.
The package's central invariant is that nothing is ever written outside the root. That is what keeps backups out of the user's tree, so it is enforced structurally — paths are mirrored from the cleaned absolute path, which cannot contain ".." — and checked again before any write.
Index ¶
- Constants
- Variables
- func DefaultRoot() (string, error)
- type Store
- func (s *Store) AutosaveNewer(file string) (bool, time.Time, error)
- func (s *Store) AutosavePath(file string) string
- func (s *Store) BackupPath(file string) string
- func (s *Store) Keep(kind, name string, content []byte) (string, error)
- func (s *Store) ReadAutosave(file string) ([]byte, error)
- func (s *Store) RemoveAutosave(file string) error
- func (s *Store) Root() string
- func (s *Store) WriteAutosave(file string, content []byte) error
- func (s *Store) WriteBackup(file string, content []byte) error
Constants ¶
const ( // Rescued holds the text of buffers with no file, written when nem was // ending without being able to ask about them: *scratch* typed into, when // the terminal closed. Rescued = "rescued" // Faults holds reports of nem's own bugs: what went wrong, and where. Faults = "faults" )
Kinds of file Keep writes, each in a directory of its own under the root.
Variables ¶
var ErrEscapesRoot = errors.New("backup: mirrored path escapes the store root")
ErrEscapesRoot reports a mirrored path that fell outside the store's root. Reaching it means the mirroring is broken; it exists so that a bug shows up as a refused write rather than as a file written into the user's project.
Functions ¶
func DefaultRoot ¶
DefaultRoot returns the state directory nem keeps its backups in: $XDG_STATE_HOME/nem, or ~/.local/state/nem when that is unset.
A relative XDG_STATE_HOME is ignored, as the XDG base directory specification requires — resolving it against the working directory would scatter state wherever nem happened to be started from.
Types ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store holds backups and autosaves beneath a single root directory.
A Store is cheap to construct and creates nothing; directories appear on the first write. It holds no mutable state, so it is safe to share.
func (*Store) AutosaveNewer ¶
AutosaveNewer reports whether file has an autosave holding work the saved file does not, along with the autosave's modification time.
A missing autosave is (false, zero, nil). An autosave whose file has since been deleted counts as newer: that is the case where recovery matters most.
func (*Store) AutosavePath ¶
AutosavePath returns where file's autosave is kept.
func (*Store) BackupPath ¶
BackupPath returns where file's backup is kept.
func (*Store) Keep ¶ added in v0.10.0
Keep writes content to a new file called name in the store's directory for kind, and returns its path. A name already taken gets a number after it: nothing kept is ever written over. Characters that could not be part of a file name, or could climb out of the directory, are replaced.
func (*Store) ReadAutosave ¶
ReadAutosave returns file's autosaved contents. A missing autosave wraps fs.ErrNotExist, so callers can distinguish it with errors.Is.
func (*Store) RemoveAutosave ¶
RemoveAutosave discards file's autosave.
A missing autosave is not an error: this is called after every successful save, and most saves have no autosave to discard. Reporting one would turn an ordinary save into a failure in the echo area.
func (*Store) WriteAutosave ¶
WriteAutosave stores the current, unsaved contents of file.