1125

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

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

  1. 交替使用左手和右手是使用键盘的最快方法。
  2. 永远不要触摸鼠标是第二种尽可能快的方法。你需要很长时间才能移动你的手,抓住鼠标,移动它,然后把它带回键盘(你经常需要查看键盘以确保你的手正确地回到了正确的位置)

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

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

使用 Vim 很可怕:

  • yy复制一行(你几乎从不想要整行!)
  • [number xx]yy将行复制xx到缓冲区中。但是你永远不知道你是否选择了你想要的东西。我经常不得不做[number xx]dd然后u撤消!

另一个例子?搜索和替换。

  • PSPad中:Ctrl+f然后输入您要搜索的内容,然后按Enter
  • 在 Vim:/中,然后键入要搜索的内容,然后如果在每个\特殊字符之前放置了一些特殊字符,然后按。Enter

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

注意:我已经阅读了 Vim备忘 :)

我的问题是:

你使用 Vim 的哪种方式比使用现代编辑器更高效?

4

50 回答 50

2854

你对Vim的问题是你不了解vi

你提到切割yy并抱怨你几乎从不想切割整条线。事实上,编辑源代码的程序员经常希望在整行、行范围和代码块上工作。但是,yy这只是将文本拉入匿名复制缓冲区(或在vi中调用的“注册” )的众多方法之一。

vi的“禅”是你在说一种语言。首字母y是动词。该声明yy是 的同义词y_y加倍以使其更易于键入,因为它是一种常见的操作。

