reddit / emacs

Completion command for common file moving/copying commands

tdstoff7 · 2022-10-27 13:51
I'd like to have a completing-read type command that can perform commonly used file moving/copying operations. For example, I'm constantly syncing a couple of projects to a remote machine where they run. Currently I bind a key for each one to an `rsync` shell command call like so: (defun myprojectA-sync () (interactive) (shell-command (concat "rsync -a --progress --exclude-from='~/myprojectA/.syncignore' ~/myprojectA/ remotemachine1:~/myprojectA/ && echo 'Done.'")))) (map! :leader :desc "Sync my project A from local machine" "c b" #'myprojectA-sync) It'd be helpful to have one single command to call a completion list that can run the pre-defined file operations for Project A, B, C, etc. I don't see why they couldn't act on multiple machines (`remotemachine1`, `remotemachine2`, etc.) or use different commands (`mv`, `scp`, `rsync`, etc.). Is there some feature/package that already exists to do something like this? If not, does anyone have suggestions for a novice in elisp when it comes to writing the function? My thoughts so far were just a bunch of lists like (setq sync-names '("Sync project A" "Sync project B")) (setq sync-method '("rsync" "scp")) (setq sync-dest-dir '("remotemachine1:~/dir1" "remotemachine2:~/otherdir")) to call `shell-command` wrapped in `competing-read`.
arthurno1 · 2022-10-27 14:58
> It'd be helpful to have one single command to call a completion list that can run the pre-defined file operations for Project A, B, C, etc. > Is there some feature/package that already exists to do something like this? [Helm](https://github.com/emacs-helm/helm) for example can. If I C-x C-f for a file, I can mark several files and then just press a shortcut to delete, or move/copy those files to a different folder or some more. And for operations that don't have a shortcut, you can press TAB and then just type name of operation and Helm will do narrowing of candidates in the buffer with possible operations. [Looks like this](https://imgur.com/a/G0vS15i). Probably others like [Embark](https://github.com/oantolin/embark) can do something similar too. I don't see any packages for operations on remote stuff, but you can add your own action. About rsync, I understand you have your own, but I suggest checking [this](https://truongtx.me/tmtxt-dired-async.html) and [this](https://vxlabs.com/2018/03/30/asynchronous-rsync-with-emacs-dired-and-tramp/). They have done it quite nicely, so it might of interest to you :). I am not sure if later Emacs has got some built-in connection to rsync; I remember that RMS wanted 'c' in Dired on Emacs mailing list to use rsync, but no idea what they have done of it. I didn't follow the discussion. You might wish to check it, though.
tdstoff7 · 2022-10-27 15:14
Thanks for the reply, I hadn't seen those last two posts which are nice. Lately I've been using [Dirvish](https://github.com/alexluigit/dirvish) for those type of operations. But this isn't exactly what I was looking for. I may not have been totally clear. What I'm asking for would end up looking like a command-bookmarking system. You run the universal command, it pulls up a list which says "Sync project A to machine 1", "Sync project B to machine 2", etc., you pick one and then it runs the associated command. This way one wouldn't have to open the file in dired, mark all the files, open the destination in dired, and then run a command repeatedly.
arthurno1 · 2022-10-27 15:20
> What I'm asking for would end up looking like a command-bookmarking system. Yes, that is exactly how Helm and Embark work. > This way one wouldn't have to open the file in dired, mark all the files, open the destination in dired, and then run a command repeatedly. Yep, that is what I described with Helm. I press C-x C-f, which in my Emacs is bound to helm-find-files, it gives me a list of files. In that list I can move up and down and mark file(s) I wish with C-space. I can then press a key shortcut to execute an action on those files. No Dired involved. The difference is that Helm will exit, so I will have to repeat the process, for another action, while I believe Embark (or some other package) will stay alive and let you choose another action. In either case you will probably have to write your own actions, but that is about it, the rest works as you describe it. If you look at the screenshot, Helm already has "rsync" command, and you can edit the command before it is executed, so you can use it directly if you can live with one action at time approach.
big_lentil · 2022-10-27 18:58
I think your best bet here is just writing your own function that calls completing-read a few times. Like (defun some-stuff () (interactive) (let ((x (completing-read nil (list "foo" "bar"))) (y (completing-read nil (list "baz" "qux")))) (print (list x y)))) With such a function whatever completion framework you use like ido, helm, ivy etc. should just kick in automatically, and it seems better than doing something like writing helm specific code so you have multiple actions.
arthurno1 · 2022-10-27 19:38
He will only get some generic completion buffer that Helm does as replacement for standard completing-read, but Helm will have no idea that he.is doing file completion and thus will not offer file relaterade functions. I don't know how Embark works in that regard, but I guess He has to tell Embark too in some way that the He would like to see file related actions? Not to mention that hard coding completing read per every case he might have, sounds like a tedious way of using Emacs.
big_lentil · 2022-10-27 20:08
I am fairly sure that this is the simplest and most appropriate solution. I don't think actions are too relevant here. OP sounds like they actually want to hardcode project paths for convenience, and hardcoding remote machines is unavoidable, so actions would at most shave off one completing read call which doesn't seem relevant once project paths are hardcoded anyway.
c256 · 2022-10-28 06:54
You might be interested in dwim-shell-command: https://github.com/xenodium/dwim-shell-command
arthurno1 · 2022-10-28 13:59
> I don't think actions are too relevant here I think they are very relevant because Op can reuse already written funcionality available in Helm or Embark, and just plug-in the functionality that interests him. I think Embark is what he wants, but he could probably do with plain Dired as well judging from his description. > hardcoding remote machines is unavoidable, ( ... ) project paths are hardcoded anyway You would rather hardcode paths into function so you have to write new function for each set of paths or edit your function each time you change a path? Instead of just changing a variable value? You don't believe in separation between code and data? Observe that the variable value could be read from a dir-local file and have different paths for different projects, without much additional effort. > actions would at most shave off one completing read call which doesn't seem relevant I am not sure what you wanna "shave off" here :-). You could use combating read to choose to which machines to sink and you would still want to read those from a variable or a file? Maybe you don't want to sink to each machine every time? But honestly, after the clarification, he can also just use Dired, with dired-narrow from dired hacks, and write ordinary functions that act on marked files. I would still though put paths into a variable and use dir local variables when needed, or offer a completing read that reads those from a list or a configuration file.
big_lentil · 2022-10-28 16:18
I'm gonna be 100% honest with you chief I'd hardcode that shit without a thought. And I've hardcoded worse things 🗿 It's perfectly fine for personal use stuff that you do frequently
helm05 · 2022-10-31 15:59
Helm already has rsync integrated with helm-find-files (M-V from helm-find-files).
arthurno1 · 2022-10-31 16:00
Yes I know; I pointed it out already, check some other comment in this thread.
helm05 · 2022-10-31 16:20
Oh yes, I see it now, sorry!