动态

详情 返回 返回

使用vim做筆記-vimtex - 动态 详情

本文基本上是對 How I'm able to take notes in mathematics lectures using LaTeX and Vim一文的實踐操作。感謝原作者的分享。

本文基礎

平台

  • Windows 11

    軟件

  • gvim
  • SumatraPDF
  • miktex
  • Strawberry perl

    Vim 插件

  • vimtex
  • utilsnip

正文

  1. 下載安裝上述軟件,包括 gvim, SumatraPDF, miktex, Strawberry perl.

    • SumatraPDF就是一個支持 rpc的PDF瀏覽器,其它平台的推薦瀏覽器可以在 vimtex上的文檔中尋找,比如上述 Castel小哥在文章中在 linux上用的 Zathura。
    • MiKTeX是 Windows平台上的一個 LaTeX實現,在本文中它作為用於編譯 LaTex文件的後端存在。
    • Strawberry perl是 MiKTeX的依賴項,用於安裝管理豐富的數學符號包
  2. 在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庫的開始。

  3. vim配置

    1. 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瀏覽器,查看編譯後的結果。

    1. 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個元素。

user avatar y_luoe_hai_61a734cbf3c94 头像
点赞 1 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.