这也可以表示为dd P(删除当前行并将副本粘贴回原处;在匿名寄存器中留下副本作为副作用)。theyd“动词”以任何动作为“主语”。因此yW是“从这里(光标)拉到当前/下一个(大)单词的末尾”并且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 次击键开销(如果我们从“插入”开始,则为 6 "模式和需要Esc出命令模式)。一旦我们剪切或复制,然后粘贴副本是一个单一的击键:p.

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

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

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

除了“动词”和“主语”,vi还有“宾语”(在语法意义上)。到目前为止,我只描述了匿名寄存器的使用。但是,我可以通过在“对象”引用前加上(双引号修饰符)使用 26 个“命名”寄存器中的任何一个。"因此,如果我使用"add我将当前行剪切到' a '寄存器中,如果我使用"by/foo然后我将文本的副本从这里拉到包含“foo”的下一行到' b '寄存器中。要从寄存器粘贴,我只需在粘贴前加上相同的修饰符序列:粘贴“ a ”寄存器"ap的副本"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,$

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

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

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

我们可以使用m来移动线条,并j加入线条。例如,如果您有一个列表,并且您想分隔所有匹配的内容(或者相反地不匹配某些模式)而不删除它们,那么您可以使用类似的内容::% g/foo/m$...并且所有“foo”行都将被移动到文件的结尾。(注意关于使用文件末尾作为暂存空间的另一个提示)。这将保留所有“foo”行的相对顺序,同时从列表的其余部分中提取它们。(这相当于执行以下1G!GGmap!Ggrep foo<ENTER>1G:1,'a g/foo'/d操作:(将文件复制到它自己的尾部,通过 过滤尾部grep,并从头部删除所有内容)。

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

几乎不用说,您可以将我们的老朋友s(substitute) 与gand v(global/converse-global) 命令一起使用。通常你不需要这样做。但是,考虑某些情况,您只想对匹配其他模式的行执行替换。通常,您可以使用带有捕获的复杂模式并使用反向引用来保留您不想更改的行部分。但是,将匹配项与替换项分开通常会更容易::% g/foo/s/bar/zzz/g-- 对于包含“foo”的每一行,将所有“bar”替换为“zzz”。(就像是:% s/\(.*foo.*\)bar\(.*\)/\1zzz\2/g仅适用于同一行中“foo”之前的“bar”实例;它已经够难看的了,必须进一步处理才能捕捉到“bar”在“foo”之前的所有情况)

关键是命令集中不仅仅是p, s, 和d行。ex

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

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

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

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

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

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

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

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

viVim+的命令行选项通常用于在给定的行号处启动编辑会话。然而,一个鲜为人知的事实是,可以跟随任何有效的ex命令/表达式,例如“source”命令我已经在这里完成了;举个简单的例子,我有一些脚本可以调用:在我重新映像一组服务器时,以非交互方式从我的 SSH 已知主机文件中删除一个条目)。+vi +'/foo/d|wq!' ~/.ssh/known_hosts

通常使用 Perl、AWK、 sed(实际上,就像greped命令启发的实用程序一样)编写这样的“宏”要容易得多。

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

  1. 0i:r(将当前行变成有效的:r命令),
  2. "cdd(将行删除到“c”寄存器中)和
  3. @c执行该命令。

这只是 10 次击键(对我来说,这个表达式"cdd @c实际上是一个手指宏,所以我几乎可以像任何常见的六个字母单词一样快速地输入它)。


发人深省的想法

我只是触及了vi功能的表面,我在这里所描述的甚至都不是vim命名的“改进”的一部分!我在这里描述的所有内容都应该适用于20 或 30 年前的任何旧vi副本。

有些人使用vi的能力比我以往任何时候都多。

于 2009-08-02T23:08:04.560 回答
504

您正在谈论文本选择和复制,我认为您应该看看Vim Visual Mode

在可视模式下,您可以使用 Vim 命令选择文本,然后您可以对选择进行任何操作。

考虑以下常见场景:

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

你可以这样做:

  • v%如果光标在开始/结束括号上
  • vib如果光标在括号块内

您想在引号之间选择文本:

  • vi"用于双引号
  • vi'用于单引号

你想选择一个花括号块(在 C 风格的语言中很常见):

  • viB
  • vi{

您要选择整个文件:

  • ggVG

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

于 2009-08-02T08:27:12.863 回答
207

一些生产力提示:

智能动作

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

快速编辑命令

  • I在开头插入。
  • A追加到结尾。
  • o/O在当前行之后/之前打开一个新行。
  • v//可视模式VCtrl+V选择文字!)
  • Shift+R替换文本
  • C更改行的剩余部分。

组合命令

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

  • cW= 更改到词尾
  • 3cW= 改变 3 个字
  • BcW= 以全字开头,更改全字
  • ciW= 改变内在词。
  • ci"=在“..”之间更改内部
  • ci(= 在 ( .. ) 之间更改文本
  • ci<= 在 < .. > 之间更改文本(set matchpairs+=<:>vimrc 中需要)
  • 4dd= 删除 4 行
  • 3x= 删除 3 个字符。
  • 3s= 替换 3 个字符。

有用的程序员命令

  • r替换一个字符(例如rd用 替换当前字符d)。
  • ~改变大小写。
  • 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")

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

source /etc/vimrc.local

(您必须将#注释字符替换"为使其在 VIM 中工作,我想在此处给出正确的语法突出显示)。

我在这里列出的命令非常基本,也是我目前使用的主要命令。他们已经让我变得更有效率,而不必知道所有花哨的东西。

于 2010-04-01T09:08:06.630 回答
98

Control+R机制非常有用:-) 在插入模式命令模式下(即在:键入命令时在行上),继续使用编号或命名的寄存器:

  • a-z命名寄存器
  • "未命名的寄存器,包含上次删除或抽出的文本
  • %当前文件名
  • #备用文件名
  • *剪贴板内容(X11:主要选择)
  • +剪贴板内容
  • /最后的搜索模式
  • :最后一个命令行
  • .最后插入的文本
  • -最后一个小(不到一行)删除
  • =5*5在文本中插入 25(迷你计算器)

查看:help i_CTRL-R:help c_CTRL-R了解更多详细信息,并在附近窥探以获取更多 CTRL-R 优点。

于 2010-06-02T18:49:57.400 回答
91

Vim 插件

这里有很多很好的答案,还有一个关于 vi 之禅的令人惊叹的答案。我没有看到提到的一件事是 vim 通过插件非常可扩展。有一些脚本和插件可以让它做原作者从未考虑过的各种疯狂的事情。以下是一些非常方便的 vim 插件示例:

导轨.vim

Rails.vim 是 tpope 编写的插件。对于从事 Rails 开发的人来说,这是一个令人难以置信的工具。它做了神奇的上下文敏感的事情,使您可以轻松地从控制器中的方法跳转到关联的视图,跳转到模型,并下到该模型的单元测试。作为 Rails 开发人员,它已经节省了数十甚至数百小时。

要点.vim

该插件允许您在可视模式下选择文本区域并键入快速命令将其发布到gist.github.com。这允许轻松访问 pastebin,如果您通过 IRC 或 IM 与某人协作,这将非常方便。

空间.vim

这个插件为空格键提供了特殊的功能。它将空格键变成类似于句号的东西,但不是重复动作,而是重复动作。这对于以您动态定义的方式快速浏览文件非常方便。

环绕.vim

该插件使您能够处理以某种方式分隔的文本。它为您提供了表示括号内的事物、引号内的事物等的对象。它可以方便地处理分隔文本。

超级标签.vim

该脚本为 vim 带来了精美的制表符补全功能。自动完成功能已经存在于 vim 的核心中,但这会将其带到一个快速选项卡上,而不是多个不同的多键快捷键。非常方便,使用起来非常有趣。虽然它不是 VS 的智能感知,但它是一个伟大的步骤,并带来了您希望从选项卡完成工具中获得的大量功能。

语法的.vim

该工具将外部语法检查命令引入 vim。我没有亲自使用过它,但我听说过关于它的好消息,而且这个概念很难被击败。无需手动检查语法可以节省大量时间,并且可以帮助您在引入语法错误时而不是在最终停止测试时发现它们。

逃犯.vim

从 vim 内部直接访问 git。同样,我没有使用过这个插件,但我可以看到该实用程序。不幸的是,我所处的文化中 svn 被认为是“新的”,所以在相当长的一段时间内我不太可能看到 git 在工作。

书呆子树.vim

vim 的树形浏览器。我最近开始使用它,它真的很方便。它使您可以将树视图垂直拆分并轻松打开文件。这对于一个有很多源文件的项目来说非常棒,你经常在它们之间跳转。

FuzzyFinderTextmate.vim

这是一个无人维护的插件,但仍然非常有用。它提供了使用“模糊”描述性语法打开文件的能力。这意味着在稀疏的文件树中,您只需键入足够的字符即可将您感兴趣的文件与其他文件区分开来。

结论

有很多令人难以置信的工具可用于 vim。我敢肯定我在这里只触及了表面,值得搜索适用于您的域的工具。结合了传统 vi 的强大工具集、vim 对其的改进以及进一步扩展 vim 的插件,它是有史以来最强大的文本编辑方式之一。Vim 很容易与 emacs、eclipse、visual studio 和 textmate 一样强大。

谢谢

感谢duwanisvim 配置,我从中学到了很多,并借用了这里列出的大部分插件。

于 2010-04-01T03:44:29.657 回答
53

.重复上一个文本更改命令

我用这个节省了很多时间。

之前提到了可视模式,但是块可视模式在编辑文本文件中的固定大小列时为我节省了很多时间。(使用 Ctrl-V 访问)。

于 2010-02-27T11:28:44.660 回答
48

转到最后编辑的位置(如果您执行了一些搜索并且不想返回编辑,则非常有用)

^P 和 ^N

完成上一个 (^P) 或下一个 (^N) 文本。

^O 和 ^I

转到上一个(^O-"O"表示旧)位置或下一个(^I-"I"就在 附近"O")。当您执行搜索、编辑文件等操作时,您可以前后导航这些“跳转”。

于 2009-08-02T10:07:28.917 回答
46

我最近(得到)发现了这个网站:http: //vimcasts.org/

它很新而且真的很好。运行该站点的人从 textmate 切换到 vim,并就特定的 vim 主题主持了非常出色和简洁的演员表。看看这个!

于 2010-03-31T19:37:33.913 回答
42

CTRL+A增加您站立的数字。

于 2009-08-02T14:01:46.670 回答
38

全部处于正常模式:

f<char>移动到当前行上特定字符的下一个实例,并且; 重复。

F<char>移动到当前行上特定字符的上一个实例和; 重复。

如果巧妙地使用,以上两个可以让你在一条线上快速移动。

*在一个词上搜索下一个实例。

#在一个词上搜索前一个实例。

于 2009-08-02T19:19:17.967 回答
34

会议

一种。保存会话

:mks会话名称

湾。强制保存会话

:mks!会话名称

C。加载会话

gvim 或 vim -S会话名


加减法

一种。加减法

CTRL-A ;在光标处或之后的数字或字母字符上加 [count]。{不在 Vi 中

CTRL-X ;从光标处或之后的数字或字母字符中减去 [count]。{Vi 无此功能}

湾。窗口键取消映射

在窗口中,Ctrl-A 已经映射为您需要在 rc 文件中取消映射的整个文件选择。将 mswin.vim CTRL-A 映射部分标记为注释或使用 unmap 添加您的 rc 文件

C。带宏

CTRL-A 命令在宏中非常有用。示例:使用以下步骤制作编号列表。

  1. 创建第一个列表条目,确保它以数字开头。
  2. qa - 开始录制到缓冲区“a”中
  3. Y - 拉出条目
  4. p - 将条目的副本放在第一个条目的下方
  5. CTRL-A - 增加数字
  6. q - 停止录制
  7. @a - 重复 yank、put 和 increment 时间
于 2010-08-19T08:08:28.973 回答
32

上周在工作中,我们的项目从另一个项目中继承了很多 Python 代码。不幸的是,代码不适合我们现有的架构——它都是用全局变量和函数完成的,这在多线程环境中是行不通的。

我们有大约 80 个文件需要重新设计为面向对象 - 所有的函数都移到类中,参数更改,导入语句添加等等。我们有一个大约 20 种类型的修复列表,需要对每个文件进行修复。我估计一个人每天可以做 2-4 次。

所以我手工做了第一个,然后编写了一个 vim 脚本来自动进行更改。其中大部分是 vim 命令的列表,例如

" delete an un-needed function "
g/someFunction(/ d

" add wibble parameter to function foo "
%s/foo(/foo( wibble,/

" convert all function calls bar(thing) into method calls thing.bar() "
g/bar(/ normal nmaf(ldi(`aPa.

最后一个值得解释一下:

g/bar(/  executes the following command on every line that contains "bar("
normal   execute the following text as if it was typed in in normal mode
n        goes to the next match of "bar(" (since the :g command leaves the cursor position at the start of the line)
ma       saves the cursor position in mark a
f(       moves forward to the next opening bracket
l        moves right one character, so the cursor is now inside the brackets
di(      delete all the text inside the brackets
`a       go back to the position saved as mark a (i.e. the first character of "bar")
P        paste the deleted text before the current cursor position
a.       go into insert mode and add a "." 

对于一些更复杂的转换,例如生成所有导入语句,我将一些 python 嵌入到 vim 脚本中。

经过几个小时的工作,我有一个脚本可以完成至少 95% 的转换。我只是在 vim 中打开一个文件然后运行:source fixit.vim,文件在眨眼间就被转换了。

我们仍然需要更改剩余 5% 的不值得自动化的部分并测试结果,但是通过花费一天的时间编写这个脚本,我估计我们节省了数周的工作。

当然,使用 Python 或 Ruby 之类的脚本语言可以自动执行此操作,但编写时间会更长,而且灵活性会降低 - 最后一个示例会很困难,因为单独的正则表达式无法处理嵌套括号,例如转换bar(foo(xxx))foo(xxx).bar(). Vim 非常适合这项任务。

于 2010-02-27T12:06:13.683 回答
28

使用内置文件浏览器!该命令是:Explore,它允许您非常快速地浏览您的源代码。我有这些映射在我的.vimrc

map <silent> <F8>   :Explore<CR>
map <silent> <S-F8> :sp +Explore<CR>

资源管理器也允许您进行文件修改。我将发布一些我最喜欢的键,按下<F1>将为您提供完整列表:

  • -:最有用的:切换到上层目录(cd ..
  • mf : 标记文件
  • D:删除标记的文件或光标所在的文件,如果没有标记。
  • R:重命名光标所在的文件。
  • d : 在当前目录下新建目录
  • % : 在当前目录新建文件
于 2009-08-02T08:34:06.373 回答
25

我是美国密码协会的成员。双月刊杂志包括 100 多种不同类型的密码。其中大约有 15 个是“密码”——各种类型的算术问题,用字母代替数字。其中两个或三个是数独,除了用字母而不是数字。当网格完成后,九个不同的字母将在网格某处的某条线上、对角线、螺旋线等处拼出一个或多个单词。

我没有用铅笔工作,也没有手工输入问题,而是从他们网站的会员区下载问题。

在处理这些数独游戏时,我使用 vi,只是因为我正在使用 vi 拥有的其他编辑器很少有的功能。主要是在将字母格转换成编号格,因为我发现它更容易解决,然后将完成的编号格重新转换为字母格以找到解决方案的单词或单词。

问题被格式化为九组,每组九个字母,-s 代表空格,写成两行。第一步是将它们格式化为九行,每行九个字符。这没什么特别的,只是在适当的地方插入八个换行符。

结果将如下所示:

T-O-----C
-E-----S-
--AT--N-L
---NASO--
---E-T---
--SPCL---
E-T--OS--
-A-----P-
S-----C-T

因此,将其转换为数字的第一步是制作不同字母的列表。首先,我制作了块的副本。我将光标放在块的顶部,然后键入:y}}p. :让我进入命令模式,y猛拉下一个移动命令。由于}是移动到下一段的末尾,因此y}拉出该段。 }然后将光标移动到段落的末尾,并p粘贴我们刚刚在光标之后拉出的内容。因此y}}p创建下一段的副本,并以光标在两个副本之间结束。

接下来,我将其中一个副本变成不同字母的列表。该命令有点复杂:

:!}tr -cd A-Z | sed 's/\(.\)/\1\n/g' | sort -u | tr -d '\n'

:再次让我进入命令模式。 !表示下一个 yank 的内容应该通过命令行传递。 }抽出下一段,然后命令行使用该tr命令删除除大写字母以外的所有内容,该sed命令将每个字母打印在一行上,并使用该sort命令对这些行进行排序,删除重复项,然后tr删除换行符,将九个不同的字母留在一行中,替换最初组成段落的九行。在这种情况下,字母是:ACELNOPST

下一步是制作网格的另一个副本。然后使用我刚刚确定的字母将每个字母替换为从 1 到 9 的数字。这很简单::!}tr ACELNOPST 0-9. 结果是:

8-5-----1
-2-----7-
--08--4-3
---4075--
---2-8---
--7613---
2-8--57--
-0-----6-
7-----1-8

然后可以以通常的方式解决这个问题,或者输入您可能喜欢的任何数独求解器。然后可以将完成的解决方案转换回带有 的字母:!}tr 1-9 ACELNOPST

vi 中的强大功能很少有人能与之匹敌。最大的问题是,只有极少数的 vi 教程书籍、网站、帮助文件等,几乎没有触及可能的表面。

于 2010-04-02T05:17:26.527 回答
23

批量文本操作!

通过宏:

  • 从录音开始:qq
  • 做东西
  • 停止录制:q
  • 重复:(@q第一次),@@之后。
  • 重复 20 次:20@@

或者通过正则表达式:

  • 替换东西::%s/[fo]+/bar/g

(但要注意:如果你做后者,你会有两个问题:)。)

