你使用 Vim 最高效的捷径是什么? [英] What is your most productive shortcut with Vim?

查看:23
本文介绍了你使用 Vim 最高效的捷径是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我听说过很多关于 Vim 的信息,既有优点也有缺点.看起来您(作为开发人员)使用 Vim 确实应该比使用任何其他编辑器更快.我正在使用 Vim 来做一些基本的事情,而使用 Vim 最多可以使我的工作效率降低 10 倍.

I've heard a lot about Vim, both pros and cons. It really seems you should be (as a developer) faster with Vim than with any other editor. I'm using Vim to do some basic stuff and I'm at best 10 times less productive with Vim.

当你谈论速度时,你应该关心的唯一两件事(你可能不太关心它们,但你应该关心)是:

The only two things you should care about when you talk about speed (you may not care enough about them, but you should) are:

  1. 左右交替使用手是最快使用键盘.
  2. 从不触摸鼠标是第二种方法是尽可能快.你需要很长时间才能移动你的手,抓住鼠标,移动它,然后把它带来回到键盘(你经常有看键盘确定你将您的手正确地放回正确的位置)

这里有两个例子说明为什么我使用 Vim 的效率要低得多.

Here are two examples demonstrating why I'm far less productive with Vim.

复制/剪切&粘贴.我一直这样做.对于所有当代编辑器,您可以用左手按 Shift,然后用右手移动光标来选择文本.然后 Ctrl+C 复制,移动光标并 Ctrl+V 粘贴.

Copy/Cut & paste. I do it all the time. With all the contemporary editors you press Shift with the left hand, and you move the cursor with your right hand to select text. Then Ctrl+C copies, you move the cursor and Ctrl+V pastes.

Vim 太可怕了:

  • yy 复制一行(您几乎从不想要整行!)
  • [number xx]yyxx 行复制到缓冲区中.但是你永远不知道你是否已经选择了你想要的东西.我经常要做[number xx]dd然后u来撤销!
  • yy to copy one line (you almost never want the whole line!)
  • [number xx]yy to copy xx lines into the buffer. But you never know exactly if you've selected what you wanted. I often have to do [number xx]dd then u to undo!

另一个例子?搜索&替换.

  • PSPad 中:Ctrl+f 然后输入您要搜索的内容,然后按 Enter.
  • 在Vim中:/,然后输入你要搜索的内容,如果有特殊字符输入\每个特殊字符之前,然后按回车.
  • In PSPad: Ctrl+f then type what you want you search for, then press Enter.
  • In Vim: /, then type what you want to search for, then if there are some special characters put \ before each special character, then press Enter.

Vim 的一切都是这样:似乎我不知道如何以正确的方式处理它.

And everything with Vim is like that: it seems I don't know how to handle it the right way.

注意:我已经阅读了 Vim cheat 表格 :)

NB : I've already read the Vim cheat sheet :)

我的问题是:

与现代编辑器相比,您使用 Vim 的方式是什么让您更有效率?

What is the way you use Vim that makes you more productive than with a contemporary editor?

推荐答案

Vim 的问题在于你不理解 vi.

