我在Vim工作了八年,不断发现新东西。 它被认为是Vim的优点。 对我而言,这是缺乏开放性的:一堆隐藏函数隐藏得太深了。
他们谈论了模态编辑和文本对象的美丽,但在我看来,Vim的本质并非如此。 Vim是被其他工具阻塞的拼凑而成的子系统。 仅在普通编辑模式下,一百多个键盘快捷键! 工具包的密集程度在很大程度上解释了Vim为什么如此有用。 如果“显示关键字的所有标签”仅为
g]
,则此命令将更频繁地使用。
在缺乏开放性的系统中,必须依靠领导才能。 但是对于Vim来说,并不是很多。 有适合初学者的文章,例如
ciw
(请勿与CIA混淆,
CIA手册针对Vim )等。 并且有沉浸在子系统中的专家文章。 但是没有人真正谈论让您惊叹的这些特殊技巧:该死的,因为过去六年中我需要它!
本文是关于我在Vim中使用的一些小技巧。 它们都不是所有细节都可以分解的,因此,如果有兴趣,我建议您挖掘其他信息。 它们也彼此不相关。 但这是正常的。 总的来说,有太多的东西可以真正帮助几乎每个人。
文章结构
Vim用户非常粗鲁,分为两类。
纯粹主义者赞赏其体积小和普遍存在。 通常,如果您必须在不熟悉的计算机上工作(例如,通过ssh),它们会最小化配置。 另一方面,扩展器在Vim中填充了插件,函数和本地映射,从而徒劳地假装使用Emacs。 如果您从他们那里取走vimrc,那么这些家伙将仍然完全无助。
您可能会猜到,与纯粹主义者相比,我更接近扩张者。 我根据基本Vim是否需要更改将技巧分为两部分。
纯粹主义者
对于模式命令,使用标准帮助视图,即
<cr>
表示按Enter键。 当您需要帮助时
:h
用于特定行,例如
:h E676
,该行将放在括号中。
普通模式下的各种命令
“:和@:
":
是保存最后执行的命令的寄存器。您可以键入
":p
以将其打印到缓冲区。
@:
重复最后一个命令。
“ =
注册“表达式”。 在这里,您可以输入任何vimL表达式并将其插入并与ctrl-R一起使用,等等。因此,例如,通过键入
"=strftime("%c")<cr>p
来插入本地时间戳。
毫安
m{letter}
将标记放置在光标位置。 然后
'{letter}
将转到此行。 对于小写字母,它作用在缓冲区上,因此适合导航。 它在全局上适用于大写字母:即使您在另一个文件中,
'A
也会转到标有
的文件中”
您可以使用命令
:marks:
查看所有标签
:marks:
ctrl-A和ctrl-X
在光标位置或其右侧的行中增加和减少下一个数字。 由于它会立即显示数字,因此可以在任何地方使用该组合。
10c-A
比
wwwwwciw20
简单得多。
问:
打开以前团队的历史。 您可以像处理任何Vim文本一样使用它,但是不会保存更改。 但是,您可以使用
<CR>
运行修改后的命令。 这使您可以非常快速地更改和重新启动命令,或查找旧命令以供重用。
q /,q?
与
q:
相同,但搜索除外。
Ctrl-I,Ctrl-O
移动到跳转列表中的下一个或上一个位置。 用于快速检查然后回溯。 读取帮助文件非常好。
巨集
请参阅
这篇文章 ,以更深入地了解宏的使用。
视觉模式
gv
选择上一个视觉项目。
v_o
转到可视块的另一侧。 如果您开始的行太低或类似的情况很有用。 在块模式下,它将变为相反的对角,并使用
v_O
切换到相反的
v_O
。
g ctrl-A / ctrl-X
在可视模式下,Ctrl-A只是增加每行的第一个数字。 另一方面,
g ctrl-A
每行将增加一行。 在表中更容易解释:
运算子:v,V,cv(:h o_v)
您可能知道,在可视模式下可以选择字符(v),行(V)和块(ctrl-V)。 但是这三个组合可以用作相应片段的运动运算符。 例如,您具有以下文本:
abc
abc
abc
如果将光标放在顶部
b
并按
d2j
,它将删除所有三行,因为
j
逐行移动。 如果改为按
d<cV>2j
,则移动将逐块进行,仅删除带有三个字母
b
的中间列。
一种用例是在搜索中删除。 正常
d/
逐个字符移动。 因此,我将
dV/
用于逐行删除运动。 还有另一种方法:
/正则表达式/ {n}
在匹配项下移动n行,如果该值为负,则向上移动多行。 作为副作用,移动是逐行发生的。 因此,如果要删除与
regex
对应的第一行,
regex
可以输入
d/regex//0
。
前队
您可以在命令模式下输入前命令,例如,命令
:s
。 除了替换以外,还有许多其他有用的命令。 所有这些示例都需要一个范围,例如
%
。
:g / regex / ex
仅在与正则表达式匹配的行上运行命令。 例如,您可以输入
g/regex/d
删除所有与regex匹配的行。
v
命令类似于
g
,但可在所有
不匹配正则表达式的行上使用。
技巧随着规范和其他方面变得更加强大。
:规范{Vim}
就像您在范围的每一行上运行{Vim}一样。 例如,
g/regex/norm f dw
将删除与regex正则表达式对应的每一行中第一个空格之后的第一个单词。 这通常比宏简单得多。
norm
遵循您的所有比较。 例如,如果您在插入模式下将
jk
分配给
<esc>
,则
norm I jk$diw
将
norm I jk$diw
的开头添加一个空格,
离开insert模式 ,然后删除该行的最后一个单词。 我真的很喜欢此功能,但是如果您不想使用映射,则可以应用
norm!
。
:公司
将范围复制到当前行。 您还可以指定任意值而不是句点,例如
+3
或
'a. mv
'a. mv
移动。
:y {reg}
将范围复制到
{reg}
寄存器。 如果
{reg}
大写,则将其添加到现有案例中。 即这样的团队
let @a = '' | %g/regex/y A
将复制到整个文件中与
regex
对应
a
所有行。 这有助于从文件中提取损坏的文本并将其复制到系统剪贴板(使用
let @+ = @a
)。
:windo {ex}
在所有窗口中运行命令。 例如
:windo $
向下
:windo $
所有窗口。 有
bufdo
,
cdo
,
tabdo
等。
与
g
和
s
配合得很好。 要将所有
AA
组合替换为
BB
并提供替换预览,您可以通过将所有匹配项加载到quickfix中来输入
vimgrep AA
,然后使用
cdo s/AA/BB/cge
搜索/替换所有匹配项。
Vim的扩展
这里列出了一些技巧,需要保存设置或更改Vim会话。 假设地,它们可以仅通过输入命令就可以在“清教徒”模式下使用,但是有些涉及相当严重的变化,与清教徒的精神背道而驰。
这只是最不寻常的。 许多人将
H
分配给cap
^
,所以这些事情不值得一提。 另外,谈论
vim-sensible
或
vim-surround
毫无意义,而只谈论更多奇特的插件。
如果您一直在配置vimrc,请您自己做,并为此添加一个单独的命令:
command! Vimrc :vs $MYVIMRC
设定值
我将所有设置,按键绑定和功能存储在单个vimrc文件中。 拆分成多个文件使搜索变得困难。
大多数设置实际上并不是任何“技巧”。 最好看一下适合
vim的内容 :几乎所有在那里的设置都适合您的vimrc。
设置lazyredraw
不要在宏中间重画屏幕(以提高性能)。
设置smartcase / ignorecase
使用这两个设置,不使用大写字母的搜索将不区分大小写,而使用大写字母的搜索将区分大小写。
设置撤消文件
即使关闭并打开Vim,也要保存操作,以使撤消操作始终可用。 与undotree插件结合使用非常方便。
设置foldcolumn = {n}
带有折叠块的侧柱。
n
越大,该列中折叠的块越多,其余数字则用数字表示。
set suffixesadd = {str}
gf
通常表示“转到光标下的文件”,但该行中需要文件扩展名。
suffixesadd
添加指定的扩展名。 如果
suffixesadd=.md
,则在'foo'行上的
gf
命令将查找文件
foo
和
foo.md
设置inccommand = nosplit
仅适用于Neovim。
incommand
实时显示团队将进行哪些更改。 当前仅支持
s
,但即使这样也非常有用。 如果输入
:s/regex
,
:s/regex
所有匹配项都突出显示。 如果您随后添加
/change
,它将显示所有替换项。 适用于所有正则表达式属性,包括反向链接和组。
设置状态行(:h状态行)
确定在每个窗口底部的面板中显示什么。 与其他设置相比,此处的格式要复杂得多,而且比较挑剔,因此您必须花一些时间来解释它。 有一些简单的技巧。 首先,查看默认的Vim状态栏:
:set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
在这里,最容易替换
%P
(光标上的文件百分比)。 状态栏格式是百分号后的值。 因此,对于Markdown文件,您可以这样编写:
:set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %{wordcount()[\"words\"]}
并用文档中的单词数替换文件的百分比。
或安装
tabline
。 如果您不使用制表符,则可以将该行设置为“全局状态行”。 举个例子
set tabline=%{strftime('%c')}
将始终在顶部显示日期。
按键绑定
我有
很多绑定。
默认情况下,愚蠢地分配了Vim中许多方便的键。 例如,保存击键
s
与
cl
(保存一个击键)是同义词,并且
U
与
u
相同,除了将undo作为新更改写入,这在功能上是无用的。
Q
与
gQ
相同,并且在任何情况下都是一个巨大的陷阱。
Z
仅用于
ZZ
和
ZQ
。 天哪,甚至Vim手册也建议将
_
和键重新分配给某些功能,因为“您可能永远不会使用它们”。 我不想保存一键,而是要向键盘添加全新的功能。 这是我的一些绑定:
nnoremap Q @@
在不减慢向ex模式的过渡的情况下,重复最后一个宏。
nnoremap s“ _d
它使
s
键(具有
ss
和
S
的适当设置)的工作方式与d相似,只是不将已删除的文本保存在寄存器中。 有用以免阻塞寄存器。
nnoremap <cj> <cw> j
转到下面的窗口。
h
,
k
,
l
适当分配。 使用Windows更容易。
nnoremap <leader> e:exe getline(行('。'))<cr>
像命令一样运行当前行。 在实验中,它通常比
q:
更方便
q:
特殊参数(:h map-arguments)
map <buffer> lhs rhs
激活此缓冲区的键映射。 它确实可以方便地与自动命令一起用作临时键组合,或者在通过函数定义分配时使用。 缓冲区分配优先于全局分配,也就是说,您可以覆盖在特定情况下更有用的常规命令。
map <expr> {lhs} {expr}
检查
{expr}
并将返回值用作键的最终重映射。 一个简单的用例是根据条件进行绑定。 我有这些:
nnoremap <expr> k (v:count == 0 ? 'gk' : 'k')
nnoremap <expr> j (v:count == 0 ? 'gj' : 'j')
这使得
j
和
k
沿着直线移动,
直到找到
一个数字,然后取消该键。 因此,我可以浏览散文的较长段落而不会破坏
10j
组合。
<silent>
参数有助于在任何绑定中运行ex命令。
inoremaps
感谢
inoremap
绑定可以在插入模式下工作。 他们在那里开始工作,因此是
inoremap ;a aaaa
将引入'aaaa'而不是'; a'。 如果要在普通模式下执行某些操作,请使用
<cO>
。 例如,如果我们有
inoremap ;1 <co>ma
然后
;1
设置
'a
。
我喜欢指定使用分号作为重新分配的键,因为在普通文本中,分号后几乎总是有空格或换行符。
自动命令
自动命令非常适合配置。 通常,您可以这样配置它们:
augroup {name} autocmd! " Prevents duplicate autocommands au {events} {file regex} {command} augroup END
然后,如果{file regex}文件中发生任何{events}事件,则将触发{command}命令。 事件被列出
:h event
。 例如,如果您写
augroup every autocmd! au InsertEnter * set norelativenumber au InsertLeave * set relativenumber augroup END
然后vim将仅在插入模式下禁用relativenumber。
au {event} <buffer> {ex}
命令仅将auto命令应用于当前缓冲区。 有时,我使用它向特定文件添加短期事件处理程序。
BufNewFile,BufRead
BufnewFile
在创建新文件
BufnewFile
时启动-首次打开缓冲区时。 它们通常用于向特定文件类型添加参数和重新映射。 我有一个这样的:
augroup md autocmd! au BufNewFile,BufRead *.md syntax keyword todo TODO au BufNewFile,BufRead *.md inoremap <buffer> ;` ```<cr><cr>```<Up><Up> augroup END
仅在Markdown文件中突出显示TODO行,并且在插入模式下的字符
;`
会添加代码符号。
自动团队可以让您做更复杂的事情。 例如,用于
BufWriteCmd
au
会覆盖标准保存,从而允许您实现自定义逻辑。 这超出了“技巧”,而进入了“黑暗魔术”的领域。
外挂程式
大多数人都知道流行的插件,例如
vim-surround
和
NERDtree
。 这是一些我认为非常有用的鲜为人知的列表。
在大多数文本编辑器中,撤消操作是线性发生的。 如果对A进行更改,请撤消它,然后对B进行更改,那么A将永远丢失。 但是,Vim存储整个未完成操作的树。
u
命令回滚当前树分支中的操作,并且
g
转到先前的
时间顺序版本。 您可以使用以下命令查看已取消操作的列表
:undolist
。
但是这种格式不是很清楚。 最好查看实际的树。 这正是
Undotree
所做的:它以便捷的导航方式对取消的动作树进行了良好的ASCII表示。
该插件提供用于交换参数的命令,因此您可以通过几次击键将
(a, f(b, c))
替换为
(f(b, c), a)
。 我经常必须进行此类编辑,因此这是生活质量的重大改善。
将更高级别的API连接到neo / vim嵌入式终端。 例如
:T {text}
将{text}发送到控制台。 非常适合创建交互式环境。
“ TODO {{{
本文不讨论许多主题,因为它们过于技术性或需要详细解释,例如函数编写或语法系统。 而且我了解不多。 我想更详细地研究以下主题:
预览,快速修复和列表窗口
我有时会在这些窗口上使用工具,但是我不知道如何操作它们。 我想在我的
TLA +插件中添加quickfix错误。 我也喜欢将支持信息和回调命令放在预览窗口中的想法。 这提供了一些很难在IDE中重现的可能性。
Neovim API
Neovim提供了用于将Vim与外部程序集成的高级API。 您的Python脚本可以将命令发送到Neovim实例,例如,您可以通过服务器控制编辑器。 我看到了一些很酷的概念演示,其中基于浏览器中的信息进行自动完成。 看起来很酷!
文字对象
从来没有创造这样的。
因此,这是Vim某些隐式功能的简要概述。 希望您发现有用的东西!