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

有太多的问题,人们谈论常见的技巧,特别是“Vim+ctags提示和技巧”。

然而,我指的不是那些刚接触Vim的人会觉得很酷的常用快捷方式。我说的是一个经验丰富的Unix用户(无论是开发人员还是管理员,等等),他们认为他们知道一些我们99%的人从未听说过或梦想过的东西。一些不仅让他们的工作更轻松的东西,而且很酷和哈基什。毕竟,Vim驻留在世界上最黑暗角落丰富的操作系统中,因此它应该有只有少数特权阶层知道并想与我们分享的错综复杂之处。

131129 次浏览

让我们看看一些漂亮的小型IDE编辑器进行列转换。

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

补充说明

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

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

记住所有内容,然后是^I(tab),然后是所有内容。

>>> \2^I\1

将上述内容替换为“你记得的第二件事”,然后是“你记得的第一件事”-本质上是做转置。

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

基本的命令,但非常有用。

:w !sudo tee %

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

显然,您必须在安装了sudo并具有sudo权限的系统上。

我最近发现了一些我认为很酷的东西:

:earlier 15m

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

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

:e ++enc=cp1250 %:p

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

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

cd %:h

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

  • diw删除当前单词
  • di(在当前父级中删除
  • di"删除引号之间的文本

其他可以在:help text-objects上找到

当我在一个项目上工作时,我经常使用许多窗口,有时我需要调整它们的大小。这是我使用的:

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

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

:%!xxd

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

:%!xxd -r

复位。

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

这里有一些不明显的东西。如果你的$HOME中有很多自定义插件/扩展,并且你有时需要从su/sudo/…工作,那么这可能会很有用。

在你的~/. bashrc中:

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

在你的~/. vimrc中:

如果$HOME=='/root'如果$USER=='root'如果is目录('/home/your_typical_username')rtuser='your_typical_username'elseif is目录('/home/your_other_username')rtuser='your_other_username'endif否则对于rtuser=$USER,我们使用rtuser=$USERendif//rtuser//rtuser//rtuser//rtuser///rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rtuser//rt结束if

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

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

if! is目录(展开('~/vimtmp'))调用mkdir(展开('~/vimtmp'))endifif is目录(展开('~/vimtmp'))设置目录=~/vimtmp否则设置目录=.,/var/tmp,/tmpendif

此外,我使用一些映射来使编辑更容易-使ctrl+s像转义一样工作,并使ctrl+h/l切换选项卡:

inoremapvnoremap#查看gtnoremapgT

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

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

_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 existsif [ ! -r ./tags ]thenreturnfi
# Escape slashes to avoid confusing awkcur=${cur////\\/}
COMPREPLY=( $(compgen -W "`awk -vORS=" "  "/^${cur}/ { print \\$1 }" tags`" ) );;*)_filedir_xspec;;esac}
# Files matching this pattern are excludedexcludelist='*.@(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

我发现它真的很有用,当我跳进一个快速bug修复。

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

您可以使用它来做某些在脚本语言中很容易做但使用Vim内置程序不那么明显的事情。例如反转一行中单词的顺序:

:perldo $_ = join ' ', reverse split

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

:rubydo $_ += ' ' + (1..8).collect{('A'..'Z').to_a[rand 26]}.join

您一次只能在一行上执行操作,并且不能添加换行符。

不确定这是否算得上黑暗的角落,但我才刚刚学会…

:g/match/y A

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

当您想在项目的两个不同副本之间比较文件而不会磨损小指(来自项目1的根目录)时,%也很好:

:vert diffs /project2/root/%

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

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

不完全是一个黑暗的秘密,但我喜欢将以下映射放入我的. 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>

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

map m* *#
imap jj <esc>

把这个放在你的. vimrc中,有一个命令来漂亮地打印xml:

function FormatXml()%s:\(\S\)\(<[^/]\)\|\(>\)\(</\):\1\3\r\2\4:gset filetype=xmlnormal gg=Gendfunction
command FormatXml :call FormatXml()

想看看你的:命令历史吗?

q:

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

曾经对两个文件进行过类似的更改并在它们之间来回切换吗?(比如说,源文件和头文件?)

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

然后在这些文件之间来回选项卡。

使用鼠标右键切换gVim中的插入模式,设置如下在~/. gvimrc中:

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

我爱: ls命令。

:! [command]在Vim中执行外部命令。

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

例如:

:.! ls

