Vim最有效的捷径是什么?

我听说过许多关于Vim的优点和缺点。 看起来,你应该(作为开发人员)比Vim更快地使用其他编辑器。 我正在使用Vim来做一些基本的工作,而Vim的工作效率最高只有10倍。

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

  • 使用左手和右手是使用键盘的最快捷方式。
  • 切勿触摸鼠标是第二种尽可能快的方式。 它需要很长时间才能移动你的手,拿起鼠标,移动它并将它带回到键盘(并且你经常必须看着键盘,以确保你将手正确地放回到正确的位置)
  • 这里有两个例子说明为什么我用Vim的效率低得多。

    复制/剪切并粘贴。 我一直这样做。 使用所有当代编辑器,用左手按住Shift,然后用右手移动光标以选择文本。 然后按Ctrl + C复制,移动光标和Ctrl + V粘贴。

    用Vim这很可怕:

  • yy复制一行(你几乎不需要整行!)
  • [number xx]yyxx行复制到缓冲区中。 但你永远不知道你是否选择了你想要的东西。 我经常必须做[number xx]dd然后u解开!
  • 另一个例子? 搜索和替换。

  • 在PSPad中:Ctrl + f然后输入你想要搜索的内容,然后按Enter键。
  • 在Vim中: / ,然后键入要搜索的内容,那么如果有一些特殊的字符放在每个特殊字符前,然后按Enter键。
  • 而Vim的一切都是这样的:看来我不知道如何正确处理它。

    注意: 我已经阅读过Vim作弊表 :)

    我的问题是:

    你使用Vim的方式是什么让你比当代编辑更有效率?


    你对Vim的问题是,你没有注意到vi

    你提到切割与yy和抱怨说,你几乎从来不想削减整条线。 实际上,程序员编辑源代码通常需要处理整行代码,行代码块和代码块。 然而, yy只是将文本放入匿名复制缓冲区(或者称为vi中的 “注册”)的方法之一。

    vi的“禅”是你在说一种语言。 最初的y是一个动词。 声明yyy_的同义词。 因为这是一种常见的操作,所以y被加倍以便于输入。

    这也可以表示为dd P (删除当前行并将副本粘贴回原处;将副本留在匿名寄存器中作为副作用)。 yd “动词”以任何动作作为他们的“主语”。 因此yW是“从这里(光标)到当前/下一个(大)字的y'a ”并且y'a是“从这里y'a包含名为'a'的标记的行。

    如果你只理解基本的向上,向下,向左和向右的光标移动,那么vi将不会比你的“记事本”副本更有效率。 (好吧,你仍然有语法突出显示和处理大于45KB左右的文件的能力;但在这里与我一起工作)。

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

    因为这些是“运动”,所以它们也可以用作其他“陈述”的主题。

    所以,削减任意文本选择的一种方法是放弃一个标记(我通常使用'a'作为我的“第一个”标记,'z'作为我的下一个标记,'b'作为另一个标记,'e'作为还有一个(我不记得在使用vi的 15年中交互式地使用了四个以上的标记;一个创建了自己的约定,关于宏如何使用标记和寄存器,而不会干扰一个人的交互式上下文)。我们所需文本的另一端。我们可以开始在两端,也没关系那么我们可以简单地使用d`a削减或y`a 。复制因此,整个过程有一个5个按键开销(SIX如果我们以“插入”模式开始并需要退出命令模式)。一旦我们剪切或复制,粘贴复制就是单击键盘: p

    我说这是剪切或复制文本的一种方法。 但是,它只是其中的一个。 通常我们可以更简洁地描述文本的范围,而不用移动光标并放下标记。 例如,如果我在一段文字中,我可以分别在段落的开头或结尾使用{}动作。 因此,要移动一段文字,我使用{ d} (3个按键)将其剪下。 (如果我碰巧已经在段落的第一行或最后一行,我可以简单地分别使用d}d{

    “段落”的概念默认为通常直观合理的事物。 因此它通常适用于代码和散文。

    我们经常知道某些模式(正则表达式),它标记了我们感兴趣的文本的一端或另一端。 向前或向后搜索是vi中的移动。 因此,它们也可以在我们的“陈述”中用作“主题”。 因此,我可以使用d/foo从当前行切换到包含字符串“foo”和y?bar的下一行,以便从当前行复制到包含“bar”的最近(前一行)行。 如果我不想整行,我仍然可以使用搜索动作(作为他们自己的语句),放下我的标记并使用前面所述的`x命令。

    除了“动词”和“主语”之外, vi还有“宾语”(用语的语法意义)。 到目前为止,我只描述了使用匿名注册。 但是,我可以使用26个“已命名”寄存器中的任何一个,在“对象”引用前添加" (双引号修饰符)。因此,如果我使用"add我将当前行切入'a'寄存器,并且if我使用"by/foo然后我从这里到下一行包含”foo“的文本拷贝到”b“寄存器中。要从寄存器中粘贴,我只需在paste前添加相同的修饰符序列: "ap将“a”寄存器内容的副本粘贴到光标后面的文本中, "bP将副本从'b'粘贴到当前行之前。

    这个“前缀”的概念也增加了语法“形容词”和“副词”的类似物到我们的文本操作语言中。大多数命令(动词)和移动(动词或对象,取决于上下文)也可以带数字前缀。 3J表示“加入下三行”,而d5}表示“从第五段开始,从当前行删除”。

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


    一些更高级的技巧:

    有许多的:命令,最引人注目的是:% s/foo/bar/g全局替换技术。 (这不是先进的,但其他:命令可以)。 整个:一套命令历来被vi的先前版本继承为ed (行编辑器)和后来的ex (扩展行编辑器)实用程序。 事实上, vi是如此命名的,因为它是ex的可视化界面。

    :命令通常对文本行进行操作。 edex是在一个终端屏幕不常见的时代写成的,许多终端是“电传打字机”(TTY)设备。 所以通常从文本的打印副本开始工作,通过非常简洁的界面使用命令(常见连接速度为110波特,或者大约每秒11个字符 - 这比快速打字员慢;延迟常见多用户交互式会话;另外还有一些保存纸张的动机)。

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

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

    有趣的是,普通的Unix命令grep实际上受到这个ex命令的启发(并且以它被记录的方式命名)。 ex命令:g/re/p (grep)是他们记录如何“全局”“打印”包含“正则表达式”(重新)的行的方式。 当使用edex时, :p命令是任何人学习的第一个,并且常常是编辑任何文件时使用的第一个命令。 这是你打印当前内容的方式(通常只用一页完整版,使用:.,+25p或其他)。

    请注意:% g/.../d或(它的reVerse / conVerse对应:: :% v/.../d是最常见的使用模式,但还有其他一些ex命令值得记住:

    我们可以使用m来移动线条, j可以连接线条。 例如,如果你有一个列表,并且你希望将所有匹配的东西(或者反过来不匹配某个模式)分开而不删除它们,那么你可以使用像:% g/foo/m$ ...和所有的“ foo“行将被移动到文件末尾。 (请注意关于使用文件末尾作为暂存空间的其他技巧)。 这将保留所有“富”行的相对顺序,同时从列表的其余部分提取它们。 (这将相当于: 1G!GGmap!Ggrep foo<ENTER>1G:1,'ag/foo'/d (将文件复制到自己的尾部,通过grep过滤尾部,并删除所有东西从头开始)。

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

    几乎不用提你可以用gv (全局/反向全局)命令来使用我们的老朋友s (替代)。 通常你不需要这样做。 但是,考虑一些您只想在匹配其他模式的行上执行替换的情况。 通常,您可以使用带有捕获的复杂模式,并使用反向引用来保留您不想更改的部分行。 但是,将匹配与替换分开比较容易:% g/foo/s/bar/zzz/g - 对于包含“foo”的每行,将所有“bar”替换为“zzz”。 (例如:% s/(.*foo.*)bar(.*)/1zzz2/g只适用于那些以“foo”为前缀的“bar”实例同一条线;已经够不够用了,并且必须进一步修补,以便抓住“foo”之前的“bar”之前的所有情况)

    重点是在ex命令集中不仅有psd行。

    The :地址也可以引用标记。 因此,如果位于'a'和'b'标记之间的行之间,则可以使用:: :'a,'bg/foo/j将包含字符串foo的任何行连接到其后续行。 (是的,所有前面的ex命令示例都可以通过在这些类型的寻址表达式前加上限制到文件行的子集)。

    这非常晦涩(我在过去的15年里只用了几次)。 然而,我会毫不犹豫地承认,我经常以迭代方式和交互方式完成这些事情,如果我花时间想出正确的咒语,可能会更有效地做到这一点。

    另一个非常有用的viex命令是:r读入另一个文件的内容。 因此:: :r foo在当前行插入名为“foo”的文件的内容。

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

    !更强大! (爆炸)和:... !ex bang)命令。 这些还执行外部命令并将结果读入当前文本。 但是,他们也通过命令过滤我们的文本选择! 我们可以使用1G!GsortGvi “goto”命令;它默认为转到文件的最后一行,但可以用一个行号作为前缀,比如1,第一行)。 这相当于前面的变体:1,$!sort 。 作家经常使用! 使用Unix fmtfold工具重新格式化或“文字换行”选择文本。 一个非常常见的宏是{!}fmt (重新设置当前段落的格式)。 程序员有时使用它通过缩进或其他代码重新格式化工具来运行他们的代码,或者只是其中的一部分。

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

    另一个有用的ex命令是:so (short for :source )。 这将读取文件的内容作为一系列命令。 当你启动vi时,它通常隐式地在~/.exinitrc文件上执行一个:source (而Vim通常在~/.vimrc上执行此操作,当然就足够了)。 使用它可以通过简单地获取一组新的宏,缩写和编辑器设置来即时更改编辑器配置文件。 如果你是鬼鬼祟祟的,你甚至可以使用这个技巧来存储ex编辑命令序列,以便按需将文件应用到文件中。

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

    (该+命令行选项来viVim通常被用于在给定的行号,开始编辑会话。然而,它的一个鲜为人知的事实,人们可以按照+通过任何有效的ex命令/表达,诸如“源”命令,就像我在这里完成的那样;对于一个简单的例子,我有脚本调用: vi +'/foo/d|wq!' ~/.ssh/known_hosts从我的SSH已知主机文件中非交互地删除条目重新映像一组服务器)。

    通常使用Perl,AWK, sed编写这样的“宏”会更容易(实际上,它就像grepED命令启发的实用程序)。

    @命令可能是最不明显的vi命令。 在偶尔教授高级系统管理课程近十年的时间里,我遇到过很少有人曾经使用它。 @执行寄存器的内容,就像它是viex命令一样。
    示例:我经常使用:: :r!locate ...在我的系统上查找某个文件,并将其名称读入我的文档中。 从那里我删除任何多余的命中,只留下我感兴趣的文件的完整路径。而不是费力地选择路径的每个组件(或更糟糕的是,如果我碰巧在没有Tab完成的机器上卡住在vi的副本中提供支持)我只是使用:

  • 0i:r (将当前行转换为有效的:r命令),
  • "cdd (将行删除到”c“寄存器中)和
  • @c执行该命令。
  • 这仅仅是10次击键(表达式"cdd @c对我来说实际上是一个手指宏,所以我可以像任何常见的六个字母字一样快速地输入它”)。


    一个清醒的想法

    我只是抓住了vi的力量,而我在这里描述的任何内容都不是vim命名的“改进”的一部分! 我在这里描述的所有内容都应该适用于20或30年前的任何vi旧版本。

    有些人比以往任何时候都更多地使用了vi的力量。


    你正在谈论文本选择和复制,我认为你应该看看Vim Visual模式。

    在可视化模式下,您可以使用Vim命令选择文本,然后您可以根据需要随意选择。

    考虑以下常见情况:

    您需要选择下一个匹配的括号。

    你可以这样做:

  • 如果光标位于开始/结束括号上,则为v%
  • 如果光标位于括号内,则vib
  • 你想在引号之间选择文本:

  • vi“用于双引号
  • vi'单引号
  • 你想选择一个花括号块(在C风格的语言中很常见):

  • viB
  • vi{
  • 你想选择整个文件:

  • ggVG
  • 可视化块选择是另一个非常有用的功能,它允许你选择一个矩形区域的文本,你只需要按下Ctrl-V来启动它,然后选择你想要的文本块并执行任何类型的操作,比如yank,删除,粘贴,编辑等。编辑面向列的文本非常棒。


    一些生产力提示:

    智能运动

  • *#在光标向前/向后搜索单词。
  • w到下一个单词
  • W到下一个空格分隔的单词
  • b / e到当前单词的开始/结尾。 (只适用于空间分隔的B / E
  • gg / G跳转到文件的开始/结尾处。
  • %跳转到匹配的{..}或(..)等。
  • { / }跳转到下一段。
  • '. 跳回到上次编辑的行。
  • g; 跳回到上次编辑的位置。
  • 快速编辑命令

  • I在开始插入。
  • A追加结束。
  • o / O在当前/之前打开一个新行。
  • v / V / Ctrl+V可视模式(选择文本!)
  • Shift+R替换文字
  • C改变线的剩余部分。
  • 组合命令

    大多数命令都接受数量和方向,例如:

  • cW =改变直到结束
  • 3cW =更改3个单词
  • BcW =开始全字,更改全字
  • ciW =改变内部词。
  • ci" =改变”..“之间的内部。
  • ci( =更改(...)之间的文本)
  • ci< =在<..>之间改变文本(需要在vimrc中set matchpairs+=<:>
  • 4dd =删除4行
  • 3x =删除3个字符。
  • 3s =替换3个字符。
  • 有用的程序员命令

  • r替换一个字符(例如rdd替换当前字符)。
  • ~改变的情况。
  • J加入两行
  • Ctrl + A / Ctrl + X增加/减少一个数字。
  • . 重复上一个命令(一个简单的宏)
  • ==修复行缩进
  • >缩进块(在可视模式下)
  • < unindent块(在可视模式下)
  • 宏录制

  • q[ key ]开始录制。
  • 然后按q停止录制。
  • 该宏可以使用@[ key ]进行播放。
  • 通过使用非常具体的命令和动作,VIM可以重播下一行的确切动作。 (例如,A表示追加到结尾, b / e分别将光标移动到单词的开头或结尾)

    完善设置的示例

    # reset to vim-defaults
    if &compatible          # only if not set before:
      set nocompatible      # use vim-defaults instead of vi-defaults (easier, more user friendly)
    endif
    
    # display settings
    set background=dark     # enable for dark terminals
    set nowrap              # dont wrap lines
    set scrolloff=2         # 2 lines above/below cursor when scrolling
    set number              # show line numbers
    set showmatch           # show matching bracket (briefly jump)
    set showmode            # show mode in status bar (insert/replace/...)
    set showcmd             # show typed command in status bar
    set ruler               # show cursor position in status bar
    set title               # show file in titlebar
    set wildmenu            # completion with menu
    set wildignore=*.o,*.obj,*.bak,*.exe,*.py[co],*.swp,*~,*.pyc,.svn
    set laststatus=2        # use 2 lines for the status bar
    set matchtime=2         # show matching bracket for 0.2 seconds
    set matchpairs+=<:>     # specially for html
    
    # editor settings
    set esckeys             # map missed escape sequences (enables keypad keys)
    set ignorecase          # case insensitive searching
    set smartcase           # but become case sensitive if you type uppercase characters
    set smartindent         # smart auto indenting
    set smarttab            # smart tab handling for indenting
    set magic               # change the way backslashes are used in search patterns
    set bs=indent,eol,start # Allow backspacing over everything in insert mode
    
    set tabstop=4           # number of spaces a tab counts for
    set shiftwidth=4        # spaces for autoindents
    #set expandtab           # turn a tabs into spaces
    
    set fileformat=unix     # file mode is unix
    #set fileformats=unix,dos    # only detect unix file format, displays that ^M with dos files
    
    # system settings
    set lazyredraw          # no redraws in macros
    set confirm             # get a dialog when :q, :w, or :wq fails
    set nobackup            # no backup~ files.
    set viminfo='20,"500   # remember copy registers after quitting in the .viminfo file -- 20 jump links, regs up to 500 lines'
    set hidden              # remember undo after quitting
    set history=50          # keep 50 lines of command history
    set mouse=v             # use mouse in visual mode (not normal,insert,command,help mode
    
    
    # color settings (if terminal/gui supports it)
    if &t_Co > 2 || has("gui_running")
      syntax on          # enable colors
      set hlsearch       # highlight search (very useful!)
      set incsearch      # search incremently (search while typing)
    endif
    
    # paste mode toggle (needed when using autoindent/smartindent)
    map <F10> :set paste<CR>
    map <F11> :set nopaste<CR>
    imap <F10> <C-O>:set paste<CR>
    imap <F11> <nop>
    set pastetoggle=<F11>
    
    # Use of the filetype plugins, auto completion and indentation support
    filetype plugin indent on
    
    # file type specific settings
    if has("autocmd")
      # For debugging
      #set verbose=9
    
      # if bash is sh.
      let bash_is_sh=1
    
      # change to directory of current file automatically
      autocmd BufEnter * lcd %:p:h
    
      # Put these in an autocmd group, so that we can delete them easily.
      augroup mysettings
        au FileType xslt,xml,css,html,xhtml,javascript,sh,config,c,cpp,docbook set smartindent shiftwidth=2 softtabstop=2 expandtab
        au FileType tex set wrap shiftwidth=2 softtabstop=2 expandtab
    
        # Confirm to PEP8
        au FileType python set tabstop=4 softtabstop=4 expandtab shiftwidth=4 cinwords=if,elif,else,for,while,try,except,finally,def,class
      augroup END
    
      augroup perl
        # reset (disable previous 'augroup perl' settings)
        au!  
    
        au BufReadPre,BufNewFile
         *.pl,*.pm
         set formatoptions=croq smartindent shiftwidth=2 softtabstop=2 cindent cinkeys='0{,0},!^F,o,O,e' " tags=./tags,tags,~/devel/tags,~/devel/C
        # formatoption:
        #   t - wrap text using textwidth
        #   c - wrap comments using textwidth (and auto insert comment leader)
        #   r - auto insert comment leader when pressing <return> in insert mode
        #   o - auto insert comment leader when pressing 'o' or 'O'.
        #   q - allow formatting of comments with "gq"
        #   a - auto formatting for paragraphs
        #   n - auto wrap numbered lists
        #   
      augroup END
    
    
      # Always jump to the last known cursor position. 
      # Don't do it when the position is invalid or when inside
      # an event handler (happens when dropping a file on gvim). 
      autocmd BufReadPost * 
         if line("'"") > 0 && line("'"") <= line("$") | 
           exe "normal g`"" | 
         endif 
    
    endif # has("autocmd")
    

    这些设置可以存储在/etc/vimrc.local ~/.vimrc或系统范围内,然后使用以下命令从/etc/vimrc文件读取:

    source /etc/vimrc.local
    

    (您必须将#注释字符替换为"使其在VIM中工作,我想在此提供适当的语法高亮显示)。

    我在这里列出的命令是非常基本的,并且是我迄今使用的主要命令。 他们已经使我更富有成效,而不必知道所有花哨的东西。

    链接地址: http://www.djcxy.com/p/1375.html

    上一篇: What is your most productive shortcut with Vim?

    下一篇: What are the dark corners of Vim your mom never told you about?