于 2009-08-02T08:59:30.177 回答
23

我最近发现q:。它打开“命令窗口”并显示您最近的前模式(命令模式)命令。您可以像往常一样在窗口内移动,然后按<CR>执行命令。您也可以编辑等。当您在处理一些复杂的命令或正则表达式并且您不想重新输入整个内容时,或者您想要做的复杂事情是 3 个命令时,这是无价的。它几乎就像 bash 的set -o vi,但对于 vim 本身(嘿!)。

:help q:来回查看更多有趣的内容。

于 2012-04-02T07:56:22.900 回答
22

前几天我刚刚发现了 Vim 的全补全功能,虽然我承认我对具体做什么有点模糊,但我在插入模式下将Ctrl+ x Ctrl+uCtrl+ n/ Ctrl+混合在一起,我得到了令人惊讶的好结果。p它不完全是IntelliSense,但我仍在学习它。

试试看!:help ins-completion

于 2009-08-02T08:54:00.017 回答
20

这些不是捷径,但它们是相关的:

  1. 使大写锁定一个额外的 ESC(或 Ctrl)
  2. 使用以下命令将领导者映射到“,”(逗号):let mapleader=","

它们提高了我的工作效率。

于 2010-03-14T19:49:18.493 回答
19

我经常使用的另一个有用的vi“快捷方式”是'xp'。这会将光标下的字符与下一个字符交换。