我经常使用它来将当前日期添加到我正在键入的文档中:

:.! date

替换所有

  :%s/oldtext/newtext/igc

给一个替换所有:)

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用于向前滚动,Ctrl+b用于向后滚动。Ctrl+Y和Ctrl+E一次向下或向上滚动一行。

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

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

de——从光标删除到单词末尾(您也可以执行dE删除直到下一个空格)

bde--删除当前单词,从左到右分隔符

df[空间]--删除直到并包括下一个空格

dt.--删除直到下一个点

dd--删除整行

是(或是)--将文本从这里拖到单词的末尾

ce-切入单词的末尾

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

yy--复制当前行

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

viwy或viwc. Yank或更改当前单词。多次点击w以保持选择每个后续单词,使用b向后移动

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

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

b和e逐字移动光标,类似于Ctrl+箭头通常的操作。单词的定义有点不同,因为几个连续的删除器被视为一个单词。如果你从一个单词的中间开始,按b总是会让你到当前单词的开头,每个连续的b都会跳到下一个单词的开头。同样,容易记住,e将光标放在当前单词的末尾,以及每个后续单词的末尾。

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

大写D(深呼吸)删除光标右侧的其余行,与普通编辑器中的Shift+End/Del相同(注意2次按键-Shift+D-而不是3次)

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

:set paste

在粘贴你的数据之前。这将防止它搞砸。

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

打开高对比度配色有时也很有帮助。这可以用

:color blue

我注意到它并不适用于我使用的所有版本的vim,但它适用于大多数版本。

有时您的. vimrc中的设置会被插件或自动命令覆盖。要调试此问题,一个有用的技巧是结合: set使用:详细命令。例如,要找出cindent在哪里设置/取消设置:

:verbose set cindent?

这将输出如下内容:

cindentLast set from /usr/share/vim/vim71/indent/c.vim

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

:verbose nmap Un  U             <C-R>Last set from ~/.vimrc
:verbose highlight NormalNormal         xxx guifg=#dddddd guibg=#111111 font=Inconsolata Medium 14Last set from ~/src/vim-holodark/colors/holodark.vim
:r! <command>

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

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

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

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

:r! ls *.c

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

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

我的一些必备品是:

