这是我写的关于用vim编辑latex文档的第二篇. 第一篇的链接是
李老师的好学生:Vim Latex 的使用和配置技巧 (一)zhuanlan.zhihu.com在这一篇里, 我将继续介绍vimtex插件的应用, 用vim编译latex以及其他的一些编辑小技巧.
5. vimtex 插件
5.1 vimtex 插件的安装
如果你用vundle
的插件管理器, 在vimrc
文件中, 加入这么一行:
Plugin 'lervag/vimtex'
5.2 vimtex的基本用法
5.2.1 常用命令
如下表:
![a79d5ddd928c6514a5e978c5eb85a5a0.png](https://i-blog.csdnimg.cn/blog_migrate/d4e8a98c2e1ba19447044696d6f1eae8.jpeg)
5.2.2 imaps映射
imap 映射, 在latex-suite中也有, 而且二者的命令十分类似. 我们可以在normal模式下, 用lm
来查看内置的imaps命令. 如下
![71170b4bfba09e514dc50b18010d8bd8.png](https://i-blog.csdnimg.cn/blog_migrate/06f15f600d63648c31696a4676e3185c.jpeg)
举例来说, 如果你想输入 infty
, 那么只需要输入 `+ 8 就行了 (因为8躺下了就是
当然, 你可以针对性地取消一些命令. 比如,
" Disable alpha and beta mappings
let g:vimtex_imaps_disabled = ['a', 'b']
这个也可以新定义: 比如,
" Add custom mapping through vimtex#imap#add_map
call vimtex#imaps#add_map({
'lhs' : 'test', " input
'rhs' : 'tested', " output
'wrapper' : 'vimtex#imaps#wrap_trivial'
})
" wrapper 类型#wrap_trivial另外可选#wrap_math 和 #wrap_environment,
" 这样就只在数学或者环境下适用.
就可以将 test
映射为 tested
. 不过, 这样做并没多大意义, 只是一个说明.
5.2.3 模块编辑
在vim中, 可以快速编辑一些模块. 比如: di)
是删除( )
内的东西, 这里, )
就代表( )
的模块. 在vimtex
中, 我们定义了一些常用的latex
模块. 比如:
![6b3c9c8abb87037bbe42f2fbfc10f4f2.png](https://i-blog.csdnimg.cn/blog_migrate/b56fe90416907d41a724abdef107f9fc.jpeg)
比如在一个环境align
周围, 我们按下按键cse
, 在命令行里就会出现:
Change surrounding environment: align
> [光标]
的提示, 然后在光标处输入equation, 那么这个环境就会变成
begin{equation}
...
end{equation}
在这里, tsd
默认的变换list
是
let g:vimtex_delim_toggle_mod_list = [
['left', 'right'],
['mleft', 'mright'],
]
当然我们可以进行修改, 比如, 在tex.vim
中, 我们可以设置:
let g:vimtex_delim_toggle_mod_list = [
['bigl', 'bigr'],
['Bigl', 'Bigr'],
['biggl', 'biggr'],
['Biggl', 'Biggr'],
]
这样一来, 通过tsd
命令, 我们可以在这些型号的括号选择了. 注意, 我们也可以用 tsD
对这个顺序进行逆向变换. 这个命令可以配合数字使用, 比如:
( a + b + int_0^infty f(x) dd x )
--tsd--> bigl( a + b + int_0^infty f(x) dd x bigr)
--2tsd--> biggl( a + b + int_0^infty f(x) dd x biggr)
--tsD--> Bigl( a + b + int_0^infty f(x) dd x Bigr)
这个也是我经常用到的命令.
csd
是括号之间的变换. 比如我们有
bigl( a + b bigr)
我们想把(
变成{
, 那么用 csd
命令, 并在光标处输入 {
, 如下图 :
![97cc141e78717a68fac56241aa8d254e.png](https://i-blog.csdnimg.cn/blog_migrate/6acd8dcd29b27bc6b65ca708c9a3c9e1.png)
这样, 就变成了
bigl{ a + b bigr}
默认情况下, 括号的类型变了, 但是大小不会变.
另外还有下面的几个常用textobj
模块, 这些可以和y(复制)
, d (删除)
及c (修改)
搭配使用:
按键效果模式]]补全括号和环境[^2]iac全部command
命令xoiccommand{...}
括号内的内容xoad整个括号和括号里的内容xoid括号里的内容xoae整个环境和环境里的内容xoie环境里的内容xoa$整个$ ... $
的内容xoi$$ ... $
里的内容xoK在usepackage{package} 跳到
package`的帮助文档n
在vim-textobj-user
的帮助下, 我们开可以自己定义模块, 比如说:
call textobj#user#plugin('latex', {
'bracket-math': {
'*pattern*': ['[', ']'],
'select-a': 'au',
'select-i': 'iu',
},
'paren-math': {
'*pattern*': ['(', ')'],
'select-a': 'a',
'select-i': 'i',
},
'double-quote': {
'*pattern*': ['``', "''"],
'select-a': 'aQ',
'select-i': 'iQ',
},
'biglimiter': {
'*pattern*': ['{', '}'],
'select-a': 'aU',
'select-i': 'iU',
},
})
在这里, 我们定义了( )
, { }
, quotes
和[ ]
的几个模块. 这样一来, 比如在:
[
f(x) = sin(x) + frac{a}{b} [光标]
]
在光标处, 如果我们用 ciu
, 就可以把 [ ... ]
中的内容修改了.
5.2.4 自动补全label
- labels: >
ref{sec:<CTRL-X><CTRL-O> - numbers: >
eqref{2<CTRL-X><CTRL-O> - labels and numbers together (separated by whitespace): >
eqref{eq 2<CTRL-X><CTRL-O>
这里多提一句, 用vim-latex-suite
插件的话, 还可以用 F7
和 F9
键来补全 ref
和 cite
.
至于其他的自动补全, 可以参考YouCompleteMe 插件 和 neocomplete 插件. 欢迎大家补充. 两个补全插件的好处之一, 就是可以搭配 snippet 命令使用.
在这里需要注意一下, 如果用了自动补全的插件, 需要设置:
let g:vimtex_fold_manual=1
不然会变得好慢.
6. 用vim-latex-suite插件编译latex文档
在这里提一下, vimtex插件也有编译的命令, 跟vim-latex-suite的插件类似. 在这里, 我们以vim-latex-suite为例, 说明一下.
6.1 LaTeX
的编译
假如我现在编译好了一个tex
文档, 文件名是testLaTeX.tex
, 如下:
% 导言区
documentclass[a4paper]{article}
usepackage{ams math}
% 文档区
begin{document}
% 正文开始
This is a LaTeX file.
end{document}
编译好LaTeX
文档之后, 我们不必在别的编译器里编译文档, 可以考虑下面几种办法:
6.1.1 用vim自带的命令行
我们知道, 在Terminal里, 用
pdflatex testLaTeX.tex
就可以编译文档. 结果如下:
![319d8dd09c94b403c542d3e51157f17f.png](https://i-blog.csdnimg.cn/blog_migrate/c5c0120350980b78b5a2e92b0849f13f.jpeg)
在vim里, 我们可以用它自带的命令行来运行: !
+ shell 命令. 比如, 在vim里, 我们可以用
!pdflatex %
来编译当前文档. 其中, %
代表当前文档名. 结果如下:
![4fd2f6f6db3747534ea5e672914158b3.png](https://i-blog.csdnimg.cn/blog_migrate/69a38da43ac238f30ec174c5215d7458.jpeg)
如何打开编译出来的pdf
文档呢? 可以用:
!open %:r.pdf
这样, 就可以用默认的pdf
浏览器来打开你的pdf
文档了. 当然, 也可以给这两个命令添加一个快捷方式. 比如, 在~/.vim/ftplugin/tex.vim
文件里, 添加:
imap <F2> <ESC>:w<CR>:!pdflatex % && open %:r.pdf<CR><CR>
nmap <F2> <ESC>:w<CR>:!pdflatex % && open %:r.pdf<CR><CR>
重新打开tex
文件, 当你再按一下<F2>
键, 就可以编译+打开文档了. 在这里, 我们解析一下这一行代码的含义.
imap
和nmap
是定义映射的命令. 开头的i
代表insert
模式的映射,n
代表normal
模式下的映射. 如果想定义一个对于所有模式的映射, 可以直接用map
来定义.<F2>
: 是映射的快捷键.<ESC>:w<CR>
: 退出编辑模式, 并保存.:!pdflatex %
: 用pdflatex
编译该文件.open %:r.pdf<CR><CR>
打开编译出来的pdf
文件.&&
: 命令的连接.~/.vim/ftplugin/tex.vim
: 这是tex
文件的local配置文件, 如果没有, 可以自己创建.
6.1.2 LaTeX-suite的编译
当然, LaTeX-suite自带一些编译文档的命令. 默认情况下, 在normal模式下,
ll
: 编译文档lv
: 查看文档ls
: 查看文档, 并跳到当前光标所在的位置.
如果lv
不管用, 可能需要改一下pdf浏览器的设置. 比如, 在MacOS
中, 我用的是skim
. 安装Skim
之后, 在~/.vim/ftplugin/tex.vim
中, 我们加入下面一行:
let g:Tex_ViewRule_pdf = 'Skim'
若使用vimtex插件, 则在tex.vim
中,加入:
let g:vimtex_view_method='Skim'
当然, 你也可以选择其他的, 在MacOS系统上, 我选用的是skim
.
至于Skim
的安装, 可以用brew
命令:
brew cask install skim
另外多说一句, 有些时候, 我们不光需要用pdflatex
编译, 也需要用bibtex
编译. 这时, 我们可以通过定义
let g:Tex_MultipleCompileFormats='pdf,bib,pdf,pdf'
这样一来, 按一下ll
, 就可以以pdflatex
, bibtex
, pdflatex’, ‘pdflatex
的顺序, 一下子编译好文档.
在我自己的tex.vim
文件里, 我还有下面一行自定义的命令:
imap <C-b> <ESC><ESC>:w<CR>ll:only<CR>ls
nmap <C-b> <ESC>:w<CR>ll:only<CR>ls
这样一来, 用Ctrl+b
, 就可以保存文档、编译文档并查看pdf文件.
6.1.3 LaTeX project的编译
在LaTeX project中, 我们可能会有很多源文件, 比如:
thesis/
main.tex
abstract.tex
intro/
intro.tex
figures/
fig1.eps
fig2.eps
chapter1/
chap1.tex
figures/
fig1.eps
conclusion/
conclusion.tex
figures/
在这个文件夹里, main.tex
是主要文件:
% file: main.tex
documentclass{report}
begin{document}
input{abstract.tex}
input{intro/intro.tex}
input{chapter1/chap1.tex}
input{conclusion/conclusion.tex}
end{document}
这个时候, 在main.tex
所在的文件夹里, 创建一个空文件: main.tex.latexmain
. 这样一来, 在main.tex
相关的文件里, 用ll
会自动找到main.tex
文件, 并编译.
7 vim-latex-suite中的Alt 命令
在这一节, 我补充一下我另外经常用到的几个vim-latex-suite的命令. 其他关于vim-latex-suite的介绍, 可以参考我的上一篇文章:
李老师的好学生:Vim Latex 的使用和配置技巧 (一)zhuanlan.zhihu.com7.1 添加特殊字体
在tex
中, 我们经常会需要不同的字体. 比如mathbb{R}
代表实数域, mathcal{F}
代表sigma-域等等. 这时, 我们可以用LaTeX-suite中的Alt
命令来做:
R<Alt-B> --> mathbf{R}, # 粗体
F<Alt-C> --> mathcal{F}. # 花体
我们可以自己定义这个命令. 比如说, 我们想定义mathbb
的相关命令, 就可以在~/.vim/ftplugin/tex.vim
中, 添加下面这个函数:
" Tex_Mathbb:
function! Tex_Mathbb()
return "<Left>mathbb{<Right>}"
endfunction
imap <A-x> <C-r>=Tex_Mathbb()<CR>
这样一来, 我们就可以:
R<Alt-x> -> mathbb{R}
7.2 添加括号
LaTeX中的大号的括号有两种模式, 一个是用left( frac{a}{b} right)
, 另一种是B{b}igl( frac{a}{b} B{b}igr)
. 这里, 我想做到下面这种效果:
( + <Alt-g> --> bigl( 光标 bigr) <++>
怎么可以做到这一点呢?
可以定义如下的vim
函数:
" Map <A-g> as bigl( bigr)
function! Tex_bigLR()
let line = getline(line("."))
let char = line[col(".")-2]
let previous = line[col(".")-3]
let matchedbrackets = '()[]{}|?'
if char =~ '(|[|{|||?'
let add = ''
if char =~ '{'
let add = ""
endif
let rhs = matchstr(matchedbrackets, char.'zs.ze')
if char =~ '|'
let add = ''
let char='lvert'
let rhs='rvert'
endif
if char =~ '?'
let add = ''
let char='lVert'
let rhs='rVert'
endif
return "<BS>".IMAP_PutTextWithMovement('bigl'.add.char.' <++> bigr'.add.rhs.'<++>')
else
return ''
endif
endfunction " }}}
"定义映射
inoremap <silent> <Plug>Tex_bigLR <C-r>=Tex_bigLR()<CR>
imap <A-g> <Plug>Tex_bigLR
这样一来,
( + <Alt-g> --> bigl( 光标 bigr) <++>
[ + <Alt-g> --> bigl[ 光标 bigr] <++>
{ + <Alt-g> --> bigl{ 光标 bigr} <++>
| + <Alt-g> --> bigllvert bigrrvert<++>
? + <Alt-g> --> bigllVert 光标 bigrrVert <++>
<++>
就像latex-suite的其他命令一样, 再用<C-j>
就可以跳出括号外.
至于Big
, bigg
和Bigg
, 可以类似地定义. 用snippet插件也可以做到类似的效果, 但是可能需要借助 python
语言, 因为这里有配对的情况存在. 那么关于snippet的应用, 我们可以参考
![c04fb6f45b62583fc20de2739565774e.png](https://i-blog.csdnimg.cn/blog_migrate/7622ab2e76ad9154f3eb0531a802a075.jpeg)
这是我自己多年用vim编辑latex的一些心得和体会, 欢迎大家多多提出意见, 可以把这个笔记丰富起来, 然后更好地分享给大家. 谢谢!