于 2010-09-20T10:34:50.607 回答
18

<Ctrl> + W, V 垂直分割屏幕
<Ctrl> + W, W 在窗口之间切换

!python % [args] 运行我在这个窗口中编辑的脚本

ZF 在可视模式下折叠任意线

于 2009-08-02T09:47:38.397 回答
18

视觉模式

正如其他几个人所说,视觉模式是您复制/剪切和粘贴问题的答案。Vim 为您提供 'v'、'V' 和 Cv。vim 中的小写 'v' 与记事本中的 shift 键基本相同。好处是你不必按住它。您可以使用任何移动技术有效地导航到您选择的起点(或终点)。然后点击“v”,再次使用有效的移动技术导航到选择的另一端。然后“d”或“y”允许您剪切或复制该选择。

vim 的可视化模式比 Jim Dennis 在 vi​​ 中对剪切/复制/粘贴的描述的优势在于您不必完全正确地获取位置。有时,使用快速运动到达您想去的地方的大致附近,然后用其他运动对其进行改进,而不是想出一个更复杂的单一运动命令来让您准确地到达您想去的地方,这样做效率更高。

以这种方式广泛使用可视模式的缺点是它可能会成为您一直使用的拐杖,这会阻止您学习可能使您更有效地做事的新 vi(m) 命令。但是,如果您非常积极主动地学习 vi(m) 的新方面,那么这可能不会对您产生太大影响。

我还将再次强调,视觉线和视觉块模式为您提供了同一主题的变化,它们可能非常强大……尤其是视觉块模式。

关于有效使用键盘

我也不同意您关于交替双手是使用键盘的最快方式的说法。它里面有真理的成分。很笼统地说,重复使用同一个东西是很慢的。这个原理最重要的例子是用同一根手指连续敲击键盘非常慢。您的断言可能源于在此模式上使用 s/finger/hand/ 转换的自然趋势。在某种程度上它是正确的,但在效率谱的极高端它是不正确的。

只要问任何钢琴家。询问他们是交替演奏连续几个音符还是按顺序使用单手的连续手指是否更快。键入 4 次击键的最快方法不是交替双手,而是用同一只手的 4 个手指按升序或降序进行键入(称之为“运行”)。一旦你考虑了这种可能性,这应该是不言而喻的。

更困难的问题是为此进行优化。优化键盘上的绝对距离非常容易。Vim 就是这样做的。在“运行”级别进行优化要困难得多,但是 vi(m) 与它的模态编辑相比,任何非模态方法(ahem,emacs)都比任何非模态方法(ahem,emacs)都有更好的机会来做到这一点。

在 Emacs 上

以免 emacs 狂热者因为最后的括号评论而完全无视我的整个帖子,我觉得我必须描述 emacs 和 vim 宗教之间差异的根源。我从来没有在编辑大战中说过话,我可能不会再这样做了,但我从来没有听过有人这样描述这些差异,所以就这样吧。不同之处在于以下权衡:

Vim 为您提供无与伦比的原始文本编辑效率 Emacs 为您提供无与伦比的自定义和编程编辑器的能力

盲目的 vim 狂热者会声称 vim 有一种脚本语言。但它是一种晦涩难懂的临时语言,旨在为编辑服务。Emacs 有 Lisp!说够了。如果您不理解最后两句话的重要性,或者希望充分了解函数式编程和 Lisp 以培养这种理解,那么您应该使用 vim。

emacs 狂热者会声称 emacs 具有 viper 模式,因此它是 vim 的超集。但毒蛇模式不是标准的。我的理解是大多数emacs用户不使用viper模式。由于它不是默认设置,因此大多数 emacs 用户可能不会真正理解模态范式的好处。

在我看来,这些差异是正交的。我相信 vim 和 emacs 的好处,正如我所说的那样,它们都是有效的。这意味着终极编辑器还不存在。emacs 可能是作为终极编辑器基础的最简单的平台,这可能是真的。但是模态编辑并没有根深蒂固于 emacs 的思维模式。emacs 社区将来可能会朝着这个方向发展,但这似乎不太可能。

因此,如果您想要原始编辑效率,请使用 vim。如果您想要为您的编辑器编写脚本和编程的终极环境,请使用 emacs。如果您想要两者都强调可编程性,请使用带有 viper 模式的 emacs(或编写您自己的模式)。如果您想要两全其美,那么您现在就不走运了。

于 2010-04-01T16:49:49.550 回答
17

花 30 分钟学习 vim 教程(在终端中运行 vimtutor 而不是 vim)。您将学习基本动作和一些击键,这将使您使用 vim 至少与使用之前使用的文本编辑器一样高效。在那之后,好吧,再次阅读吉姆丹尼斯的回答:)

于 2010-03-31T22:44:38.187 回答
16

我惊讶地发现没有人提及这项t运动。我经常将它与dt,或形式的参数列表一起使用yt,

于 2010-04-01T11:30:31.540 回答
16

在搜索中的任何位置使用\c以忽略大小写(覆盖您的忽略大小写或智能大小写设置)。例如/\cfooor/foo\c将匹配foo, Foo, fOO,FOO等。

在搜索中的任何位置使用\C强制大小写匹配。例如/\Cfooor/foo\C只会匹配 foo。

于 2010-06-09T10:29:11.787 回答
16

你使用 Vim 的哪种方式比使用现代编辑器更高效?

能够用很少的按键(通常使用)执行复杂、重复的编辑。看看VimGolf,见证 Vim 的强大!

经过十多年几乎每天的使用,很难想象使用任何其他编辑器。

于 2011-01-12T22:52:32.003 回答
16

奇怪的是没有人提到ctags。下载“exuberant ctags”并将其放在搜索路径中已有的糟糕预装版本之前。cd 到你正在处理的任何东西的根目录;例如 Android 内核分发。键入“ctags -R”。在名为“tags”的文件中,在该目录下的任何位置构建源文件的索引。这包含所有标签,无论语言还是目录中的位置,都在一个文件中,因此跨语言工作很容易。

然后在该文件夹中打开 vim 并阅读 :help ctags 以获取一些命令。我经常使用的几个:

  • 将光标放在方法调用上并键入 CTRL-] 以转到方法定义。

  • 键入 :ta name 以转到名称的定义。

于 2012-02-04T22:54:14.407 回答
14

自动缩进:

gg(转到文档开头)
=(缩进时间!)
shift-g(转到文档末尾)

您需要在文件中使用“filetype plugin indent on” .vimrc,并且可能需要适当的“shiftwidth”和“expandtab”设置。

于 2009-08-06T01:56:28.140 回答
14

您询问了高效的快捷方式,但我认为您真正的问题是:vim 值得吗?这个stackoverflow问题的答案是->“是”

你一定注意到了两件事。Vim 很强大,vim 很难学。它的大部分功能在于它的可扩展性和无尽的命令组合。不要感到不知所措。慢慢来。一个命令,一次一个插件。不要过度。

您投入 vim 的所有投资将获得一千倍的回报。在你死之前,你将在文本编辑器中呆上很多很多小时。Vim 将成为您的伴侣。

于 2010-07-24T05:41:20.577 回答
13