cope+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.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><CR><html xmlns="http://www.w3.org/1999/xhtml"><CR>  <head><CR>  <title></title><CR><link href="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"^[

这张地图会让_引用一个字符串

我什么都使用Vim。当我编辑电子邮件时,我使用:

gqap(或gwap

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

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

一个值得注意的补充是将一个添加到fo(format选项)参数。这将在您键入和浏览内容时自动重新格式化段落,但可能会干扰消息中包含的错误或奇怪的格式或导致问题。

我确信有人已经发布了这个,但这里有。

选择您喜欢的任何构建系统;make、mvn、ant等。在项目目录的根目录中,创建一个您一直使用的命令文件,如下所示:

mvn安装
mvn干净安装
…等等

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

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

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

为了让vim更像一个IDE编辑器:

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

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

注释代码块。

按CTRL-V进入顺时针可视模式。

标记您要评论的块。

点击I(大写I)并在行首输入注释字符串。(//C++)

命中ESC,所有选定的行都将在行的前面加上//。

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

g; and g,

在变更列表中移动(向前,向后)。

让我展示一下我是如何使用它的。有时我需要复制和粘贴一段代码或字符串,比如CSS文件中的十六进制颜色代码,所以我搜索,跳转(不在乎匹配的位置),复制它,然后跳回(g;)到我编辑代码的地方,最终粘贴它。不需要创建标记。更简单。

我的2美分。

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

想要一个IDE?

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

:syntax on开启vim的语法高亮。

我喜欢使用“sudo bash”,而我的系统管理员讨厌这个。他锁定了“sudo”,所以它只能与少数命令(ls、chmod、chown、vi等)一起使用,但我还是能够使用vim来获取root shell:

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

在换行模式下在当前屏幕行上操作动作的映射。我前段时间在Vim技巧的评论中发现了这一点,事实证明它非常方便。

function! ScreenMovement(movement)if &wrapreturn "g" . a:movementelsereturn a:movementendifendfunctiononoremap <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("$")

设置本地自动读取

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

检查vim中的编译错误。根据语言设置makeprg变量,比如perl

设置本地makeprg=perl\-c\%

对于php

设置makeprg=php\-l\%
设置错误格式=%m\in\%f\on\line\%l

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

映射F5以快速ROT13您的缓冲区:

map <F5> ggg?G``

您可以将其用作Boss键:)。

^o和^i

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

gi

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

gf

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

gF

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

^p和^n

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

^x^l

当编辑完成到同一行时(对编程有用)。你编写代码,然后你想起你在文件中的某个地方有相同的代码。只需按^X^L,整行就完成了

^X^F

完整的文件名。您写“/etc/pass”嗯。您忘记了文件名。只需按^X^F,文件名就完成了

^Z或: sh

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

  • 按^Z(将vi置于背景中)返回到原始shell并按fg返回到vim
  • press: sh进入subshell并按^D/退出返回到vi返回

:sp %:h-使用当前文件目录的目录列表/file-chooser

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

为此线程

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

一种方法是块选择(在…中提到)。一般来说,你可以通过ctrl-V然后光标移动来选择一个矩形区域。突出显示一个矩形后,按Shive-I将在矩形左侧插入字符,或者Shive-A将在矩形右侧附加字符。所以你可以使用这种技术制作一个矩形,其中包括你想要前缀的行的最左侧列,点击Shive-I,键入前缀,然后点击转义。

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

: s/^/您的PREFIX/

^是一个正则表达式(在本例中是行的开头)。通过在可视行模式下键入this,您将看到'<,'>自动插入在s之前。这意味着替换的范围将是可视选择。

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

: s:^:// :

对于添加后缀,替换方法通常更容易,除非所有行的长度完全相同。只需对模式使用$而不是^,您的字符串将被追加而不是pre-pend。

如果您想同时添加前缀和后缀,您可以这样做:

: s/.*/PREFIX&SUFFIX/

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

顺便说一句:在注释掉代码时,你可能想稍后取消注释。你可以使用视觉块(ctrl-V)选择斜杠,然后按d删除它们,或者你可以使用替换(可能使用可视行选择,使用shive-V制作)来删除前导斜杠,如下所示:

: s://::

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

" insert range ip's""          ( O O )" =======oOO=(_)==OOo======
:for i in range(1,255) | .put='10.0.0.'.i | endfor
==========================================================In normal mode==========================================================gf ................ open file under cursor in same window --> see :h pathCtrl-w f .......... open file under cursor in new windowCtrl-w q .......... close current windowCtrl-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

尝试使用perltidy进行=正常模式命令的格式化

:set equalprg=perltidy

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

eg:

qq0dwj@qq@q

…将删除每行中的第一个单词,直到文件末尾。

这是一个相当简单的例子,但它展示了vim的一个非常强大的功能

以下两个都不是真正的顽固,但我发现它非常有用。

琐碎的绑定,但我不能没有。它可以在插入模式下启用hjkl风格的移动(使用ctrl键)。在正常模式下:ctrl-k/j向上/向下滚动半个屏幕,ctrl-l/h转到下一个/上一个缓冲区。µ和u映射特别适用于AZERTY键盘,然后转到下一个/上一个出错。

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”以了解您当前的颜色主题设置)用法:使用ww(默认“\ww”)保存文件。为此您需要ctags。

nmap <Leader>ww :call SaveCtagsHighlight()<CR>
"Based on: http://stackoverflow.com/questions/736701/class-function-names-highlighting-in-vimfunction SaveCtagsHighlight()write
let extension = expand("%:e")if extension!="c" && extension!="cpp" && extension!="h" && extension!="hpp"returnendif
silent !ctags --fields=+KS *redraw!
let list = taglist('.*')for item in listlet 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'elsecontinueendif
let name = item.nameif name != 'operator=' && name != 'operator ='exec 'syntax keyword '.kw.' '.nameendifendforecho 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 listif item.kind == "function"  &&  item.name != "main"let name = item.namelet retType = item.cmdlet retType = substitute( retType, '^/\^\s*','','' )let retType = substitute( retType, '\s*'.name.'.*', '', '' )
if has_key( item, 'signature' )let sig = item.signaturelet sig = substitute( sig, '\s*\w\+\s*,',        ',',   'g')let sig = substitute( sig, '\s*\w\+\(\s)\)', '\1', '' )elselet sig = '()'endiflet proto = retType . "\t" . name . sig . ';'call append( line, proto )let line = line + 1endifendforendfunction

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 listif item.kind == "function"  &&  item.name != "main"let name = item.namelet retType = item.cmdlet retType = substitute( retType, '^/\^\s*','','' )let retType = substitute( retType, '\s*'.name.'.*', '', '' )
if has_key( item, 'signature' )let sig = item.signatureelselet sig = '(void)'endiflet proto = retType . "\t" . name . sig . ';'call append( line, proto )let line = line + 1endifendforendfunction

在复制和粘贴到stackoverflow之前:

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

现在复制并粘贴代码。

如评论中所要求的:

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

%s/^I/ /g:请注意^I是点击tab的结果。这将搜索所有标签并用一个空格替换它们。由于我们刚刚做了重新标记,这不应该导致格式更改,但由于将标签放入网站会被点击并错过,因此最好将它们删除。

%s/^//:用四个空格替换该行的开头。由于您无法实际用任何东西替换该行的开头,因此它在该行的开头插入四个空格(SO格式化需要这一点以使代码突出)。

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

你将需要

  • 1x gVim
  • 远程和本地机器上的1x rsync
  • 1xSSH远程计算机的私钥认证,因此您无需键入密码
  • 1x选美
  • 1x PuTTY

设置远程机器

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

address = 127.0.0.1hosts allow = 127.0.0.1port = 40000use chroot = false[bledge_ce]path = /home/xplasil/divine/bledge_ceread 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现在很容易了。我们将使用快速修复功能(: make and error list),但编译将在远程机器上运行。所以我们需要设置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错误列表中。

这些是我多年来收集的。

" Pasting in normal mode should append to the right of cursornmap <C-V>      a<C-V><ESC>" Savingimap <C-S>      <C-o>:up<CR>nmap <C-S>      :up<CR>" Insert mode control deleteimap <C-Backspace> <C-W>imap <C-Delete> <C-O>dwnmap    <Leader>o       o<ESC>knmap    <Leader>O       O<ESC>j" tired of my typonmap :W     :w

当我在一个构建过程很慢的项目上工作时,我总是在后台构建并将输出通过管道传输到一个名为errors.err的文件(类似于make debug 2>&1 | tee errors.err)。这使得我可以在构建过程中继续编辑或查看源代码。当它准备好了(在GTK上使用py通知通知我它已经完成),我可以使用快速修复在vim中查看结果。首先发出:cf[ile],它读取错误文件并跳转到第一个错误。我个人喜欢使用cwindows在单独的窗口中获取构建结果。

一些有用的:

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

我的最爱:Ctrl+n单词完成!

gg=G

更正整个文件的缩进。我在Eclipse中缺少我值得信赖的<C-a><C-i>,但刚刚发现vim处理得很好。

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

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

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

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

然后按=%立即得到这个:

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

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

创建一个函数来执行当前缓冲区,使用它的sheang(假设设置了一个)并使用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." %")endifendfun

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

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

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

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

