你母亲从未告诉过你的Vim的黑暗角落是什么?

时间:2009-04-07 17:57:30

标签: unix vim editor vi

有很多问题让人们谈论常见的伎俩,特别是“Vim+ctags tips and tricks”。

但是,我没有提到Vim的新手会觉得很酷的常用快捷方式。我说的是一个经验丰富的Unix用户(他们是开发人员,管理员,两者等),他们认为他们知道我们99%的人从未听过或梦到过的东西。有些东西不仅让他们的工作更轻松,而且还有COOL和 hackish 。毕竟, Vim 位于世界上最黑暗的角落操作系统中,因此它应该只有少数特权知道并希望与我们分享的错综复杂。

70 个答案:

答案 0 :(得分:766)

可能不是99%的Vim用户不知道的,但这是我每天使用的东西,任何Linux + Vim poweruser都必须知道。

基本命令,但非常有用。

:w !sudo tee %

在编辑文件之前我经常忘记sudo我没有写权限。当我来保存该文件并获得权限错误时,我只发出该vim命令以保存文件而无需将其保存到临时文件中,然后再将其复制回来。

你显然必须安装sudo并拥有sudo权限的系统。

答案 1 :(得分:601)

我刚才发现的一些我认为非常酷的东西:

:earlier 15m

将文档还原为15分钟前的状态。可以针对您想要回滚的时间量采用各种参数,并且取决于undolevels。可以使用相反的命令:later

进行反转

答案 2 :(得分:402)

当你在Vim时,

:! [command]执行一个外部命令。

但是在冒号:.! [command]之后添加一个点,它会将命令的输出转储到当前窗口。那是: . !

例如:

:.! ls

我经常使用它来处理将当前日期添加到我正在输入的文档中的内容:

:.! date

答案 3 :(得分:307)