多个缓冲区,特别是它们之间的快速跳转以将两个文件与:bpand进行比较:bn(正确地重新映射到单个Shift+pShift+ n

vimdiff模式(分成两个垂直缓冲区,用颜色显示差异)

Ctrl带+的区域复制v

最后,标识符的制表符补全(搜索“mosh_tab_or_complete”)。这是一个改变生活的人。

于 2009-08-02T09:23:06.010 回答
12

同意顶级海报 - :r!命令非常有用。

大多数情况下,我用它来“粘贴”东西:

:r!cat
**Ctrl-V to paste from the OS clipboard**
^D

这样我就不用折腾了:set paste

于 2009-08-28T16:07:18.983 回答
10

加快编辑速度的第三个标准是所需的击键次数。我想说这比你的其他 2 更重要。在 vim 中,几乎所有操作都需要比我熟悉的任何其他编辑器更少的击键。

您提到您在剪切和粘贴时遇到问题,但听起来您需要更多关于 vim 中一般运动命令的经验。yank 3 个单词:y3w 从光标拉到下一个分号:yf;拉到您最近搜索的下一个位置: yn 所有这些都比在按住修改键时尝试用鼠标导航要快得多。此外,正如 CMS 响应中的一些示例所示,vim 的运动命令针对 C 和 C++ 源代码中的高效导航进行了高度优化。

至于“如何使用 vim 让我更有效率?”这个问题,我希望答案是:“高效”。

于 2009-08-02T13:36:18.623 回答
10

我最高效的 vi/Vim 技巧是:

:%s

我喜欢能够即时使用正则表达式来替换文件中我想要的任何内容。每个文本编辑器都应该支持正则表达式恕我直言。

于 2009-08-28T16:48:52.533 回答
10

cit – 在插入模式下使用转换清空标签的内容

yit - 复制标签的内容

于 2010-09-10T21:27:21.953 回答
10

您可以在替换字符串中使用 \= ,这是我经常做的事情。

如果您在 vim 中有本质上是无序列表的内容,例如使用 # 作为标记,您可以将其转换为有序列表。

# CSSLINT
# PHPCS
# Charlie
# Delta

如果它从第一行开始,你可以做

:1,6s/#/\=line(".")/g

将其转换为

1 CSSLINT
2 PHPCS
3 Charlie
4 Delta

如果它没有从第一行开始,只需进行数学运算:

:16,20s/#/\=line(".") - 15/g

更多信息:help sub-replace-expression

于 2011-08-27T09:04:48.070 回答
9

将以下内容映射到一个简单的组合键后,以下内容对我非常有用:

在文件路径上跳转到文件

gf

获取现有文件的完整路径名

:r!echo %:p

获取现有文件的目录

:r!echo %:p:h

运行代码:

:!ruby %:p

红宝石缩写:

ab if_do if end<esc>bi<cr><esc>xhxO
ab if_else if end<esc>bi<cr><esc>xhxO else<esc>bhxA<cr> <esc>k$O
ab meth def method<cr>end<esc>k<esc>:s/method/
ab klas class KlassName<cr>end<esc>k<esc>:s/KlassName/
ab mod module ModName<cr>end<esc>k<esc>:s/ModName/

运行当前程序:

   map ,rby :w!<cr>:!ruby %:p<cr>

检查当前程序的语法:

   map ,c :w!<cr>:!ruby -c %:p<cr>

运行当前规范程序的所有规范:

   map ,s :w!<cr>:!rspec %:p<cr>

破解它打开irb:

   map ,i :w!<cr>:!irb<cr>

rspec 缩写:

   ab shared_examples shared_examples_for "behavior here" do<cr>end
   ab shared_behavior describe "description here" do<cr>  before :each do<cr>end<cr>it_should_behave_like "behavior here"<cr><bs>end<cr>
   ab describe_do describe "description here" do<cr>end
   ab context_do describe "description here" do<cr>end
   ab it_do it "description here" do<cr>end
   ab before_each before :each do<cr>end<cr>

轨道缩写:

用户认证:

     ab userc <esc>:r $VIMRUNTIME/Templates/Ruby/c-users.rb<cr>
     ab userv <esc>:r $VIMRUNTIME/Templates/Ruby/v-users.erb<cr>
     ab userm <esc>:r $VIMRUNTIME/Templates/Ruby/m-users.rb<cr>

在 Firefox 中打开视觉选择的 url:

"function
   function open_url_in_firefox:(copy_text)
     let g:open_url_in_firefox="silent !open -a \"firefox\" \"".a:copy_text."\""
     exe g:open_url_in_firefox
   endfunction

"abbreviations
   map ,d :call open_url_in_firefox:(expand("%:p"))<cr>
   map go y:call open_url_in_firefox:(@0)<cr> 

rspec:运行包含当前行的规范:

"function
   function run_single_rspec_test:(the_test)
     let g:rake_spec="!rspec ".a:the_test.":".line(".")
     exe g:rake_spec
   endfunction

"abbreviations
   map ,s :call run_single_rspec_test:(expand("%:p"))<cr>

rspec-rails:运行包含当前行的规范:

"function
   function run_single_rails_rspec_test:(the_test)
     let g:rake_spec="!rake spec SPEC=\"".a:the_test.":".line(".")."\""
     exe g:rake_spec
   endfunction

"abbreviations
   map ,r :call run_single_rails_rspec_test:(expand("%:p"))<cr>

rspec-rails:运行包含当前行的规范并进行调试:

"function
   function run_spec_containing_current_line_with_debugging:(the_test)
     let g:rake_spec="!rake spec SPEC=\"".a:the_test.":".line(".")." -d\""
     exe g:rake_spec
   endfunction

"abbreviations
   map ,p :call run_spec_containing_current_line_with_debugging:(expand("%:p")) <cr>

html

"abbreviations

  "ab htm <html><cr><tab><head><cr></head><cr><body><cr></body><cr><bs><bs></html>
   ab template_html <script type = 'text/template' id = 'templateIdHere'></script>
   ab script_i <script src=''></script>
   ab script_m <script><cr></script>
   ab Tpage <esc>:r ~/.vim/templates/pageContainer.html<cr>
   ab Ttable <esc>:r ~/.vim/templates/listTable.html<cr>

"function to render common html template

   function html:() 
     call feedkeys( "i", 't' )
     call feedkeys("<html>\<cr>  <head>\<cr></head>\<cr><body>\<cr> ", 't')
     call feedkeys( "\<esc>", 't' )
     call feedkeys( "i", 't' )
     call include_js:()
     call feedkeys("\<bs>\<bs></body>\<cr> \<esc>hxhxi</html>", 't')
   endfunction

javascript

"jasmine.js
  "abbreviations
   ab describe_js describe('description here', function(){<cr>});
   ab context_js context('context here', function(){<cr>});
   ab it_js it('expectation here', function(){<cr>});
   ab expect_js expect().toEqual();
   ab before_js beforeEach(function(){<cr>});
   ab after_js afterEach(function(){<cr>});

"function abbreviations

   ab fun1 function(){}<esc>i<cr><esc>ko
   ab fun2 x=function(){};<esc>hi<cr>
   ab fun3 var x=function(){<cr>};

"method for rendering inclusion of common js files

   function include_js:()
     let includes_0  = "  <link   type = 'text\/css' rel = 'stylesheet' href = '\/Users\/johnjimenez\/common\/stylesheets\/jasmine-1.1.0\/jasmine.css'\/>"
     let includes_1  = "  <link   type = 'text\/css' rel = 'stylesheet' href = '\/Users\/johnjimenez\/common\/stylesheets\/screen.css'\/>"
     let includes_2  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/jquery-1.7.2\/jquery-1.7.2.js'><\/script>"
     let includes_3  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/underscore\/underscore.js'><\/script>"
     let includes_4  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/backbone-0.9.2\/backbone.js'><\/script>"
     let includes_5  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/jasmine-1.1.0\/jasmine.js'><\/script>"
     let includes_6  = "<script type = 'text\/javascript' src = '\/Users\/johnjimenez\/common\/javascripts\/jasmine-1.1.0\/jasmine-html.js'><\/script>"
     let includes_7  = "<script>"
     let includes_8  = "  describe('default page', function(){ "
     let includes_9  = "it('should have an html tag', function(){ "
     let includes_10 = "  expect( $( 'head' ).html() ).not.toMatch(\/^[\\s\\t\\n]*$\/);"
     let includes_11  = "});"
     let includes_12 = "});"
     let includes_13 = "$(function(){"
     let includes_14 = "jasmine.getEnv().addReporter( new jasmine.TrivialReporter() );"
     let includes_15 = "jasmine.getEnv().execute();"
     let includes_16 = "});"
     let includes_17 = "\<bs>\<bs><\/script>"

     let j = 0

     while j < 18
       let entry = 'includes_' . j
       call feedkeys( {entry}, 't' )
       call feedkeys( "\<cr>", 't' )
       let j = j + 1
     endwhile

   endfunction

"jquery

  "abbreviations

     ab docr $(document).ready(function(){});
     ab jqfun $(<cr>function(){<cr>}<cr>);
于 2012-03-24T03:30:19.353 回答
9

这是我发现对学习 Vim 很有帮助的另一个网站。也很好玩!:)

