1
0
wiki/FormalSciences/ComputerScience/GettingStarted/3.CommandLineTools/Vim/3.Vim 高级功能.md
2024-10-13 20:54:08 +08:00

16 KiB
Raw Blame History

title description keywords tags author date
Vim 高级功能 探索 Vim 的高级功能如正则表达式、多行编辑、宏录制、VimScript 脚本语言及自动化工作流。
Vim
高级功能
正则表达式
宏录制
VimScript
自动化
技术/入门
Vim
仲平 2024-08-08

高级技巧

高级文本操作

正则表达式

功能 命令或表达式 说明
向前搜索 /pattern 向前搜索匹配的模式
向后搜索 ?pattern 向后搜索匹配的模式
全文替换 :%s/pattern/replacement/g 全文替换所有匹配的模式
当前行替换 :s/pattern/replacement/g 替换当前行所有匹配的模式
删除行首空白 :%s/^\s\+//g 删除每行开头的空白字符
删除行尾空白 :%s/\s\+$//g 删除每行结尾的空白字符
匹配任意字符 . 匹配任意字符
匹配数字字符 \d 匹配数字字符
匹配非数字字符 \D 匹配非数字字符
匹配字母或数字字符 \w 匹配字母或数字字符
匹配非字母或数字字符 \W 匹配非字母或数字字符
匹配行首 ^ 匹配行首
匹配行尾 $ 匹配行尾

多行编辑

功能 命令 说明
行可视模式 V 进入行可视模式
字符可视模式 v 进入字符可视模式
块可视模式 Ctrl+v 进入块可视模式
在每行开头添加 :%s/^/#/ 使用正则表达式在每行开头添加 #
在每行结尾添加 :%s/$/;/ 使用正则表达式在每行结尾添加 ;

宏录制与播放

功能 命令 说明
录制宏 qx ... q 开始录制宏,x 是寄存器名,执行一系列命令后停止录制
播放宏 @x 播放寄存器 x 中的宏
重复播放宏 @@ 重复播放上一个宏
多次播放宏 10@x 播放寄存器 x 中的宏 10 次

VimScript

基本语法

VimScript 是 Vim 的脚本语言,用于扩展和定制 Vim 的功能。以下是一些基本语法:

" 这是一个注释

" 变量
let myvar = 42           " 整数变量
let mystr = "Hello"      " 字符串变量

" 条件语句
if myvar > 0
    echo "Positive"
elseif myvar == 0
    echo "Zero"
else
    echo "Negative"
endif

" 循环语句
let i = 0
while i < 5
    echo i
    let i += 1
endwhile

for item in [1, 2, 3, 4, 5]
    echo item
endfor

函数和变量

" 定义函数
function! MyFunction(arg)
    echo a:arg
endfunction

" 调用函数
call MyFunction("Hello")

" 局部变量
function! MyFunction()
    let l:localVar = "I am local"
    echo l:localVar
endfunction

" 全局变量
let g:globalVar = "I am global"
echo g:globalVar

编写和调试简单的 VimScript 脚本

编写脚本

将 VimScript 代码写入 .vim 文件,例如 myplugin.vim

" myplugin.vim
function! SayHello()
    echo "Hello, Vim!"
endfunction
command! SayHello call SayHello()

加载脚本

将脚本放入 Vim 的 plugin 目录,启动 Vim 自动加载:

mkdir -p ~/.vim/plugin
cp myplugin.vim ~/.vim/plugin/

调试脚本

使用 echo 命令输出调试信息:

echo "Debug info: " . someVar

使用 :messages 查看所有输出信息。

自动化

使用自动命令

自动命令autocommand允许在特定事件发生时自动执行命令例如文件保存、打开等。

augroup MyAutoCmd
    autocmd!
    autocmd BufWritePost *.txt :echo "Text file saved!"
augroup END
事件 说明 权重
BufReadPost 文件读取后 5
BufWritePost 文件写入后 5
BufNewFile 新建文件 4
FileType 文件类型检测 5
BufEnter 缓冲区进入 4
BufLeave 缓冲区离开 4
VimEnter Vim 启动后 5
VimLeave Vim 退出前 5
WinEnter 窗口进入 3
WinLeave 窗口离开 3

配置文件模板

~/.vim/templates/ 目录中创建模板文件,例如 python_template.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on <++>