您提到使用 yy 进行剪切并抱怨您几乎从不想剪切整行.事实上,程序员在编辑源代码时,经常希望在整行、行范围和代码块上工作.但是,yy 只是将文本拖入匿名复制缓冲区(或在 vi 中称为注册")的众多方法之一.

Your problem with Vim is that you don't grok vi.

You mention cutting with yy and complain that you almost never want to cut whole lines. In fact programmers, editing source code, very often want to work on whole lines, ranges of lines and blocks of code. However, yy is only one of many way to yank text into the anonymous copy buffer (or "register" as it's called in vi).

禅"vi 是你在说一种语言.开头的 y 是动词.语句yyy_ 的同义词.y 加倍以方便打字,因为它是如此常见的操作.

The "Zen" of vi is that you're speaking a language. The initial y is a verb. The statement yy is a synonym for y_. The y is doubled up to make it easier to type, since it is such a common operation.

这也可以表示为 dd P(删除当前行并将副本粘贴回原位;在匿名寄存器中保留副本作为副作用).yd 动词"以任何动作为主题".因此 yW 是从这里(光标)拉到当前/下一个(大)词的末尾";并且 y'a 是从这里拉到包含名为 'a' 的标记的行."

This can also be expressed as dd P (delete the current line and paste a copy back into place; leaving a copy in the anonymous register as a side effect). The y and d "verbs" take any movement as their "subject." Thus yW is "yank from here (the cursor) to the end of the current/next (big) word" and y'a is "yank from here to the line containing the mark named 'a'."

如果您只了解基本的向上、向下、向左和向右光标移动,那么 vi 将不会比记事本"的副本更有效率.为你.(好吧,您仍然可以使用语法高亮显示和处理大于 45KB 左右的文件的能力;但在这里和我一起工作).

If you only understand basic up, down, left, and right cursor movements then vi will be no more productive than a copy of "notepad" for you. (Okay, you'll still have syntax highlighting and the ability to handle files larger than a piddling ~45KB or so; but work with me here).

vi 有 26 个标记";和26个寄存器".使用 m 命令将标记设置到任何光标位置.每个标记由一个小写字母指定.因此,ma 将 'a' 标记设置为当前位置,而 mz 设置了 'z' 标记.您可以使用 '(单引号)命令移动到包含标记的行.因此 'a 移动到包含 'a' 标记的行的开头.您可以使用 `(反引号)命令移动到任何标记的精确位置.因此 `z 将直接移动到 'z' 标记的确切位置.

vi has 26 "marks" and 26 "registers." A mark is set to any cursor location using the m command. Each mark is designated by a single lower case letter. Thus ma sets the 'a' mark to the current location, and mz sets the 'z' mark. You can move to the line containing a mark using the ' (single quote) command. Thus 'a moves to the beginning of the line containing the 'a' mark. You can move to the precise location of any mark using the ` (backquote) command. Thus `z will move directly to the exact location of the 'z' mark.

因为这些是运动"它们也可以用作其他陈述"的主语.

Because these are "movements" they can also be used as subjects for other "statements."

因此,剪切任意文本选择的一种方法是删除标记(我通常使用a"作为我的第一个"标记,z' 作为我的下一个标记,'b' 作为另一个标记,'e' 作为另一个标记(我不记得在 15多年使用 vi;关于宏如何使用标记和寄存器,不会干扰一个人的交互上下文,创建了自己的约定.然后我们转到所需文本的另一端;我们可以从任一端开始,没有关系.然后我们可以简单地使用d`a来剪切或y`a来复制.这样整个过程有5个按键开销(如果我们以插入"模式开始并且需要Esc退出命令模式,则为六个.一旦我们剪切或复制,然后粘贴到副本中就是一个按键:p.

So, one way to cut an arbitrary selection of text would be to drop a mark (I usually use 'a' as my "first" mark, 'z' as my next mark, 'b' as another, and 'e' as yet another (I don't recall ever having interactively used more than four marks in 15 years of using vi; one creates one's own conventions regarding how marks and registers are used by macros that don't disturb one's interactive context). Then we go to the other end of our desired text; we can start at either end, it doesn't matter. Then we can simply use d`a to cut or y`a to copy. Thus the whole process has a 5 keystrokes overhead (six if we started in "insert" mode and needed to Esc out command mode). Once we've cut or copied then pasting in a copy is a single keystroke: p.

我说这是剪切或复制文本的一种方式.然而,这只是其中之一.通常,我们可以更简洁地描述文本范围,而无需四处移动光标并留下标记.例如,如果我在一段文本中,我可以分别使用 {} 移动到段落的开头或结尾.因此,为了移动一段文本,我使用 { d} (3 次按键)剪切它.(如果我碰巧已经在段落的第一行或最后一行,我可以分别使用 d}d{ .

I say that this is one way to cut or copy text. However, it is only one of many. Frequently we can more succinctly describe the range of text without moving our cursor around and dropping a mark. For example if I'm in a paragraph of text I can use { and } movements to the beginning or end of the paragraph respectively. So, to move a paragraph of text I cut it using { d} (3 keystrokes). (If I happen to already be on the first or last line of the paragraph I can then simply use d} or d{ respectively.

段落"的概念默认为通常直观合理的东西.因此,它通常适用于代码和散文.

The notion of "paragraph" defaults to something which is usually intuitively reasonable. Thus it often works for code as well as prose.

我们经常知道一些模式(正则表达式)来标记我们感兴趣的文本的一端或另一端.向前或向后搜索是 vi 中的动作.因此,它们也可以用作主题";在我们的声明"中.所以我可以使用 d/foo 从当前行剪切到包含字符串foo"的下一行.和 y?bar 从当前行复制到包含bar"的最近(上一个)行.如果我不想要整行,我仍然可以使用搜索动作(作为他们自己的陈述),删除我的标记并使用前面描述的 `x 命令.

Frequently we know some pattern (regular expression) that marks one end or the other of the text in which we're interested. Searching forwards or backwards are movements in vi. Thus they can also be used as "subjects" in our "statements." So I can use d/foo to cut from the current line to the next line containing the string "foo" and y?bar to copy from the current line to the most recent (previous) line containing "bar." If I don't want whole lines I can still use the search movements (as statements of their own), drop my mark(s) and use the `x commands as described previously.

除了动词"之外和主题"vi 也有对象"(在该术语的语法意义上).到目前为止,我只描述了匿名寄存器的使用.但是,我可以使用 26 个命名"中的任何一个.通过前缀对象"来注册;使用 "(双引号修饰符)引用.因此,如果我使用 "add 我将当前行剪切到 'a' 寄存器,如果我使用 "by/foo然后我将文本的副本从这里拉到包含foo"的下一行.进入 'b' 寄存器.要从寄存器粘贴,我只需在粘贴前加上相同的修饰符序列:"ap 将 'a' 寄存器内容的副本粘贴到光标后的文本中,然后"bP 将 'b' 的副本粘贴到当前行之前.

In addition to "verbs" and "subjects" vi also has "objects" (in the grammatical sense of the term). So far I've only described the use of the anonymous register. However, I can use any of the 26 "named" registers by prefixing the "object" reference with " (the double quote modifier). Thus if I use "add I'm cutting the current line into the 'a' register and if I use "by/foo then I'm yanking a copy of the text from here to the next line containing "foo" into the 'b' register. To paste from a register I simply prefix the paste with the same modifier sequence: "ap pastes a copy of the 'a' register's contents into the text after the cursor and "bP pastes a copy from 'b' to before the current line.

前缀"的概念还添加了语法形容词"的类似物.和副词"到我们的文本操作语言".大多数命令(动词)和动作(动词或对象,取决于上下文)也可以使用数字前缀.因此 3J 的意思是加入接下来的三行";和 d5} 表示从当前行删除到第五段的末尾."

This notion of "prefixes" also adds the analogs of grammatical "adjectives" and "adverbs' to our text manipulation "language." Most commands (verbs) and movement (verbs or objects, depending on context) can also take numeric prefixes. Thus 3J means "join the next three lines" and d5} means "delete from the current line through the end of the fifth paragraph down from here."

这都是中级vi.没有一个是 Vim 特定的,如果您准备好学习它们,vi 中还有更高级的技巧.如果您只掌握这些中级概念,那么您可能会发现您很少需要编写任何宏,因为文本操作语言足够简洁和富有表现力,可以使用编辑器的本机"轻松完成大多数事情.语言.

This is all intermediate level vi. None of it is Vim specific and there are far more advanced tricks in vi if you're ready to learn them. If you were to master just these intermediate concepts then you'd probably find that you rarely need to write any macros because the text manipulation language is sufficiently concise and expressive to do most things easily enough using the editor's "native" language.

有许多 : 命令,最著名的是 :% s/foo/bar/g 全局替换技术.(这不是高级,但其他 : 命令可以).整个 : 命令集历史上由 vi 以前的化身作为 ed(行编辑器)和后来的 ex 继承(扩展行编辑器)实用程序.事实上,vi 之所以如此命名是因为它是 ex 的可视化界面.

There are a number of : commands, most notably the :% s/foo/bar/g global substitution technique. (That's not advanced but other : commands can be). The whole : set of commands was historically inherited by vi's previous incarnations as the ed (line editor) and later the ex (extended line editor) utilities. In fact vi is so named because it's the visual interface to ex.

: 命令通常在文本行上操作.edex 是在终端屏幕不常见且许多终端是电传打字机"的时代编写的.(TTY) 设备.因此,通常使用文本的印刷副本,通过极其简洁的界面使用命令(常见的连接速度为 110 波特,或者大约每秒 11 个字符——这比快速打字员慢;延迟很常见)多用户互动会议;此外,通常还有一些节约纸张的动机).

: commands normally operate over lines of text. ed and ex were written in an era when terminal screens were uncommon and many terminals were "teletype" (TTY) devices. So it was common to work from printed copies of the text, using commands through an extremely terse interface (common connection speeds were 110 baud, or, roughly, 11 characters per second -- which is slower than a fast typist; lags were common on multi-user interactive sessions; additionally there was often some motivation to conserve paper).

所以大多数 : 命令的语法包括一个地址或地址范围(行号),后跟一个命令.自然可以使用文字行号::127,215 s/foo/bar 来改变foo"的第一次出现.进入酒吧"在 127 到 215 之间的每一行上.还可以使用一些缩写,例如 .$ 分别表示当前行和最后一行.还可以使用相对前缀 +- 分别表示当前行之后或之前的偏移量.因此: :.,$j 表示从当前行到最后一行,将它们全部合并为一行".:%:1,$(所有行)同义.

So the syntax of most : commands includes an address or range of addresses (line number) followed by a command. Naturally one could use literal line numbers: :127,215 s/foo/bar to change the first occurrence of "foo" into "bar" on each line between 127 and 215. One could also use some abbreviations such as . or $ for current and last lines respectively. One could also use relative prefixes + and - to refer to offsets after or before the curent line, respectively. Thus: :.,$j meaning "from the current line to the last line, join them all into one line". :% is synonymous with :1,$ (all the lines).

:... g:... v 命令有一些解释,因为它们非常强大.:... g 是全局"的前缀.将后续命令应用于匹配模式(正则表达式)的所有行,而 :... v 将此类命令应用于所有不匹配给定模式的行(v"来自对话").与其他 ex 命令一样,这些命令可以以寻址/范围引用作为前缀.因此 :.,+21g/foo/d 的意思是删除任何包含字符串foo"的行;从当前行到接下来的 21 行"而 :.,$v/bar/d 表示从这里到文件末尾,删除任何不包含字符串bar"的行.

The :... g and :... v commands bear some explanation as they are incredibly powerful. :... g is a prefix for "globally" applying a subsequent command to all lines which match a pattern (regular expression) while :... v applies such a command to all lines which do NOT match the given pattern ("v" from "conVerse"). As with other ex commands these can be prefixed by addressing/range references. Thus :.,+21g/foo/d means "delete any lines containing the string "foo" from the current one through the next 21 lines" while :.,$v/bar/d means "from here to the end of the file, delete any lines which DON'T contain the string "bar."

有趣的是,常见的 Unix 命令 grep 实际上受到了这个 ex 命令的启发(并以其记录的方式命名).ex 命令 :g/re/p (grep) 是他们记录如何全局"调用的方式.打印"包含正则表达式"的行(关于).当使用 edex 时,:p 命令是任何人最早学会的命令之一,并且通常是编辑任何文件时使用的第一个命令.这就是您打印当前内容的方式(通常使用 :.,+25p 或类似方式一次只打印一页).

It's interesting that the common Unix command grep was actually inspired by this ex command (and is named after the way in which it was documented). The ex command :g/re/p (grep) was the way they documented how to "globally" "print" lines containing a "regular expression" (re). When ed and ex were used, the :p command was one of the first that anyone learned and often the first one used when editing any file. It was how you printed the current contents (usually just one page full at a time using :.,+25p or some such).

请注意,:% g/.../d 或(其反向/conVerse 对应物::% v/.../d 是最常见的用法模式.但是还有其他几个 ex 命令值得记住:

Note that :% g/.../d or (its reVerse/conVerse counterpart: :% v/.../d are the most common usage patterns. However there are couple of other ex commands which are worth remembering:

我们可以使用 m 来移动行,使用 j 来连接行.例如,如果您有一个列表,并且您想将所有匹配的内容(或相反地不匹配某个模式)分开而不删除它们,那么您可以使用以下内容: :% g/foo/m$...以及所有的foo"行将被移动到文件的末尾.(注意关于使用文件末尾作为临时空间的另一个提示).这将保留所有foo"的相对顺序.行,同时从列表的其余部分中提取它们.(这相当于执行以下操作:1G!GGmap!Ggrep foo1G:1,'ag/foo'/d(将文件复制到它自己的尾部,过滤尾部grep,并删除头部的所有内容).

We can use m to move lines around, and j to join lines. For example if you have a list and you want to separate all the stuff matching (or conversely NOT matching some pattern) without deleting them, then you can use something like: :% g/foo/m$ ... and all the "foo" lines will have been moved to the end of the file. (Note the other tip about using the end of your file as a scratch space). This will have preserved the relative order of all the "foo" lines while having extracted them from the rest of the list. (This would be equivalent to doing something like: 1G!GGmap!Ggrep foo<ENTER>1G:1,'a g/foo'/d (copy the file to its own tail, filter the tail through grep, and delete all the stuff from the head).

为了加入行,通常我可以找到需要连接到它们的前辈的所有行的模式(在某些项目符号列表中,所有以^"而不是^ *"开头的行,对于例子).对于那种情况,我会使用: :% g/^/-1j (对于每个匹配的行,向上一行并加入它们).(顺便说一句:对于尝试搜索项目符号线并加入下一个项目符号的列表,由于几个原因不起作用......它可以将一个项目符号行连接到另一个项目符号行,并且它不会将任何项目符号行连接到 所有它的延续;它只会在比赛中成对工作).

To join lines usually I can find a pattern for all the lines which need to be joined to their predecessor (all the lines which start with "^ " rather than "^ * " in some bullet list, for example). For that case I'd use: :% g/^ /-1j (for every matching line, go up one line and join them). (BTW: for bullet lists trying to search for the bullet lines and join to the next doesn't work for a couple reasons ... it can join one bullet line to another, and it won't join any bullet line to all of its continuations; it'll only work pairwise on the matches).

几乎不用说,您可以使用我们的老朋友 s(替代)与 gv(全局/反向全局)命令.通常你不需要这样做.但是,请考虑某些情况,您只想在匹配其他模式的行上执行替换.通常,您可以使用带有捕获的复杂模式并使用反向引用来保留不想更改的行部分.但是,将匹配与替换分开通常会更容易: :% g/foo/s/bar/zzz/g -- 对于包含foo"的每一行替换所有bar"带有zzz".(类似 :% s/\(.*foo.*\)bar\(.*\)/\1zzz\2/g 的东西只适用于那些bar"实例的情况.前面有foo"在同一行;这已经够笨拙了,必须进一步处理以捕获bar"在foo"之前的所有情况)

Almost needless to mention you can use our old friend s (substitute) with the g and v (global/converse-global) commands. Usually you don't need to do so. However, consider some case where you want to perform a substitution only on lines matching some other pattern. Often you can use a complicated pattern with captures and use back references to preserve the portions of the lines that you DON'T want to change. However, it will often be easier to separate the match from the substitution: :% g/foo/s/bar/zzz/g -- for every line containing "foo" substitute all "bar" with "zzz." (Something like :% s/\(.*foo.*\)bar\(.*\)/\1zzz\2/g would only work for the cases those instances of "bar" which were PRECEDED by "foo" on the same line; it's ungainly enough already, and would have to be mangled further to catch all the cases where "bar" preceded "foo")

重点是ex中不仅仅是psd行命令集.

The point is that there are more than just p, s, and d lines in the ex command set.

: 地址也可以引用标记.因此,您可以使用: :'a,'bg/foo/j 将包含字符串 foo 的任何行连接到其后续行,如果它位于 'a' 和 'b' 标记.(是的,所有前面的 ex 命令示例都可以通过使用这些寻址表达式作为前缀来限制为文件行的子集.

The : addresses can also refer to marks. Thus you can use: :'a,'bg/foo/j to join any line containing the string foo to its subsequent line, if it lies between the lines between the 'a' and 'b' marks. (Yes, all of the preceding ex command examples can be limited to subsets of the file's lines by prefixing with these sorts of addressing expressions).

这很晦涩(在过去的 15 年中,我只使用过几次类似的东西).但是,我会坦率地承认,我经常以迭代和交互方式完成一些事情,如果我花时间思考正确的咒语,这些事情本可以更有效地完成.

That's pretty obscure (I've only used something like that a few times in the last 15 years). However, I'll freely admit that I've often done things iteratively and interactively that could probably have been done more efficiently if I'd taken the time to think out the correct incantation.

另一个非常有用的viex 命令是:r,用于读入另一个文件的内容.因此: :r foo 插入名为foo"的文件的内容;在当前行.

Another very useful vi or ex command is :r to read in the contents of another file. Thus: :r foo inserts the contents of the file named "foo" at the current line.

更强大的是 :r! 命令.这会读取命令的结果.这与暂停 vi 会话、运行命令、将其输出重定向到临时文件、恢复您的 vi 会话以及从临时文件中读取内容是一样的.文件.

More powerful is the :r! command. This reads the results of a command. It's the same as suspending the vi session, running a command, redirecting its output to a temporary file, resuming your vi session, and reading in the contents from the temp. file.

更强大的是 ! (bang) 和 :... ! (ex bang) 命令.它们还执行外部命令并将结果读入当前文本.然而,他们也通过命令过滤我们的文本选择!我们可以使用 1G!Gsort 对文件中的所有行进行排序(Gvigoto"命令;它默认为 go到文件的最后一行,但可以以行号作为前缀,例如 1,第一行).这等效于 ex 变体 :1,$!sort.编写者经常将 ! 与 Unix fmtfold 实用程序一起用于重新格式化或自动换行".文本的选择.一个非常常见的宏是 {!}fmt(重新格式化当前段落).程序员有时会通过缩进或其他代码重新格式化工具使用它来运行他们的代码,或者只是其中的一部分.

Even more powerful are the ! (bang) and :... ! (ex bang) commands. These also execute external commands and read the results into the current text. However, they also filter selections of our text through the command! This we can sort all the lines in our file using 1G!Gsort (G is the vi "goto" command; it defaults to going to the last line of the file, but can be prefixed by a line number, such as 1, the first line). This is equivalent to the ex variant :1,$!sort. Writers often use ! with the Unix fmt or fold utilities for reformating or "word wrapping" selections of text. A very common macro is {!}fmt (reformat the current paragraph). Programmers sometimes use it to run their code, or just portions of it, through indent or other code reformatting tools.

使用 :r!! 命令意味着任何外部实用程序或过滤器都可以被视为我们编辑器的扩展.我偶尔会将这些用于从数据库中提取数据的脚本,或者用于从网站中提取数据的 wgetlynx 命令,或 ssh从远程系统中提取数据的命令.

Using the :r! and ! commands means that any external utility or filter can be treated as an extension of our editor. I have occasionally used these with scripts that pulled data from a database, or with wget or lynx commands that pulled data off a website, or ssh commands that pulled data from remote systems.

另一个有用的ex 命令是:so(:source 的缩写).这将读取文件的内容作为一系列命令.当您启动 vi 时,它通常会隐式地对 ~/.exinitrc 文件(和 Vim通常在 ~/.vimrc 上这样做,很自然).这样做的用途是,您可以通过简单地获取一组新的宏、缩写和编辑器设置来即时更改您的编辑器配置文件.如果您很狡猾,您甚至可以将其用作存储 ex 编辑命令序列以按需应用于文件的技巧.

Another useful ex command is :so (short for :source). This reads the contents of a file as a series of commands. When you start vi it normally, implicitly, performs a :source on ~/.exinitrc file (and Vim usually does this on ~/.vimrc, naturally enough). The use of this is that you can change your editor profile on the fly by simply sourcing in a new set of macros, abbreviations, and editor settings. If you're sneaky you can even use this as a trick for storing sequences of ex editing commands to apply to files on demand.

例如,我有一个七行文件(36 个字符),它通过 wc 运行一个文件,并在包含该字数数据的文件顶部插入一个 C 样式的注释.我可以应用那个宏"使用如下命令到文件:vim +'so mymacro.ex' ./mytarget

For example I have a seven line file (36 characters) which runs a file through wc, and inserts a C-style comment at the top of the file containing that word count data. I can apply that "macro" to a file by using a command like: vim +'so mymacro.ex' ./mytarget

(viVim+ 命令行选项通常用于在给定的行号处启动编辑会话.但是它是一个鲜为人知的事实是,可以通过任何有效的 ex 命令/表达式来跟随 +,例如我在这里所做的源"命令;对于一个简单的例如,我有脚本调用: vi +'/foo/d|wq!' ~/.ssh/known_hosts 以非交互方式从我的 SSH 已知主机文件中删除条目,而我重新对一组服务器进行映像).

(The + command line option to vi and Vim is normally used to start the editing session at a given line number. However it's a little known fact that one can follow the + by any valid ex command/expression, such as a "source" command as I've done here; for a simple example I have scripts which invoke: vi +'/foo/d|wq!' ~/.ssh/known_hosts to remove an entry from my SSH known hosts file non-interactively while I'm re-imaging a set of servers).

通常编写这样的宏"要容易得多.使用 Perl、AWK、sed(实际上,它类似于 grep 一个受 ed 命令启发的实用程序).

Usually it's far easier to write such "macros" using Perl, AWK, sed (which is, in fact, like grep a utility inspired by the ed command).

@ 命令可能是最晦涩的 vi 命令.在近十年来偶尔教授高级系统管理课程的过程中,我遇到过很少有人使用过它.@ 像执行 viex 命令一样执行寄存器的内容.
示例:我经常使用: :r!locate ... 在我的系统上查找某个文件并将其名称读入我的文档.从那里我删除任何无关的点击,只留下我感兴趣的文件的完整路径.卡在一台没有 Tab 补全支持的机器上,vi) 我只是使用:

The @ command is probably the most obscure vi command. In occasionally teaching advanced systems administration courses for close to a decade I've met very few people who've ever used it. @ executes the contents of a register as if it were a vi or ex command.
Example: I often use: :r!locate ... to find some file on my system and read its name into my document. From there I delete any extraneous hits, leaving only the full path to the file I'm interested in. Rather than laboriously Tab-ing through each component of the path (or worse, if I happen to be stuck on a machine without Tab completion support in its copy of vi) I just use:

  1. 0i:r(将当前行转换为有效的:r命令),
  2. "cdd(删除进入c"寄存器的行)和
  3. @c 执行该命令.
  1. 0i:r (to turn the current line into a valid :r command),
  2. "cdd (to delete the line into the "c" register) and
  3. @c execute that command.

这只是 10 次按键(而且表达式 "cdd @c 对我来说实际上是一个手指宏,所以我几乎可以像任何常见的 6字母词).

That's only 10 keystrokes (and the expression "cdd @c is effectively a finger macro for me, so I can type it almost as quickly as any common six letter word).

我只是触及了 vi 的强大功能的表面,我在此处描述的任何内容甚至都不是改进"的一部分.vim 就是为此命名的!我在此描述的所有内容都适用于 20 或 30 年前的任何 vi 旧副本.

I've only scratched to surface of vi's power and none of what I've described here is even part of the "improvements" for which vim is named! All of what I've described here should work on any old copy of vi from 20 or 30 years ago.

有些人使用了比我以往任何时候都多得多的 vi 的力量.

There are people who have used considerably more of vi's power than I ever will.

这篇关于你使用 Vim 最高效的捷径是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