1

I have used the moreutils suite a few times and I find it makes you think further about base utilities and is insightful(and fun). For instance, vipe allows running an editor - like vim - in the middle of a pipeline and editing the data before continuing the execution1. For instance:

function refcheck_vipe() { echo -n "$@ documentation last udate: "; links -dump "http://www.gnu.org/software/$@/manual"| vipe | grep 'last updated' | vipe | cut -d ' ' -f 7,8,9 | vipe ; }
# refcheck_vipe grep

Every time(3) vipe is arbitrarily placed in the pipeline, and therefore called, you are presented with the data in vim, and once you quit, the execution continues. So here you'll get the webpage, the matched line and finally the isolated string. Maybe what is missing is that I keep the used buffers along the way to compare the contents in some cases...


I did not know you could multiplex the layout of the buffers in vim(!). Now I wonder if I were to launch my command on the vim cli, could there be a way to redirect every vipe execution "step" to a different buffer. And allow the tmp file to continue displaying the contents in some way after I quit. Indeed, you must do :q for the execution to continue until the next "step" so I don't know how to reconcile what I've just said with this. On the other hand I note that I can do :split new then :r! ls and the output of this goes into that.


To summarize and add context, I'm thinking about something like this:

command1 | vipe1 | command2 | vipe2 | command n | vipe n

would be wrapped by the answer to produce this in vim(the vipe part):
-------------------------
|       |       |       |           A buffer would open to the right side
| vipe  | vipe  | vipe  |           for every vipe command in the pipeline.
| step1 | step..| step n|           
|       |       |       |
|       |       |       |
-------------------------
|           |           |           Bottom left you see a "file manager".
|find . | \ | whatever  |           Its contents could be refreshed, from
|vidir -    |           |           time to time.
-------------------------
:cli

I know vim is not a window manager or multiplexer. The goal here is showcasing the processing of data in shell commands, while improving my vim skills2. The focus is vim, but considering vipe reads the EDITOR variable, I would also read with interest a solution leveraging emacs.

So is there some alias/function/setup I could implement to accomplish what I have described(allowing comparison of the output I get in a sort of integrated way by adding buffers visually to the right side in the editor, for every vipe command in the pipeline)?


1. If I string together some commands with regular expressions and it doesn't work(often the case), I'll backtrack, removing commands and simplifying expressions in the pipeline until I can isolate the issue. So vipe can assist in some cases.

2. As well as coping with the scenario where I have to use a system and Openbox or i3 is not present!!

[..] Not referenced but making an appearance in the code sample, vidir.

  • vipe calls $EDITOR and waits until it ends. You need either replace vipe or write a custom $EDITOR script which opens a tab in an existing vim and waits until the temporary file is changed. – jofel Aug 8 '14 at 10:53
  • @jofel Thank you. So you're saying a part of it is vim invocation and redirection. I can see that vipe is a perl script and I get a general idea looking at it but that's it. So a subset question becomes how do you interrupt arbitrarily the execution of a pipeline of commands in the shell and send the output to the editor and wait for it to exit, i.e. what you're saying. And how to manipulate the layout of the editor accordingly... – user44370 Aug 8 '14 at 11:13
1

vipe uses temporary files (for me in /tmp) to pass and receive the pipe contents to / from Vim. Because of the pipeline, previous vipe invocations cannot be re-edited anymore; they've already been re-read by vipe and sent along the pipeline. So, it should be sufficient to save the previous vipe temp file (as the original one is removed by vipe), and re-open that one in the next Vim invocation from vipe.

The following autocmds do that for a single previous pipeline step. As I couldn't recognize any pattern in the vipe temp files, this broadly handles all files opened in /tmp; it would be better if vipe is reconfigured to use a separate directory or unique naming scheme:

Sketch

autocmd BufWritePost /tmp/* silent! bdelete ~/.previous-vipe | keepalt write! ~/.previous-vipe
autocmd BufRead /tmp/* pedit ~/.previous-vipe
  • Thank you! I put this in .vimrc. Surely using automcmd is part of the solution. When you say a single step, you mean command vipe command vipe? It splits once, but I don't ever get to see data in the top buffer. It is empty. But I understand the concept. Also, do you know indeed of a way to specify where vim should create its tmp files? – user44370 Aug 8 '14 at 12:34
  • The temp file is created by vipe (using something like mktemp()), and that filename is passed to Vim, I suppose. – Ingo Karkat Aug 8 '14 at 12:40
  • 1
    You're right, it's just a concept, not a complete solution. With more than two invocations in the pipeline, that is probably much more complex. I wonder whether it isn't sufficient to just manually :write! save-pipe, followed by :pedit save-pipe whenever you need it?! – Ingo Karkat Aug 8 '14 at 12:42
  • Your remarks are very insightful because yes that is sufficient and works. I have to close the top buffer each time, then I repeat the write, etc. so I always see the last step and the current. Surely this can go further and show all the steps from the beginning with different names for the tmp files, something? I'll think about it... Thank you! – user44370 Aug 8 '14 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy