4

I have mapped a key shortcut to copy all lines to system clipboard, which is working fine

 nnoremap <localleader>o :silent %w !pbcopy<cr>

I would like to display the message as 'Copied' in the status bar. Reading other answers, I found echom or echo can be used to display the messages

I have tried below

 nnoremap <localleader>o :silent %w !pbcopy<cr>|:echom "Copied"
 nnoremap <localleader>o :silent %w !pbcopy<cr>|echom "Copied"

These lines are placed in .vimrc. It appears lines are getting copied to clipboard, but the message is not being displayed anywhere.

1) How do I display the message from mapped command?

2) On opening a file, I see the 'Copied' message, and a line that says 'Press Enter to continue'. It appears the mapping is being invoked on sourcing the vimrc. The message should not be echoed while sourcing the vimrc file. How do I stop this?

3
  • Does this answer your question? Concatenate vim command after :terminal. More specifically, the technique of wrapping the command on an :execute. But for this specific case, Martin's answer below is really good.
    – filbranden
    Commented Apr 24, 2020 at 14:32
  • 1
    @filbranden I disagree. It's not a duplicate. Someone trying the task I was trying to do, he won't/can't land to the linked question with any keyword that he can think of. What I'm trying to say is that, there is no way a searcher can hit that linked post. Hope i'm clear.
    – mtk
    Commented Apr 24, 2020 at 18:57
  • Yeah I definitely understand. That solution also works here, but I can see how it might be hard to get the context from the way that question is phrased...
    – filbranden
    Commented Apr 24, 2020 at 19:00

1 Answer 1

4

From :help :!:

A '|' in {cmd} is passed to the shell, you cannot use
it to append a Vim command.  See :bar.

An alternative would be to use the system() function, like so:

:call system('pbcopy', getline(1, '$'))

The second argument is the stdin; in this case all all lines (like the % range).

In a mapping, it might look like:

nnoremap <localleader>o :silent :call system('pbcopy', getline(1, '$')) \| :echom 'Copied'<CR>

Notice that I used \| here, since otherwise Vim will see use the | to seperate echom from nnoremap, which isn't what we want. See :help map-bar

Vim stores the command's exit code in v:shell_error, so you can improve a bit on always showing "copied" by checking the value of that; for example:

:nnoremap <localleader>o :silent :call system('pbcopy', getline(1, '$'))
          \ \| :echom (v:shell_error > 0 ? ('Error: ' . v:shell_error) : 'Copied')<CR>

You can also display the pbcopy output on error instead of just the status code, but that's left as an exercise for the reader ;-)

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.