提示

Nvim :help 页面,从 源代码 生成,使用 tree-sitter-vimdoc 解析器。


使用 Vim 的技巧和想法
这些只是一些我们认为对许多用户有用的提示。你可以在维基页面上找到更多提示。网址可以在 https://www.vim.org 上找到。
不要忘记浏览用户手册,它也包含许多有用的提示 usr_toc.txt

编辑 C 程序 C-editing

Vim 中有相当多的功能可以帮助你编辑 C 程序文件。以下是一个带有标签的概述,你可以跳转到这些标签。
usr_29.txt 用户手册中“在程序中移动”一章。 usr_30.txt 用户手册中“编辑程序”一章。 C-indenting 在键入文本时自动设置行的缩进。 = 重新缩进几行。 format-comments 格式化注释。
:checkpath 显示所有递归包含的文件。 [i 在当前文件和包含文件中搜索光标下的标识符。 [_CTRL-I 跳到“[i”的匹配项。 [I 列出当前文件和包含文件中所有光标下标识符匹配的行。 [d 在当前文件和包含文件中搜索光标下的定义。
CTRL-] 跳到光标下的标签(例如,函数的定义)。 CTRL-T 跳回CTRL-]命令之前的状态。 :tselect 从匹配标签列表中选择一个标签。
gd 转到光标下局部变量的声明。 gD 转到光标下全局变量的声明。
gf 转到光标下的文件名。
% 转到匹配的 (),{},[],/* */,#if,#else,#endif。 [/ 转到前一个注释的开始。 ]/ 转到下一个注释的结束。 [# 回到未闭合的 #if,#ifdef 或 #else。 ]# 前进到未闭合的 #else 或 #endif。 [( 回到未闭合的 '(' ]) 前进到未闭合的 ')' [{ 回到未闭合的 '{' ]} 前进到未闭合的 '}'
v_ab 从 "[(" 到 "])" 选择一个“块”,包括大括号 v_ib 从 "[(" 到 "])" 选择一个“内部块” v_aB[{]} 选择一个“块”,包括中括号 v_iB[{]} 选择一个“内部块”

查找标识符的使用位置 ident-search

你可能已经知道,标签 可用于跳转到函数或变量的定义位置。但是有时你希望能够跳转到函数或变量的所有使用位置。这可以通过两种方式实现:1. 使用 :grep 命令。这应该在大多数 Unix 系统上工作,但速度可能很慢(它读取所有文件)并且只在一个目录中搜索。2. 使用 ID 工具。这很快,并且可以在多个目录中工作。它使用数据库来存储位置。你需要一些额外的程序才能使它工作。并且你需要保持数据库的最新状态。
使用 GNU id-tools
你需要什么
安装了 GNU id-tools(需要 mkid 来创建 ID,需要 lid 来使用宏)。
当前目录中有一个名为“ID”的标识符数据库文件。你可以使用 shell 命令“mkid file1 file2 ..”来创建它。
将此代码放在你的 init.vim 文件中
map _u :call ID_search()<Bar>execute "/\\<" .. g:word .. "\\>"<CR>
map _n :n<Bar>execute "/\\<" .. g:word .. "\\>"<CR>
function! ID_search()
  let g:word = expand("<cword>")
  let x = system("lid --key=none " .. g:word)
  let x = substitute(x, "\n", " ", "g")
  execute "next " .. x
endfun
要使用它,将光标放在一个词上,输入“_u”,vim 将加载包含该词的文件。使用“n”在同一文件中搜索该词的下一个出现位置。使用“_n”转到下一个文件。
这已经在 id-utils-3.2 上测试过(这是你最接近的 gnu-ftp-镜像上的 id-tools 存档文件的名字)。
[这个想法来自 Andreas Kutschera]

在插入模式下滚动 scroll-insert

如果你处于插入模式,并且想要查看屏幕上看不到的内容,你可以使用 CTRL-X CTRL-ECTRL-X CTRL-Y 来滚动屏幕。 i_CTRL-X_CTRL-E
为了使这更方便,你可以使用以下映射
:inoremap <C-E> <C-X><C-E>
:inoremap <C-Y> <C-X><C-Y>
这样你将失去从光标上方/下方复制文本的能力 i_CTRL-E
还可以考虑将 'scrolloff' 设置为更大的值,这样你就可以始终看到光标周围的一些上下文。如果 'scrolloff' 大于窗口高度的一半,光标将始终位于中间,并且在光标向上/向下移动时文本将滚动。

平滑滚动 scroll-smooth

如果你喜欢滚动更平滑一些,你可以使用以下映射
:map <C-U> <C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y>
:map <C-D> <C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E><C-E>

纠正常见的打字错误 type-mistakes

当你一直用错误的方式键入某些词时,可以创建缩写来纠正它们。例如
:ab teh the
:ab fro for

计算单词、行等 count-items

要计算当前缓冲区中任何模式出现的次数,请使用替换命令并添加“n”标志以避免替换。报告的替换次数就是项目数量。示例
:%s/./&/gn                characters
:%s/\i\+/&/gn                words
:%s/^//n                lines
:%s/the/&/gn                "the" anywhere
:%s/\<the\>/&/gn        "the" as a word
你可能想要重置 'hlsearch' 或执行“:nohlsearch”。如果不想在没有匹配项时出现错误,请添加“e”标志。
另一种方法是在可视模式下使用 v_g_CTRL-G
如果你想要在多个文件中查找匹配项,请使用 :vimgrep
count-bytes
如果你想要计算字节,可以使用以下方法
可视地选择字符(也可以选择块)。使用“y”来剪切字符。使用 strlen() 函数。
:echo strlen(@")
换行符计为一个字节。

恢复光标位置 restore-position

有时你想要编写一个映射,它会在文件中的某个位置进行更改并恢复光标位置,而不会滚动文本。例如,要更改文件中的日期标记
:map <F2> msHmtgg/Last [cC]hange:\s*/e+1<CR>"_D"=strftime("%Y %b %d")<CR>p'tzt`s
将保存位置分解:ms 将光标位置存储在“s”标记中。H 转到窗口的第一行。mt 将此位置存储在“t”标记中。
将恢复位置分解:“t 转到之前位于窗口顶部的行。zt 滚动以将此行移动到窗口顶部。s 跳到光标的原始位置。
对于更高级的功能,请参阅 winsaveview()winrestview()

重命名文件 rename-files

假设我有一个包含以下文件的目录(随机选择的目录 :-)
buffer.c charset.c digraph.c

...

并且我想将 *.c 重命名为 *.bla。我会这样做
$ vim
:r !ls *.c
:%s/\(.*\).c/mv & \1.bla
:w !sh
:q!

在多个文件中更改名称 change-name

使用脚本文件在多个文件中更改名称的示例
创建一个名为“subs.vim”的文件,其中包含替换命令和一个:update 命令
:%s/Jones/Smith/g
:%s/Allen/Peter/g
:update
对要更改的所有文件执行 Vim,并为每个参数源代码该脚本
vim *.let
argdo source subs.vim
请参阅 :argdo

加快外部命令速度 speed-up

在某些情况下,执行外部命令的速度可能非常慢。这也会减慢 Unix 上通配符扩展的速度。以下是一些提高速度的建议。
如果你的 .cshrc(或其他文件,取决于使用的 shell)非常长,你应该将其分为一个用于交互式使用的部分和一个用于非交互式使用的部分(通常称为二级 shell)。当从 Vim 执行命令(如“:!ls”)时,你不需要交互式内容(例如,设置提示符)。将不需要的内容放在以下行之后
if ($?prompt == 0) then
        exit 0
endif
另一种方法是在 'shell' 选项中包含“-f”标志,例如
:set shell=csh\ -f
(反斜杠用于在选项中包含空格)。这将使 csh 完全跳过使用 .cshrc 文件。不过,这可能会导致某些功能停止工作。

有用的映射 useful-mappings

以下是一些一些人喜欢使用的映射。
map-backtick
:map ' `
使单引号像反引号一样工作。将光标放在标记的列上,而不是转到行中的第一个非空白字符。
emacs-keys
在命令行上使用 Emacs 风格的编辑
" start of line
:cnoremap <C-A>                <Home>
" back one character
:cnoremap <C-B>                <Left>
" delete character under cursor
:cnoremap <C-D>                <Del>
" end of line
:cnoremap <C-E>                <End>
" forward one character
:cnoremap <C-F>                <Right>
" recall newer command-line
:cnoremap <C-N>                <Down>
" recall previous (older) command-line
:cnoremap <C-P>                <Up>
" back one word
:cnoremap <Esc><C-B>        <S-Left>
" forward one word
:cnoremap <Esc><C-F>        <S-Right>
format-bullet-list
此映射将格式化任何项目符号列表。它要求每个列表条目上方和下方都有一行空行。使用表达式命令可以对映射的部分进行注释。
:let m =     ":map _f  :set ai<CR>"   " need 'autoindent' set
:let m ..= "{O<Esc>"                      " add empty line above item
:let m ..= "}{)^W"                      " move to text after bullet
:let m ..= "i     <CR>     <Esc>"     " add space for indent
:let m ..= "gq}"                      " format text after the bullet
:let m ..= "{dd"                      " remove the empty line
:let m ..= "5lDJ"                      " put text after bullet
:execute m                              |" define the mapping
(<> 符号 <>。注意,这些符号都是按字面意思输入的。^W 是“^” “W”,而不是

CTRL-W)。

注意,最后一个注释以 |" 开头,因为“:execute”命令不直接接受注释。
你还需要将 'textwidth' 设置为非零值,例如
:set tw=70
一个完成几乎相同功能的映射,但会从第一行获取列表的缩进(注意:此映射是一行很长的行,包含很多空格)
:map _f :set ai<CR>}{a                                                          <Esc>WWmmkD`mi<CR><Esc>kkddpJgq}'mJO<Esc>j
collapse
这两个映射将一系列空行 (;b) 或空白行 (;n) 缩减为一行
:map ;b   GoZ<Esc>:g/^$/.,/./-j<CR>Gdd
:map ;n   GoZ<Esc>:g/^[ <Tab>]*$/.,/[^ <Tab>]/-j<CR>Gdd

压缩帮助文件 gzip-helpfile

对于那些磁盘空间非常紧张的用户,你可以压缩帮助文件,仍然可以使用 Vim 查看它们。这使得访问帮助文件的速度稍微慢一些,并且需要“gzip”程序。
(1) 压缩所有帮助文件:“gzip doc/*.txt”。
(2) 编辑“doc/tags”并将“.txt”更改为“.txt.gz”。
:%s=\(\t.*\.txt\)\t=\1.gz\t=
(3) 在你的 vimrc 中添加以下行
set helpfile={dirname}/help.txt.gz
其中 {dirname} 是帮助文件所在的目录。 gzip 插件将负责解压缩文件。你必须确保 $VIMRUNTIME 设置为其他 Vim 文件所在的目录,当它们不在与压缩的“doc”目录相同的位置时。请参阅 $VIMRUNTIME

十六进制编辑 hex-editing using-xxd

请参阅用户手册的 23.3 节。
如果有人为二进制文件使用特定的扩展名(例如 exe,bin 等),你可能会发现使用以下自动命令来自动化该过程非常有用,这些自动命令用于你的 init.vim 文件中。将“*.bin”更改为你想要编辑的任何以逗号分隔的扩展名列表
" vim -b : edit binary using xxd-format!
augroup Binary
  autocmd!
  autocmd BufReadPre  *.bin set binary
  autocmd BufReadPost *.bin
    \ if &binary
    \ |   execute "silent %!xxd -c 32"
    \ |   set filetype=xxd
    \ |   redraw
    \ | endif
  autocmd BufWritePre *.bin
    \ if &binary
    \ |   let s:view = winsaveview()
    \ |   execute "silent %!xxd -r -c 32"
    \ | endif
  autocmd BufWritePost *.bin
    \ if &binary
    \ |   execute "silent %!xxd -c 32"
    \ |   set nomodified
    \ |   call winrestview(s:view)
    \ |   redraw
    \ | endif
augroup END

在自动命令中使用 <> 符号 autocmd-<>

在 :autocmd 的参数中不识别 <> 符号。为了避免使用特殊字符,可以使用一个自毁映射来获取 <> 符号,然后从自动命令调用映射。示例
map-self-destroy
" This is for automatically adding the name of the file to the menu list.
" It uses a self-destroying mapping!
" 1. use a line in the buffer to convert the 'dots' in the file name to \.
" 2. store that in register '"'
" 3. add that name to the Buffers menu list
" WARNING: this does have some side effects, like overwriting the
" current register contents and removing any mapping for the "i" command.
"
autocmd BufNewFile,BufReadPre * nmap i :nunmap i<CR>O<C-R>%<Esc>:.g/\./s/\./\\./g<CR>0"9y$u:menu Buffers.<C-R>9 :buffer <C-R>%<C-V><CR><CR>
autocmd BufNewFile,BufReadPre * normal i
另一种方法,可能更好,是使用 ":execute" 命令。在字符串中,可以通过在前面加上反斜杠来使用 <> 符号。不要忘记将现有反斜杠的数量加倍,并在 '"' 前面加一个反斜杠。
autocmd BufNewFile,BufReadPre * exe "normal O\<C-R>%\<Esc>:.g/\\./s/\\./\\\\./g\<CR>0\"9y$u:menu Buffers.\<C-R>9 :buffer \<C-R>%\<C-V>\<CR>\<CR>"
对于真正的缓冲区菜单,应该使用用户函数(参见 :function),但这样就不能使用 <> 符号,这使得它不适合用作此处的示例。

突出显示匹配的括号 match-parens

此示例演示了几个高级技巧的用法
使用 CursorMoved 自动命令事件
使用 searchpairpos() 查找匹配的括号
使用 synID() 检测光标是否在字符串或注释中
使用 :match 突出显示某些内容
使用 pattern 匹配文件中的特定位置。
这应该放在 Vim 脚本文件中,因为它使用脚本局部变量。它会跳过字符串或注释中的匹配项,除非光标从字符串或注释中开始。这需要语法高亮。
matchparen 插件中使用了稍微高级一点的版本。
let s:paren_hl_on = 0
function s:Highlight_Matching_Paren()
  if s:paren_hl_on
    match none
    let s:paren_hl_on = 0
  endif
  let c_lnum = line('.')
  let c_col = col('.')
  let c = getline(c_lnum)[c_col - 1]
  let plist = split(&matchpairs, ':\|,')
  let i = index(plist, c)
  if i < 0
    return
  endif
  if i % 2 == 0
    let s_flags = 'nW'
    let c2 = plist[i + 1]
  else
    let s_flags = 'nbW'
    let c2 = c
    let c = plist[i - 1]
  endif
  if c == '['
    let c = '\['
    let c2 = '\]'
  endif
  let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' ..
        \ '=~?        "string\\|comment"'
  execute 'if' s_skip '| let s_skip = 0 | endif'
  let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip)
  if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
    exe 'match Search /\(\%' .. c_lnum .. 'l\%' .. c_col ..
          \ 'c\)\|\(\%' .. m_lnum .. 'l\%' .. m_col .. 'c\)/'
    let s:paren_hl_on = 1
  endif
endfunction
autocmd CursorMoved,CursorMovedI * call s:Highlight_Matching_Paren()
autocmd InsertEnter * match none

在当前窗口中打开帮助 help-curwin

默认情况下,帮助会在拆分窗口中显示。如果您希望它在当前窗口中打开,请尝试使用此自定义 :HelpCurwin 命令
command -bar -nargs=? -complete=help HelpCurwin execute s:HelpCurwin(<q-args>)
let s:did_open_help = v:false
function s:HelpCurwin(subject) abort
  let mods = 'silent noautocmd keepalt'
  if !s:did_open_help
    execute mods .. ' help'
    execute mods .. ' helpclose'
    let s:did_open_help = v:true
  endif
  if !empty(getcompletion(a:subject, 'help'))
    execute mods .. ' edit ' .. &helpfile
    set buftype=help
  endif
  return 'help ' .. a:subject
endfunction
主要
命令索引
快速参考