我承认,我是标题党。
本文主旨是记录我如何配置我的电脑。这肯定对换机很有帮助。
Windows Subsystem for Linux \text{Windows Subsystem for Linux} Windows Subsystem for Linux
简称 WSL \text{WSL} WSL 。我们需要它,因为我们需要 v i m \rm vim vim!
下载安装
首先去
Microsoft Store
\text{Microsoft Store}
Microsoft Store 里1下载
U
b
u
n
t
u
\rm Ubuntu
Ubuntu 和
Windows Terminal
\text{Windows Terminal}
Windows Terminal(在
win11
\text{win11}
win11 中已经出厂自带)。然后去 启用或关闭 Windows 功能
内选中 Hyper-V
和 适用于 Linux 的 Windows 子系统
。
运行 Ubuntu \text{Ubuntu} Ubuntu,无论哪个版本。它会自动安装。——如果出错,并提示 WSL 2 \text{WSL 2} WSL 2 后接若干问号,那么需要升级 L i n u x \rm Linux Linux 内核。官网上有下载链接。
搞定之后我们就获得了 wsl.exe
,可以用 cmd
或 powershell
或 win+R
运行之,都可以进入
subsystem
\text{subsystem}
subsystem 的命令行。本机会被挂载到路径 /mnt
下,内有 /c
、/d
等就是本地磁盘。
记得更换软件源。这是国内
U
b
u
n
t
u
\rm Ubuntu
Ubuntu 基本操作。比如清华源。然后你可以装 g++
和 gdb
咯!
Note. 虚拟机实际上占用 C C C 盘空间。这就是为什么我不在其中安装 TeX l i v e \TeX\;live TEXlive 的原因。
启动配置
用 cmd
呼出 wsl
不太美观,所以才推荐下载
Windows Terminal
\text{Windows Terminal}
Windows Terminal 。不出意外它会自动装填两个配置文件(可用选项卡),图标分别是经典小企鹅,还有下载的
U
b
u
n
t
u
\rm Ubuntu
Ubuntu 的图标。在设置里查看配置文件,其一的运行方案(即 命令行
子项)是 wsl.exe
,另一个是 ubuntu*.exe
。保留前者。
将 wsl.exe
对应标签页设为启动时默认配置文件(于左侧 启动
项中)。然后你就可以用鼠标右键菜单中 “在终端中打开”,直接用 “虚拟机” 进入本机文件夹了!再把 启动目录
设为 /mnt/?
等本地路径,以后就用 win+R
运行 wt.exe
,好使。
Ubuntu Server \text{Ubuntu Server} Ubuntu Server
如果你有钱、设备多、想要尝尝鲜,这可以替代 W S L \rm WSL WSL 。
用机房电脑的
VMWare
\text{VMWare}
VMWare 搭了个
Ubuntu Server
\text{Ubuntu Server}
Ubuntu Server,然后自己的电脑就可以直接 ssh
连上去 🤪
可以参考这篇文章搭建上网环境,然后 service ssh start
启动。无法启动请用 sshd -t
检查。
可能需要 scp
传输文件,可能需要这篇文章作参考。
V I M \rm VIM VIM 配置
我中意的配色:终端配色方案 Tango Dark
,字体 Ubuntu Mono
2,
v
i
m
\rm vim
vim 配色方案 ron
,背景颜色 #300A24
。这是
noi linux 2
\text{noi linux 2}
noi linux 2 配色。
然后是光标的问题。用此文中所述方式(这也是
v
i
m
\rm vim
vim 给出的方案,见 :h xterm
),可以改变光标的形状(和闪烁)但是没法做到光标亮起时文字自动反色!这就导致方块型光标很影响文本可见性……我去查了
xterm
\text{xterm}
xterm 的控制序列,根本没找到当前字符反色的选项……
而且,上面的光标配置方案是永久的(退出
v
i
m
\rm vim
vim 后仍起效)所以最好 autocmd
改回来。
对于
WSL
\text{WSL}
WSL,可以使用 clip.exe
和 paste.exe
。因为没安装
g
e
d
i
t
\rm gedit
gedit,最好能直接复制到系统剪贴板。可见此文,大体来说就是调用
Windows
\text{Windows}
Windows 自带程序 clip.exe
来实现剪切。注意它只能剪切一整行,而不能是行中部分文字。
paste.exe
非系统自带,可以下载,也可以就用 Shift+Insert
,因为
L
i
n
u
x
\rm Linux
Linux 下这也是很好的选择。我的笔记本没有小键盘,也可以用 ctrl+V
,这是由
Windows Terminal
\text{Windows Terminal}
Windows Terminal 决定的。
关于 t a b \rm tab tab 的长度设置,请见此文。
快捷键杂谈
你需要知道的快捷键:a/A
,i/I
,d/D
,v/V
是最基础的。
gg
去到首行,[count]G
跳转到指定行(无数字则默认末行)。用 %
跳转到匹配括号。
折叠使用 zo
和 zc
,
o
p
e
n
\rm open
open 和
c
l
o
s
e
\rm close
close 。zO
和 zC
则递归。或 za
和 zA
来
t
o
g
g
l
e
\rm toggle
toggle 。
:tab
好东西,配合 :new
得到 :tabnew
就可以变成强大
I
D
E
\rm IDE
IDE 了,好耶!——或许我们更喜欢 :term
吧。
用 <>
来缩进。用 /
查找,用 #
或 *
找光标所在的
word
\text{word}
word,用 n
重复上次查找(从当前位置继续)。用 :s(ubstitute)
来替换。
真正让
vim
\text{vim}
vim 快于其他编辑器的:如 ciw
。相关内容可见 :h v_iw
。
插件增强
m a r k d o w n \rm markdown markdown 的 “所见即所得” 是其特色,故建议使用 T y p o r a \rm Typora Typora 等编辑器。而 LaTeX \LaTeX LATEX 确实可以试试用 v i m \rm vim vim 。
可以用
vim-plug
\text{vim-plug}
vim-plug 管理插件。可惜 raw.github
被墙,要么 git clone
(然而这也慢的离谱)要么看 blame
,将 plug.vim
置于 ~/.vim/autoload
下(无则创建之)。使用 :PlugInstall
和 :PlugClean
管理插件。
我最倾心的插件是 UltiSnips \text{UltiSnips} UltiSnips,可以自己写 snippet \text{snippet} snippet,这才能真正体现 vim \text{vim} vim 的强大吧!它的配置可以参考知乎回答(有过时内容,建议看最新原文英文博客)。
LaTeX
\LaTeX
LATEX 的安装可以看粉兔博客中对应章节。然而 texdoc lshort-zh-cn
太长;某些知乎回答更短。
然而
W
S
L
\rm WSL
WSL 的问题是:文件的路径是 /mnt/?
的
L
i
n
u
x
\rm Linux
Linux 格式,我们要调用
W
i
n
d
o
w
s
\rm Windows
Windows 下
p
d
f
\rm pdf
pdf 阅读器,就需要微调。而
v
i
m
t
e
x
\rm vimtex
vimtex 不允许对打开的
p
d
f
\rm pdf
pdf 文件的路径作修改(指无法进行字符串操作)。
所以我干脆全部用 single shot \text{single shot} single shot 编译,用浏览器打开,自己手动刷新。
目前我用它写化学方程式,以及做数学作业。用某些模板可能会方便。
完整配置文件
这一部分是通用的。如果你不是
W
S
L
\rm WSL
WSL,将最后的光标设置与 clip.exe
去掉即可。
set nocompatible
filetype on
syntax on
function s:ClosePair(prev)
if a:prev == '('
return ')'
elseif a:prev == '['
return ']'
elseif a:prev == '{'
return '}'
elseif (a:prev == '"') || (a:prev == "'")
return a:prev
else
return '\<ESC>'
endif
endfunction
inoremap ( ()<LEFT>
inoremap [ []<LEFT>
inoremap { {}<LEFT>
inoremap " ""<LEFT>
inoremap <BS> <c-r>=BasicAutoDelete()<CR>
function BasicAutoDelete()
let prev = getline('.')[col('.')-2]
if getline('.')[col('.')-1] == s:ClosePair(prev)
return "\<ESC>2s"
else
return "\<BS>"
endif
endfunction
set showcmd
set showmode " often on by default
set ruler " often on as well
set number
set cindent
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
set mouse=a
set foldenable
set foldmethod=indent
set hlsearch " highlight search result
set incsearch " real-time match
colorscheme ron
" light yellow
hi Operator ctermfg=229
hi clear Label
hi link Label Operator
function s:CPP_Settings()
nnoremap <F9> :!clear<CR><CR>:w<CR>:!g++ % -o %:r.exe -std=c++11 -O2 -Wall -Wconversion -Wshadow<CR>
nnoremap <F10> :!clear<CR><CR>:!time ./%:r.exe<CR>
nnoremap <C-b> :!clear<CR><CR>:w<CR>:!g++ % -o %:r.exe -std=c++11 -Wall -Wconversion -Wshadow -fsanitize=undefined -g<CR>
nnoremap ;g :term gdb %:r.exe<CR>
set colorcolumn=80
inoremap ' ''<LEFT>
endfunction
autocmd FileType cpp call s:CPP_Settings()
inoremap <CR> <c-r>=BraceAutoNewline()<CR>
function BraceAutoNewline()
if len(getline('.')) == col('.') && getline('.')[col('.')-2] == '{' && getline('.')[col('.')-1] == '}'
return "\<CR>\<ESC>O"
else
return "\<CR>"
endif
endfunction
if &term =~ "xterm"
let cursorCommand = "\<ESC>[1 q" . "\<ESC>]12;rgb:ad00/c000/ad00\<ESC>\\"
let &t_SI = cursorCommand " Start Insert mode
let &t_SR = cursorCommand " Start Replace mode
let &t_EI = cursorCommand " End Insert or replace mode
autocmd VimLeave * :!echo -ne "\033[1 q \033]12;rgb:ee00/ee00/ec00\x7"
endif
vnoremap ;y :!/mnt/c/Windows/System32/clip.exe<cr>u
然后是对
LaTeX
\LaTeX
LATEX 的支持。某些选项应根据自身情况设置。若不懂,可以直接 :help
对应的变量,如 :h g:vimtex_view_method
。说明:用 \ll
编译,用 \lv
观看结果。不会自动刷新。
call plug#begin()
Plug 'SirVer/ultisnips'
Plug 'lervag/vimtex'
call plug#end()
let g:tex_flavor = 'latex'
set conceallevel=1
let g:vimtex_quickfix_mode = 0
let g:tex_conceal = 'abdmg'
let g:UltiSnipsExpandTrigger = '<tab>'
let g:UltiSnipsJumpForwardTrigger = '<tab>'
let g:UltiSnipsJumpBackwardTrigger = '<s-tab>'
let g:UltiSnipsSnippetDirectories = ['mysnippet']
let g:vimtex_compiler_latexmk = {
\ 'build_dir': {-> expand("%:t:r")},
\ 'callback' : 1,
\ 'continuous' : 1,
\ 'executable' : '/mnt/d/texlive2022/bin/win32/latexmk.exe',
\ 'hooks' : [],
\ 'options' : [
\ '-verbose',
\ '-file-line-error',
\ '-synctex=1',
\ '-interaction=nonstopmode',
\ ],
\}
let g:vimtex_view_method = 'general'
let g:vimtex_view_general_viewer = ''
let g:vimtex_view_general_options = ''
nnoremap \ll :w<CR>:VimtexCompileSS<CR>
function LinuxPathToWindows(str)
let got = strcharpart(a:str,6)
let driver = strcharpart(a:str,5,1)
return shellescape(toupper(driver).':'.got)
endfunction
nnoremap \lv :execute '!/mnt/d/texlive2022/evince' LinuxPathToWindows(expand('%:p:r').'/'.expand('%:t:r').'.pdf')<CR><CR>
最后是 s n i p p e t \rm snippet snippet 。很难确保说它就是最终版了。
global !p
def math():
return vim.eval('vimtex#syntax#in_mathzone()') == '1'
endglobal
snippet $ "Math" wA
$$1$$0
endsnippet
snippet dm "Display Math" wA
\[
$1
.\] $0
endsnippet
context "math()"
snippet '([A-Za-z])(\d)' "auto subscript" wrA
`!p snip.rv = match.group(1)`_`!p snip.rv = match.group(2)`
endsnippet
context "math()"
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 // "Empty Fraction" iA
\\frac{$1}{$2}$0
endsnippet
context "math()"
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
context "math()"
priority 10
snippet "bar" "bar" riA
\overline{$1}$0
endsnippet
context "math()"
priority 100
snippet "([a-zA-Z])bar" "bar" riA
\overline{`!p snip.rv=match.group(1)`}
endsnippet
context "math()"
priority 10
snippet "hat" "hat" riA
\hat{$1}$0
endsnippet
context "math()"
priority 100
snippet "([a-zA-Z])hat" "hat" riA
\hat{`!p snip.rv=match.group(1)`}
endsnippet
context "math()"
snippet OO "emptyset" iA
\varnothing
endsnippet
context "math()"
snippet => "implies" wA
\implies
endsnippet
snippet beg "begin{} / end{}" bA
\begin{$1}
$0
\end{$1}
endsnippet
context "math()"
snippet <= "less or equal" wA
\leqslant
endsnippet
context "math()"
snippet >= "greater or equal" wA
\geqslant
endsnippet
context "not math()"
snippet --- "horizontal split line" bA
\quad\hrule\quad
endsnippet