VIM Adventures是一款基于 VIM 键盘快捷键(命令、动作和操作符)的在线游戏。这是“塞尔达遇到文本编辑”游戏。这是一款用于练习和记忆 VIM 命令的益智游戏(当然,还涵盖了不错的旧 VI)。这是学习 VIM 的一种简单方法,没有陡峭的学习曲线。

于 2012-04-25T04:41:39.287 回答
7

将文本插入代码中的某个位:

ctrl + v, (selecting text on multiple lines), I, (type something I want), ESC

录制宏以编辑文本并运行 N 次:

q, a (or some other letter), (do the things I want to record), q, ESC,
(type N, as in the number of times I want to run the macro), @, a
于 2009-08-02T08:27:52.160 回答
7

暂时忽略这个问题(我的答案在下面),有几件事可能有助于解决您使用 vim 的问题:

:map <C-F> /\V

这将使 Ctrl-F 以搜索的第一个字符开始搜索\V,这会关闭所有“魔术”,因此您不必转义任何内容(就像 PsPad 一样)。

" CTRL-X and SHIFT-Del are Cut
vnoremap <C-X> "+x
vnoremap <S-Del> "+x

" CTRL-C and CTRL-Insert are Copy
vnoremap <C-C> "+y
vnoremap <C-Insert> "+y

" CTRL-V and SHIFT-Insert are Paste
map <C-V>       "+gP
map <S-Insert>      "+gP

cmap <C-V>      <C-R>+
cmap <S-Insert>     <C-R>+

(直接从 Vim 发行版的 mswin.vim 中取出)。这将为您提供 Ctrl-C、Ctrl-V 等用于复制和粘贴的功能。

就个人而言,我发现使用标准 Vim 的复制和粘贴要好得多。在 Vim 中,我可以将光标放在一行上,键入yy以复制它,10p粘贴 10 个副本。使用Align插件,我可以使用Ctrl-V(假设没有使用上面的 windows 映射)来可视化块选择已创建的一列数字;:II然后自动增加该列的数字。同样,使用YankRing,我可以一个接一个地复制 10 行(或更多)行,然后将它们一个接一个地粘贴回去。

