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

4
  • 2
    Have you tried replacing | with <bar>?
    – statox
    May 2, 2016 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, 2016 at 13:06
  • 2
    The second pipe between 0read and the bang should also be removed. May 2, 2016 at 13:07
  • @user9433424 that was the issue, thanks.
    – meain
    May 2, 2016 at 16:48

1 Answer 1

7

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'.

3
  • 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, 2016 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. May 2, 2016 at 16:54
  • 2
    @meain in addition to what user9433424 says, also see :h special-buffers (in particular the scratch buffer)
    – muru
    May 2, 2016 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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