1

This question already has an answer here:

I use VIM for writing in LaTeX and I would like to have a single key to compile the text and open a PDF of it. I have the line

map <F10> :!pdflatex % && start %.pdf 

in my vimrc. It seems to compile fine, but % represents the filename including the file extension, so the second command will not run (it is attempting to start filename.tex.pdf). Is there a way to call the filename without the file extension? For example, % returns filename.tex. Is there something that would return just filename?

Thanks so much for the help!

marked as duplicate by muru Feb 9 '16 at 4:54

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • You could try using a filename-modifier like :r or a combination of several like :t:r. :t should allow you to get the tail of the path, that is just the last element in the path (baz in /foo/bar/baz). And :r the root of the path, the path without the extension of the last item (/foo/bar/baz in /foo/bar/baz.c). So you could try: !pdflatex % && start %:r.pdf or !pdflatex % && start %:t:r.pdf – saginaw Feb 8 '16 at 21:45
  • @saginaw You should post that as an answer. – Karl Yngve Lervåg Feb 8 '16 at 22:04
  • 2
    @electriccello You might be interested in my LaTeX plugin vimtex. It provides a mapping (default \ll) that starts latexmk in continuous compilation mode, which IMHO is a very convenient way of working with LaTeX documents. – Karl Yngve Lervåg Feb 8 '16 at 22:06
  • I think the linked answer is better, but a quick modification to your current code is start $(basename % .tex).pdf – Steve Feb 9 '16 at 14:13
2

You could try using a filename-modifier like :r or a combination of several like :t:r.

:t should allow you to get the tail of the path, that is just the last element in the path (baz in /foo/bar/baz). And :r the root of the path, the path without the extension of the last item (/foo/bar/baz in /foo/bar/baz.c). So you could try one of the 2 following commands:

map <F10> :!pdflatex % && start %:r.pdf<CR> 
map <F10> :!pdflatex % && start %:t:r.pdf<CR>

If your filenames may contain special characters which you want to protect from the shell, you can use the function shellescape(). But in this case you would also probably have to:

  • use the function expand() to force the expansion of % and %:r before the call to shellescape(),

  • build the mapping with a concatenation of strings to force the evaluation of the functions before sending the command to the shell,

  • execute the result with the command :execute.

Maybe something like this:

map <F10> :execute '!pdflatex ' . shellescape(expand('%')) . ' && start ' . shellescape(expand('%:r') . '.pdf')<CR>

And if your filenames may contain special characters which you want to protect from Vim (like !, % and #, because they have a special meaning on Vim's command-line), you can pass a 2nd non-zero argument to the shellescape() function.

map <F10> :execute '!pdflatex ' . shellescape(expand('%'), 1) . ' && start ' . shellescape(expand('%:r') . '.pdf', 1)<CR>

For more information, see:

:help filename-modifiers
:help :execute
:help expand()
:help shellescape()

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