3

I wanted to have the output of a(any) shell command to open up in a vim split. Did a bit of research and found out that the command to do so was:

:new | 0read | ! ls                       ---  (or something of this form)

But the issue I am facing is that when I try to bind it to something like this :

nmap ,s :new | 0read | !            --- (without a specific command at the end)

Also tried with a specific command at the end and same result

it is showing up this error everytime I open up vim:

line  277:
E32: No file name
Press ENTER or type command to continue

Edit : It was not exactly an issue with binding, the command had a small issue.

Use this command:

nmap ,s :new | 0read !


Btw the accepted answer has a function implementation which is much better than this simple mapping

  • 2
    Have you tried replacing | with <bar>? – statox May 2 '16 at 13:05
  • 2
    That, or escape the pipe character, otherwise Vim believes you want to have 3 commands on a single line - try \| – VanLaser May 2 '16 at 13:06
  • 2
    The second pipe between 0read and the bang should also be removed. – user9433424 May 2 '16 at 13:07
  • @user9433424 that was the issue, thanks. – meain May 2 '16 at 16:48
6

To open the output of a command in a new window:

:new +0r!ls

Note the syntax of new:

:[N]new [++opt] [+cmd]                                  :new

And for +cmd:

                                                        +cmd [+cmd]
The [+cmd] argument can be used to position the cursor in the newly opened
file, or execute any other command:
        +               Start at the last line.
        +{num}          Start at line {num}.
        +/{pat}         Start at first line containing {pat}.
        +{command}      Execute {command} after opening the new file.
                        {command} is any Ex command.
To include a white space in the {pat} or {command}, precede it with a
backslash.  Double the number of backslashes. 
        :edit  +/The\ book           file
        :edit  +/dir\ dirname\\      file
        :edit  +set\ dir=c:\\\\temp  file
Note that in the last example the number of backslashes is halved twice: Once
for the "+cmd" argument and once for the ":set" command.

So, to run a command in a new window, you can just + with :new, the command being 0r!ls. This can quickly become a pain with complex commands, though.

In an map, leaving the command to you to enter:

nnoremap ,s :new +0r!

You could also write a function to read in the command:

function! SplitRunCommand()
    call inputsave()
    let l:cmd = input('Command: ')
    new
    call append(0, systemlist(l:cmd))
    call inputrestore()
endfunction

nnoremap ,s :call SplitRunCommand()<cr>

Now, when you type ,s you'll be prompted:

Command:

Then, say:

Command: date '+%y%m%d'

And you will have a new window with the output of date '+%y%m%d'.

  • Thanks a lot for the explanation and especially for the function. Btw I have set the buffers to ask whether to save or not on close by default. How to change this behaviour for this specific split? – meain May 2 '16 at 16:37
  • 2
    @meain In your temporary split, you could set the local-buffer value of the buftype option to nofile. It could give something like: nnoremap ,s :new \| setlocal buftype=nofile \| 0r! Or you could add setlocal buftype=nofile inside the SplitRunCommand() function, just after the new command. – user9433424 May 2 '16 at 16:54
  • 2
    @meain in addition to what user9433424 says, also see :h special-buffers (in particular the scratch buffer) – muru May 2 '16 at 17:10

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.