Today I was browsing some of the plugins for blosxom (an excellent blogging tool BTW), and I encountered some Emacs code for preserving the last time modified timestamp on a file. This is especially useful for blosxom which uses this timestamp as the date to show when the post was made. So having Emacs automatically do this work for you is really neat. Each time I find such a nice little tool, I love Emacs even more ;)
Trying to hook-up that code in my Emacs I discovered it was referring to functions from Tramp, a package I never heard of before. After doing a quick search on Google, I discovered it's a mode very similar to ange-ftp, which allows the editing of remote files. However it works completely transparent over ssh too, really nice!
As with ange-ftp, you specify a remote file as
/user@machine:filename, if you want to login as a different user on the remote machine. File name and directory completion on the remote system works as expected, really cool!
The way this mode works is by uploading some simple programs on the remote system to allow the sending and receiving of files over ssh. You can also use scp as an alternative method of uploading and downloading files, which may be faster for larger files (I still need to investigate this option).
I'm quite impressed the way tramp works, and is definitely a much better alternative to starting a remote Emacs instance, especially if you're running an X11 version.
To use tramp, add the following to your
If you're using XEmacs, you will need to modify the
save-buffer-same-timestamp function from here to read like below instead. Upon successful completion,
t on XEmacs, and as a result
(= 0 t) throws an exception. The change below simply removes this check, as well as the enclosing
(defun save-buffer-same-timestamp (&optional args)
"Save the current buffer in visited file if modified. Versions are
controlled with ARGS as with `save-buffer'. The difference between
this command and save-timestamp is that this command saves the
modification time of the file from disk and resets it after the file
(message "save-buffer-same-timestamp %s" (buffer-file-name))
(let* ((buffer (current-buffer))
(file-name (if (tramp-tramp-file-p (buffer-file-name))
(file-attributes (file-attributes (buffer-file-name)))
(time-string (if file-attributes
(nth 5 file-attributes))))
(shell-cmd (if (tramp-tramp-file-p (buffer-file-name))
(format "touch -t %s %s" time-string file-name))
(revert-buffer nil t)))