I have this command to open the pdf created by a latex document:

autocmd FileType tex nnoremap <leader>p :silent !open $(echo "%:p" \| sed s/.tex/.pdf/g)<CR>

which works, but I'd like to make 2 modifications:

  1. the command should be executed silently, without appearing on the command line;
  2. if there is no pdf document associated with the tex file, I'd like to display an error message saying something like 'No pdf file...'

how can I do this?


To execute the mapping silently, without the command appearing in the command-line, you should use the <silent> modifier to nnoremap.

To check that the file exists, you can use the filereadable() function.

You'll have to generate the PDF filename within Vim, but that shouldn't be hard, by using the additional :r modifier to remove the extension. You'll also need expand() to perform that expansion.

It's easier to use a separate function for the action, so you don't need to escape so many special characters.

One more note is that for a filetype mapping, you probably want to create a local mapping on the buffers with TeX files only. You might also want to use the <LocalLeader> prefix.

When running the external shell command, you'll want to use shellescape() to ensure the file name is safe and that you can properly handle paths with spaces.

Putting it all together:

function! OpenPdf() abort
  let fname = expand('%:p:r').'.pdf'
  if filereadable(fname)
    execute 'silent !open '.shellescape(fname, 1)
    echohl ErrorMsg
    echomsg 'No pdf file "'.fname.'"'
    echohl None

augroup tex_pdf
  au FileType tex nnoremap <buffer> <silent> <LocalLeader>p :<C-U>call OpenPdf()<CR>
augroup END
  • 1
    Thanks! This works great if the pdf file exists, but if it doesn't exist I don't just get the error message, I also get a line that says Error detected while processing function OpenPdf:, followed by the line on which the error occurs line 5:, then the error msg I actually want, and then a confirmation dialog Press ENTER or type command to continue. Here's a screenshot of what I see. How can I have the error message and nothing else?
    – noibe
    Apr 25 '20 at 14:34
  • @noibe Just drop the abort on the definition of the function. I'll update the answer to do that. I guess that's exactly what you specified, right?
    – filbranden
    Apr 25 '20 at 15:52
  • Even after dropping abort the output is the same, nothing's changed.
    – noibe
    Apr 25 '20 at 16:02
  • @noibe Ah, indeed! Let's use echohl instead. Updating again.
    – filbranden
    Apr 25 '20 at 16:05
  • 1
    Great, it works now!
    – noibe
    Apr 25 '20 at 16:23

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.