reddit / emacs

Command to send an Ex command to an external process

ir210 · 2022-01-24 15:21
As you've already known the Evil implementation of Ex commands is not complete. There are a lot of things that it doesn't support. To work around this limitation I created an Elisp command that sends an Ex command to Vim and gets the output back in Emacs. [https://gist.github.com/ir210/18ec921312575cc2f35153c607abf5fd](https://gist.github.com/ir210/18ec921312575cc2f35153c607abf5fd) It's not a package since most likely you have to adjust it to fit your system and I don't have the capability to make it works for everyone. Also, it has a major drawback that I will mention at the end. When you call this command it asks for an input command exactly like Evil. The only difference is that the evaluation of the command is done by vim. This has both advantages and disadvantages. Advantages: * It understands more ex commands than evil. * It has pretty much the same experience as `evil-ex`. * Editing the last search pattern from `q/` will make the pattern available in vim too. * The z register set by vim is available to evil. * The address `.`, \``'<`, `'>`, `\/` and `\?` work. * The last search pattern is available to vim. * The message or error from vim is shown in the minibuffer. * Vim knows the current emacs cursor position. * The `"z` register is available to emacs after executing this ex command. Disadvantages: * The preview might sometimes be wrong. This is because the preview only understands the `evil-ex` commands. * Any interactive command will obviously not work. * Vim's regex is not exactly the same as Emacs's. * No sharing of all registers but `"/`, `"<` and `">`. * Evil's extension such as `\,()` obviously doesn't work. * Executing the command from the command list buffer `q:` will not call this method. But C-f in the minibuffer works. * The tab character size is according to vim's settings. * Slow for large files since it uses `(replace-buffer-contents)`. That last disadvantage is the main reason why I posted it here. It is very slow for big files. It is currently using `(replace-buffer-contents)`. Is there a better method to copy a large chunk of text into the current buffer while still preserving a lot of things that don't change?
tom_dl · 2022-01-24 23:44
Awesome work! Looks very interesting. I'm not sure I can help you with your issue, but may I ask, which missing ex features do you most miss from vim? I work on evil and I'm planning to expand ex at some point. Any things you'd especially like to see?
leungbk · 2022-01-25 05:17
It would be nice if `|` worked as a command separator (cf. `:help :bar` in vim). There's an existing issue about this ([https://github.com/emacs-evil/evil/issues/584](https://github.com/emacs-evil/evil/issues/584)). I tried looking into the Vim codebase, but the Ex grammar isn't formally specified, and the Vim core is fairly unpleasant to read.
ir210 · 2022-01-25 05:31
What I find very helpful is the ability to chain more than one command with the pipe operator. I believe evil has an issue entry for that in github. Vim's regex has a couple of interesting features but I believe the one that evil uses is enough especially with the \,() extension.
tom_dl · 2022-02-07 23:18
So it turns out adding an unambiguous bar expression separator is a lot of work. The ex parser needs to know whether a bar at a given location belongs to an individual command or to the command line as a separator. Work I may do one day. In the meantime, I've added `||` as a separator, but made it a customizable variable. You can customize it to `|` but you'll lose the ability to use that as an arg to any ex command (e.g alternation in :substitute). If you want to try it, check out the branch: https://github.com/emacs-evil/evil/tree/ex-bar and let me know any feedback. If it works as expected, it'll justify the work of implementing the single bar properly.
tom_dl · 2022-02-07 23:19
Check my comment to u/ir210 for a first stab at an (inferior) approach. Feedback very welcome!