至于 Vim 让我更有效率的方式,我想说标签文件是我再也离不开的一件事了。当光标在一个标签上时,我可以按Ctrl-]下去功能(和 Ctrl-T 返回,我喜欢多少级别)或,p在预览窗口中打开功能或宏定义(或其他)(可以然后用 :pcl 快速关闭)或[i只在状态栏上显示宏定义。对于浏览复杂的源代码,这些工具非常宝贵。

预览窗口确实依赖于 .vimrc 中的映射,但是:

:map ,p :ptag <C-R><C-W><CR>

标签文件还允许使用几个(我的)插件,当您将鼠标移到关键字上时,这些插件可以提供更清晰地显示错误的语法突出显示(通过突出显示已识别的标签而不是突出显示未识别的标签)和标签签名。

于 2009-08-02T08:47:51.230 回答
7
Ctrl-w Ctrl-f ............ open file under cursor in new window
Ctrl-6 ................... alternate file
'0 ....................... open last file
:x ....................... close if save
于 2010-11-04T22:51:50.403 回答
6

特别是对于复制/剪切和粘贴,使用可视模式可以更容易地适应其他编辑器。所以我通常剪切和粘贴的方式是:

  • Esc- 退出插入模式(如果您已经处于正常模式,请跳过)
  • v- 打开视觉模式
  • 移动文件以选择您想要的文本 - 视觉模式将显示您选择了哪些字符。对于几个单词we并且b很有用(分别移动到下一个单词的开头、下一个单词的结尾和这个/上一个单词的开头)。
  • d- 剪切文本(y如果你想复制文本使用)
  • 移动到你想要文本去的地方
  • p- 粘贴(粘贴在当前字符之后,P粘贴在当前字符之前。

同样有用的是V进入可视模式(行),它会自动选择整行,无论光标在哪里。

于 2010-03-16T15:42:09.917 回答
6

http://www.viemu.com/a-why-vi-vim.html是一篇很好的宣传文章。它解释了使用.命令重复上次编辑的强大功能。

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

使用 Vim 很可怕:

* 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

如果你选择了你想要的。我经常要做 [number xx]dd 然后你撤消!

我确信其他答案解释得更好,但你做错了。我经常使用可视模式来选择要拉出或删除的文本,这类似于您的 shift + select 示例,但 Vim 在这里具有明显的优势,因为您的手永远不会离开主行来执行此操作。yy 是一个很棒的命令,但如果我想拉一整行,我经常会使用 Vy。

于 2010-03-16T15:53:56.120 回答
5

实际上我总是丢失缓冲区,所以我通常复制一系列行的方式是将其写入临时文件,然后在适当的位置读入。

例如

ka(设置标记)

'一种,。哇!t(将标记中的所有内容复制到文件 t 中)

.. 移动光标 ..

:.rt (将 t 读入当前位置)。

与使用缓冲区相比,这可能涉及更少的击键,更容易跟踪,并且您可以拥有长期存在的粘贴文件。为了速度,我通常为文件使用 1 个字母的名称。

这样做速度快的关键原因是,如果您在到达您想去的地方之前遇到另一个模式的出现,只需使用搜索功能“/”和“n”就可以在您周围移动光标。

于 2009-12-22T19:04:34.087 回答
5

进一步的快捷方式如何?


放入你的 .vimrc:
nnoremap ; :

这种方式进入命令模式更容易: ;qor;w工作,而不是:qor :w

两次击键而不是三次,你会经常需要这个。


对系统管理员不利,因为他们需要开箱即用的相同功能才能在任何地方的每个盒子上都相同。

但是对于使用 vi的程序员来说是一个巨大的改进。

于 2012-06-28T12:51:26.200 回答
4

除了关于 grokking vi 的好评之外,应该注意的是,vim确实添加了一些非常类似于 vi 的特性,这些特性使得使用 vi 命令更好。首先想到的是文本对象:不是{!}fmt重新格式化当前段落,!apfmt而是这样做。它首先指定我们要选择a文本对象,即当前段落。类似地,要更改当前字符串文字(例如footo bar),而不是T"ct"bar(移动到上一个之后"更改到下一个之前",插入bar),您可以说ci"bar:更改内部(最里面的)引号,插入bar

考虑文本对象而不是移动命令是非常好的。

于 2010-04-01T13:25:20.687 回答
4

您可以搜索寄存器的内容。

假设您的寄存器x包含

要搜索的字符串

要搜索此字符串,您必须在普通模式下输入
/CTRL-rxENTER

它将粘贴x寄存器的内容。

于 2012-06-28T14:16:49.353 回答
3

有很多 vim 技巧,但到目前为止,我真正喜欢的是Ctrl+ A,因为我碰巧正在处理一些硬编码数组索引的 st**d 代码。

于 2011-10-14T12:43:51.083 回答
3

这一系列 vim 命令ggVGg?将 Rot13 密码应用于当前文档中的文本。

Gung vf zl zbfg cebqhpgvir fubegphg fvapr V nyjnlf glcr va Ebg13。

于 2012-07-07T02:15:58.997 回答
2

行的快速剪切和覆盖部分:

当您编辑一行时,一个非常常见的任务是从当前光标位置剪切到某个位置并覆盖新内容。

您可以使用以下命令:

ct<identifier>用于前切。

cT<identifier>用于向后切割。

您要剪切的行中的字符在哪里。

示例:假设这是您要编辑的行并且您的光标位于I

Hi There. I am a Coder and I code in : Python and R.

您想剪切:并用 覆盖I am a programmer,您输入:ct:然后输入I am a programmer。这将导致:Hi There. I am a programmer: Python and R

行的快速删除部分:

就像上面下面的命令从当前光标位置删除内容直到'标识符'

dt<identifier>用于前向删除

dT<identifier>用于向后删除

希望这对你也有用。

于 2012-07-20T13:35:30.577 回答
1

聪明的制表符完成^^

http://vim.wikia.com/wiki/Smart_mapping_for_tab_completion

于 2012-07-18T07:47:43.767 回答
0

nnoremap q; q:在我的 .vimrc 中,在制作复杂的搜索和替换时保持流程。

于 2012-07-18T13:03:30.890 回答