3

I know I can edit a remote file over SSH by opening a file path of the form /ssh:user@host:/path/to/file.

However, right now I'm working on a kernel module in a Linux VM. Since my kernel module might brick/corrupt my VM (if I make a stupid mistake), I'm worried about losing my remote source files for the kernel module.

I'd like Emacs to save a local copy of the file I'm editing, just to make sure I don't lose my latest work if I ruin my VM*. Ideally the local copy won't have name mangling applied (i.e. appending ~ to the name, like Emacs does normally for backup files).

*Yes, I'm using source control, but I don't want to have commit and push for every single change. I'm rather new to kernel module hacking, so I'll be making lots of little edits and testing my module a lot as I go. Constantly committing and pushing half-baked changes is far from ideal.

Is there an easy way to get Emacs to save a local copy of a file when editing a remote file? I'm looking at the docs (Remote Files, Auto Save Files, Backup Files, Singled or Numbered Backups) and can't see how do to this.

2
  • 1
    I guess the question should be: "How can I get emacs...". You might have more luck: emacs.stackexchange.com
    – Dror
    Apr 11, 2015 at 19:38
  • 1
    It looks like your answer is a few paragraphs down on the Emacs wiki Backup Directory page -- see the variable tramp-backup-directory-alist -- emacswiki.org/emacs/BackupDirectory
    – lawlist
    Apr 12, 2015 at 3:17

3 Answers 3

1

I don't really like the backup solution as it doesn't depends only on you. What I've made is to have a hook before saving and, in case the file is under a directory I want to handle specifically, I make a copy.

I put a simple example here:

(defun my-copy-file ()
  (interactive)
  (cond ((equal "home.org" (file-name-nondirectory (buffer-file-name)))
         (write-region (point-min) (point-max)
                       (concat "~/org/" (file-name-nondirectory (buffer-file-name)))))))

(add-hook 'before-save-hook #'my-copy-file)

To check for directory components Emacs docs.; you may use file-name-directory and variants.

Here you may have a simple function to mirror remote files locally. You have to create the directories beforehand however (although having a code repository that shouldn't be a problem unless it is a new directory.)

;; /plink:[email protected]:/the/remote/path/finename.cc
(defun my-mirror-remote-file ()
  (interactive)
  ;; first search the at sign `@' in the buffer file name
  (let* ((file_name (buffer-file-name))
         (atpos (string-match "@" file_name)))
    ;; if there is an at sign in the file name, we assume it is a remote file
    (cond (atpos
       ;; we look for the second colon, which is after the host part
       ;; and we get the diretory and file name
       (let* ((hoston (substring file_name atpos))
              (colonpos (string-match ":" hoston)))
         ;; and we write the file locally (it will NOT create the dir though)
         (write-region (point-min) (point-max)
                       (concat "~" (substring hoston (+ colonpos 1)))))))))
1

shadowfile.el would do it for you. Unfortunately, it still lives in the ange-ftp world. Porting it to understand Tramp is on my todo list, but I haven't done yet.

0

I am not familiar with emacs, but I can think of several solutions:

1) Work in a NAS folder that is actually a file system that is not on the machine you are running to begin with, but it is rather an NFS of CIFS share. Not sure how well will this work given your VM hoses up

2) Create a custom macro that will save the file locally and then invoke an scp command to push the changed file elsewhere

3) Edit the files on the machine that runs the VM and have it automatically push any changes to the VM. You could run something like below in a second terminal window

FILE=thenameofthefileIwanttoeditandsend
inotifywait -E CLOSE_WRITE $FILE && scp -p $FILE user@host:/target/folder/

Above would good for one time execution. You could also make an endless loop:

FILE=thenameofthefileIwanttoeditandsend
while true; do inotifywait -E CLOSE_WRITE $FILE && scp -p $FILE user@host:/target/folder/; done

Note: This assumes you configure passwordless ssh key authentication so scp does not prompt for credentials.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .