I have this sort of command in my vim settings which read the output of some external command (here is date) and then run another external app. My problem is I want to run it without leaving current UI (i.e. not opening another shell and press Enter to continue). I've tried to add <silent> but it didn't work as expected i.e. it leaves the current UI and I have to press Enter to get back to current document. Here is the map in my vimrc:

nnoremap <silent> sp :r! date "+\%T"<CR> :!echo $PWD/'%' > /dev/null<CR>

apparently, I also can not do something like nnoremap sp :silent exec "..." as well or I miss something in the syntax.

  • nnoremap <silent> sp :silent r! date "+\%T"<CR>:silent !echo $PWD/'%' > /dev/null<CR>
    – Maxim Kim
    Dec 2 '21 at 7:45
  • @MaximKim, it didn't work it still opens a new shell (UI) and this time I had to type :q! to quit vim
    – PiTao
    Dec 2 '21 at 7:49
  • well, it doesn't for me, but your environment might be different.
    – Maxim Kim
    Dec 2 '21 at 7:50
  • @MaximKim, Well I tried with vim -u barevimrc test.txt in which bare vimrc only has the nnoremap command and pretty default vim, it act differently in the seinse that doesn't throw new UI but kind of freeze without put the time as expected. I think it kinds of waits for second command or something. Have no clue what might be needed.
    – PiTao
    Dec 2 '21 at 7:57
  • @MaximKim, I solve it with adding :redraw!<CR> at the end of your command. It's not as sleek but much better flow than previous. You may write your solution as a post for me to approve if there is no better solution.
    – PiTao
    Dec 2 '21 at 8:29

I don't know if your end goal is to be able to chain any shell commands or not...

nnoremap <silent> sp :silent r! date "+\%T"<CR>:silent !echo $PWD/'%' > /dev/null<CR>:redraw!<CR>

Might do what you need.

You can also check :h system() or :h systemlist() functions to do the same:

nnoremap <silent> sp :call append('.', systemlist("date +%T")[0] . ' ' . systemlist("echo $PWD/" . expand('%'))[0])<CR>

You could also try vimscript only

" add to the next line
nnoremap <silent> sp :call append('.', printf("%s %s/%s", strftime("%H:%M:%S"), expand("$PWD"), expand("%")))<CR>
" replace current line
nnoremap <silent> sp :call setline('.', printf("%s %s/%s", strftime("%H:%M:%S"), expand("$PWD"), expand("%")))<CR>
" add to the end of current line
nnoremap <silent> sp :call setline('.', printf("%s %s %s/%s", getline('.'), strftime("%H:%M:%S"), expand("$PWD"), expand("%")))<CR>
" prepend current line
nnoremap <silent> sp :call setline('.', printf("%s %s/%s %s", strftime("%H:%M:%S"), expand("$PWD"), expand("%"), getline('.')))<CR>

And further simplify it with using :h expand() modifiers, for example:

nnoremap <silent> sp :call append('.', printf("%s %s", strftime("%H:%M:%S"), expand("%:p")))<CR>

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.