例如,Vim将打开一个URL

vim http://stackoverflow.com/

不错,当你需要调出页面的源代码以供参考时。

重用

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

txfxFx

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

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

在视觉模式下重复,与上面的提示结合时功能强大。

;

地图宏

我经常发现动态定义一些键映射很有用,就像定义宏一样。这里的转折是,映射是递归并被执行直到它失败。

示例:

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,

举个愚蠢的例子:)。

我完全意识到所有的缺点-碰巧我发现它在某些场合相当有用。在工作中看它也很有趣;)。

gv

重新选择上次可视选择。

不是一个模糊的功能,但非常有用和节省时间。

如果您想保存打开的缓冲区、选项卡、标记和其他设置的会话,您可以发出以下命令:

mksession session.vim

您可以使用以下命令打开会话:

vim -S session.vim

在插入模式下,ctrl+xctrl+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_ONELONG_ID_GOSH_FORGOT_THISLONG_ID_ETC∶

能够在基于客户端/服务器的模式下运行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

:%TOhtml

创建当前文件的html呈现。

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

如果您垂直拆分窗口并想从右侧窗口复制某些内容,这将特别有用。使用set鼠标=r不会帮助您解决这种情况,因为它也会选择左侧窗口上的所有内容。

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

sudo写的变体:

到. vimrc

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

重新加载vim后,您可以执行“sudo保存”

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

如果我们想在vim中生成序列号,这将非常有用
假设我们想插入1-10行,数字从1到10[例如第一行的“1”,第二行的“2”…]
在第一行插入“0”并复制该行和过去9次所以所有行都将显示“0”。

运行以下Ex命令

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

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

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

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

set colorcolumn=+1set cc=+1对于vim 7.3