vim+latex(0.01)
vim operator
vim configure information
vim translate
这套基于 Gilles Castel 的配置被誉为“以思考的速度编写 LaTeX”。要在 Fedora 43 (KDE Wayland) 上流畅操作这套系统,你需要掌握其核心的自动化逻辑。
以下是这份配置的操作指南,分为四个核心阶段:
概述:
第一阶段:启动与实时预览 (VimTeX)
在写代码之前,先建立“左手代码,右手 PDF”的反馈环。
1.启动编译:在 Vim 中按下 \ll (Local Leader, 通常是反斜杠)。
- 效果:VimTeX 会启动 latexmk 的连续监听模式。
- 反馈:Zathura 会自动打开。之后你每按一次 :w 保存,Zathura 都会实时刷新。
2.正向跳转 (\lv):光标停在代码某处,按 \lv。
- 效果:Zathura 会自动跳转到对应的 PDF 页面并高亮。
3.反向跳转 (Ctrl + Click):在 Zathura 中按住 Ctrl 并左键点击文字。
- 效果:Vim 会自动跳转到对应的代码行(即使是在不同的源文件中)。
第二阶段:数学模式的“瞬间移动” (UltiSnips)
Gilles Castel 配置的核心在于上下文感知 (Context-aware)。
- 进入数学环境
- 输入 mk:自动补全为 $ | $ (行内公式)。
- 输入 dm:自动补全为 [ | ] (独立公式块)。
- 自动下标与上标 (无需 Shift)
- 这是该配置最爽的地方:
- 自动下标:直接输入 x1 $\rightarrow$ 变成 $x_1$。输入 x12 $\rightarrow$ 变成 $x_{12}$。
- 快速平方/立方:在数学模式下输入 sr (square) $\rightarrow$ $^2$;输入 cb (cube) $\rightarrow$ $^3$。
- 任意上标:输入 td (top dot) $\rightarrow$ ^{|}。
- 革命性的分式输入 (Fraction)
- 简单分式:输入 // $\rightarrow$ \frac{|}{}。
- 自动抓取前项:输入 3/ $\rightarrow$ \frac{3}{|}。输入 x^2/ $\rightarrow$ \frac{x^2}{|}。
- 括号抓取:输入 (a+b+c)/ $\rightarrow$ \frac{a+b+c}{|}。这省去了手动移动光标包围分子的麻烦。
第三阶段:符号计算与后处理
- 符号修饰 (Postfix)
- 向量:输入 v,. $\rightarrow$ \vec{v} (或者 .,)。
- Bar/Hat:输入 abar $\rightarrow$ \overline{a};输入 ahat $\rightarrow$ \hat{a}。
- 量子力学 (Dirac Notation)
- 输入 <q| $\rightarrow$ \bra{\psi}。
- 输入 |q> $\rightarrow$ \ket{\psi}。
- 输入 \bra{phi}q> $\rightarrow$ \braket{\phi}{\psi}。
- 外部计算引擎 (SymPy / Wolfram)(可选部分)
- SymPy:输入 sympy 触发块,写下 solve(x**2 - 1, x),然后再次触发,它会直接把结果转为 LaTeX 填入文档。
- Wolfram:输入 math 触发块,写下 Integrate[x^2, x],触发后会自动替换为 \frac{x^3}{3}。
第四阶段:Fedora KED 43 环境下的维护
由于你使用 Wayland,如果发现反向搜索(PDF 跳回 Vim)失效,请检查以下两点:
- DBus 监听:Zathura 在 Wayland 下依赖 DBus 通信。确保你的环境变量中没有禁用它。
- Vim 实例名:当你启动 Vim 时,如果反向跳转不工作,尝试使用 vim --servername VIM 启动(如果安装了 gvim 包)。
常用快捷键速查表
| 动作 | 键位 | 备注 |
|---|---|---|
| 开启/停止编译 | \ll or \lk | 实时监控文件变动 |
| 查看编译错误 | \le | 快速定位语法错误 |
| 查看文档结构 | \lt | 左侧显示 TOC 目录 |
| 清理中间文件 | \lc | 删除 .aux, .fls 等 |
| 跳转到对应PDF | \lv | 同步光标位置 |
安装及配置
安装依赖:
sudo dnf install zathura python3 latexmk zathura-pdf-poppler texlive-scheme-full texlive-latexextra texlive-synctex python3-sympy(可选)
安装Wolfram Engine(可选)
访问Wolfram Engine官网(点击上述蓝色链接跳转)