不完全晦涩,但有几个“删除”命令非常有用,比如..

  • diw删除当前字词
  • di(要删除当前的parens
  • di"删除引号之间的文字

其他人可以在:help text-objects

找到

答案 4 :(得分:235)

de 按下即可删除所有字词,直到字词结尾。按照你的心愿。

ci(xyz [Esc] - 这是一个奇怪的。这里,'i'并不意味着插入模式。相反,它意味着在括号内。所以这个序列切割内部的文本您正站在括号中并用“xyz”替换它。它也适用于方形和图形括号 - 只需要执行ci [或ci {相应地。当然,您可以执行di(如果您只想删除所有文本而不键入如果您想要删除括号而不仅仅是文本内部的文字,也可以a代替i

ci“ - 剪切当前引号中的文字

ciw - 剪切当前字词。除了(替换为w之外,其效果与前一个相同。

C - 剪切其余部分并切换到插入模式。

ZZ - 保存并关闭当前文件(比Ctrl-F4更快地关闭当前标签!)

ddp - 将当前行向下移动一行

xp - 将当前字符向右移动一个位置

U - 大写,所以viwU根据这个词

- 切换大小写,因此viw~将反转整个单词的大小写

Ctrl + u / Ctrl + d 向上或向下滚动页面半屏幕。这似乎比通常的全屏分页更有用,因为它可以更容易地看到两个屏幕的关系。对于那些仍然想要一次滚动整个屏幕的人来说,Ctrl + f代表Forward,Ctrl + b代表Backward。 Ctrl + Y和Ctrl + E一次向下或向上滚动一行。

疯狂但非常有用的命令是zz - 它滚动屏幕使这条线出现在中间。这非常适合将您正在处理的代码放在注意力的中心。兄弟姐妹命令 - zt和zb - 使这条线在sreen上面的顶部或底部,这不是很有用。

找到并跳转到匹配的括号。

de - 从光标删除到单词的结尾(您还可以dE删除直到下一个空格)

bde - 从左到右分隔符

删除当前单词

df [空格] - 删除直至并包含下一个空格

dt。 - 删除到下一个点

dd - 删除整行

ye(或yE) - 将文字从这里拉到文字末尾

ce - 切断单词

的结尾

再见 - 复制当前的单词(让我想知道“hi”的作用!)

yy - 复制当前行

cc - 剪切当前行,您也可以执行S。还有一个较低的上限s可以切断当前字符并切换到插入模式。

viwy或viwc 。猛拉或更改当前单词。多次点击w以继续选择每个后续字词,使用b向后移动

vi { - 选择图括号中的所有文字。 va { - 选择所有文本,包括{} s

vi(p - 突出显示()中的所有内容并替换为粘贴的文本

b和e逐字移动光标,类似于Ctrl +箭头通常的方式。虽然单词的定义有点不同,因为几个连续的delmiters被视为一个单词。如果从单词的中间开始,按b将始终将您带到当前单词的开头,并且每个连续的b将跳转到下一个单词的开头。同样,并且易于记忆,e将光标移动到当前和每个后续单词的末尾。

b / e类似,大写BE只使用空格作为分隔符逐字移动光标。

大写字母D(深呼吸)删除光标右侧的其余部分,与正常编辑器中的Shift + End / Del相同(注意2个按键 - Shift + D - 而不是3)

答案 5 :(得分:199)

我在大多数Vim教程中很少找到的,但它对于我来说是非常有用的(至少对我而言)是

g; and g,

通过更改列表移动(前进,后退)。

让我说明我是如何使用它的。有时我需要复制并粘贴一段代码或字符串,比如CSS文件中的十六进制颜色代码,所以我搜索,跳转(不关心匹配的位置),复制它然后跳回(g;)到哪里我正在编辑代码以最终粘贴它。无需创建标记。简单。

只是我的2点。

答案 6 :(得分:184)

:%!xxd

将vim变为十六进制编辑器。

:%!xxd -r

还原

警告:如果您不使用二进制文件(-b)进行编辑,则可能会损坏文件。 - Josh Lee在评论中。

答案 7 :(得分:120)

gv

重新选择最后一个视觉选择。

答案 8 :(得分:119)

有时,.vimrc中的设置会被插件或自动命令覆盖。要调试它,一个有用的技巧是使用:verbose命令和:set。例如,要找出cindent设置/取消设置的位置:

:verbose set cindent?

这将输出如下内容:

cindent
    Last set from /usr/share/vim/vim71/indent/c.vim

这也适用于地图和高光。 (感谢joeytwiddle指出这一点。)例如:

:verbose nmap U
n  U             <C-R>
        Last set from ~/.vimrc

:verbose highlight Normal
Normal         xxx guifg=#dddddd guibg=#111111 font=Inconsolata Medium 14
        Last set from ~/src/vim-holodark/colors/holodark.vim

答案 9 :(得分:98)

不确定这是否算作暗角,但我只是刚学会了......

:g/match/y A

会将包含“匹配”的所有行(都复制)到"a / @a寄存器中。 (大写为A使vim 附加 yankings而不是替换以前的寄存器内容。)我最近在制作Internet Explorer样式表时使用了很多。

答案 10 :(得分:97)

:%TOhtml

创建当前文件的html呈现。

答案 11 :(得分:89)

想看看你的:命令历史记录?

q:

然后浏览,编辑并最终执行命令。

是否对两个文件进行了类似的更改并在它们之间来回切换? (比方说,源文件和头文件?)

:set hidden
:map <TAB> :e#<CR>

然后在这些文件之间来回切换。

答案 12 :(得分:79)

Vim会打开一个网址,例如

vim http://stackoverflow.com/

当您需要提取页面来源以供参考时,这很好。

答案 13 :(得分:68)

宏可以调用其他宏,也可以调用自己。

例如:

qq0dwj@qq@q

...将从每行删除第一个单词,直到文件结尾。

这是一个非常简单的例子,但它展示了vim

的一个非常强大的功能

答案 14 :(得分:55)

假设你编译了Perl和/或Ruby支持,:rubydo:perldo将在一个范围内的每一行(默认为整个缓冲区)上运行Ruby或Perl一行代码,{ {1}}绑定到当前行的文本(减去换行符)。操作$_将改变该行的文本。

您可以使用它来执行某些易于使用脚本语言执行的操作,但使用Vim内置函数则不那么明显。例如,要反转一行中单词的顺序:

$_

在每一行的末尾插入一个8个字符(A-Z)的随机字符串:

:perldo $_ = join ' ', reverse split

您一次只能在一行上行动,而且无法添加换行符。

答案 15 :(得分:54)

^ O和^ I

转到较旧/较新的位置。 当您浏览文件时(通过搜索,移动命令等),vim将这些“跳跃”重新加入,这样您就可以向后重复这些跳转(旧的^ O - O)并向前跳转(^ I - 在键盘上我旁边)。我发现在编写代码和执行大量搜索时非常有用。

<强> GI

转到最后停止插入模式的位置。 我发现自己经常编辑,然后搜索一些东西。要返回编辑位置,请按gi。

<强> GF

将光标放在文件名上(例如包含头文件),按gf并打开文件

<强>中gF

类似于gf但识别格式“[文件名]:[行号]”。按gF将打开[文件名]并将光标设置为[行号]。

^ P和^ N

编辑时自动完成文本(^ P - 上一个匹配和^ N下一个匹配)

<强> ^ X ^→

编辑完成到同一行(对编程很有用)。 你编写代码,然后你还记得你在文件中的某个地方有相同的代码。只需按^ X ^ L并完成整行

<强> ^ X ^ F

完整的文件名。 你写“/ etc / pass”嗯。你忘了文件名。只需按^ X ^ F即可完成文件名

^ Z或:sh

将临时移动到shell。如果你需要快速抨击:

  • 按^ Z(将vi放入后台)返回原始shell并按fg返回vim
  • 按:sh转到子shell并按^ D /退出以返回vi

答案 16 :(得分:47)

这是使用不同编码重新打开当前文件的一个很好的技巧:

:e ++enc=cp1250 %:p

在必须使用旧版编码时很有用。受支持的编码列在encoding-values下的表格中(请参阅help encoding-values)。类似的事情也适用于++ff,因此如果您第一次弄错了,可以使用Windows / Unix行结束重新打开文件(请参阅help ff)。

答案 17 :(得分:47)

" insert range ip's
"
"          ( O O )
" =======oOO=(_)==OOo======

:for i in range(1,255) | .put='10.0.0.'.i | endfor

答案 18 :(得分:46)

键入 == 将根据上面的行更正当前行的缩进。

实际上,您可以执行一个=符号后跟任何移动命令。的 = {运动}

例如,您可以使用在匹配大括号之间移动的%移动。将光标定位在{在以下代码中:

if (thisA == that) {
//not indented
if (some == other) {
x = y;
}
}

然后按 =%立即获取此信息:

if (thisA == that) {
    //not indented
    if (some == other) {
        x = y;
    }
}

或者,您可以在代码块中执行 = a {,而不是将自己定位在{character。

上。

答案 19 :(得分:41)

imap jj <esc>

答案 20 :(得分:37)

让我们看看一些非常小的IDE编辑器进行列转换。

:%s/\(.*\)^I\(.*\)/\2^I\1/

解释

\(\)是如何在regex-land中记住的东西。 \1\2等是如何检索记住的内容。

>>> \(.*\)^I\(.*\)

记住所有内容后跟^I(标签),然后是所有内容。

>>> \2^I\1

将上面的内容替换为“你记得的第二个东西”,接着是“你记得的第一个东西” - 基本上是进行转置。

答案 21 :(得分:30)

不完全是一个黑暗的秘密,但我喜欢将以下映射放入我的.vimrc文件中,因此我可以随时点击“ - ”(减号)打开文件资源管理器以显示与我相邻的文件只需编辑。在文件资源管理器中,我可以点击另一个“ - ”来移动一个目录,提供复杂目录结构的无缝浏览(就像现在的MVC框架所使用的那样):

map - :Explore<cr>

这些对某些人也有用。我喜欢滚动屏幕并同时前进光标:

map <c-j> j<c-e>
map <c-k> k<c-y>

标签导航 - 我喜欢标签,我需要在它们之间轻松移动:

map <c-l> :tabnext<enter>
map <c-h> :tabprevious<enter>

仅适用于Mac OS X:类似Safari的标签导航:

map <S-D-Right> :tabnext<cr>
map <S-D-Left> :tabprevious<cr>

答案 22 :(得分:27)

我喜欢使用'sudo bash',我的系统管理员讨厌这个。他锁定了'sudo'所以它只能用于少量命令(ls,chmod,chown,vi等),但我仍然可以使用vim来获得root shell:

bash$ sudo vi +'silent !bash' +q
Password: ******
root#

答案 23 :(得分:26)

通常,我喜欢在编辑时更改当前目录 - 所以我必须指定较少的路径。

cd %:h

答案 24 :(得分:24)

我在处理项目时经常使用很多窗口,有时我需要调整它们的大小。这是我使用的:

map + <C-W>+
map - <C-W>-

这些映射允许增加和减小当前窗口的大小。这很简单,但速度很快。

答案 25 :(得分:22)

不是一个不起眼的功能,但非常有用且节省时间。

如果要保存打开缓冲区,标签,标记和其他设置的会话,可以发出以下命令:

mksession session.vim

您可以使用以下方式打开会话:

vim -S session.vim

答案 26 :(得分:21)

:r! <command>

将外部命令的输出粘贴到缓冲区中。

做一些数学运算并直接在文本中得到结果:

:r! echo $((3 + 5 + 8))

在编写Makefile时获取要编译的文件列表:

:r! ls *.c

不要查看您在维基百科上阅读的那个事实,将其直接粘贴到您正在撰写的文档中:

:r! lynx -dump http://en.wikipedia.org/wiki/Whatever

答案 27 :(得分:21)

将F5映射到ROT13缓冲区:

map <F5> ggg?G``

您可以将其用作老板键:)。

答案 28 :(得分:19)

我今天刚刚通过NSFAQ找到了这个:

注释代码块。

按CTRL-V进入Blockwise Visual模式。

标记您要评论的区块。

点击I(大写I)并在该行的开头输入您的注释字符串。 (// for C ++)

按ESC键,所有选中的行将//前置于该行的前面。

答案 29 :(得分:17)

我使用vim进行任何文本编辑,所以我经常使用复制和粘贴。问题是vim默认情况下经常会通过粘贴扭曲导入的文本。阻止这种情况的方法是使用

:set paste
在粘贴数据之前

。这样可以避免搞乱。

请注意,您必须发出:set nopaste才能恢复自动缩进。粘贴预格式化文本的其他方法是剪贴板寄存器(*+)和:r!cat(您必须使用^ D结束粘贴的片段)。

打开高对比度配色方案有时也很有帮助。这可以通过

完成
:color blue

我注意到它在我使用的vim的所有版本上都不起作用,但它在大多数情况下都有效。

答案 30 :(得分:11)

这是不明显的事情。如果你的$ HOME中有很多自定义插件/扩展,你需要在su / sudo / ...中工作,那么这可能很有用。

在〜/ .bashrc中:

export VIMINIT=":so $HOME/.vimrc"

在〜/ .vimrc中:

if $HOME=='/root'
        if $USER=='root'
                if isdirectory('/home/your_typical_username')
                        let rtuser = 'your_typical_username'
                elseif isdirectory('/home/your_other_username')
                        let rtuser = 'your_other_username'
                endif
        else
                let rtuser = $USER
        endif
        let &runtimepath = substitute(&runtimepath, $HOME, '/home/'.rtuser, 'g')
endif

它将允许您加载本地插件 - 无论您使用何种方式来更改用户。

您可能还希望将* .swp文件从当前路径中取出并放入〜/ vimtmp(这将进入.vimrc):

if ! isdirectory(expand('~/vimtmp'))
   call mkdir(expand('~/vimtmp'))
endif
if isdirectory(expand('~/vimtmp'))
   set directory=~/vimtmp
else
   set directory=.,/var/tmp,/tmp
endif

另外,我使用一些映射来简化编辑 - 使ctrl + s像escape一样工作,ctrl + h / l切换标签:

inoremap <C-s> <ESC>
vnoremap <C-s> <ESC>
noremap <C-l> gt
noremap <C-h> gT

答案 31 :(得分:11)

在插入模式下,Ctrl-n将根据打开缓冲区中的所有单词自动完成您键入的任何单词。如果有多个匹配,它将为您提供一个可以使用ctrl-n和ctrl-p循环的可能单词列表。

答案 32 :(得分:10)

gg=G

更正整个文件的缩进。我在Eclipse中错过了我可靠的<C-a><C-i>,但发现vim很好地处理了它。

答案 33 :(得分:9)

sudo写的变化:

进入.vimrc

cmap w!! w !sudo tee % >/dev/null

重新加载vim后,您可以执行“sudo save”作为

:w!!

答案 34 :(得分:9)

能够在基于客户端/服务器的模式下运行Vim。

例如,假设您正在处理一个项目,该项目在会话文件session.vim上保存了大量缓冲区,选项卡和其他信息。

您可以通过发出以下命令打开会话并创建服务器:

vim --servername SAMPLESERVER -S session.vim

请注意,如果要创建服务器,则可以打开常规文本文件,但不一定是会话。

现在,假设您在另一个终端并需要打开另一个文件。如果您通过发出以下命令定期打开它:

vim new_file.txt

您的文件将在单独的Vim缓冲区中打开,这很难与会话中的文件进行交互。要在服务器上的新选项卡中打开new_file.txt,请使用以下命令:

vim --servername SAMPLESERVER --remote-tab-silent new_file.txt

如果没有服务器正在运行,则该文件将像普通文件一样打开。

由于每次要运行它们时都提供这些标记非常繁琐,您可以创建一个单独的别名来创建客户端和服务器。

我将以下内容放在我的bashrc文件中:

alias vims='vim --servername SAMPLESERVER'
alias vimc='vim --servername SAMPLESERVER --remote-tab-silent'

您可以在http://vimdoc.sourceforge.net/htmldoc/remote.html

找到有关此内容的更多信息

答案 35 :(得分:9)

想要一个IDE吗?

:make将在当前目录中运行makefile,解析编译器输出,然后可以使用:cn:cp逐步执行打开每个文件的编译错误并寻求有问题的行号。

:syntax on打开了vim的语法高亮显示。

答案 36 :(得分:8)

HOWTO:在Bash中使用Vim时自动完成Ctags。 对于使用Vim和Ctags的其他人,我为Bash写了一个小的自动完成函数。将以下内容添加到〜/ .bash_completion文件中(如果不存在则创建它):

感谢fashionpants的许多修复和改进。

_vim_ctags() {
    local cur prev

    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    case "${prev}" in
        -t)
            # Avoid the complaint message when no tags file exists
            if [ ! -r ./tags ]
            then
                return
            fi

            # Escape slashes to avoid confusing awk
            cur=${cur////\\/}

            COMPREPLY=( $(compgen -W "`awk -vORS=" "  "/^${cur}/ { print \\$1 }" tags`" ) )
            ;;
        *)
            _filedir_xspec
            ;;
    esac
}

# Files matching this pattern are excluded
excludelist='*.@(o|O|so|SO|so.!(conf)|SO.!(CONF)|a|A|rpm|RPM|deb|DEB|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MP?(E)G|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)'

complete -F _vim_ctags -f -X "${excludelist}" vi vim gvim rvim view rview rgvim rgview gview

重新启动Bash会话(或创建一个新会话)后,您可以输入:

代码:

~$ vim -t MyC<tab key>

它会像对文件和目录一样自动完成标记:

代码:

MyClass MyClassFactory
~$ vim -t MyC

当我快速修复错误时,我发现它非常有用。

答案 37 :(得分:8)

我经常想要突出显示特定的单词/函数名称,但不想搜索它的下一个实例:

map m* *#

答案 38 :(得分:7)

当你想要跨项目的两个不同副本区分文件时,

%也不错,而不会弄脏小指(从project1的根目录):

:vert diffs /project2/root/%

答案 39 :(得分:7)

  

:setlocal autoread

自动重新加载当前缓冲区。在查看日志文件时特别有用,它几乎在vim中提供unix中“tail”程序的功能。

从vim中检查编译错误。 根据perl

所说的语言设置makeprg变量
  

:setlocal makeprg = perl \ -c \%

对于PHP

  

设置makeprg = php \ -l \%
  set errorformat =%m \ in \%f \ on \ line \%l

发出“:make”运行相关的makeprg并在quickfix窗口中显示编译错误/警告,并可以轻松导航到相应的行号。

答案 40 :(得分:7)

我将Vim用于一切。当我编辑电子邮件时,我使用:

gqap(或gwap

广泛地在逐段的基础上轻松正确地重新格式化,即使使用引号字符也是如此。为了实现此功能,我还添加:

-c 'set fo=tcrq' -c 'set tw=76'

到外部调用编辑器的命令。一个值得注意的补充是将“ a ”添加到fo(formatoptions)参数中。这将在您键入和导航内容时自动重新格式化段落,但可能会干扰或导致消息中包含的错误或奇怪格式的问题。

答案 41 :(得分:6)

我确信有人会发布这个,但现在就去了。

请选择任何构建系统;制作,mvn,蚂蚁,等等。在项目目录的根目录中,创建一直使用的命令文件,如下所示:

mvn install
mvn clean install
......等等

要进行构建,请将光标放在该行上并键入!! sh。即过滤那条线;将它写入shell并替换为结果。

构建日志替换了该行,准备滚动,搜索等等。

查看完日志后,输入u进行撤消,然后返回到命令文件。

答案 42 :(得分:6)

从十六进制值(插入模式)输入一个字符:

<C-Q>x[type the hexadecimal byte]

答案 43 :(得分:6)

==========================================================
In normal mode
==========================================================
gf ................ open file under cursor in same window --> see :h path
Ctrl-w f .......... open file under cursor in new window
Ctrl-w q .......... close current window
Ctrl-w 6 .......... open alternate file --> see :h #
gi ................ init insert mode in last insertion position
'0 ................ place the cursor where it was when the file was last edited

答案 44 :(得分:6)

将它放在你的.vimrc中,以获得一个完美打印xml:

的命令
function FormatXml()
    %s:\(\S\)\(<[^/]\)\|\(>\)\(</\):\1\3\r\2\4:g
    set filetype=xml
    normal gg=G
endfunction

command FormatXml :call FormatXml()

答案 45 :(得分:6)

由于延迟和缺乏色彩(我喜欢配色方案:)我不喜欢在PuTTY的远程机器上编程。所以我开发了这个技巧来解决这个问题。我在Windows上使用它。

您需要

  • 1x gVim
  • 远程和本地计算机上的1x rsync
  • 将1个SSH私钥验证到远程计算机,因此您无需输入密码
  • 1x Pageant
  • 1x PuTTY

设置远程计算机

配置rsync以使您的工作目录可访问。我使用SSH隧道,只允许来自隧道的连接:

address = 127.0.0.1
hosts allow = 127.0.0.1
port = 40000
use chroot = false
[bledge_ce]
    path = /home/xplasil/divine/bledge_ce
    read only = false

然后启动rsyncd:     rsync --daemon --config = rsyncd.conf

设置本地计算机

从Cygwin安装rsync。启动Pageant并加载远程计算机的私钥。如果您正在使用SSH调整,请启动PuTTY以创建隧道。在工作目录中创建一个批处理文件push.bat,它将使用rsync将更改的文件上载到远程计算机:

rsync --blocking-io *.cc *.h SConstruct rsync://localhost:40001/bledge_ce

SConstruct是scons的构建文件。修改文件列表以满足您的需要。如果不使用SSH调整,请将localhost替换为远程计算机的名称。

配置Vim 这很容易。我们将使用quickfix功能(:make和错误列表),但编译将在远程计算机上运行。所以我们需要设置makeprg:

set makeprg=push\ &&\ plink\ -batch\ xplasil@anna.fi.muni.cz\ \"cd\ /home/xplasil/divine/bledge_ce\ &&\ scons\ -j\ 2\"

这将首先启动push.bat任务以上传文件,然后使用SSH(PuTTY套件中的Plink)在远程计算机上执行命令。该命令首先将目录更改为工作目录,然后开始构建(我使用scons)。

构建结果将在您当地的gVim错误列表中方便地显示。

答案 46 :(得分:5)

对于vim 7.3,

set colorcolumn=+1set cc=+1

答案 47 :(得分:4)

在复制并粘贴到stackoverflow之前:

:retab 1
:% s/^I/ /g
:% s/^/    /

现在复制并粘贴代码。

根据评论中的要求:

retab 1.这会将标签大小设置为1。但它也会通过代码并添加额外的选项卡和空格,以便格式化不会移动任何实际文本(即ratab后文本看起来相同)。

%s / ^ I / / g:注意^ I是击中标签的结果。这将搜索所有选项卡并将其替换为单个空格。由于我们刚刚进行了重新设置,因此不应该导致格式化更改,但由于将标签放入网站会受到影响,因此最好将其删除。

%s / ^ / /:用四个空格替换行的开头。由于你无法用线条实际替换线条的开头,所以它会在线条的边缘插入四个空格(SO格式化需要这样才能使代码脱颖而出)。

答案 48 :(得分:4)

:sp %:h - 使用当前文件目录的目录列表/文件选择器

(属于猖獗的cd提示下的评论,但我还没有评论权利)

答案 49 :(得分:4)

一些有用的:

:set nu # displays lines
:44     # go to line 44
'.      # go to last modification line

我的最爱: Ctrl + n WORD COMPLETION!

答案 50 :(得分:4)

当处理构建过程缓慢的项目时,我总是在后台构建并将输出传递给名为errors.err的文件(类似make debug 2>&1 | tee errors.err)。这使我可以在构建过程中继续编辑或查看源代码。当它准备就绪时(在GTK上使用pynotify通知我它已完成)我可以使用quickfix在vim中查看结果。首先发出:cf [ile],它读取错误文件并跳转到第一个错误。我个人喜欢使用cwindow在单独的窗口中获取构建结果。

答案 51 :(得分:3)

In Insert mode 
<C-A>   - Increments the number under cursor 
<C-X>   - Decrements the number under cursor

如果我们想在vim中生成序列号,那将非常有用 让我们说如果我们想插入1-10号线,数字从1到10 [在第1行像“1”,在第2行是“2”..]
在第一行插入“0”并复制该行并过去9次 这样所有行都会显示“0”。

运行以下Ex命令

:g/^/exe "norm " . line(".") . "\<C-A>"

答案 52 :(得分:3)

我喜欢:ls命令。

答案 53 :(得分:3)

在插入模式下, ctrl + x ctrl + p 将完成(带有可能的完成菜单)如果这就是你喜欢的方式)你输入的当前长标识符。

if (SomeCall(LONG_ID_ <-- type c-x c-p here
            [LONG_ID_I_CANT_POSSIBLY_REMEMBER]
             LONG_ID_BUT_I_NEW_IT_WASNT_THIS_ONE
             LONG_ID_GOSH_FORGOT_THIS
             LONG_ID_ETC
             ∶

答案 54 :(得分:3)

让vim更像IDE编辑器:

  • 设置nu - 左边距中的行号。
  • set cul - 突出显示包含光标的行。

答案 55 :(得分:3)

<强>重用

与其他命令混合的动作,更多here

tx
fx
Fx

在Vim中使用您喜欢的工具。

:r !python anything you want or awk or Y something

在视觉模式下重复,与上述提示结合使用时非常强大。

;

答案 56 :(得分:2)

以下两者都不是真的很难,但我发现它非常有用。

琐碎的绑定,但我不能没有。它在插入模式下启用hjkl样式的移动(使用ctrl键)。在正常模式下:ctrl-k / j向上/向下滚动半个屏幕,ctrl-l / h进入下一个/上一个缓冲区。 μ和ù映射尤其适用于AZERTY键盘并转到下一个/上一个make错误。

imap <c-j> <Down>
imap <c-k> <Up>
imap <c-h> <Left>
imap <c-l> <Right>
nmap <c-j> <c-d>
nmap <c-k> <c-u>
nmap <c-h> <c-left>
nmap <c-l> <c-right>

nmap ù :cp<RETURN>
nmap µ :cn<RETURN>

我写的一个小函数,用于突出显示函数,全局变量,宏,结构和typedef。 (对于非常大的文件,可能会很慢)。每种类型都有不同的突出显示(请参阅“:help group-name”以了解您当前的colortheme设置) 用法:使用ww保存文件(默认为“\ ww”)。你需要ctags。

nmap <Leader>ww :call SaveCtagsHighlight()<CR>

"Based on: http://stackoverflow.com/questions/736701/class-function-names-highlighting-in-vim
function SaveCtagsHighlight()
    write

    let extension = expand("%:e")
    if extension!="c" && extension!="cpp" && extension!="h" && extension!="hpp"
        return
    endif

    silent !ctags --fields=+KS *
    redraw!

    let list = taglist('.*')
    for item in list
        let kind = item.kind

        if     kind == 'member'
            let kw = 'Identifier'
        elseif kind == 'function'
            let kw = 'Function'
        elseif kind == 'macro'
            let kw = 'Macro'
        elseif kind == 'struct'
            let kw = 'Structure'
        elseif kind == 'typedef'
            let kw = 'Typedef'
        else
            continue
        endif

        let name = item.name
        if name != 'operator=' && name != 'operator ='
            exec 'syntax keyword '.kw.' '.name
        endif
    endfor
    echo expand("%")." written, tags updated"
endfunction

我养成了编写大量代码和函数的习惯,我不喜欢为它们编写原型。所以我做了一些函数来生成C风格源文件中的原型列表。它有两种形式:一种删除形式参数的名称,另一种保留它。 每次我需要更新原型时,我只刷新整个列表。它避免了不同步的原型和函数定义。还需要ctags。

"Usage: in normal mode, where you want the prototypes to be pasted:
":call GenerateProptotypes()
function GeneratePrototypes()
    execute "silent !ctags --fields=+KS ".expand("%")
    redraw!
    let list = taglist('.*')
    let line = line(".")
    for item in list
        if item.kind == "function"  &&  item.name != "main"
            let name = item.name
            let retType = item.cmd
            let retType = substitute( retType, '^/\^\s*','','' )
            let retType = substitute( retType, '\s*'.name.'.*', '', '' ) 

            if has_key( item, 'signature' )
                let sig = item.signature
                let sig = substitute( sig, '\s*\w\+\s*,',        ',',   'g')
                let sig = substitute( sig, '\s*\w\+\(\s)\)', '\1', '' )
            else
                let sig = '()'
            endif
            let proto = retType . "\t" . name . sig . ';'
            call append( line, proto )
            let line = line + 1
        endif
    endfor
endfunction


function GeneratePrototypesFullSignature()
    "execute "silent !ctags --fields=+KS ".expand("%")
    let dir = expand("%:p:h");
    execute "silent !ctags --fields=+KSi --extra=+q".dir."/* "
    redraw!
    let list = taglist('.*')
    let line = line(".")
    for item in list
        if item.kind == "function"  &&  item.name != "main"
            let name = item.name
            let retType = item.cmd
            let retType = substitute( retType, '^/\^\s*','','' )
            let retType = substitute( retType, '\s*'.name.'.*', '', '' ) 

            if has_key( item, 'signature' )
                let sig = item.signature
            else
                let sig = '(void)'
            endif
            let proto = retType . "\t" . name . sig . ';'
            call append( line, proto )
            let line = line + 1
        endif
    endfor
endfunction

答案 57 :(得分:2)

多年来我收集了这些。

" Pasting in normal mode should append to the right of cursor
nmap <C-V>      a<C-V><ESC>
" Saving
imap <C-S>      <C-o>:up<CR>
nmap <C-S>      :up<CR>
" Insert mode control delete
imap <C-Backspace> <C-W>
imap <C-Delete> <C-O>dw
nmap    <Leader>o       o<ESC>k
nmap    <Leader>O       O<ESC>j
" tired of my typo
nmap :W     :w

答案 58 :(得分:2)

要将文本从Vim复制到剪贴板以供其他应用程序使用,请选择要以可视模式复制的文本,然后按“+ y。这样,您可以轻松地将文本粘贴到其他应用程序。

如果您垂直拆分窗口并且想要从右侧窗口复制某些内容,则此功能特别有用。使用set mouse = r对这种情况没有帮助,因为它也会选择左侧窗口中的所有内容。

请注意,您的vim必须使用xterm支持进行编译。

答案 59 :(得分:2)

地图宏

我经常发现在动态定义一些键映射时非常有用,就像定义一个宏一样。这里的扭曲是,映射是递归并执行直到失败。

示例:

enum ProcStats
{
        ps_pid,
        ps_comm,
        ps_state,
        ps_ppid,
        ps_pgrp,
:map X /ps_<CR>3xixy<Esc>X

给出:

enum ProcStats
{
        xypid,
        xycomm,
        xystate,
        xyppid,
        xypgrp,

只是一个愚蠢的例子:)。

我完全意识到所有的缺点 - 我发现它在某些情况下非常有用。在工作中观看它也很有趣;)。

答案 60 :(得分:2)

使用鼠标右键在gVim中使用以下设置切换插入模式 在〜/ .gvimrc:

"
"------------------------------------------------------------------
" toggle insert mode <--> 'normal mode with the <RightMouse>-key
"------------------------------------------------------------------
nnoremap  <RightMouse> <Insert>
inoremap  <RightMouse> <ESC>
"

答案 61 :(得分:2)

使用它的shebang创建一个函数来执行当前缓冲区(假设有一个设置)并用crtl-x调用它。

map <C-X> :call CallInterpreter()<CR>

au BufEnter *
\ if match (getline(1) , '^\#!') == 0 |
\   execute("let b:interpreter = getline(1)[2:]") |
\ endif

fun! CallInterpreter()
    if exists("b:interpreter")
        exec("! ".b:interpreter." %")
    endif
endfun

答案 62 :(得分:2)

尝试使用perltidy=普通模式命令

进行格式化
:set equalprg=perltidy

答案 63 :(得分:2)

全部替换

  :%s/oldtext/newtext/igc

给一个替换所有:)

答案 64 :(得分:1)

我正在使用宏而不是搜索 - 将宏与可视模式相结合有时会更有效。

答案 65 :(得分:1)

我喜欢在窗户之间来回切换的食谱:

function! SwitchPrevWin()
    let l:winnr_index = winnr()
    if l:winnr_index > 1
       let l:winnr_index -= 1
    else
       "set winnr_index to max window open
        let l:winnr_index = winnr('$')
    endif
    exe l:winnr_index . "wincmd w" 
endfunction

nmap <M-z> :call SwitchPrevWin()
imap <M-z> <ESC>:call SwitchPrevWin()

nmap <C-z> :wincmd w
imap <C-z> <ESC>:wincmd w

答案 66 :(得分:1)

按此thread

要为一组行添加前缀,我使用两种不同的方法之一:

一种方法是块选择(由sth提及)。通常,您可以使用ctrl-V选择一个矩形区域,然后选择光标移动。一旦你突出显示一个矩形,按shift-I将在矩形的左侧插入字符,或者shift-A将它们附加在矩形的右侧。因此,您可以使用此技术创建一个矩形,其中包含您想要前缀的行的最左侧列,单击shift-I,键入前缀,然后单击escape。

另一种方法是使用替换(如Brian Agnew所述)。 Brian的替换将影响整个文件(命令中的%表示“所有行”)。为了影响几行,最简单的方法是在第一行/最后一行上点击shift-V(启用可视线模式),然后移动到最后一行。然后输入:

:s / ^ /你的PREFIX /

^是一个正则表达式(在这种情况下,是行的开头)。通过在可视线模式下输入此内容,您会看到'&lt;,'&gt;在s之前自动插入。这意味着替换的范围将是视觉选择。

额外提示:如果您的前缀包含斜杠,您可以使用反斜杠转义它们,也可以使用不同的标点字符作为命令中的分隔符。例如,要添加C ++行注释,我通常会写:

:s:^://:

对于添加后缀,替换方法通常更容易,除非您的所有行都具有完全相同的长度。只需使用$代替^而你的字符串将被追加而不是预先填充。

如果要同时添加前缀和后缀,可以执行以下操作:

:s /.*/ PREFIX&amp; SUFFIX /

。*匹配整行。 &amp;在替换中放回匹配的文本(整行),但现在它将添加你的前缀和后缀。

BTW:在评论代码时,您可能希望稍后取消注释。您可以使用visual-block(ctrl-V)选择斜杠然后点击d删除它们,或者你可以使用替换(可能使用shift-V制作的视觉线选择)来删除这样的前导斜杠:

:s:// ::

答案 67 :(得分:1)

我的一些必备品是:

cscope + ctags + vim,可以在网上找到。

快速启动新代码文件的一些疏忽,例如:

ab cpph #include <iostream><CR>#include <string><CR>#include <cstdlib><CR>#include <cassert><CR>#include <vector><CR>#include <
stdexcept><CR>using namespace std;<CR>int main(int argc, char *argv[]) {
ab perlh #!/usr/bin/perl<CR>use strict;<CR>use warnings;<CR>
ab chdr #include <stdio.h><CR>#include <sys/types.h><CR>#include <unistd.h><CR>#include <stdlib.h><CR>#include <sys/stat.h><CR>
#include <sys/wait.h><CR>#include <string.h><CR>int main(int argc, char *argv[]) {
ab xhtmlhdr <?xml version="1.0" encoding="UTF-8"?><CR><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.o
rg/TR/xhtml1/DTD/xhtml1-strict.dtd"><CR><html xmlns="http://www.w3.org/1999/xhtml"><CR>  <head><CR>  <title></title><CR><link h
ref="style.css" rel="STYLESHEET" type="text/css"><CR></head>

例如,cpph将插入main.cc文件的基本框架

还有我的功能键映射:

map <F1> <Esc>:w<CR>:perl $e = `./error.pl`; my ($f,$l,@w) = split(":",$e); my $w=join(":",@w); $curwin->Cursor($l,0); VIM::Msg($w);<CR>
map <F2> :wincmd w<CR>
map <F3> :wincmd s<CR>
map <F4> :wincmd v<CR>
map <F5> :wincmd o<CR>
map <F6> :sball<CR>
map <F7> :wq<CR>
map <F8> :wincmd q<CR>
map <F9> :wincmd -<CR>
map <F10> :wincmd +<CR>
map <F11> :wincmd <<CR>
map <F12> :wincmd ><CR>

在这种情况下,我的F1被映射为将光标放在需要针对源代码迁移进行纠正的下一个错误上。

map _ ebi"^[ea"^[

此地图会使_引用字符串

答案 68 :(得分:1)

以换行模式在当前屏幕行上进行移动的映射。我在前一段时间对Vim小贴士的评论中发现了这一点,并且它已被证明非常方便。

function! ScreenMovement(movement)
  if &wrap
    return "g" . a:movement
  else
    return a:movement
  endif
endfunction
onoremap <silent> <expr> j ScreenMovement("j")
onoremap <silent> <expr> k ScreenMovement("k")
onoremap <silent> <expr> 0 ScreenMovement("0")
onoremap <silent> <expr> ^ ScreenMovement("^")
onoremap <silent> <expr> $ ScreenMovement("$")
nnoremap <silent> <expr> j ScreenMovement("j")
nnoremap <silent> <expr> k ScreenMovement("k")
nnoremap <silent> <expr> 0 ScreenMovement("0")
nnoremap <silent> <expr> ^ ScreenMovement("^")
nnoremap <silent> <expr> $ ScreenMovement("$")

答案 69 :(得分:1)

我想在after-directory中安排一些自己的配置文件。它对ftplugin特别有用。

您可以避免在.vimrc文件中编写一长串augroup而不是每种类型的单独文件。

但是,显然,.vim / ftplugin目录与.vim / after / ftplugin做同样的事情,但我更愿意将.vim目录留给vim插件。