本文基本上是對 How I'm able to take notes in mathematics lectures using LaTeX and Vim一文的實踐操作。感謝原作者的分享。
本文基礎
平台
-
Windows 11
軟件
- gvim
- SumatraPDF
- miktex
-
Strawberry perl
Vim 插件
- vimtex
- utilsnip
正文
-
下載安裝上述軟件,包括 gvim, SumatraPDF, miktex, Strawberry perl.
- SumatraPDF就是一個支持 rpc的PDF瀏覽器,其它平台的推薦瀏覽器可以在 vimtex上的文檔中尋找,比如上述 Castel小哥在文章中在 linux上用的 Zathura。
- MiKTeX是 Windows平台上的一個 LaTeX實現,在本文中它作為用於編譯 LaTex文件的後端存在。
- Strawberry perl是 MiKTeX的依賴項,用於安裝管理豐富的數學符號包
-
在vim上安裝上述的 vim插件。我使用的是 vim plug, 所以我在我的 _vimrc中加入了:
call plug#begin() ... Plug 'lervag/vimtex',{'tag':'v2.15'} Plug 'godlygeek/tabular' Plug 'sirver/ultisnips' ''Plug 'your/vim-snippets' ... call plug#end()注意最後一行有個被註釋的插件,我建議你在gayhub上創建一個自己的vim-snippets倉庫,用來管理自己的snippets。ultisnips的 github頁上推薦的是 honza/vim-snippets, 你可以fork一份作為自己的snippets庫的開始。
-
vim配置
- vimtex的配置
" Noting {{{ let g:tex_flavor='latex' let g:vimtex_quickfix_mode=0 set conceallevel=1 let g:vimtex_view_general_viewer = 'SumatraPDF.exe' let g:vimtex_view_general_options \ = '-reuse-instance -forward-search @tex @line @pdf' let g:tex_conceal='abdmg' " PDF reader " let g:Tex_ViewRule_pdf = 'SumatraPDF " -reuse-instance -inverse-search "gvim -c \":RemoteOpen +\%l \%f\""' let g:vimtex_view_general_viewer = 'SumatraPDF' "這裏放置你的sumatrapdf 安裝路徑 let g:vimtex_view_general_options \ = ' -reuse-instance -forward-search @tex @line @pdf' \ . ' -inverse-search "' . ' wt -w 0 \"\" ' . 'gvim' \ . ' -v --not-a-term -T dumb -c \"VimtexInverseSearch %l ''%f''\""' "for vim/gvim " 編譯過程中忽略警告信息 let g:vimtex_quickfix_open_on_warning=0 " 這裏是LaTeX編譯引擎的設置,這裏默認LaTeX編譯方式為-pdf(pdfLaTeX), " vimtex提供了magic comments來為文件設置編譯方式 " 例如,我在tex文件開頭輸入 % !TEX program = xelatex 即指定-xelatex "(xelatex)編譯文件 let g:vimtex_compiler_latexmk_engines = { \ '_' : '-pdf', \ 'pdflatex' : '-pdf', \ 'dvipdfex' : '-pdfdvi', \ 'lualatex' : '-lualatex', \ 'xelatex' : '-xelatex', \ 'context (pdftex)' : '-pdf -pdflatex=texexec', \ 'context (luatex)' : '-pdf -pdflatex=context', \ 'context (xetex)' : '-pdf -pdflatex=''texexec --xtx''', \} " 這裏是設置latexmk工具的可選參數 let g:vimtex_compiler_latexmk = { \ 'build_dir' : '', \ 'callback' : 1, \ 'continuous' : 1, \ 'executable' :'latexmk', \ 'hooks' : [], \ 'options' : [ \'-verbose', \'-file-line-error', \'-shell-escape', \'-synctex=1', \'-interaction=nonstopmode', \], \} " }}}要注意的主要是latex客户端和pdf瀏覽器的名稱、路徑。
在配置完後,可以新建一個 .tex文件,隨便寫點啥,比如:\documentclass{article} \begin{document} \title{Hello world} \author{BugCatcher} \endP{document}保存然後在普通模式下輸入
<localleader>ll開始編譯,編譯完成後會自動打開 pdf瀏覽器,查看編譯後的結果。- ultisnips的配置
" UltiSnips {{{ let g:tex_flavor = "latex" let g:UltiSnipsSnippetDirectories=["UltiSnips",'$HOME/vimfiles/plugged/vim-snippets/UltiSnips'] let g:UltiSnipsExpandOrJumpTrigger="<TAB>" let g:UltiSnipsExpandTrigger="<TAB>" let g:UltiSnipsJumpForwardTrigger="<TAB>" let g:UltiSnipsJumpBackwardTrigger="<S-TAB>" " }}}要注意的主要是,在使用 ultisnip的同時我也使用了 coc,coc默認的補全觸發鍵也是 <tab>,所以我把 coc的補全觸發鍵改為了<c-k>。
在選擇 snippets插件的時候我一度猶豫過使用 coc-snippets,它的優點是它本身就是 coc的一個模塊,和 coc其它部分兼容,不會存在像 ultisnips和 coc的觸發鍵衝突這樣的問題。但是缺點是它是基於nodejs開發的,有些 ultisnips的強大功能它無法支持,詳情可以參考 coc-snippets的 github頁面。
其中一個強大的功能正是 pre_expand, post_expand等 snippet actions。比如説,我正要學習的數學知識涉及大量的矩陣,沒有 snippets得寫到手抽筋;但是面對不同尺寸的矩陣,難道説我要一個個寫 snippets來展開嗎?這時候,我扒到了一個 snippets:global !p ... def create_matrix(snip): matrix_str = (snip.buffer[snip.line].split('mat')[0]+'matrix').strip() rows = 'x'.join(snip.buffer[snip.line].split("x", 2)[:-1]) cols = 'x'.join(snip.buffer[snip.line].split("x", 2)[-1:]) int_val = lambda string: int(''.join(s for s in string if s.isdigit())) rows = int_val(rows) cols = int_val(cols) offset = cols + 1 old_spacing = snip.buffer[snip.line][:snip.buffer[snip.line].rfind('\t') + 1] snip.buffer[snip.line] = '' final_str = old_spacing + "\\begin{"+matrix_str+"}\n" for i in range(rows): final_str += old_spacing + '\t' final_str += " & ".join(['$' + str(i * cols + j + offset) for j in range(cols)]) final_str += " \\\\\\\n" final_str += old_spacing + "\\end{"+matrix_str+"}\n$0" snip.expand_anon(final_str) endglobal ... pre_expand "create_matrix(snip)" snippet "(small|[bBpvV])?mat(rix)?(\d+)x(\d+)" "Generate (small|[bBpvV])?matrix of *rows* by *columns*" br endsnippet上面的 snippet,它首先在snippet文件的開頭的全局 python腳本中寫了一個根據輸入返回對應矩陣snippet的函數,然後加了一個使用正則表達式的snippet,自動匹配矩陣的格式,比如 bmat3x3。在實際使用時你輸入 bmat3x3,觸發補全,然後它就會調用
create_matrix函數生成對應的snippet填充到文件中,這時你只用一下下tab來遍歷輸入 3x3 矩陣的 9個元素。