How to have Emacs save file at multiple locations?
Is there an easy way to have emacs save current buffer in two locations? I could in the 'after-save-hook' programmatically copy the current file to a second location, but writing lisp code for that might take some time.
For those that are curious why I want this: I want the changes I make to my JSP immediately be deployed in tomcat's webapps/myapp directory.
So everytime I save a JSP file I want it saved in both my current version controlled source location as well as in the directory where my Tomcat application is deployed.
I can't use symlinks because I use a windows machine and the destination location is 开发者_开发技巧a directory in Linux box that is exported through Samba.
Something like this should work:
(add-hook 'local-write-file-hooks 'my-save-hook)
(defun my-save-hook ()
"write the file in two places"
(let ((orig (buffer-file-name)))
(write-file (concat "/some/other/path" (file-name-nondirectory orig)) nil)
(write-file orig nil)))
For more on local-write-file-hooks
see this answer.
Obviously customize the file name created in the first call to 'write-file
.
Given the problem you are trying to solve is to deploy changes immediately, I would suggest writing a script (in your case a batch file) that invokes rsync
with the appropriate options. You could either run this in the after-save-hook
(which is probably overkill) or assign a hotkey to run it for you when you have made a set of changes that you want to test. Something like:
(global-set-key 'f11 (shell-command "c:/dev/deploy_to_test.bat"))
where the script would look like this:
rsync -avz --del c:/dev/mywebapp z:/srv/tomcat/mywebapp
This is probably better than saving the same file in multiple places, as it ensures the deployment directory always matches what you have in your source repository.
Probably a more general solution is a hook similar to this Gist: https://gist.github.com/howardabrams/67d60458858f407a13bd :
(defun ha/folder-action-save-hook ()
"A file save hook that will look for a script in the same directory, called .on-save. It will then execute that script asynchronously."
(let* ((filename (buffer-file-name))
(dir (file-name-directory filename))
(script (concat dir ".on-save"))
(cmd (concat script " " filename)))
(write-file filename nil)
(when (file-exists-p script)
(async-shell-command cmd))))
(add-hook 'local-write-file-hooks 'ha/folder-action-save-hook)
Essentially, on any file save, if the directory where the file is being saved has an executable script called .on-save
, it will execute that script with the name of the file being saved.
This allows you to specify an rsync
command (or one or more other commands) on a per-directory basis. Granted, this could be expanded to walk up a directory tree looking for this sort of pattern.
精彩评论