做UVM验证的兄弟一天到晚打交道最多的工具除了仿真器八成就是编辑器了。项目一跑起来每天面对的不是上万行的tb代码就是仿真日志这时候回头一看自己的gvim还处于“裸奔”状态看代码全靠眼睛扫跳转全靠CtrlF慢慢翻那效率真的挺劝退。这篇是UVM环境搭建系列的第六篇专门把Linux下gvim的插件配置梳理一遍。目标很直接让写SystemVerilog和UVM代码时类名能补全、定义能跳转、文件能秒开、关键模板能自动生成把日常重复操作省下来的时间全部花在真正该花的地方——分析问题和调代码。这套配置不挑机器远程SSH到公司的Linux服务器同样适用不管是CentOS、Ubuntu还是其他发行版核心思路都是相通的。适合正在搭建个人验证环境的新手也适合想把手头“裸vim”升级成“验证专用轻量IDE”的老手参考。下面开始。1. 配置前的整体思路验证工程师为什么要在gvim上花功夫在动手配插件之前先聊几句为什么我坚持推荐gvim而不是直接换IDE。很多刚入行的同事问我Verdi不是自带代码编辑器吗VSCode不是有远程插件吗非得在gvim上折腾个什么劲我的理解是这样的验证环境开发的大部分时间其实是“短平快”操作改半个小时的代码仿真三个小时再花一个小时看波形。仿真跑着的时候你要反复打开文件、查信号名、确认类定义、搜索日志这些动作如果每一步都要等IDE加载项目、建立索引人是会被磨疯的。gvim在这类场景下的优势是启动快、不占图形资源、ssh下一键拉起只要把插件配到位日常写代码的手感完全不输商业IDE。另一个现实原因是很多公司的芯片验证服务器并不会给每个人开图形桌面环境平时干活全靠MobaXterm或者Xshell远程连上去。这种前提下VSCode的远程开发方案虽然能用但经过一层转发之后输入延迟和内存占用都比较感人。gvim作为纯文本编辑器配合tmux和插件几乎可以在任何网络条件下保持流畅。所以我把gvim定位成“验证工程师的瑞士军刀”它不需要包揽一切但在你需要在各种环境下快速切入代码状态时它是最后、也是最可靠的那道保障。1.1 配置目标不是炫技是把高频操作压缩到一次按键插件配置最忌讳一上来不管三七二十一装一堆最后启动一次vim要等两秒那不如不装。我给自己定了几条硬性目标也建议你按这个标准来权衡每个插件值不值得装启动时间控制在0.5秒以内装上任何插件之后都要复测超过1秒就要找原因。日常最高频的操作——打开文件、跳转定义、搜索关键词、切换文件——全部要有快捷键不许点菜单。插件只服务于SystemVerilog/UVM开发这条主线和验证无关的“花活”一律不装。所有配置必须能在新服务器上一键复现不能依赖一堆手动的环境变量和临时脚本。按这个标准去选插件其实最后能留下来的并不算多。我目前在用的方案是vim-plug做插件管理universal-ctags做标签索引vim-systemverilog做语法高亮NERDTree和fzf解决文件导航UltiSnips解决代码模板再加上tagbar和vim-airline让代码结构和状态信息一目了然。这一套组合拳下来日常验证代码的编写体验基本能达到“指哪打哪”的程度。1.2 方案选型插件管理器、vim版本和依赖项一次说清插件管理器我推荐vim-plug理由很简单单文件安装、配置直观、支持并行安装和延迟加载。Vundle年代久远Pathogen只管加载不管安装dein.vim功能强但配置复杂对验证工程师来说性价比不高。vim-plug的配置方式就是在.vimrc里写一段plug#begin和plug#end中间列出插件仓库地址保存后执行:PlugInstall就能装好非常省心。vim版本方面强烈建议使用8.0以上最好是Vim 9。很多插件的新版本都依赖8.1之后的特性比如定时器、部分异步支持。老版本不是不能用但你会遇到各种莫名其妙的兼容性问题排查起来很浪费时间。在Ubuntu上直接安装vim-gtk3在CentOS上安装vim-X11这样带图形界面的gvim和终端vim都有。安装完记得确认一下vim --version输出里有没有python3和clipboard前者是部分重型插件的前置条件后者关系到系统剪贴板和gvim的交互。依赖项里另外两个关键包是git和universal-ctags。git不用多说vim-plug拉取插件全靠它。ctags这里要特别提一句系统自带的Exuberant Ctags对SystemVerilog的支持比较弱很多UVM里的类定义和宏标记识别不出来。建议直接安装universal-ctags它对C、SystemVerilog、VHDL的支持都要好得多后面讲tags跳转时会详细展开。2. 环境准备与基础.vimrc配置先把地基打牢插件是房子的装修.vimrc才是房子的地基。很多新手一上来就在网上找一段“超级配置”往家目录一放结果各种用不习惯又不知道哪里能改最后干脆回到裸vim。我建议自己从零开始搭也不用把它想得多复杂先把最影响日常体验的基础选项搞清楚之后再按需往上加插件每一行配置都知道是干什么的出了问题也能立刻定位。2.1 .vimrc基础设置缩进、行号、搜索、编码一次配好打开终端编辑~/.vimrc按下面的骨架逐段添加。先看基础交互部分set nocompatible 不与旧vi兼容必须放在第一行附近 syntax on 语法高亮 set number 显示绝对行号 set relativenumber 相对行号方便按行数跳转 set showcmd 右下角显示未完成的命令 set showmode 左下角显示当前模式 set cursorline 高亮当前行长代码更容易定位 set scrolloff5 光标距离窗口上下边缘保持5行滚动时更从容 set history500 保存500条命令历史缩进部分是验证工程师写SV代码最在意的点。UVM代码层级深class套class、task套fork缩进一乱整个文件就没法看。我的习惯是空格代替Tab每级缩进4个空格折行后继续缩进4格set expandtab Tab键展开为空格 set tabstop4 文件中已有的Tab显示为4个空格宽度 set shiftwidth4 、、自动缩进一次移动4个空格 set softtabstop4 按Tab和Backspace时按4个空格处理 set autoindent 继承上一行缩进 set smartindent 识别语法做智能缩进对C风格代码友好 filetype plugin indent on 对不同文件类型应用不同的缩进规则搜索相关的设置直接影响查代码效率。Vim默认的搜索是不高亮、不增量、大小写敏感的用起来非常难受。我通常会开成下面这样set hlsearch 搜索关键词高亮 set incsearch 边输入边搜索 set ignorecase 搜索时忽略大小写 set smartcase 但关键词包含大写字母时自动变成大小写敏感 set wildmenu 命令行补全时显示匹配菜单 set wildmodelist:longest,full编码部分是个大坑。服务器上经常要打开Windows那边传过来的文件中文注释偶尔还会乱码所以fileencodings这个参数我会专门设置set encodingutf-8 set fileencodingsucs-bom,utf-8,cp936,gb18030,big5,latin1 set fileformatsunix,dos,mac set termencodingutf-8cp936和gb18030覆盖大多数GBK编码的旧文件这样碰到带中文注释的老代码也不会满屏乱码。2.2 键位映射把最高频操作改成肌肉记忆Vim默认的键位已经很快但有几个操作我认为必须改。先定leader键我习惯用空格键比默认的冒号键好按太多let mapleader let g:mapleader 然后是保存文件。写代码的时候CtrlS是Windows时代留下的肌肉记忆在Vim里默认不生效反而会进入冻结状态。我把它重新映射为保存命令noremap C-s :updateCR inoremap C-s Esc:updateCR再一个是取消搜索高亮。每次搜索完屏幕上所有匹配项都亮着看下一段代码时很干扰。我映射成连续按两次Esc取消高亮顺手又不冲突nnoremap EscEsc :nohlsearchCR窗口切换也是高频操作。水平分屏、垂直分屏之后习惯用CtrlH/J/K/L在窗口之间跳而不是先按CtrlW再按方向键nnoremap C-h C-wh nnoremap C-j C-wj nnoremap C-k C-wk nnoremap C-l C-wl这些设置都很朴素但每一条都直接影响日常操作节奏。配完之后先别急着装插件用Vim打开一个大文件试试手感确认基础部分没问题了再继续。3. UVM/SystemVerilog专用配置让验证代码写起来真正顺手基础配置完成之后接下来到了这篇文章的核心面向UVM/SystemVerilog开发的插件配置。这里选择的每一个插件都跟验证工作直接相关配置完之后打开任意一个SV/UVM文件应该能明显感觉到跟之前的裸vim是两个世界。3.1 语法高亮补齐SystemVerilog的关键字和UVM宏支持Vim自带的verilog语法文件还停留在老版本class、interface、modport这些SystemVerilog关键字很少有完整高亮uvm_开头的宏和类名就更别想了。解决方案是安装vim-systemverilog插件它在github上可以直接通过vim-plug安装Plug vhda/verilog_systemverilog.vim这个插件是目前比较活跃的SystemVerilog语法高亮方案之一对uvm_*系列宏、SV的类定义、随机化约束、接口和断言都有覆盖。装完之后打开一个UVM环境里的agent或者sequence文件关键字颜色层次分明注释和字符串区分明显读代码的疲劳感会直线下降。我还习惯在里面打开变量高亮和标识符高亮选项let g:verilog_efm_ignore 1 let verilog_compiler vcs let g:verilog_syntax_fold 1verilog_syntax_fold会把module、class、task内部内容自动折叠起来在大文件里快速收缩到顶层结构定位外层的组件连接关系时非常省事。3.2 标签跳转用ctags给UVM源码库建立索引写验证代码最频繁的动作之一是点开一个uvm_component_utils宏或者uvm_sequence_item的子类去查它继承的方法或者父类的定义。如果每个文件都用CtrlF去搜效率会非常低。正确做法是用ctags给整个工程目录和UVM源码库建立标签索引然后在gvim里通过Ctrl]直接跳转定义Ctrlt返回。再次强调用universal-ctags而不是系统自带的ctags。ubuntu下安装sudo apt install universal-ctagscentos/rhel下可以源码编译安装步骤不复杂git clone https://github.com/universal-ctags/ctags.git cd ctags ./autogen.sh ./configure make -j$(nproc) sudo make install编译过程中依赖的包主要是gcc、make和pkg-config确保这几个已经装了就行。装完之后把/usr/local/bin放到PATH最前面确认which ctags指向的是universal-ctags。生成UVM标签的命令我一般分两步。第一步给UVM库源码建tag这个可以复用不必每个工程重新生成cd /path/to/uvm-1.2/src ctags -R --languagesSystemVerilog --langmapSystemVerilog:.sv.svh --fieldsnKSt .第二步给当前验证工程建tag工程下通常有rtl、tb、tests、agents这些目录cd /path/to/your_project ctags -R --languagesSystemVerilog --langmapSystemVerilog:.sv.svh --fieldsnKSt --exclude*.log --exclude*.vcd ..vimrc里添加对tags文件的查找路径让Vim自动从当前目录往上找tagsset tags./tags;,tags;分号的含义是如果当前目录没找到tags就逐级向父目录搜索。这样在工程任意子目录打开代码都能跳转到正确位置。跳转操作本身是Vim内建的Ctrl]跳到定义Ctrlt跳回Ctrlo和Ctrli在历史位置间来回。建议把Ctrlo/Ctrli这两个键位练成肌肉记忆用起来跟IDE里的“后退/前进”一样顺滑。实际使用中有一个细节很容易被忽略UVM库的tags和工程tags如果同名放在不同目录就行Vim会按tags顺序找到第一个匹配就把结果跳过去。所以我会把UVM库的tags位置直接追加到tags搜索路径里这样就算没进工程目录也能跳到UVM源码set tags/path/to/uvm-1.2/src/tags3.3 自动补全与代码模板从“少敲键盘”到“少动脑子”补全这块很多人的第一反应是上YouCompleteMe或者coc.nvim但对SystemVerilog来说这些通用语言服务器的支持并不算成熟装起来又重又容易踩坑。我的实际经验是在UVM开发这种语言结构高度模板化的场景里tag文件补全加代码模板的组合已经能覆盖九成以上的补全需求。Vim自带的关键字补全是Ctrln和Ctrlp默认只匹配当前文件打开tags之后可以把tags也纳入补全来源效果立刻提升一大截set completeoptmenu,menuone,longest set omnifuncsyntaxcomplete#Complete set complete.,w,b,u,tt选项表示从tags文件补充候选词。配合vim-systemverilog的语法文件输入uvm_之后再敲补全键就能列出UVM库里的各种类和宏虽然不如IDE的语义补全那么智能但写一个组件类名还是绰绰有余。模板方面我用的是UltiSnips。它可以自定义代码片段输入短前缀再按Tab自动展开成完整代码块。对UVM来说最实用的莫过于标准组件骨架比如新建一个sequence时只需输入seq再加Tab就能快速生成一大段UVM标准框架。我的UltiSnips配置里有一个专门的verilog.snippets文件定义了几个高频模板snippet seq UVM sequence skeleton class 1 extends uvm_sequence #(2); uvm_object_utils(1) function new(string name 1); super.new(name); endfunction uvm_declare_p_sequencer(3) virtual task body(); // TODO endtask endclass endsnippet实际效果就是在文件里输入seq按Tab展开成整个类骨架类名、参数名直接用Tab跳转点填充。UVM的agent、driver、monitor、test我都做了对应的模板新建组件时基本只需要填类名和几个参数省下大量重复敲击。UltiSnips的安装需要先装vim-plug然后Plug SirVer/ultisnips Plug honza/vim-snippets另外注意UltiSnips和另一个补全库可能会同时占用Tab键如果发现Tab被别的插件抢了可以在.vimrc里显式指定let g:UltiSnipsExpandTriggertab let g:UltiSnipsJumpForwardTriggertab let g:UltiSnipsJumpBackwardTriggers-tab4. 辅助插件与效率提升文件导航、注释和状态栏的细节代码写起来顺了接下来就是文件切换和导航。UVM工程动辄上百个文件tb顶层、agent、sequence、reg_model、testcase分布在几十个目录里光靠CtrlP一个个拼路径显然不现实。辅助插件的价值就在这里体现它们不直接参与代码编辑但能大幅度压缩你“找文件、看结构、切上下文”的时间。4.1 文件导航NERDTree加fzf组合拳NERDTree是老牌的文件树插件装好后用Ctrln一键开关所有文件层级一眼看清。对UVM工程来说把源码目录挂在左侧点开agent目录、找到seq目录、打开某个sequence文件整个路径关系在脑子里会非常清晰。安装配置Plug preservim/nerdtree nnoremap C-n :NERDTreeToggleCR nnoremap C-f :NERDTreeFindCRNERDTreeFind特别实用当你正在编辑一个文件时按一下就能在文件树里定位到当前文件的位置快速了解自己正处于工程什么层级。但文件树只是第一步当工程规模大了以后tree的展开速度会变慢按钮点起来也不如在IDE里那么跟手。这时就要上模糊搜索我用的是fzf.vim配合fd或ripgrep。fzf本身是一个通用的模糊查找器集成进gvim之后Ctrlp变成按文件名搜索Ctrlg变成按文件内容搜索基本替代了grep加CtrlF的老流程Plug junegunn/fzf Plug junegunn/fzf.vim let g:fzf_layout { down: 40% } nnoremap C-p :FilesCR nnoremap C-g :RgCR注意fzf.vim依赖系统里的fzf二进制和ripgrep需要额外安装sudo apt install fzf ripgrepripgrep负责内容搜索速度非常快在整仓UVM代码里搜一个信号名一秒内返回全部匹配结果。对比一下Vim内建grep简直是马车和动车组的差别。4.2 注释、环绕编辑和窗口操作写代码的“加速键”写代码的时候经常要做两步操作选中一大段代码注释掉、给某个信号名加上反引号或者括号。这些操作看起来小但积累起来很耗时间。我装了nerdcommenter处理注释以及vim-surround处理成对符号Plug preservim/nerdcommenter Plug tpope/vim-surroundnerdcommenter默认用法是在可视化模式下选中代码然后按gc注释、按gcu取消注释。配置文件里我额外设置了几个映射方便不切模式的注释nmap leader/ gcc vmap leader/ gcvim-surround则是用cs、ds、ys三个操作符控制包围符号。比如光标在变量名上按ysiw就把整个单词包上双引号按cs把双引号换成单引号按ds直接删除。写UVM代码时经常要把信号名包进反引号、把参数包进括号这套操作节省的时间非常可观。窗口操作方面由于验证工程师经常要对照着看两份文件比如sequence和对应的driver我做了几个快速分屏映射nnoremap leaderwv :vsplitCR nnoremap leaderwh :splitCR nnoremap leaderwq :qCR nnoremap leadere :editSpace配合前面的CtrlH/J/K/L窗口切换基本能做到鼠标不碰所有窗口操作键盘完成。4.3 状态栏、结构预览与视觉体验最后是让gvim看起来更“现代”的部分。vim-airline让底部状态栏显示文件类型、光标位置、git分支和当前函数名tagbar则把当前文件的函数、类、任务、宏列成一个大纲面板点一下就跳转。这两个配合起来在大文件里摸清代码结构非常直观Plug vim-airline/vim-airline Plug preservim/tagbar nnoremap F8 :TagbarToggleCRtagbar依赖ctags生成当前文件的结构如果用了我前面说的universal-ctags它能正确定位到UVM类里的task和function显示粒度比默认ctags细很多。在agent文件里按F8左侧大纲列出run_phase、connect_phase、build_phase点击直接跳到对应实现比手动找快一个数量级。颜色主题方面白天用desert或者industry晚上用gruvbox或者monokai。我自己用得最多的是gruvbox颜色柔和、对比度高长时间盯屏不会太疲劳Plug morhetz/gruvbox set backgrounddark colorscheme gruvbox set t_Co256字体这块如果用的是gvim图形界面建议设一个支持中文和特殊字符的等宽字体比如Noto Sans Mono CJK SC或者Source Code Proset guifontNoto\ Sans\ Mono\ CJK\ SC\ 12终端环境下的字体交给终端模拟器管gvim里设置了反而可能出现乱码这一点在不同环境里要多试几次。5. 常见问题与排查技巧实录踩过的坑都在这里配置插件的过程中有几个问题属于“网上教程都说过但真要复现时还是会卡住”的类型。我把这些年踩过的坑整理成一个清单按问题现象、原因、解决方案的格式列出来方便你直接对照排查。5.1 插件管理器装插件报错经常卡在下载环节现象vim-plug执行:PlugInstall时部分插件一直显示“Installing”或者报网络错误。原因插件仓库托管在代码托管平台内网服务器访问外网时往往需要代理或者网络本身就不稳定。加上部分仓库体积比较大容易超时。排查思路这一步一定先确认git能否正常访问插件仓库地址可以手动执行git clone https://github.com/SomeAuthor/SomePlugin.git /tmp/test_plugin如果手动clone也超时那就是网络层问题需要配置git代理或者换一个网络环境。如果手动clone正常大概率是vim-plug的超时阈值太短可以加长let g:plug_timeout 120另外一个经验是很多插件在国内有镜像或者用户自建的加速仓库把Plugin地址换成对应的镜像地址也能绕过问题。但这里我不推荐依赖第三方镜像因为维护状态不稳定日期一长容易失效。最稳妥的办法还是从仓库获取原始代码耐心等它下载完。5.2 Vim启动时间明显变慢从0.3秒涨到2秒现象装了五六个插件之后每次启动gvim都会卡一下状态栏迟迟不出来。原因默认情况下vim-plug会把所有插件全部加载哪怕只是打开一个txt文件也会加载verilog语法、加载fzf、加载tagbar这些跟当前文件无关的插件。排查方法先量一下启动时间Vim自带性能分析vim --startuptime /tmp/vim.log打开log看看哪一行消耗时间最多基本都是某个插件在加载时执行了大量初始化脚本。解决办法是利用vim-plug的延迟加载特性把某些插件改成按命令或按文件类型加载Plug preservim/nerdtree, { on: NERDTreeToggle } Plug preservim/tagbar, { on: TagbarToggle } Plug junegunn/fzf, { on: Files }这样NERDTree、tagbar、fzf这些只在按快捷键时才会初始化日常启动时完全不载入启动时间能压回0.5秒以内。UltiSnips属于日常写代码就会用到的我选择按文件类型加载Plug SirVer/ultisnips, { for: verilog_systemverilog }5.3 Ctrl]跳转没反应或者跳错地方现象在某个UVM类名上按Ctrl]Vim提示找不到tag或者跳到了一个完全不相干的位置。排查步骤先确认tags文件是否存在于当前目录或者上级目录Vim是否真的加载了它:set tags? :echo taglist(uvm_component_utils)如果tags路径没问题但就是找不到某个特定符号最可能的原因是工具有限。检查一下当前用的ctags是否universal-ctagsctags --version老版ctags对SystemVerilog的宏和重名类支持不足跳转自然不准。另外如果有多个同名类分布在不同的class文件里Vim会默认跳到第一个匹配这时可以在跳转后用:ts列出所有匹配项再选择具体目标。我习惯映射一个快捷键替代默认Ctrl]nnoremap C-] :tjump C-RC-wCR这样在类名上按Ctrl]如果匹配项多于一个会弹出选择列表不会直接跳到错误位置。5.4 打开文件中文乱码现象从Windows拷贝过来的SV文件用gvim打开后中文注释变成一片乱码。原因文件以GBK编码保存但Vim默认按utf-8解码两边对不上。解决方法前面提到的fileencodings已经覆盖了这种情况但要注意配置顺序。fileencodings里的编码顺序决定了Vim尝试解码的先后顺序ucs-bom要放第一位因为带BOM的utf-8文件如果不先识别BOM后续解码容易出错。我的顺序是set fileencodingsucs-bom,utf-8,cp936,gb18030,big5,latin1如果发现某个文件局部乱码还可以在打开后手动指定编码重新加载:e encgb18030乱码主要是显示问题最根源的解决办法还是统一工程内的文件编码标准建议所有代码文件统一用utf-8保存提交到版本控制时也能避免各种跨平台diff的凌乱结果。5.5 gvim图形界面颜色、字体和终端环境不一致现象同样的colorscheme终端下看着正常gvim图形界面下颜色很刺眼或者字体模糊。原因终端和图形界面使用的字体渲染方式不同颜色显示也受终端256色配置影响。解决方法图形界面下通过guifont指定字体终端环境下通过background和t_Co调整颜色。我通常会把两种环境的配置分开处理if has(gui_running) set guifontNoto\ Sans\ Mono\ CJK\ SC\ 12 set backgrounddark colorscheme gruvbox else set t_Co256 set backgrounddark colorscheme gruvbox endif有一点要特别提醒如果你用MobaXterm或者Xshell连接服务器远程的终端模拟器本身也要设置正确的字体和256色支持否则Vim里配置的colorscheme到了终端显示会大打折扣。5.6 UltiSnips模板展开失败现象输入seq后按Tab没展开成模板反而插入了一个普通Tab。原因通常是UltiSnips没有正确加载对应文件类型的snippets或者Tab键被其他插件占用了。排查方法命令模式下检查UltiSnips是否正常:UltiSnipsList如果能列出snippets说明加载没问题问题出在按键冲突。用:verbose imap 查看Tab键被什么映射占用可以清楚看到UltiSnips和其他插件的“抢键”情况。找到占用Tab的插件后在.vimrc里调整两者的加载顺序或者改造快捷键方案。5.7 fzf显示异常或者搜索不到内容现象按Ctrlp弹出fzf窗口但里面是空白的或者结果少得离谱。原因fzf本身没装好或者vim插件里的fzf二进制版本不匹配。排查方法先在shell里直接运行fzf测试echo test | fzf如果shell里正常再检查vim里:echo $PATH是否包含fzf所在目录。服务器环境的PATH经常被各种脚本改来改去vim继承到的PATH和登录shell不一致的情况很常见直接在.vimrc里指定fzf路径最省心let $FZF_DEFAULT_COMMAND rg --files --hidden set rtp/usr/local/bin/fzf6. 最后再聊聊“定制”这件事以上这些插件和配置我按自己的使用习惯整理下来用了很长时间。你可以直接照抄也可以只挑其中一部分重要的是理解每一条配置背后的逻辑——它不是装饰品而是在真正解决写代码过程中遇到的具体问题。我个人的体会是gvim插件配置这件事没有“最终版”。今天用下来完美顺手的方案换一个工程、换一种网络环境、甚至换一个UVM版本之后可能就需要微调。比如有的项目里UVM库版本从1.2换成1.1d某些宏定义变化导致tag跳转失效这种时候维护一个属于自己的“配置笔记”比背一个“万能配置”更实用。把每次都调整的原因和操作记录下来时间久了这套配置就成了完全贴合你工作习惯的私人工具。最后分享一个小技巧把整个.vimrc和vim-plug的插件列表放到自己的dotfiles仓库里配合一个一键安装脚本。到新服务器干活时clone下来跑一遍五分钟内就能恢复到和本地完全一致的工作环境。这个习惯帮我省了无数次在新机器上重新配环境的时间也建议你早点养成。
