人们谈论常见技巧的问题很多,特别是“Vim+ctags提示和技巧”。
然而,我并没有提到Vim新手会觉得很酷的常用快捷方式。我所说的是一位经验丰富的Unix用户(无论是开发人员、管理员,还是两者都有),他们认为自己知道99%的人从未听说过或梦想过的东西。这不仅让他们的工作更容易,而且很酷,很粗糙。毕竟,Vim位于世界上最黑暗的角落丰富的操作系统中,因此它应该具有只有少数特权人士知道并想与我们分享的复杂性。
人们谈论常见技巧的问题很多,特别是“Vim+ctags提示和技巧”。
然而,我并没有提到Vim新手会觉得很酷的常用快捷方式。我所说的是一位经验丰富的Unix用户(无论是开发人员、管理员,还是两者都有),他们认为自己知道99%的人从未听说过或梦想过的东西。这不仅让他们的工作更容易,而且很酷,很粗糙。毕竟,Vim位于世界上最黑暗的角落丰富的操作系统中,因此它应该具有只有少数特权人士知道并想与我们分享的复杂性。
让我们看看一些非常小的IDE编辑器如何进行列转换。
:%s/\(.*\)^I\(.*\)/\2^I\1/
解释
\(和\)是如何记住正则表达式中的内容。1、2等是如何检索记忆中的内容。
>>> \(.*\)^I\(.*\)
记住所有内容,然后是^I(tab),然后是所有内容。
>>> \2^I\1
用“你记得的第二件事”替换上面的东西,然后是“你记得第一件事”——本质上是做一个换位。
也许99%的Vim用户都不知道,但这是我每天使用的东西,任何Linux+Vim超级用户都必须知道。
基本命令,但非常有用。
:w !sudo tee %
我经常在编辑一个我没有写权限的文件之前忘记sudo。当我保存该文件时遇到权限错误时,我只需发出vim命令即可保存该文件,而无需将其保存到临时文件,然后再将其复制回来。
显然,您必须在安装了sudo的系统上,并且具有sudo权限。
我最近发现了一件我觉得很酷的事:
:earlier 15m
将文档还原为15分钟前的状态。可以为您想要回滚的时间量提供各种参数,并且取决于撤消级别。可以用相反的命令反转:稍后
这是一个用不同编码重新打开当前文件的好技巧:
:e ++enc=cp1250 %:p
当您必须使用传统编码时,这很有用。支持的编码列在编码值下的表中(请参阅帮助编码值)。类似的事情也适用于++ff,这样您就可以使用Windows/Unix重新打开文件了。如果您第一次出错,则行结束(请参阅帮助ff)。
不太晦涩,但有几个“delete in”命令非常有用,例如。。
指示删除当前单词di(要在当前父对象中删除di“删除引号之间的文本
其他信息可以在:帮助文本对象上找到
当我在项目中工作时,我经常使用许多窗口,有时我需要调整它们的大小。以下是我使用的:
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'如果是目录('/home/your_typeualusername')let rtuser='your_typeal_user'elseif是目录('/home/your_other_username')let rtuser='your_other_username'结束符其他的let rtuser=$USER结束符让&runtimepath=替换(&runtimepath,$HOME,'/HOME/'.rutter,'g')结束符
它将允许您的本地插件加载-无论您使用何种方式更改用户。
您可能还想将*.swp文件从当前路径中取出,并放入~/vimtmp(这将放入.vimrc中):
如果isdirectory(展开('~/vimtmp'))调用mkdir(展开('~/vimtmp'))结束符如果是目录(展开('~/vimtmp'))设置目录=~/vimtmp其他的设置目录=/var/tmp、/tmp结束符
此外,我使用一些映射来简化编辑-使ctrl+s可以像escape和ctrl+h/l那样切换选项卡:
inoremap<C-s><ESC>vnoremap<C-s><ESC>noremap<C-l>gtnoremap<C-h>gT
HOWTO:在Bash中使用Vim时自动完成Ctag。对于其他使用Vim和Ctags的人,我已经为Bash编写了一个小型自动补全器函数。将以下内容添加到~/.bash_completion文件中(如果不存在,请创建它):
感谢stylishpants的多次修复和改进。
_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
我发现当我快速修复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
将把所有包含“match”的行拖(复制)到“a/@a”寄存器中。(大写字母a使vim附加了“yankings”,而不是替换之前的寄存器内容。)我最近在制作Internet Explorer样式表时经常使用它。
这不是一个秘密,但我喜欢将以下映射放到我的.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>
把这个放到.vimrc中,有一个命令来漂亮地打印xml:
function FormatXml()
%s:\(\S\)\(<[^/]\)\|\(>\)\(</\):\1\3\r\2\4:g
set filetype=xml
normal gg=G
endfunction
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>
"
:! [command]在Vim中执行外部命令。
但是在冒号后面加一个点:。![command],它会将命令的输出转储到当前窗口中。那就是:!
例如:
:.! ls
我经常使用此功能,例如将当前日期添加到我正在键入的文档中:
:.! date
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——它滚动屏幕使这一行显示在在中间。这非常适合将您正在处理的代码放在您的注意力中心。Sibling命令——zt和zb——使这一行成为sreen上的最上面或最下面的一行,这并不太有用。
%找到并跳转到匹配的括号。
de--从光标删除到单词末尾(也可以执行de删除,直到下一个空格)
bde--删除当前单词,从左到右分隔符
df[space]—删除直到并包括下一个空格
日期——删除到下一个点
dd--删除整行
ye(或ye)--将文本从这里拖到单词末尾
ce-贯穿单词的结尾
bye--复制当前单词(让我想知道“hi”是什么意思!)
yy--复制当前行
cc——剪切当前行,也可以改为S。还有较低的大写字母,用于剪切当前字符并切换到插入模式。
viwy或viwc。修改或更改当前单词。多次单击w以继续选择每个后续单词,使用b向后移动
vi{-选择图括号中的所有文本。va{-选中包括{}s的所有文本
vi(p-突出显示()s中的所有内容,并替换为粘贴的文本
b和e一个字一个字地移动光标,类似于Ctrl+箭头通常的操作。但是,单词的定义有点不同,因为连续的几个三角形被视为一个单词。如果你从一个单词的中间开始,按b键将始终转到当前单词的开头,而每个连续的b键将跳转到下一个单词开头。同样,容易记住的是,e将光标指向当前单词的末尾,以及随后的每个单词。
与b/e类似,大写字母b和e仅使用空格作为分隔符逐词移动光标。
大写D(深呼吸)删除光标右侧的行的其余部分,与普通编辑器中的Shift+End/Del相同(注意2个键--Shift+D--而不是3)
我使用vim进行几乎所有的文本编辑,所以我经常使用复制和粘贴。问题是默认情况下vim经常会通过粘贴扭曲导入的文本。阻止这种情况的方法是使用
:set paste
在粘贴数据之前。这将使它不致混乱。
注意,您必须发出:set nopaste以恢复自动缩进。粘贴预格式化文本的替代方法是剪贴板寄存器(*和+)和:r!cat(您必须用^D结束粘贴的片段)。
打开高对比度配色方案有时也很有用。这可以通过
:color blue
我注意到它不适用于我使用的所有版本的vim,但它适用于大多数版本。
有时,.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
:r! <command>
将外部命令的输出粘贴到缓冲区中。
做一些数学运算,直接在文本中得到结果:
:r! echo $((3 + 5 + 8))
获取编写Makefile时要编译的文件列表:
:r! ls *.c
不要在维基百科上查找你阅读的事实,直接将其粘贴到你正在编写的文档中:
:r! lynx -dump http://en.wikipedia.org/wiki/Whatever
我的一些必备品是:
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"^[
此映射将使_引用一个字符串
我什么都用Vim。编辑电子邮件时,我使用:
gqap(或gwap)
即使使用引号引导字符,也可以在逐段基础上轻松正确地重新格式化。为了实现此功能,我还添加了:
-c’集合fo=tcrq’-c’集合tw=76’
到外部调用编辑器的命令。一个值得注意的添加是将“a”添加到fo(formatoptions)参数中。这将在您键入和浏览内容时自动重新格式化段落,但可能会干扰或导致消息中错误或奇怪格式的问题。
我确信有人已经发布了这篇文章,但这里是这样的。
请选择任何构建系统;制造,mvn,蚂蚁,随便什么。在项目目录的根目录中,创建一个始终使用的命令文件,如下所示:
根项目上进行构建mvn清洁安装等等
要进行构建,请将光标放在线上并键入!!即过滤该线路;将其写入shell并替换为结果。
构建日志将替换行,随时可以滚动、搜索等。
查看完日志后,键入u以撤消,然后返回命令文件。
我今天通过NSFAQ找到了这个:
注释代码块。
点击CTRL-V进入分块视觉模式。
标记要注释的块。
点击I(大写I)并在行的开头输入注释字符串。(//对于C++)
按ESC键,所选的所有行都将//前置到行的前面。
我很少在大多数Vim教程中找到一个,但它非常有用(至少对我来说),那就是
g;和g,
在变更列表中移动(向前、向后)。
让我来演示一下我是如何使用它的。有时我需要复制并粘贴一段代码或字符串,比如CSS文件中的十六进制颜色代码,所以我搜索、跳转(不在乎匹配的位置)、复制它,然后跳回(g;)编辑代码的位置以最终粘贴它。不需要创建标记。更简单。
只是我的20美分。
在插入模式下,Ctrl-n将根据打开缓冲区中的所有单词自动完成您键入的任何单词。如果有多个匹配项,它将为您提供一个可能的单词列表,您可以使用ctrl-n和ctrl-p进行循环。
想要IDE吗?
:make将在当前目录中运行makefile,解析编译器输出,然后您可以使用:cn和:cp单步执行编译器错误,打开每个文件并查找有问题的行号。
:syntax on打开vim的语法高亮显示。
我喜欢使用“sudobash”,我的系统管理员讨厌这样。他锁定了“sudo”,因此它只能与少数命令(ls、chmod、chown、vi等)一起使用,但无论如何我都能使用vim获得根shell:
bash$ sudo vi +'silent !bash' +q
Password: ******
root#
使移动在换行模式下在当前屏幕行上操作的映射。不久前,我在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("$")
:设置本地自动读取
自动重新加载当前缓冲区。。在查看日志文件时特别有用,它几乎可以从vim中为unix中的“tail”程序提供功能。
从vim中检查编译错误。根据perl语言设置makeprg变量
:setlocal makeprg=perl\-c\%
对于PHP
设置makeprg=php\-l\%设置错误格式=%m\\%f\\line\%l
发出“:make”将运行相关的makeprg,并在快速修复窗口中显示编译错误/警告,并可以轻松导航到相应的行号。
^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
将临时文件移动到外壳。如果您需要快速抨击:
按^Z(将vi放在背景中)返回原始shell,按fg返回vim back按:sh转到子shell,按^D/exit返回vi
每个线程
要给一组行加前缀,我使用两种不同的方法之一:
一种方法是块选择(由某事物提及)。通常,可以使用ctrl-V键选择矩形区域,然后移动光标。高亮显示矩形后,按shift-I将在矩形左侧插入字符,或shift-a将在矩形右侧追加字符。因此,您可以使用此技术创建一个矩形,其中包含要添加前缀的行的最左列,单击shift-I,键入前缀,然后单击escape。
另一种方法是使用替换(如Brian Agnew所述)。Brian的替换将影响整个文件(命令中的%表示“所有行”)。要只影响几行,最简单的方法是在第一行/最后一行时按shift-V(启用视觉行模式),然后移动到最后一行/第一行。然后键入:
:s/^/您的前缀/
^是一个正则表达式(在本例中,是行的开头)。通过在视觉行模式下键入此项,您将看到“<,”>自动插入s之前。这意味着替代的范围将是视觉选择。
额外提示:如果前缀包含斜杠,可以用反斜杠转义,也可以在命令中使用不同的标点符号作为分隔符。例如,要添加C++行注释,我通常会写:
:s:^://:
对于添加后缀,替换方法通常更容易,除非所有行的长度完全相同。只需在模式中使用$而不是^,您的字符串将被追加而不是预挂起。
如果要同时添加前缀和后缀,可以执行以下操作:
:s/.*/前缀和后缀/
.*匹配整行。替换中的&将匹配的文本(整行)放回原处,但现在它将添加前缀和后缀。
顺便说一句:在注释代码时,您可能希望稍后取消注释。您可以使用视觉块(ctrl-V)选择斜线,然后单击d删除它们,或者可以使用替换(可能使用视觉线选择,使用shift-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 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
宏可以调用其他宏,也可以调用自身。
eg:
qq0dwj@qq@q
…将删除每行中的第一个单词,直到文件结束。
这是一个非常简单的示例,但它展示了vim的一个非常强大的功能
以下两项都不是真正的顽固,但我发现它非常有用。
琐碎的捆绑,但我不能没有。它在插入模式下启用hjkl风格的移动(使用ctrl键)。在正常模式下:ctrl-k/j向上/向下滚动半个屏幕,ctrl-l/h转到下一个/上一个缓冲区。µ和ù映射特别适用于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”)保存文件。你需要做这个。
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
在复制和粘贴到stackoverflow之前:
:retab 1
:% s/^I/ /g
:% s/^/ /
现在复制并粘贴代码。
根据意见要求:
表1。这会将选项卡大小设置为1。但它也会遍历代码并添加额外的制表符和空格,以便格式化不会移动任何实际文本(即文本在ratab之后看起来相同)。
%s/^I//g:请注意,^I是单击制表符的结果。这将搜索所有制表符并用一个空格替换它们。由于我们刚刚进行了重新标记,这不应导致格式更改,但由于将标签放入网站是一触即发的,因此最好将其删除。
%s/^//:用四个空格替换行首。由于实际上不能用任何东西替换行的开头,所以它在行的开头插入四个空格(SO格式需要这样做才能使代码突出)。
由于延迟和缺少颜色(我喜欢颜色方案:),我不喜欢在PuTTY的远程机器上编程。所以我开发了这个技巧来解决这个问题。我在Windows上使用它。
你需要
1次gVim远程和本地计算机上的1x rsync1x SSH私钥身份验证到远程计算机,因此您不需要键入密码1x寻呼机1个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这现在很容易。我们将使用快速修复功能(: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 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
在构建过程缓慢的项目上工作时,我总是在后台构建,并将输出通过管道发送到名为errors.err的文件(类似于make debug 2>&1|tee errors.err)。这使得我可以在构建过程中继续编辑或审阅源代码。当它准备好后(使用GTK上的pynotify通知我它已经完成),我可以使用quickfix在vim中查看结果。首先发出:cf[ile],读取错误文件并跳转到第一个错误。我个人喜欢使用cwindow在单独的窗口中获得构建结果。
一些有用的:
:set nu # displays lines
:44 # go to line 44
'. # go to last modification line
我最喜欢的:Ctrl+n单词完成!
键入==将根据上面的行更正当前行的缩进。
实际上,您可以在任何移动命令后执行一个=符号={移动}
例如,可以使用在匹配大括号之间移动的%移动。将光标放在以下代码中的{上:
if (thisA == that) {
//not indented
if (some == other) {
x = y;
}
}
然后按=%立即获得:
if (thisA == that) {
//not indented
if (some == other) {
x = y;
}
}
或者,您可以在代码块中执行=a{,而不是将自己定位在{字符上。
使用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
我最喜欢在窗口之间来回切换的食谱:
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
重新使用
与其他命令混合的动作,此处更多。
tx
fx
Fx
在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,
只是一个愚蠢的例子:)。
我完全知道所有的缺点——恰好我发现它在某些场合非常有用。此外,在工作中观看它可能会很有趣;)。
这不是一个晦涩难懂的功能,但非常有用且节省时间。
如果要保存打开的缓冲区、选项卡、标记和其他设置的会话,可以发出以下命令:
mksession session.vim
您可以使用以下方法打开会话:
vim -S session.vim
在插入模式下,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
∶
能够在基于客户端/服务器的模式下运行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
为了将文本从Vim复制到剪贴板供其他应用程序使用,请选择要在视觉模式下复制的文本,然后按“+y”。这样,您可以轻松地将文本粘贴到其他应用程序。
如果您垂直拆分了窗口,并且希望从右侧窗口复制某些内容,则这特别有用。使用set mouse=r不会帮助您解决这种情况,因为它也会选择左侧窗口中的所有内容。
注意,必须使用xterm支持编译vim。
sudo write的变化:
插入.vimrc
cmap w!! w !sudo tee % >/dev/null
重新加载vim后,您可以将“sudo save”保存为
:w!!
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>"
我想在after目录中安排一些我自己的配置文件。它对ftplugin特别有用。
您可以避免在.vimrc文件中编写一长串augroup,而不是为每种类型编写单独的文件。
但是,很明显,.vim/ftplugin目录与.vim/after/ftplugin目录的作用相同,但我更愿意将.vim目录留给vim插件。