Text Editor Saving Routines

Joe Gregorio

I have, for reasons that will become obvious in a week or so, been looking at text editors and what happens when you save a file. For example, if we are editing the file filename.txt, different things will happen when you save the file depending on which editor you are using. VIM is fairly straight forward in that it renames the original file to filename.txt~, writes the modified contents to filename.txt, and then if that is successful deletes filename.txt~.

Emacs does roughly the same thing as VIM, but by default doesn't clean up the filename.txt~ file.

Eclipse is by far the simplest, truncating filename.txt to a length of 0 and then writing the new contents.

Gedit is by far the most byzantine, first it writes the contents of the modified buffer to a hidden file .gedit-save-NNNN, then it renames the original file to filename.txt~, then renames .gedit-save-NNN to filename.txt and finally deletes filename.txt~. What makes Gedit really stand out from other text editors is that if for some reason the filesystem doesn't support 'rename' then Gedit refuses to save the file, as opposed to VIM and Emacs which will just write new contents to filename.txt. As you can imagine that's controversial behavior and there's a long and painful bug thread on it, which is filled with all the painful things you'd expect it to be filled with, like claiming it's not a bug, or that the bug is in some other piece of software, or that it's not a problem under 'normal' usage, or that any other way of saving files is unsafe. Like I said, painful.

But I'm willing to believe there are even more complex cases, and if you know of an editor that has an even more convoluted save routine I'd be glad to hear about it.

There's actually more to emacs (should be no surprise).

First, emacs will keep automatic backups, like #filename.txt#, while a file is in the process of being edited (every so-many keystrokes); these go away when a file is finally successfully saved. If it can't create the auto-backup, it will warn you but will still allow you to proceed.

When saving, to create the backup file emacs can use two methods: RENAME filename.txt to filename.txt~, or COPY filename.txt to filename.txt~. It will generally try the rename approach first, if possible, unless the original file is a link or the file ownership permissions are mismatched, or the user has customized emacs to use the copying approach first.

Also emacs can perform version controlled backups, where it creates filename.txt.~1~, filename.txt.~2~, filename.txt.~3~, etc.

Another related thing that emacs does is to use lock files. This prevents (or at least alerts the user) having two different emacs processes editing the same file simultaneously and potentially overwriting the changes of the other. This feature alone has saved me countless times, as I tend to have dozens of terminals and screen sessions and ssh's going at once.

Posted by Deron Meranda on 2009-01-05

Put:


 set backup

...in your ~/.vimrc ... to not do the delete part (ie. dtrt. :).

I'm actually surprised that (x)emacs doesn't do the same thing as gedit, as that makes the window where you have no filename.txt much smaller. Although obviously breaking when rename doesn't work is wrong (so you can't edit symlinks in gedit?)

Posted by James Antill on 2009-01-05

jEdit lets you opt in to something like vim/emacs disk writing behavior. Its label for the option, "Two-stage save (safer but resets file owner on Unix)", does raise an interesting point about the RENAME+CREATE approach.

It seems that COPY+OVERWRITE would be safer re. preservation of file permissions and ownership. However if there was an undetected write-failure during the copy operation, the original may be truncated without a usable backup. Also, COPY+OVERWRITE would require more bytes to be written compared to RENAME+CREATE. I guess that's why emacs only falls back to the former if the latter will result in changed ownership/permissions.

Posted by Paul Annesley on 2009-01-05

Back in the days before git or BitKeeper, a neat trick (§1.6) in Linux development was used - create your scratch copy of the tree using cp -av --link, then diff becomes much faster. This works because patch uses RENAME+CREATE, which doesn't change the hard-linked file, which COPY+OVERWRITE does.

Posted by James on 2009-01-05

Textmate is also quite interesting. You can use it for editing a form in Safari as I'm doing it right now. The file I'm editing for this comment is in located in /private/var/folders/F8/F8wKkW36HM424d8akEXcdE+++TI/-Tmp-/ name of the file is "Joe\ Gregorio\ \|\ BitWorking\ \|\ Text\ Editor\ Saving\ Routines.safari" Then when I save it, the content of the form is updated. When I close it, the file is destroyed and I'm back to the form. In Normal editing mode, it doesn't seem to create a temporary file or I haven't found yet where. :)

Posted by karl on 2009-01-06

You are right that at the file system level, Eclipse just overwrites the file contents. However, internally it keeps a local history of file contents for all changed files. If anything goes wrong at the file system level, your work won't be lost - you can use "Restore from Local History..." or "Replace With > History..." to get it back. The local history settings can be changed using Windows > Preferences > General > Workspace > Local History.

Posted by Boris Bokowski on 2009-01-06

BBEdit on the Mac has its own way of keeping backups, but you probably don't care about platform-specific files. BTW, for FLOSS, "joe" keeps file~.txt by default. I turn off that option as soon as I install it.

Posted by Paul Hoffman on 2009-01-07

James,

cp -av --link

That's just sick. I also just love the implicit implication in that FAQ that you would obviously know your text editors file saving algorithm.

Posted by Joe on 2009-01-08

comments powered by Disqus