@author: <++>
"""

def main():
    pass

if __name__ == "__main__":
    main()

使用自动命令应用模板:

augroup MyTemplates
    autocmd!
    autocmd BufNewFile *.py 0r ~/.vim/templates/python_template.py
augroup END

高效工作流

版本控制集成

使用 Vim-fugitive

安装 vim-fugitive

vimrc 文件中添加以下内容(以 vim-plug 为例):

call plug#begin('~/.vim/plugged')
Plug 'tpope/vim-fugitive'
call plug#end()

基本用法

功能 命令 说明
查看 Git 状态 :Gstatus 打开一个新窗口显示当前 Git 仓库的状态。可以在该窗口中导航和操作。
Git 添加 - :Gstatus 窗口中,将光标移动到文件名上,按 - 号将文件添加到索引。
Git 提交 :Gcommit 打开一个新的缓冲区输入提交信息,完成后保存并关闭缓冲区即可提交。
Git 推送 :Gpush 将本地提交推送到远程仓库。
Git 拉取 :Gpull 从远程仓库拉取最新的代码。
Git 日志 :Glog 显示 Git 提交日志,可以在日志中导航和查看每个提交的详细信息。
Git 分支 :Gbranch 显示和管理 Git 分支。

常用 Git 命令

在 Vim 中,使用 vim-fugitive 可以执行常见的 Git 命令。同时你也可以在 Vim 外部使用 Git 命令行工具:

功能 命令 说明
克隆仓库 git clone <repository_url> 克隆一个远程仓库到本地。
查看状态 git status 查看当前仓库的状态。
添加文件 git add <file> 添加文件到索引。
提交更改 git commit -m "Commit message" 提交已添加的更改。
推送到远程仓库 git push 将本地提交推送到远程仓库。
拉取最新代码 git pull 从远程仓库拉取最新的代码。
创建新分支 git checkout -b <new_branch> 创建一个新的分支并切换到该分支。
合并分支 git merge <branch> 将指定分支合并到当前分支。

项目管理

NERDTree

vimrc 文件中添加以下内容(以 vim-plug 为例):

call plug#begin('~/.vim/plugged')
Plug 'preservim/nerdtree'
call plug#end()

打开/关闭 NERDTree

:NERDTreeToggle

或者添加快捷键映射:

nnoremap <C-n> :NERDTreeToggle<CR>

在 NERDTree 中导航

  • 使用 jk 键上下移动
  • 使用 o 键打开文件或目录
  • 使用 x 键关闭目录

显示隐藏文件

:NERDTreeShowHidden

配置项目相关设置

项目特定的 vimrc

在项目根目录下创建一个 .vimrc 文件,包含项目特定的 Vim 配置。然后在主 vimrc 中添加以下内容:

if filereadable("path/to/project/.vimrc")
    source path/to/project/.vimrc
endif

自动切换项目配置

可以使用 vim-rooter 插件自动切换项目根目录并加载项目特定的配置。在 vimrc 中添加以下内容:

call plug#begin('~/.vim/plugged')
Plug 'airblade/vim-rooter'
call plug#end()
let g:rooter_patterns = ['.git', '.hg', '.svn', 'Makefile']

代码补全与调试

YouCompleteMe 代码补全

YouCompleteMe 是一个强大的代码补全插件,需要编译安装。具体步骤如下:

  1. 安装依赖(以 Ubuntu 为例):

    sudo apt install build-essential cmake python3-dev
    
  2. 安装 YouCompleteMe

    git clone https://github.com/ycm-core/YouCompleteMe.git ~/.vim/bundle/YouCompleteMe
    cd ~/.vim/bundle/YouCompleteMe
    git submodule update --init --recursive
    python3 install.py --all
    
  3. vimrc 中添加以下内容:

    call plug#begin('~/.vim/plugged')
    Plug 'ycm-core/YouCompleteMe'
    call plug#end()
    

Deoplete 代码补全

Deoplete 是另一种流行的代码补全插件,基于 Neovim。

  1. 安装依赖(以 Neovim 为例):

    pip install neovim
    
  2. vimrc 中添加以下内容:

    call plug#begin('~/.vim/plugged')
    Plug 'Shougo/deoplete.nvim', {'do': ':UpdateRemotePlugins'}
    Plug 'Shougo/neosnippet.vim'
    Plug 'Shougo/neosnippet-snippets'
    call plug#end()
    
    let g:deoplete#enable_at_startup = 1
    

Vimspector 代码调试

vimrc 文件中添加以下内容(以 vim-plug 为例):

call plug#begin('~/.vim/plugged')
Plug 'puremourning/vimspector'
call plug#end()

基本配置

.vimspector.json 文件,定义调试配置,例如:

{
    "configurations": {
        "Launch": {
            "adapter": "debugpy",
            "configuration": {
                "request": "launch",
                "program": "${workspaceFolder}/your_script.py",
                "console": "integratedTerminal"
            }
        }
    }
}

使用

  1. 启动调试会话:

    :VimspectorLaunch
    
  2. 设置断点: 将光标移动到需要设置断点的行,按 F9 键。

  3. 继续执行、单步执行和停止调试: 使用 F5F10F11F12 键进行调试控制。

性能优化

启动优化

延迟加载插件

延迟加载插件可以显著提高 Vim 的启动速度,只在需要时加载插件。

使用 vim-plug 进行延迟加载

  1. vimrc 中配置延迟加载:

    call plug#begin('~/.vim/plugged')
    Plug 'tpope/vim-fugitive', { 'on': 'Gstatus' }
    Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
    call plug#end()
    

    以上配置将 vim-fugitive 插件仅在执行 :Gstatus 命令时加载NERDTree 插件仅在执行 :NERDTreeToggle 命令时加载。

使用 lazy.nvim 插件管理器

lazy.nvim 是一个专门用于延迟加载插件的插件管理器。

  1. 安装 lazy.nvim

    git clone https://github.com/folke/lazy.nvim.git ~/.vim/pack/lazy/start/lazy.nvim
    
  2. 配置延迟加载:

    call lazy#load_plugin('nerdtree', { 'on': 'NERDTreeToggle' })
    

精简配置文件

移除不必要的配置

定期检查 vimrc 文件,移除不再使用的配置和插件,以减少 Vim 的启动时间和运行负担。

分离插件配置

将插件的配置分离到独立的文件中,以保持 vimrc 简洁。例如,将 NERDTree 的配置放在 ~/.vim/plugin/nerdtree.vim 中:

" ~/.vim/plugin/nerdtree.vim
nnoremap <C-n> :NERDTreeToggle<CR>

使用本地配置

根据项目需求,在项目根目录下创建 .vimrc.vim/ 目录,存放项目特定的配置文件,以避免在全局配置中添加过多内容。

系统集成

将 Vim 与 Tmux 结合使用

tmux 是一个终端复用器,允许你在一个终端窗口中运行多个会话,与 Vim 结合使用可以大大提高工作效率。

安装 tmux

在 Linux 或 MacOS 中,可以使用包管理器安装 tmux

sudo apt install tmux   # Debian/Ubuntu
brew install tmux       # macOS
功能 命令 说明
启动 tmux 会话 tmux 启动一个新的 tmux 会话
新建会话 tmux new -s session_name 创建一个名为 session_name 的新会话
附加会话 tmux attach -t session_name 附加到一个名为 session_name 的会话
列出会话 tmux ls 列出所有 tmux 会话
杀死会话 tmux kill-session -t session_name 杀死一个名为 session_name 的会话
分离会话 Ctrl-b d 分离当前会话
新建窗口 Ctrl-b c 创建一个新窗口
切换窗口 Ctrl-b n 切换到下一个窗口
切换窗口 Ctrl-b p 切换到上一个窗口
重命名窗口 Ctrl-b , 重命名当前窗口
分割窗格 Ctrl-b % 垂直分割当前窗格
分割窗格 Ctrl-b " 水平分割当前窗格
切换窗格 Ctrl-b o 切换到下一个窗格
关闭窗格 Ctrl-b x 关闭当前窗格
同步窗格 Ctrl-b :setw synchronize-panes on 在所有窗格中同步输入
切换会话 Ctrl-b s 列出所有会话并切换

与 Vim 集成

vimrc 中添加快捷键映射,方便与 tmux 交互:

nnoremap <silent> <Leader>h :TmuxNavigateLeft<CR>
nnoremap <silent> <Leader>j :TmuxNavigateDown<CR>
nnoremap <silent> <Leader>k :TmuxNavigateUp<CR>
nnoremap <silent> <Leader>l :TmuxNavigateRight<CR>

需要安装 christoomey/vim-tmux-navigator 插件:

call plug#begin('~/.vim/plugged')
Plug 'christoomey/vim-tmux-navigator'
call plug#end()

在终端中使用 Vim

在终端中使用 Vim 可以提高工作效率,特别是当你需要频繁切换编辑器和命令行时。

配置终端

选择一个支持丰富功能的终端,例如 iTerm2macOSAlacritty(跨平台)、GNOME TerminalLinux

终端快捷键配置

根据需要配置终端快捷键,方便打开 Vim。例如iTerm2 中,可以设置快捷键快速打开新的终端窗口或标签,并启动 Vim。

Shell 集成

~/.bashrc~/.zshrc 中添加别名和函数,提高使用 Vim 的效率:

alias vi="vim"
alias svi="sudo vim"
alias vrc="vim ~/.vimrc"

# 快速打开项目目录中的 Vim
function vproj() {
    cd ~/projects/$1 && vim
}

使用 FZF 进行文件搜索

FZF 是一个命令行模糊查找工具,可以与 Vim 集成,快速搜索和打开文件。

  1. 安装 FZF

    git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
    ~/.fzf/install
    
  2. vimrc 中配置 FZF

    call plug#begin('~/.vim/plugged')
    Plug 'junegunn/fzf'
    Plug 'junegunn/fzf.vim'
    call plug#end()
    
    " 使用 FZF 查找文件
    nnoremap <Leader>f :Files<CR>