需要获得获取免费开发许可,可以注册一个账户,绑定自己的邮箱。

后续步骤如下:
rock@192:~/Downloads$ ls
WolframEngine_14.3.0_LIN.sh
rock@192:~/Downloads$ chmod +x *.sh
rock@192:~/Downloads$ sudo ./WolframEngine_14.3.0_LIN.sh
Enter the installation directory, or press ENTER to select /usr/local/Wolfram/WolframEngine/14.3:
> /usr/local/Wolfram/WolframEngine/14.3
Type the directory path in which the Wolfram Engine script(s) will be created, or press ENTER to
select /usr/local/bin:
> /usr/local/bin
rock@192:~$ sudo ln -s /usr/local/Wolfram/WolframEngine/14.3/SystemFiles/Kernel/Binaries/Linux-x86-64/wolframscript /usr/local/bin/wolframscript
rock@192:~$ wolframscript --activate
The Wolfram Engine requires one-time activation on this computer.
Visit https://wolfram.com/engine/free-license to get your free license.
Wolfram ID: ****j*@qq.com(填写自己注册的邮箱)
Password:
Wolfram Engine activated. See https://www.wolfram.com/wolframscript/ for more information.
进行配置:
在~/.config/zathura下创建一个名为zathurarc的文件, 其内容如下:
set synctex true
set synctex-editor-command "vim --remote-silent +%{line} %{input}"
在~/.vim/UltiSnips下创建一个名为tex.snippets的文件, 其内容如下:
global !p
def math():
return vim.eval('vimtex#syntax#in_mathzone()') == '1'
def comment():
return vim.eval('vimtex#syntax#in_comment()') == '1'
def env(name):
[x,y] = vim.eval("vimtex#env#is_inside('" + name + "')")
return x != '0' and x != '0'
endglobal
snippet mk "Math" wA
$${1}$`!p
if t[2] and t[2][0] not in [',', '.', '?', '-', ' ']:
snip.rv = ' '
else:
snip.rv = ''
`$2
endsnippet
snippet dm "Math" wA
\[
$1
.\] $0
endsnippet
snippet '([A-Za-z])(\d)' "auto subscript" wrA
`!p snip.rv = match.group(1)`_`!p snip.rv = match.group(2)`
endsnippet
snippet '([A-Za-z])_(\d\d)' "auto subscript2" wrA
`!p snip.rv = match.group(1)`_{`!p snip.rv = match.group(2)`}
endsnippet
context "math()"
snippet sr "^2" iA
^2
endsnippet
snippet cb "^3" iA
^3
endsnippet
snippet compl "complement" iA
^{c}
endsnippet
snippet td "superscript" iA
^{$1}$0
endsnippet
snippet // "Fraction" iA
\\frac{$1}{$2}$0
endsnippet
snippet '((\d+)|(\d*)(\\)?([A-Za-z]+)((\^|_)(\{\d+\}|\d))*)/' "Fraction" wrA
\\frac{`!p snip.rv = match.group(1)`}{$1}$0
endsnippet
priority 1000
snippet '^.*\)/' "() Fraction" wrA
`!p
stripped = match.string[:-1]
depth = 0
i = len(stripped) - 1
while True:
if stripped[i] == ')': depth += 1
if stripped[i] == '(': depth -= 1
if depth == 0: break;
i -= 1
snip.rv = stripped[0:i] + "\\frac{" + stripped[i+1:-1] + "}"
`{$1}$0
endsnippet
snippet / "Fraction" iA
\\frac{${VISUAL}}{$1}$0
endsnippet
snippet sympy "sympy block " w
sympy $1 sympy$0
endsnippet
priority 10000
snippet 'sympy(.*)sympy' "evaluate sympy" wr
`!p
from sympy import *
x, y, z, t = symbols('x y z t')
k, m, n = symbols('k m n', integer=True)
f, g, h = symbols('f g h', cls=Function)
init_printing()
snip.rv = eval('latex(' + match.group(1).replace('\\', '') \
.replace('^', '**') \
.replace('{', '(') \
.replace('}', ')') + ')')
`
endsnippet
priority 1000
snippet math "mathematica block" w
math $1 math$0
endsnippet
priority 10000
snippet 'math(.*)math' "evaluate mathematica" wr
`!p
import subprocess
code = 'ToString[' + match.group(1) + ', TeXForm]'
snip.rv = subprocess.check_output(['wolframscript', '-code', code])
`
endsnippet
priority 10
snippet "bar" "bar" riA
\overline{$1}$0
endsnippet
priority 100
snippet "([a-zA-Z])bar" "bar" riA
\overline{`!p snip.rv=match.group(1)`}
endsnippet
priority 10
snippet "hat" "hat" riA
\hat{$1}$0
endsnippet
priority 100
snippet "([a-zA-Z])hat" "hat" riA
\hat{`!p snip.rv=match.group(1)`}
endsnippet
snippet "(\\?\w+)(,\.|\.,)" "Vector postfix" riA
\vec{`!p snip.rv=match.group(1)`}
endsnippet
snippet "\<(.*?)\|" "bra" riA
\bra{`!p snip.rv = match.group(1).replace('q', f'\psi').replace('f', f'\phi')`}
endsnippet
snippet "\|(.*?)\>" "ket" riA
\ket{`!p snip.rv = match.group(1).replace('q', f'\psi').replace('f', f'\phi')`}
endsnippet
snippet "(.*)\\bra{(.*?)}([^\|]*?)\>" "braket" riA
`!p snip.rv = match.group(1)`\braket{`!p snip.rv = match.group(2)`}{`!p snip.rv = match.group(3).replace('q', f'\psi').replace('f', f'\phi')`}
endsnippet
priority 10000
snippet 'math(.*)math' "evaluate mathematica" wr
`!p
import subprocess
# The math() context check ensures this only runs in LaTeX math zones
if math():
code = 'ToString[' + match.group(1) + ', TeXForm]'
try:
# Use the absolute path to the symlink
snip.rv = subprocess.check_output(['/usr/local/bin/wolframscript', '-code', code]).decode('utf-8').strip()
except Exception as e:
snip.rv = "Wolfram Error: " + str(e)
`
endsnippet
Plug 'lervag/vimtex'
Plug 'sirver/ultisnips'
Plug 'KeitaNakamura/tex-conceal.vim'
"----------------------vim + latex--------------------------
" vimtex
let g:tex_flavor='latex'
let g:vimtex_view_method='zathura'
let g:vimtex_quickfix_mode=0
set conceallevel=1
let g:tex_conceal='abdmg'
let g:vimtex_view_zathura_options = '-x "vim --remote-silent +%l %f"'
" ultisnips
let g:UltiSnipsExpandTrigger = '<tab>'
let g:UltiSnipsJumpForwardTrigger = '<tab>'
let g:UltiSnipsJumpBackwardTrigger = '<s-tab>'
" tex_conceal
set conceallevel=1
let g:tex_conceal='abdmg'
hi Conceal ctermbg=none
" Tell VimTeX to look for these files to determine the project root
let g:vimtex_root_markers = ['.git', '.latexmkrc', 'main.tex']
实操(还在学习中)
使用vim建立和打开一个名为math.tex的文件
根据常用快捷键速查表, 写一段latex后vim转普通模式下按\ll会调出Zathura来编译
%! TEX root = math.tex
\documentclass{article}
\usepackage{amsmath}
\begin{document}
First document. This is a simple example, with no
extra parameters or packages included.
F(n) =
\begin{case}
0 & \tex{ if } n = 0 \\
1 & \tex{ if } n = 1 \\
F(n-1) + F(n-2) & \tex{ if } n > 1
\end{case}
\]
\end{document}


浙公网安备 33010602011771号