What is your favorite vi or vim command trick?
Disclaimer: I usually edit .tex
files in Vim, but I don't use the Vim-LaTeX
suite.
I wouldn't say the following suggestions are tricks per se - they are provided by third-party plugins - but they actually help me with my usual TeX workflow:
snipMate
Created by Michael Sanders
From the manual:
snipMate.vim
aims to be an unobtrusive, concisevim
script that implements some of TextMate's snippets features in Vim. A snippet is a piece of often-typed text that you can insert into your document using a trigger word followed by a<tab>
.
snipMate
helps me a lot, mainly because it offers snippets for several languages out of the box, including TeX. For example, when editing a file mydoc.tex
, typing
begin<tab>
will expand to an environment block of the form
\begin{env}
\end{env}
with the cursor selecting the word env
. After typing the environment name, hitting <tab>
again will take the cursor to
\begin{env}
|
\end{env}
for me to type. The snippets list for TeX is not that big, but the plugin seems to have a fairly easy syntax for us to create custom snippets. Here's the code used to create the above snippet:
# \begin{}...\end{}
snippet begin
\begin{${1:env}}
${2}
\end{$1}
So far, so good.
Tabular
Created by Matt Wozniski
From the manual: Sometimes, it's useful to line up text. Naturally, it's nicer to have the computer do this for you, since aligning things by hand quickly becomes unpleasant. While there are other plugins for aligning text, the ones I've tried are either impossibly difficult to understand and use, or too simplistic to handle complicated tasks. This plugin aims to make the easy things easy and the hard things possible, without providing an unnecessarily obtuse interface. It's still a work in progress, and criticisms are welcome.
Tabular
helps me a lot when I'm trying to add elements in a tabular
environment. It organizes the columns in a human-readable format. Let's suppose we have the following mess entries:
\begin{tabular}{lll}
Hello world & I love ducks & Vim rocks\\
Think of a very long entry & How was your day & Quack!
\end{tabular}
It's quite confusing, but Tabular
can help us. I usually enter in Visual
mode, select the two rows and then issue
:'<,'>Tabularize /&
and we are done. The new rows now look like
\begin{tabular}{lll}
Hello world & I love ducks & Vim rocks\\
Think of a very long entry & How was your day & Quack!
\end{tabular}
I can also apply :Tabularize /&
, but I prefer to delimit my scope. A similar plugin Align
can also be used for this purpose, see my answer to Which text editor to make tables scripts human readable.
surround
Created by Tim Pope
From the manual:
Surround.vim
is all about "surroundings": parentheses, brackets, quotes, XML tags, and more. The plugin provides mappings to easily delete, change and add such surroundings in pairs.
I usually use this plugin when editing source code from other languages. Let's suppose I have the following text enclosed between double quotes:
"Hello world"
By calling cs"'
, the double quotes are automatically replaced by single quotes. I decided to make a different use of surround
, so I took an example from the documentation and adapted to my TeX needs. First of all, I have the following line in my .vimrc
:
autocmd FileType tex let b:surround_45 = "``\r''"
Note that 45
is the ASCII code of -
. Now I can simply call cs"-
and my text
"Hello world"
becomes
``Hello world''
The documentation has a few examples on TeX snippets.
For those who want to try the plugins I listed above, I highly recommend the use of the awesome pathogen
plugin created by Tim Pope.
From the manual: Manage your
runtimepath
with ease. In practical terms,pathogen.vim
makes it super easy to install plugins and runtime files in their own private directories.
Hope it helps. :)
I use the vim-latex
suite, and absolutely love it. However, I've found the following tweaks quite useful to help me compile my documents.
(These commands will be most useful to Linux users)
I like to 'toggle' between seeing the compiler output and not. With the setup below, I simply press t which toggles between 'silent' and 'verbose' mode
I like to be able to choose which compile method I use- either
latex
,pdflatex
, etc. I can use- f just to
latex
the main file - F to use
latex->dvips->ps2pdf
the main file - P to use
pdflatex
on the main file - F6 to view the main
pdf
file (callingevince
) - F4 to view the main
dvi
file (callingxdvi
)
- f just to
Choosing the main file with the
vim-latex
suite requires creation of a separate file in the current working directory. The script belowgrep
s the current file and searches for%*** mainfilename.tex
; if it doesn't find any, then the current file is the main file, if it does find one, then the matched expression is the main file
~/.vim/after/ftplugin/tex.vim
" by default make the compile verbose
let g:Myvar="noisy"
" function to compile the mainfile, either verbosely or not
function! CompileMainfile()
if g:Myvar=="noisy"
:! MakepdfMainfile.sh %
else
"echo "quiet"
:! MakepdfMainfile.sh % noshow
endif
endfunction
" latex => dvips => ps2pdf
function! DvipsMainfile()
if g:Myvar=="noisy"
:! compileMainfile.sh -d %
else
"echo "quiet"
:! compileMainfile.sh -dq %
endif
endfunction
" pdflatex
function! PdflatexMainfile()
if g:Myvar=="noisy"
:! compileMainfile.sh -p %
else
"echo "quiet"
:! compileMainfile.sh -pq %
endif
endfunction
" just latex
function! Justlatex()
if g:Myvar=="noisy"
:! compileMainfile.sh %
else
"echo "quiet"
:! compileMainfile.sh -q %
endif
endfunction
" function to toggle between Noisy and Quiet
function! ToggleNQ()
if g:Myvar=="noisy"
let g:Myvar="quiet"
echo "Silent mode ON"
else
let g:Myvar="noisy"
echo "Silent mode OFF"
endif
endfunction
:map f :w<CR>:call Justlatex()<CR>
:map F :w<CR>:call DvipsMainfile()<CR>
:map P :w<CR>:call PdflatexMainfile()<CR>
:map <F4> :! viewMainDVI.sh %<CR>
:map <F6> :! viewMainPDF.sh %<CR>
:map t :call ToggleNQ() <CR>
/usr/local/bin/compileMainfile.sh
#! /bin/bash
#
# compileMainfile.sh
#
# December 2011
#
# Purpose: compile a .tex file either using latex, pdflatex, or
# latex=> dvips=> ps2pdf, in silent mode or verbose mode
# examples
# compileMainfile myfile.tex # just latex myfile
# compileMainfile -d myfile.tex # latex => dvips => ps2pdf
# compileMainfile -p myfile.tex # pdflatex myfile
#
# add the -q flag for SILENT (or quiet) mode
# compileMainfile -q myfile.tex
# compileMainfile -qd myfile.tex
# compileMainfile -qp myfile.tex
#
# See pgs 249 & 250 of BASH COOKBOOK for examples of getopts- really useful!
# argument check
ERROR="Too few arguments : no file name specified"
[[ $# -eq 0 ]] && echo $ERROR && exit # no args? ... print error and exit
# define functions
function makepdf ()
{
echo "======================================="
echo "Main file is $mainFile.tex"
echo "======================================="
if [ $quiet -eq 0 ]
then
echo "VERBOSE mode on"
# latex mainFile.tex
[[ $uselatex -eq 1 ]] && [[ $convertdvips -ne 1 ]] && latex $mainFile
# latex => dvips => ps2pdf mainFile.tex
[[ $convertdvips -eq 1 ]] && makepdf.sh $mainFile 1 && echo "DVIPS"
# pdflatex
[[ $usepdflatex -eq 1 ]] && pdflatex $mainFile && echo "PDFLATEX"
egrep 'undefined' $mainFile.log
egrep 'multiply-defined' $mainFile.log
egrep '\\end occurred when \\iftrue' $mainFile.log
else
echo "SILENT mode on"
if [ $convertdvips -eq 1 ]
then
# latex => dvips => ps2pdf mainFile.tex
echo "DVIPS"
nohup makepdf.sh $mainFile 1 &
elif [ $uselatex -eq 1 ]
then
# latex mainFile.tex
echo "just LaTeX"
nohup latex $mainFile &
elif [ $usepdflatex -eq 1 ]
then
# pdflatex
echo "PDFlatex"
nohup pdflatex $mainFile &
fi
fi
}
# set default values of flags
quiet=0
uselatex=1
usepdflatex=0
convertdvips=0
# check flags, and change defaults appropriately
while getopts 'abpqd' OPTION
do
case $OPTION in
q) quiet=1
echo "Silent mode ON"
;;
p) usepdflatex=1
uselatex=0
;;
d) convertdvips=1
;;
?) printf "Usage: %s: [-a] [-b value] args\n" $(basename $0) >&2
exit 2
;;
esac
done
shift $(($OPTIND - 1))
# check we haven't called with -dp
# which would mean dvips and pdflatex
[[ $usepdflatex -eq 1 ]] && [[ $convertdvips -eq 1 ]] && echo "Option clash: cannot be called with -dp" && exit
# name of MAINFILE
mainFile=$1
# incase we're compiling from within the CHAPTER file
set `grep -F %*** $1 | tr -d "%*" `""
dummy=$1
# delete the file extension
mainFile=${mainFile/%.tex/}
dummy=${dummy/\.*/}
# check the length of the dummy string, if it's 0 then latex the current file
# otherwise latex the referenced latex file
if [ $dummy ]
then
mainFile=$dummy
fi
# call the makepdf function
makepdf
exit
/usr/local/bin/MakepdfMainfile.sh
#! /bin/bash
#
# December 2011
#
# Purpose: compile latex->dvips->ps2pdf
# either silently or verbosely
#
# Options: noshow
#
# examples: MakepdfMainfile.sh myfile.tex noshow # silent mode
# MakepdfMainfile.sh myfile.tex # verbose mode
# argument check
ERROR="Too few arguments : no file name specified"
[[ $# -eq 0 ]] && echo $ERROR && exit # no args? ... print error and exit
# assume VERBOSE mode by default
noshow=0
[[ $# -eq 2 ]] && [[ $2 == "noshow" ]] && noshow=1 # otherwise turn on SILENT mode
# name of MAINFILE
mainFile=$1
# incase we're compiling from within the CHAPTER file
set `grep -F %*** $1 | tr -d "%*" `""
dummy=$1
# delete the file extension
mainFile=${mainFile/%.tex/}
dummy=${dummy/\.*/}
# check the length of the dummy string, if it's 0 then latex the current file
# otherwise latex the referenced latex file
if [ $dummy ]
then
mainFile=$dummy
fi
echo "======================================="
echo "Making PDF : Main file is $mainFile"
echo "======================================="
if [ $noshow -eq 1 ]
then
echo "SILENT mode on"
nohup makepdf.sh $mainFile 1 &
else
echo "VERBOSE mode on"
makepdf.sh $mainFile 1
echo "======================================="
echo "Made PDF : Main file is $mainFile".tex
echo "======================================="
egrep 'undefined' $mainFile.log
egrep 'multiply-defined' $mainFile.log
egrep '\\end occurred when \\iftrue' $mainFile.log
fi
Tables
I write a lot of tables which are all pretty much the same. I bind most of my commands to ;word
, table being bound to ;tab
. It asks for number of columns, caption, and whether or not it's fixed width. I of course use the Tabularize plugin as well for formatting.
function! TableCreator()
let curline=getline('.')
call inputsave()
let cols = input('Enter number of columns: ')
let caption = input('Caption: ')
let centering = input('Fixed width? (y/n) :')
call inputrestore()
exe "normal a\\begin{table}[!h]\r\\caption{" . caption . "\\label{tab:}}\r\\begin{center}\r\\begin{tabular}{\e"
let numcols = cols
while cols > 0
if centering == 'y'
exe "normal ap{4cm}\e"
else
exe "normal ac\e"
endif
let cols = cols-1
endwhile
exe "normal a}\e"
let cols = numcols - 1
exe "normal a\r\r\r\e"
exe "normal a\\end{tabular}\r\\end{center}\r\\end{table}\\ \\\\"
endfunction
Spell Checking
I write a couple different languages, and depending on my target audience. I use this to conveniently switch between them.
" Spell Check
let b:myLang=0
let g:myLangList=["nospell","de","en_gb","en_us"]
function! ToggleSpell()
let b:myLang=b:myLang+1
if b:myLang>=len(g:myLangList) | let b:myLang=0 | endif
if b:myLang==0
setlocal nospell
else
execute "setlocal spell spelllang=".get(g:myLangList, b:myLang)
endif
echo "spell checking language:" g:myLangList[b:myLang]
endfunction