分类: LINUX
2009-06-23 20:10:17
Here's something very curious:
:%s/foo/bar/gc
is of course a substitution effective for the entire file
with confirm on each occurrence of "foo"
with the option of quitting at any point.
However, using something similar,
:g/foo/s//bar/gc
using the global g to effect the entire file --
does NOT allow quitting at any point
(even with the use of
If there are hundreds of "foo" -- it's an important fine point...
Invite further comments...
Arun Easi, April 23, 2002 23:33
g/foo/s//bar/gc => run the command s//bar/gc for each of the line
matching foo. It is like running multiple "s//" commands (Hence
you have to press q for each of the invocation). The
g in "s///gc" does not imply entire file, it just implies all occurence
on a line (or else, it would have substituted only the first)
, May 30, 2002 9:04
Here is one that deletes every other line (adjusting double spaced files):
:g/.*/norm jdd
pagaltzis()gmx_de, August 6, 2002 15:12
This can be done much simpler:
:%norm jdd
, February 10, 2003 4:49
Another cool g feature is to count the number of lines matching /regexp/
let x=0 | g/regexp/let x=x+1
echo x
Great, if you are editing data files.
Regards
Mike
, March 27, 2003 2:14
Reverse all the lines in a file:
:g/^/m0
I have found that useful . . . honest!
PK
, September 3, 2003 5:06
Can I do something like this using ":g" (or anything else)
I have a file which contains following kind of lines
abc123=1,2,3
bcd123=100,200,300
abcb123=1,3,4
I want to convert this to following
abc123=1,abc,2,abc,3,abc
bcd123=100,bcd,200,bcd,300,bcd
abcb123=1,abcb,3,abcb,4,abcb
Basically I want to replace each comma in a line with first few
letters, which are coming before 123, of that line surrounded by 2
commas.
Anonymous, September 3, 2003 12:45
To answer kkgahlot's question:
global // execute "s/\\([=,][^,]*\\)/\\1, " . matchstr (getline ("."), "^.\\{-}\\(123\\)\\@=") . "/g"
To make the whole thing a little more transparent some explanations (from the inside out):
We want to execute on each line a command like
s/\([=,][^,]*\)/\1, abc/g
for each line, but abc gets changed on each line.
The function
matchstr (getline ("."), "^.\\{-}\\(123\\)\\@=")
returns the string that matches the pattern /^.\{-}\(123)\@=/ on the current line. In the given examples this is the text preceding 123= at the beginning of the line. Depending on the actual requierements, a simpler expression like /^[a-z]*/ could work too.
The command
execute "s/\\([=,][^,]*\\)/\\1, " . matchstr (getline ("."), "^.\\{-}\\(123\\)\\@=") . "/g"
assembles the desired substitute command for the current line by joining some static text with the return value of the matchstr function and then executes it.
As execute works only on the current line, the command
global // execute ...
applies it to all line. If only certain lines should be proecessed replace // with some other pattern.
, November 21, 2003 10:39
Reverting lines in a file can also be done via
:%!tac
instead of tac, you can also use sort, xxd, xxd -r, cut, your-own-filter
Anonymous, March 29, 2004 7:18
too
bad :g does not have a /c parameter for confirmed execution of ex
commands. Something like the /c used in
:
or does it ??
, April 14, 2004 10:06
I
just want to add that the :g command in vi/ed is the basis for the name
for the Unix grep command, i.e. Global Regular Expression Print. The
"Print" part described the default behaviour of :g when no command was
given. Obviously this behaviour was more useful when using ed.
, August 16, 2004 23:55
Thank you for the tip
发信人: smartiger (天才虎), 信区: Linux
标 题: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 12:14:54 2003), 转信
:v/./$s/$/
Replaces multiple blank lines with just one blank line.
请问如何解释,特别是|和;
--
RedHat 8.0 Slackware 8.0
Mandrake 9.0 Debian 2.2r6
Xteam 4.0 RedFlag 3.0
SmarTiger
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 210.138.200.6]
发信人: sk8er (TRUE SK8ER), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 16:32:33 2003), 转信
我试了一下,这个好像不像你所说的那样工作。
:v/./$ 把整个文档都选中了,然后用 s 替换……怎么搞的……看不懂。
还不如用
:%s/\(\n\s*\)\{2,}/\r\r/g
来删除多余的空行。
【 在 smartiger (天才虎) 的大作中提到: 】
: Replaces multiple blank lines with just one blank line.
: 请问如何解释,特别是|和;
--
People will buy anything that's one to a customer.
※ 修改:·sk8er 于 Jan 14 16:33:55 修改本文·[FROM: 166.111.140.66]
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.140.66]
发信人: yeshao (叶少·HP加满了!), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 16:34:07 2003), 转信
:g/^[[:blank:]]*$/d
【 在 sk8er (TRUE SK8ER) 的大作中提到: 】
: 我试了一下,这个好像不像你所说的那样工作。
: 还不如用
: 来删除多余的空行。
--
痛苦和骄傲,这一生都要拥有
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 202.112.55.84]
发信人: sk8er (TRUE SK8ER), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Tue Jan 14 16:36:10 2003), 转信
你把空行全删掉了
他还想为多个留一个空行
【 在 yeshao (叶少·HP加满了!) 的大作中提到: 】
: :g/^[[:blank:]]*$/d
--
New York now leads the world's great cities in the number of people around
whom you shouldn't make a sudden move.
-- David Letterman
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.140.66]
发信人: scaner (沉默), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Thu Jan 23 16:29:02 2003), 转信
:v/./$s/$/
|是两个命令风格符号
:v/./$s/$/
'';/./-1j
$d
??
记得大概是这样.
我也看不动.
自己看help把.
大概意思是吧
所有的空行,变成
变成
........ --> n line -> ndot
然后
d掉最后一行
v那个是区域选择命令
具体的我也不清楚了.
【 在 smartiger (天才虎) 的大作中提到: 】
: Replaces multiple blank lines with just one blank line.
: 请问如何解释,特别是|和;
--
沉默是痛苦的女儿
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.168.15]
发信人: allanj (木瓜), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Thu Jan 23 18:26:01 2003), 转信
好像在那里见过
你在最后一行加个 . 然后执行下面的命令
:v/./ ; /./-1j
那个 . 就是为了防止原来最后一行为空,
不能再匹配 /./ 了
大意:
/./ 是非空行
v 是 g! 的简写, 而 g! 就是取 g 的反
所以 v/./ 就是标记出所有空行
然后对标记出的每一行 操作
; 连接 2 个行号
/./-1 就是从标记那个行号开始找非空行,
然后 (行号 - 1)
j 就是 连接 2 行
所以 () ; () j 就是把连续的几个空行 join
(如果标记的行不存在, g 方式就继续下一个存在的,
所以连接也不会出问题)
原来的:
v/./$s/$/^M./|'';/./-1j|$d
在 vim 下没试成, 设了 compatible 也没效果.
他是不是也想在最后加个 . 然后连接, 再去掉?
大致这样分
v/./
$s/$/^M./ |
'';/./-1j |
$d
v/./ 对所有的空行执行后面 3 个命令
$s/$/^M./ 对第 $ 行, 执行后面的替换
'';/./-1j 从 '' 行开始, 到第一个非空行, 执行 j 命令
$d 删除第 $ 行
【 在 smartiger (天才虎) 的大作中提到: 】
: Replaces multiple blank lines with just one blank line.
: 请问如何解释,特别是|和;
--
※ 修改:·allanj 于 Jan 23 18:26:56 修改本文·[FROM: 166.111.215.54]
※ 修改:·allanj 于 Jan 23 18:27:26 修改本文·[FROM: 166.111.215.54]
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 166.111.215.54]
发信人: sk8 (destroying Tsinghua), 信区: Linux
标 题: Re: 解释一下vi的一个高级用法
发信站: BBS 水木清华站 (Thu Jan 23 19:50:40 2003), 转信
不就是合并空行吗?何必搞得这么复杂
这不是解决这个问题的好办法
用
:%s/\(\n\s*\)\{2,}/\r\r/g
不就行了
【 在 allanj (木瓜) 的大作中提到: 】
: 好像在那里见过
: 你在最后一行加个 . 然后执行下面的命令
: :v/./ ; /./-1j
: 那个 . 就是为了防止原来最后一行为空,
: 不能再匹配 /./ 了
: 大意:
: /./ 是非空行
: v 是 g! 的简写, 而 g! 就是取 g 的反
: 所以 v/./ 就是标记出所有空行
: 然后对标记出的每一行 操作
: ; 连接 2 个行号
: ...................
--
※ 修改:·sk8 于 Jan 23 19:56:07 修改本文·[FROM: 218.88.205.178]
※ 来源:·BBS 水木清华站 smth.edu.cn·[FROM: 218.88.205.178]
vim使用技巧(1)
本文参考了vim官方网站的文档。为了查找方便起见,文中的技巧编号沿用原文档中的编号。
1. 使用 * 键可以向后搜索光标所在位置的单词。反之,使用 # 键可以向前搜索光标所在位置的单词。第一次使用 * 或者 # 进行搜索之后,则可以使用 N 或 Shift-N 继续进行搜索。另外,如果设置了hlsearch选项(:set hlsearch)的话,那么使用 * Shift-N 则可以标记当前的单词为高亮显示。
2. 经常会遇到这样的情况,就是在命令行上输入含有一个长长的路径的命令 vi /home/username/linux/src/dir1/dir2/dir3/srcfile.c,编辑结束之后发现需要编辑同一目录下的另一个文 件,这时不得不在vi中重新输入长长的路径。而将下面的脚本放在vimrc文件(Unix下为~/.vimrc,Windows下为_vimrc)中即可 快速输入路径:
" Edit another file in the same directory as the current file
" uses expression to extract path from current file's path
" (thanks Douglas Potts)
if has("unix")
map ,e :e [C-R]=expand("%:p:h") . "/" [CR]
else
map ,e :e [C-R]=expand("%:p:h") . "\" [CR]
endif
这样编辑完第一个文件之后,在vi中输入 ,e ,然后就可以利用Tab键进行自动补齐了。注意上面代码中的[]符号,实际输入的时候需要换成小于号和大于号(由于blog自身原因,小于号和大于号不能直接输入)
4. 单词自动补齐:输入一个单词(例如函数、变量名等)的开头几个字母,然后按Ctrl-N或者Ctrl+P键,vim会在当前文档中查找匹配的单词并自动将输入补齐。
6. 使用 % 键可以查找匹配的括号。
7. 使用 [{ 和 ]} 命令可以跳转到光标所在程序块的开头和结尾。
8. 如果当前光标处的单词是一个局部变量,则使用 gd 来跳转到该变量的定义处;如果当前光标处的单词是全局变量,则使用 gD 来跳转到该变量的定义处。
9. [i 命令可以快速察看光标所在位置的变量的定义,[d 命令可以快速察看光标所在位置的宏的定义。
10. 流行的文本编辑器通常都有前进和后退功能,可以在文件中曾经浏览过的位置之间来回移动。在 vim 中使用 Ctrl-O 执行后退,使用 Ctrl-I 执行前进。
相关帮助: :help CTRL-O :help CTRL-I :help jump-motions
12. 如果想在源程序中不使用TAB键并保证缩进为四字符,那么在 vimrc 中加入下列设置:
set tabstop=4
set shiftwidth=4
set expandtab
13. 使用 set incsearch 之后可以在键入搜索关键字时即时显示匹配的位置。
14. 使用 set hlsearch 可以将匹配进行高亮显示。进行一次搜索之后,执行 :nohlsearch 或 :noh 可以暂时关闭本次搜索结果的高亮显示。而使用 :set nohlsearch 则可以永久关闭搜索高亮显示。
可以将:noh命令映射到一个键上,例如:nmap
posted on 2004年10月05日 5:19 PM
1. 已经在编辑状态(insert mode)了,如何快速执行 normal mode 的命令?
在编辑文本时,需要快速定位到某个位置,如下一个 d 的位置,难道要
其实,使用 Ctrl-O 就可以临时切换到 normal mode, 执行一个命令后自动返回 insert mode。
于是上述命令序列可以改为:
Ctrl-O、fd 即可。
Ctrl-O 要按两个键呢,很麻烦,于是来个 keymap
" make ` functions
inoremap `
nnoremap ` i`
在 normal mode 下按 ` (左上角那个),会正常插入 `,
而在 insert mode 下则相当于按 Ctrl-O,
于是上述命令序列又可简化为
`fd 即可。
在 insert mode 想粘贴剪贴板内容时,可以输入 `P,爽吧?
这样就可以在 insert mode 下天马行空,不用再按
2. vim 的剪贴板怎么怪怪的?
用 y 命令拷贝的文本怎么不能在 X/Windows 的其它应用中使用呢?
事实上,vim 有多个所谓寄存器来寄存剪切的内容。
平时是不是只用 y
其实这时使用的是 unamed 寄存器(对应寄存器*,不知对否?),即没有给定名称的,
而给定名称的,可以加前缀 "r 使用。
例如,将当前行放到寄存器a中,输入: "aY
将另一行(先移到其它行)放到寄存器b中,输入: "bY
粘贴寄存器a,输入:"aP
粘贴寄存器b,输入:"bP
好了,扯远了,X/Windows 的剪贴板的内容是存在寄存器+中,不信,自己试试:"+P
能不能将简单的 y 和 p命令与系统剪贴板联系起来呢?
就这句,浪费了我许多口水:)
set clipboard+=unnamed " set clipboard
3. 我不要每次都输入 this_object.set_...
呵,在 C 的结构或 C++ 的对象设置时,那个结构名或对象名总是重复 n 次要输入,挺烦的:(
添加这两句到配置文件中吧:
" Ctrl-F to yank line upstairs
inoremap
这是在编辑模式中使用的,怎么个用法?举个例子吧(括号内是我的注释):
(在编辑模式下,先输入这句:)
this_object.set_height(1.80);
( ^)
( |)
(用
(自动补全成:)
this_object.set_
(于是你可以继续输入"weight(100);" 了)
不知大家明白没有,不明白的先试试:)
4. 我想注释一堆 C++ 代码
当然,这有许多种我不知道的方法,我的通用方法为,先在配置文件里添加:
vnoremap . :normal .
呵,一句就够了,示例如下:
假设你有如下几行代码需要注释:
this_object.set_height(1.60);
this_object.set_weight(100);
this_object.run();
你先移到第一行,输入 I//
然后移到第二行,按 V 进行 line visual mode,按 j 或其它方向移动键选好要注释的所有代码行,
最后按: .
是不是很神奇?
呵,说白了,这只是在 visual mode 里使用 redo 的功能而已,有点跑题了。
当然,殊途是同归的,只是路的长远而已。
这是条通用的路,可以用在很多地方。
回到主题,谁有更直接的办法注释一堆 C++ 代码?一堆 C 代码呢(用/* */ 风格) ?
5. vi 的自动完成有什么新奇的东东?
不就是根据 buffer 的内容来自动完成吗?
有些插件是可以动态地读取头文件或模块来提供自动完成的,例如 python 的 pydict。(此列表待补全:)
我想介绍的是 vi 基于字典的自动完成:
1. 增加基于字典的自动完成
set complete+=k "add dictionary complete
2. 设定字典文件,字典文件其实是个文件文件,每个单词占一行
(以下字典文件可能并不存在)
set dictionary=/usr/share/dict/words "set dictionary
3. 呵,因此我是不用什么英文字典来自动完成的,很少写英文文章,使用字典后反应很慢。
我用基于字典完成的原因是,使用编辑语言的关键字自动完成,见:
" complete from filetype syntax file
autocmd Syntax * execute "setlocal dictionary=".$VIMRUNTIME."/syntax/".getbufvar("%","current_syntax").".vim"
对应的语言语法文件必须存在才可使用,于是写新的 C 文件时,可以直接 inc
(请大家不吝赐教,to be continued)
编辑者: zslevin (10/16/04 10:53)
vi编辑技巧
游标的移动
本节所述皆是在 common-mode(c-mode,在 vim 又名
normal-mode)下的移动,原始的 vi 只能在 c-mode 移动,在 insert-mode 只做文字的输入,而不做游标的移动。当然
vim 及 elvis 的方向键是不论在那一种 mode 皆可移动自如。
基本的游标移动
h 左,或 Backspace 或方向键
j 下,或 Enter 或 +(要 Shift 键),或方向键
k 上,或 方向键或 -(不必 Shift 键)
l 右,或 Space 或方向键
Ctrl-f 即 PageDown 翻页。
Crtl-b 即 PageUp 翻页。
使用 hjkl 键的移动是为了使手不必离开打字区(键盘中央的部位),
以加快打字的速度,如果各位不习惯,那就使用方向键吧!
Backspace 及 Space 的移动方式是到了行首或行尾时会折行,
但方向键或 hl 键的移动则在行首或行尾时您继续按也不会折行。
转折换行的功能是 vim 的扩充功能,elvis 无此功能。
jk 及使用方向键的上下移动游标会尽量保持在同一栏位。
使用 Enter,+,- 的上下移动,游标会移至上(下)一行的
第一个非空白字元处。
好像有点复杂,各位就暂时使用方向键来移动就简单明白了!
等您爱上了 vim 后再来讲究吧。
进阶的游标移动
0 是数目字 0 而不是英文字母 o。或是 Hmoe 键,移至行首,(含空白字元)。
^ 移至第一个非空白字元,注意,要 Shift 键。
$ 移至行尾,或 End 键。要 Shift 键。
以上两个按键是源自规则表示式(regular expression),
在 regexp 中 ^ 是匹配行首,$ 是匹配行尾。
G 移至档尾(最后一行的第一个非空白字元处)
gg □至档首(第一行之第一个非空白字元处)
gg 是 vim 的扩充功能,在 elvis 或原始 vi 中可用 1G 来
移至档首(是数字 1 不是英文字 l)。
G 之原意是 goto,指移至指定数目之行首,如不指定数目,
则预设是最后一行。
w 移至次一个字(word)字首。当然是指英文单字。
W 同上,但会忽略一些标点符号。
e 移至前一个字字尾。
E 同上,但会忽略一些标点符号。
b 移至前一个字字首。
B 同上,但会忽略一些标点符号。
H 移至萤幕顶第一个非空白字元。
M 移至萤幕中间第一个非空白字元。
L 移至萤幕底第一个非空白字元。
这和 PageDown,PageUp 不一样,内文内容并未动,
只是游标在动而已。
n| 移至第 n 个字元(栏)处。注意,要用 Shift 键。n 是从头起算的。
:n 移至第 n 行行首。或 nG。
特殊的移动
) 移至下一个句子(sentence)首。
( 移至上一个句子(sentence)首。
} 移至下一个段落(paragraph)首。
{ 移至上一个段落(paragraph)首。
sentence 是以 . ! ? 为区格。paragraph 是以空白行为区格。
% 这是匹配 {},[],() 用的,例如您的游标现在在 { 上只要按 %,就会跑到相匹配的 } 上。写程式时满好用的。
另还有一些 vim 的特殊按键,但这得留待最后才来讲述,否则各位恐怕会头昏眼花了。
基本编辑指令
这个单元就开始进入主题了。下编辑指令都是在 commond-mode (c-mode),就是您一进入
vim
时的模式,只能下指令,不能键入文字。如果印象模糊,请瞄一下第一个单元的内容。这个单元说的是基本的指令,有些比较特殊的编辑指令,因为太有个性了,所
以会独立成一个单元来说明。
进入 i-mode 的指令
i 在游标所在字元前开始输入文字(insert)。
a 在游标所在字元后开始输入文字(append)。
o 在游标所在行下开一新行来输入文字(open)。
I 在行首开始输入文字。
此之行首指第一个非空白字元处,要从真正的第一个字元处开始输人文字,
可使用 0i 或 gI(vim)。
A 在行尾开始输入文字。
这个好用,您不必管游标在此行的什么地方,
只要按 A 就会在行尾等著您输入文字。
O 在游标所在行上开一新行来输入文字。
J 将下一行整行接至本行(Joint)。
并无相对的 split 功能,可在 i-mode 下按 Enter 来达成
,当然如果您熟 macro 的话,可自行定义。
使用 J 时,预设会消去本行的 EOL,且上下行接缝间会留下一个空白字元,
这符合英文习惯,却对中文会造成困扰,欲不留空白字元,
可使用 gJ(大写 J)指令,但这是 vim 的扩充功能,elvis 不适用。
请您随便找一个档案来试看看,光看文字说明太抽象了。
删除指令
x 删除游标所在处之字元。在 vim 及 elvis 亦可用 Del 键。
X 删除游标前之字元。不可使用 Spaceback 键。
vim 可以正确使用以上两个指令于中文,会删去一个中文字 elvis 则不行,
一个中文字要删两次,即使用 xx。
dd 删除一整行(delete line)。
dw 删除一个字(delete word)。不能适用于中文。
dG 删至档尾。
d1G 删至档首。或 dgg(只能用于 vim)。
D 删至行尾,或 d$(含游标所在处字元)。
d0 删至行首,或 d^(不含游标所在处字元)。
请回忆一下 $ 及 ^ 所代表的意义,您就可以理解 d$ 及 d^ 的动作,
这就是 vi(m) 可爱之处。
取代及还原
r 取代游标所在处之字元。vi(m) 很有个性的,您在 c-mode 按了 r 她就会停在那里等主人键入所要替代的字元,希望您这个当主人的,不要傻呼呼的也楞在那里,赶快键入您的新字元吧!:-)
vim 中可用于中文字,也就是可以替换一个中文字,elvis 则不行。
当然您的 vim 是要设在 taiwan 的才行。怎么样!有没有看过如此
有个性的取代方式?ㄚ!r 就是 replace 啦!
R 取代字元至按 Esc 为止。
cc 取代整行内容。或大写 S 亦可。
cw 替换一个英文字(word),中文不适用。(change)
~ 游标所在处之大小写互换。当然不能用于中文。别忘了 Shift!
C 取代至行尾,即游标所在处以后的字都会被替换。或 c$。
c0 取代至行首,或 c^。
s 替换一个字元为您所输入的字串。和 R 不同,R 是覆盖式的取代,s 则是插入式的取代,您可亲自实验看看。ㄟ!是小写的 s。
u 这个太重要了,就是 undo,传统的 vi 仅支援一次 undo,vim 及 elvis 就不只了,vim 是没有限制的。
U 在游标没离开本行之前,回复所有编辑动作。
Crtl+r 这个也是很重要,就是 redo 键。
加上数目字
喔!骚到 vi(m) 的痒处了,这是 vi(m) 一个非常骚包的功能,只此一家别无分号(当然同源的 ed,sed 等不在此限)。就是您可以在大部份的指令前加上数目字,代表要处理几次的意思。以下用实例来说明比较清楚。
5dd 删除游标所在处(含)起算以下五行内容。妙吧!
3r 按了 3r 后,您键入一个英文字,则三个字元皆会被您所键入的英文取代。很抱歉,这不能用于中文。
5J 将五行合并成一行。
3x 删除三个字元。抱歉,不能用于中文。
5i A 然后按 Ecs,插入五个 A。中文也可以!
2i system Esc 插入 systemsystem。中文也可以!
5G 游标移至第五行,是从档首开始起算。
5l 移至右第五个字元处,当然 j 是可以用方向键取代的。所有移动指令(参考第二单元)都可以加上数目字来控制,中文也通喔!elvis 当然是不能用于中文。
其它的指令和数目字结合,就留待各位去发掘吧!最重要的是请您亲自操作看看,使用 vi(m) 常常要动动脑筋,会有更妙的操作方式。
简单重排功能
>> 整行向右移一个 shiftwidth(预设是 8 个字元,可重设)。
<< 整行向左移一个 shiftwidth(预设是 8 个字元,可重设)。
:set shiftwidth? 可得知目前的设定值。:set shiftwidth=4
可马上重设为 4 个字元。shiftwidth 可简写成 sw。ㄟ,别忘了 Shift 键!
:ce(nter) 本行文字置中。注意是冒号命令!
:ri(ght) 本行文字靠右。
:le(ft) 本行文字靠左。
所谓置中、靠左右,是参考 textwidth(tw) 的设定。
如果 tw 没有设定,预设是 80,就是以 80 个字元为总宽度为标准来置放。
当然您也可以如 sw 一样马上重设。
gqip 整段重排。中文会出槌!:-(
gqq 本行重排。
重排的依据也是 textwidth。这里的重排是指您键入文字时没有按 Enter 键,
就一直在 keyin,这样会形成一个很长的一行(虽然萤幕上会替您做假性折行),
重排后,则会在每一行最后加入 EOL。gq 重排功能是 vim 才有的功能。
复制(yank)
yank
是什么意思?有疑问的请查一下字典吧!就好像是中医治疗中的「拔罐」的意思啦(是不是叫「拔罐」?知道的朋友指正一下吧)!反正在 vi(m)
中,她就是复制 copy 的意思。这在 vi(m) 的思考逻辑里,就是「拔」yank 起来,「放」put 上去。其实复制的指令就是 y
一个而已,为什么要独立成一个单元来说明呢?因为 vi(m) 复制、贴上的功能实在太独特了,再配合前面介绍的数目字,及 vi(m)
内部的缓冲区来使用的话,您会发现,原来 vi(m) 肚子里还暗藏著秘密武器。
指令说明
yy 复制游标所在行整行。或大写一个 Y。
2yy 或 y2y 复制两行。ㄟ,请举一反三好不好!:-)
y^ 复制至行首,或 y0。不含游标所在处字元。
y$ 复制至行尾。含游标所在处字元。
yw 复制一个 word。
y2w 复制两个字。
yG 复制至档尾。
y1G 复制至档首。
p 小写 p 代表贴至游标后(下)。
P 大写 P 代表贴至游标前(上)。
整行的复制,按 p 或 P 时是插入式的贴在下(上)一行。
非整行的复制则是贴在游标所在处之后(前)。
"ayy 将本行文字复制到 a 缓冲区
a 可为 26 个英文字母中的一个,如果是小写的话,原先的
内容会被清掉,如果是大写的话是 append 的作用,会把内
容附加到原先内容之后。
" 是 Enter 键隔壁的那一个同上符号(ditto marks)。
"ap 将 a 缓冲区的内容贴上。
缓冲区的术语在 vim 称为 registers,vim 扩充了相当多的
功能,有兴趣深入的朋友请 :h registers。您用 d、c、s、
x、y 等指令改变或删除的内容都是放在 registers 中的。
例如:您用 dd 删除的一行,也是可以使用 p 来贴上的。只
要是在缓冲区的内容都可以使用 p 来贴上,不是一定要 y 起
来的内容才能用 p。因此您认为 p 是 paste 也可以,认为是
put 可能较正确。
5"ayy 复制五行内容至 a 缓冲区。
5"Ayy 再复制五行附在 a 内容之后,现在 a 中有十行内容了!
ㄟ!不要我一直用 a 您就认为只有 a 可以用喔。26 个英文
字母都可以的,交叉运用下,您会发觉 vi(m) 肚量不小。
问题来了!忘记谁是谁的时候怎么办? :reg(冒号命令)就
会列出所有 registers 的代号及内容。您现在就试著按看看
咦!怎么还有数目字、特殊符号的缓冲区,原来您刚刚删除
(复制)的内容就预设放在 " 这个缓冲区,然后依序是
0,1,2,...9。也就是说您按 p 不加什么的话,是取出 " 缓
冲区的内容的。% 指的是目前编辑的档案,# 指的是前一次
编辑的档案。还有其它的呀!因为没什么重要,就请
:h registers 吧!registers 有个 "s" 结尾,不要搞错了,
而且 Tab 的补全键 vim 也支援的,也就是说您键入 :h regi
再按 Tab 键,vim 就会帮您补全,按了 Tab 后发现不是您要
的,那就继续按,总会出现您要的。:-)
Tab 补全的功能,elvis 也有,但叫出 registers 列表的命令
则没有,您得自行记忆在您的脑袋瓜子里。而且 elvis 的补全
能力并没 vim 强。
天大的指令
. 这是什么?ㄚ,是英文句点啦!没错,就是英文句点。什么意思?重复前次的编辑动作。这个指令太高明了,只要是编辑动作(移动游标不算,冒号命令也不算)都可以按英文句点来重复,要重复几次都可以。
例如:您按了 yy,然后按 p 就会复制、贴上一整行,如果要重复这个动作的话,就可以按 . ,也可以把游标移到其它地方后再按。其它 dd,dw,r,cw 等编辑指令都可以这样来重复。如果您要重复做某些编辑动作时,千万千万一定要想到有这么一个英文句点重复指令。ㄚ,拜托啦!您一定要常用这个指令。
疑难杂症
那 mouse 中键的剪贴功能还有吗?当然还有,不管在 console 或 X terminal 中都照用不误。当然在
windows 下的话就不能用了,可以用 Shift-Insert 来代替。Ctrl-v 在 vim 中另有作用,在 windows
下就不必去麻烦它了。
ㄟ,我从 netscape 用 mouse copy 东东过来的时候,常常都搞得天下大乱耶!要设成
:set paste,预设是 map 至 F9 键的,您要 copy 之前先按一下 F9,copy 完后再按一次 F9 来回复。这是 vim
的扩充功能,elvis 没有。那在 elvis 怎么办?只好 :set noai 了。在 GUI 的版本应不会有这种情形。
set 的功能先不必去理它,往后会有一个单元专门讨论。
朋友!您睡著了吗?不要被吓到了,您只要开个档案,亲自操作一下就能心领神会。那用 mouse 不是更方便吗?不见得,yyp 来复制贴上一整行比较快,还是用 mouse 来拉比较快?您可以试看看。
寻找/替换
搜寻、替换的功能几乎是每个编辑器必备的功能,那在 vi(m)
中有没有特殊的地方呢?当然有,您忘了,vi(m) 是个性十足的编辑器。最特殊的地方是和规则表示式(regular expression,简称
regexp) 结合在一起。简单的说她是一种 pattern 的表示法,在执行动作,如寻找或替换,就会依据这个 pattern 去找,所有符合
pattern 的地方就会执行您所下的动作。在这个单元里不讨论 regexp,会另立一个单元来探讨,以免搞得头昏脑胀。目前就暂不使用
regexp,您要找什么就直接键入什么就对了。
寻找
/ 在 c-mode 的情形下,按 / 就会在左下角出现一个 /,然后键入您要寻找的字串,按个 Enter 就会开始找。
? 和 / 相同,只是 / 是向前(下)找,? 则是向后(上)找。
n 继续寻找。
N 继续寻找(反向)。
更方便的寻找操作(vim 才有)
* 寻找游标所在处之 word(要完全符合)。
# 同上,但 * 是向前(下)找,# 则是向后(上)找。
g* 同 * ,但部份符合即可。
g# 同 # ,但部份符合即可。
n,N 之继续寻找键仍适用。
替换(substitute)
:[range]s/pattern/string/[c,e,g,i]
range 指的是范围,1,7 指从第一行至第七行,1,$ 指从第一行至最后一行,也就是整篇文章,也可以 % 代表。
还记得吗? % 是目前编辑的文章,# 是前一次编辑的文章。
pattern 就是要被替换掉的字串,可以用 regexp 来表示。
string 将 pattern 由 string 所取代。
c confirm,每次替换前会询问。
e 不显示 error。
g globe,不询问,整行替换。
i ignore 不分大小写。
g 大概都是要加的,否则只会替换每一行的第一个符合字串。
可以合起来用,如 cgi,表示不分大小写,整行替换,替换前
要询问是否替换。
[实例] :%s/Edwin/Edward/g
这样整编文章的 Edwin 就会替换成 Edward。
更进阶的寻找、替换的例子在说明 regexp 的时候还会再详述。目前只知道最基本的用法就可以了!其实光这样就非常好用了。:-)
书签功能
这又是 vi(m) 的一个秘密武器,简单的说,您可以在文章中的某处做个记号(marks),然后跑到其它地方去编辑,在呼叫这个 mark 时又会回到原处。妙吧!
mx x 代表 26 个小写英文字母,这样游标所在处就会被 mark。
`x 回到书签原设定位置。
` 是 backward quote,就是 Tab 键上面那一个。
'x 回到书签设定行行首。
' 是 forward quote,是 Enter 键隔壁那一个。
vim 对于书签的扩充功能
小写字母 只作用于单一档案内。
大写字母 可作用于编辑中之各档案间。
数目字 可作用于前次编辑的十个档案。
数目字的用法比较特殊,'0 是回到前一次编辑档案中离开
前的最后位置,'1 则是回到前二次编辑档案的最后位置,
依此类推。您不必使用 m 来标示,vim 会自动记忆。
很玄吧!其实这是 viminfo 的功能,您要认真追究的话,
请 :h viminfo-file-marks。viminfo 关掉,就没这个功能了!
所谓前次指的是前次启动的 vim。
:marks 得知目前所有书签的列表。
叫档、存档、紧急回复
ㄟ,是不是在灌水呀!怎么开个档也成一个单元?那您就错了,在 vi(m) 里叫档的花样可多了,而且又可以多档编辑,各编辑中的档案还可以互通讯息,这里面学问可大著呢!vim 就更骚包了,也学人家档案可以加密,虽说是噱头,但也还满好用的。
vim + 档名
这样开档后,游标会落在档案最后一行的行尾,在档案屁屁后干什么呢?方便您可以继续编辑嘛!
vim +n 档名
游标会落在第 n 行的行首。
vim +/string 档名
还记得吗? / 就是寻找指令,这样进入档案后游标就会落在第一个找到的 string 上,还可以按 n 继续找 string 喔!哦,string 还可以使用 regexp 来表示喔。
多档编辑
多档编辑会有两种情形,一种是在进入 vim 前所用的参数就是多个档(这种情形称为 argument list)。另一种情形是进入 vim 后另外再开其它的档(称为 buffer list)。不过都可以统称为 buffer。
:n 编辑下一个档案。
:2n 编辑下二个档案。
:N 编辑前一个档案。
注意,这种用法只能用于 argument list 的情形。
:e 档名 这是在进入 vim 后,在不离开 vim 的情形下再开其它档案。只要您要编辑的档案是在目前目录,Tab 补全键还是可以使用。
:e# 或 Ctrl-^ 编辑前一个档案,用于两档互相编辑时相当好用。
这种用法不管是 argument list 或 buffer list 档案间皆可使用。
还记得吗? # 代表的是前一次编辑的档案。
:files 或 :buffers 或 :ls 会列出目前 buffer 中的所有档案。
在 elvis 中可使用 :b 来叫出 buffers。
在 buffers 中,减号 - 表示这个 buffer 并未载入,不过,
不必担心,载入相当快速的。加号 + 表示这个 buffer
已经修改过了。
:bn buffer next。
:bl buffer last。
以上两个指令 elvis 不适用。
:b档名或编号 移至该档。
在 :ls 中就会出示各档案的编号,这个编号在未离开 vim 前是不会变的。
这个指令 elvis 也是可以使用。
当然 :e#编号 也是可以的,这样的用法则是所有 vi clone 都通用了。
如果您是使用 vim 的 GUI,那就在功能表上就会有 Buffers 这个选项,
可以很容易的知道及移动各 buffer 间。
:bd(elete)
buffer 在未离开 vim 前是不会移除的,可使用这个指令移除。其实移除她干什么呢?vim 是您在叫用时才会载入的,因此这些 buffers 并不是像 cache 一般要占记忆体的。
:e! 档名
这样也是会开档,但会放弃目前编辑档案的改变,否则如果档案已有变动,vim 预设是不让您随便离开的。:e! 后不接什么的话,代表舍弃一切修改,重新载入编辑中档案。
:f 或 Ctrl-g
显示目前编辑的档名、是否经过修改及目前游标所在之位置。
:f 档名
改变编辑中的档名。(file)
:r 档名
在游标所在处插入一个档案内容。(read)
:35 r 档名
将档案插入至 35 行之后。
gf
这是 vim 的特殊叫档法,会叫出游标所在处的 word 为名的档案,当然,这个档案要在目前目录内,否则会开新档案。
哦!好像有点给他复杂,主要原因是偶文笔不好啦!不过您何不选个顺手的来用就可以了,选定了,以后就是使用他,这样就不会那么复杂了。:-)
离开
:q 如本文有修改而没存档,会警告,且无法离开。(quit)
:q! 舍弃所有修改,强迫离开。
:wq 存档后离开。纵使档案未曾修改也是会再存一次档。
:x 也是存档后离开,但如果档案没有修改,则不会做存档的动作。
ZZ 和 :x 完全一样,随您高兴用哪一个。
:w 档名 另存他档。不加档名就是写入原档。(write)
:q 及 :q! 是对目前编辑中的档案作用,如果多档编辑的情形
并不会离开 vim,这时可下 :qa 或 :qa! 来整个离开 vim。
a 就是 all 的意思。
vim 的加密功能
vim -x [档名]
这样进入 vim 后会要求输入密码。以后加密过的档案由 vim 开启时会自动要求输入密码。否则无法开启。其它的编辑器当然是无法开启的。
进入 vim 编辑档案中,临时想加密,可用 :X 指令。
小心!vim 一开档就会有个 .档名.swp 这个档,是为了紧急回复用的,
一般是在您所开档案的所在目录,这是个隐藏档,ls 要有 -a 参数才看得到,
您加密的功能并没有作用在这个 swp 档,因此 root 还是知道您在
写些什么关于他的坏话的。:-) 当然啦!山不转,路转,路不转,人转,
您也是可以把 swap 的功能关掉的 :set noswf 就行了!但如果您编辑的是
大档案,则不建议您把 swap 关掉,这样会很吃记忆体的。
elvis 的话,其暂存档是统一集中存放在 /var/tmp/*.ses,
权限是档案所有者始能读写。vim 的早期版本,其 *.swp
档是依原档案的权限来设定的,最近的版本则从善如流,
已经改成档案所有人始能读写,就是 -rw------- 啦!
紧急回复
vim -r 档名,或进入 vim 后,下 :recover 档名,来回复。
大家来学 VIM (三)
各种标示方法及视窗操作
这个单元多了一种模式,那便是 visual
mode(以下简称
v-mode)v-mode下的反白区(反黑区?^_^)在本文就统一称为标示区,不知各位是否有更好的中文名称?ㄟㄟㄟ,视窗操作和标示有什么关系?为
什么摆在这里说明?ㄚ,是因为这两个单元内容都不多,没地方摆,所以就将凑在一起的啦!乱点鸳鸯谱就请各位见谅。
标示指令
v 小写 v 这是属于字元标示(character visual),按下 v 后您就可以移动游标,游标走过的地方就会标示起来。再按一次 v 就会结束 v-mode。您用 mouse 拉出的标示区也是属于这类的标示。
V 大写 V 这是行标示(line visual),按下 V 后会整行标示起来(包括空白的部分),您移动上下键,会标示多行。mouse 连按三次左钮,也是属于此类的标示。再按一次 V 就会结束 v-mode。
mouse 按两次左钮是标示一个 word。
Ctrl-v 这是方块标示(block visual),可纵向标示矩形区域。再按一次 Ctrl-v 就会结束 v-mode。
结束 v-mode 的方式亦可使用 Esc 键,或一使用 Ctrl-c。
windows 系统下 Ctrl-v 是复制键,可以使用 Ctrl-Q 来替代。
d 删除标示区内容。
y 复制标示区内容。
ㄟ…是要先标示好才按的。"ay 还能不能用呢?当然可以,
这样就会把标示区内容存于 a 缓冲区中。可以用 "ap 来贴上。
Shift-> 标示区内容向右移一个 Tab。
Shift-
可设成 dark 或
light,这是两种不同的 highlight 颜色设定,详见
$VIMRUNTIME/syntax/synload.vim。不过您要更动颜色的设定,最好是设在 ~/.vimrc 或 ~/.gvimrc
中,原始档最好不要去动她。
ㄟㄟㄟ,你从没提过 $VIMRUNTIME 好不好!其实这是最近版本的 vim
为了不至安装新版本时把旧版本的一些设定或 macro 档干掉,
所以 $VIMRUNTIME 就是 $VIM/vimxx,xx 就是版本号码啦!
例如您使用的是 vim 5.6 版,那么就是 $VIM/vim56。
backup(bk)
是否要 backup file。预设不打开。
writebackup(wb)
在写入档案前先备份一份,和 backup 的作用不尽相同,请:h backup-table。预设是打开的,所以您如果不要 backup,那要关掉的是这个项目,而不是 backup。但请先检查一下您编译时是不是有编译进去,请 :ver。
backupdir(bdir)
设定存放 backup file 的目录。预设在所编辑的档案之所在目录。
binary(bin)
设在编辑二进位档状态,这是防止存二进位档时把 EOL 也写进二进位档,那就会悔不当初,如果是图档将会无法再观看,如果是可执行档就无法执行了!因此预设是 off。
elvis 会自动判断是否为二进位档,而且会分成左右两半,左半部会以 16 进位的方式显示,
右半部则是以 ASCII 的方式来显示。
browsedir(bsdir)
浏览档案的目录,GUI 版本始有。预设是上一次浏览的目录。就是 GUI版本功能表上的 [File] -> [Open] 会打开的目录。
cindent(cin)
写 C 时很好用,indent 比一般敏感,专为 C 程序码而设。预设 off。编辑 C/C++ code 时会自动打开。
cmdheight(ch)
状态列的行数,预设一行,建议设成两行。
compatible(cp)
设为和原始 vi 相容的状态,vim 的扩充功能会被抑制。预设 off。
confirm(cf)
各种确认动作。预设 off。
directory(dir)swap 档存放的目录。前面单元已有说明。
fileformat(ff)
这是写入档案时置放 EOL(end of line) 的形式
dos 是以 0D 0A 来断行。
unix 是以 0A 来断行。
mac 是以 0D 来断行。
预设以各系统平台而定,在 Linux 当然是 unix 形式。
fileformats(ffs)
可指定多个,会依载入的档案形式来调整 ff。例如 :set ffs=unix,dos ff=unix 则预设为 unix 格式,但如读入的是
dos 格式的档案,会自动调整为 dos 格式,这样存档时就会以 dos 格式存档(状态列会显示)。此时如要改成 unix 格式,可 set
ff=unix 然后存档就会转成 unix 格式,反之亦然。
注:
如果不这样设,也就是您不管 ff 或 ffs 都设成 unix,那读入dos 格式的档案时在每行尾会出现 ^M 这个字元(就是 0D
啦!)这时纵使 :set ff=unix 也来不及了!只好 :%s/^M//g 来消去这个^M。ㄟ,还记得怎么替换吗?就是把 ^M
换成没有啦!而且 ^M 怎么打出来的还记得吧!翻一翻前面的单元吧!
Hey,你怎么知道是 0D 呀!好吧!告诉您一个密秘,您把游标移到^M 那个位置,然后按 ga 在状态列就会显示 10,16,8 进位的值。其它的字元也是可以如此显示。a 就是 ascii 的意思。但这是 vim 的扩充功能,elvis 没有。
elvis 纵使载入 dos 格式的档案,也是会自动把 ^M 隐藏起来。
ignorecase(ic)
寻找时不分大小写,这对中文会造成困扰。预设 off。
incsearch(is)
加强式寻找功能,在键入 patern 时会立即反应移动至目前键入之 patern 上。预设 off。
hlsearch(hls)
寻找时,符合字串会反白表示。预设 off。如果您是使用 vim 的预设的 vimrc 档的话,会设在 F8 键来切换。
textwidth(tw)
是一种 word wrap 的功能,从左起算之固定每行的最大字元宽度。超过此宽度就会自动折行,这可是真的折行,也就是说在折行处会插入 EOL。预设是 0,也就是没有 word wrap 的功能。
wrapmargin(wm)
和 textwidth 作用相同,只是是从右视窗边向左算起要几个字元起折行。预设是 0。textwidth 与 wrapmargin 的功能目前并不适用于中文,打中文还是您自行按 Enter 吧!
wrap
这也是折行功能,可是只是萤幕效果的折行,实际上并没有插入 EOL。
wrapscan(ws)这和折行没有关系,是指寻找时,找至档尾时,是否要从档首继续找。预设是要。
paste
这是防止在做剪贴时位置会不正确,前面单元已有说明。
ruler(ru)
会在状态列显示游标所在处之行列状态,预设不打开,但建议打开。最右边之代号的意义如下:
Top 档案第一行在萤幕可见范围。
Bot 档案最后一行在萤幕可见范围。
All 档案首尾皆在一个萤幕范围内。
如非以上三种情形,则会显示相对百分比位置。
statusline(stl)
状态列显示的格式,使用预设就可以了,如果您想骚包一下的话,那就请您 :h stl。
shiftwidth(sw)
指由 >> 移动整行内容时,一次移动的字元宽度,一般是使用 Tab 的值,但可由这个设定来改变。
tabstop(ts)
一个 Tab 键宽度。预设是 8 个字元宽度。最好不要随便改,以免您写的东西由其它编辑器来阅读时造成困扰,为解决这个问题,vim 有一种 softtabstop 的机制,在下一节会详细说明。
showcmd(sc)
在状态列显示目前所执行的指令。
showmode(smd)
在状态列显示目前的模式,例如是 Insert mode 或是 Visual mode。当然平常的 normal mode(commond mode)是不显示的。
viusalbell(vb)
以萤幕闪动代替 beep 声。
number(nu)
显示行号。注意,冒号命令也有 :nu 这是显示游标所在行的行号,您嫌多打一个字的话,:# 也行。不过如果 ruler 打开的话,在状态列本就会显示门前游标所在处的行列值。
list
这也可以算是一种模式,list mode。就是 Tab 的地方会以 ^I 显示,而行尾之 EOL 会显示成 $。可以让您清楚的知道 Tab 在哪里,折行是不是真的。
swapfile(swf)
是否需 swap 至磁碟。如果设为 noswf 的话,那将不会有 swapfile产生,通通会载入在记忆体中。预设是要 swapfile。
fileencoding(fe)
首先先鼓掌一下,啪啪啪…,因为有支援 taiwan,也支援 XIM,也就是说可以使用 xcin-2.5x 来作输入,当然您用
xcin-2.3x 配合XA 也是可以啦!目前支援简繁中文、日文、韩文,unicode 尚未植入。但前提是您要把 multi_byte
编译进去,这在一开始就讲过了。预设是使用 ansi。set guifont 及 set guifontset 已在一开始讲过,在此就不重复了。
history(hi)
记录冒号命令的历史纪录档,就是可以用上下方向键叫出来的那锅。预设是 20 笔。
关于 softtabstop(sts)
几乎所有的 OS 及软件都设定 Tab 就是 8
个字元长,这已经是个公认值,您硬要去改变它的话恐怕带来许多不便,但实际上关于程序风格,许多人又认为 8
个字元太长了,几个巢状回圈下来就需折行,反而不方便。因此 vim 体贴您,内建了 softtabstop 的功能,就是由 vim
来代您制造出一个假的Tab,实际上是空白字元组成的 Tab。
举个例子来说明比较清楚。
set softtabstop=4
set shiftwidth=4
这样会由 4 个空白字元取代一个 Tab,您按 Tab 键 vim 就跳 4 格,需注意的是,如果您按了三次 Tab 键,那就是一个实际的 Tab 加上四个空白字元,可不是 12 个空白字元喔!是混合 Tab 及 space 的。
问题来了!那我要按真正的 8 字元的 Tab 时怎么办?简单,还记得怎么按特殊字元吗? Ctrl-v Tab 或 Ctrl-v I 就可以了,那就是如假包换的 8 字元长之 Tab。当然,您按两次 Tab 不就得了!:-)
关于折行
前面已说过 set wrap 就可以造成萤幕折行,可是却会把一个英文单字折成两半,实在很不雅观。好了,vim
再体贴您一次,set linebreak(lbr) 就会避免这种问题发生,会在空白或标点符号的地方来折行,但也仍属萤幕折行,并不会插入
EOL。这个功能目前在中文判断上还是会出槌!:-(
规则表示式的运用
在本系列文章一开始就说明了学 vi(m) 可以顺便学规则表示式(regular
expression,以下简称 regexp),那为什么到现在才来讲呢?因为 regexp
说简单也算不很难,但您要深入去使用的话,有时会马上看不出一个复杂的 regexp 在说些什么的,就曾有人形容 regexp
为「有字天书」!而且在 vi(m) 整体都还没一个概念就加入 regexp 的话,那后面的单元恐怕就没人看了!而 regexp 各家有各家的
extensions,这也是大家视为畏途的原因之一,不过总是大同小异,只需注意一下就可以了。目前先不必管别家怎么说,就让 vim
暂时先成为我们的「标准」,以后碰到其它程序的 regexp
应该就可以触类旁通。以下我们尽量由实例去了解。当然,小小的一篇文章是没有办法详尽介绍,只能捡重点来说明了。如有疑问,可 :h pattern
或在Un*x 系统中可 man 7 regex,甚至 man ed,man sed,man grep,man awk,man perlre
里面也是会说些 regexp,但要注意和 vim 差异的地方!其中 perl 的 regexp 应该是最完整的了,如果您的系统没有 perl
那应该是「稀有动物」了!:-) ㄟㄟㄟ!vim 只是一个编辑器,可不是独立的程序语言!
基本的匹配
* 指前所绑住的字元或字元集合,出现 0 次或 0 次以上。
+ 和 * 作用相同,但不包括出现 0 次。
= 指前所绑住的字元恰好出现 0 或 1 次。
| 这是多选,就是 or 的意思,被 | 隔开的 pattern,任一个符合的话就算符合。注:
+, =, | 会加上一个 ,是因原字元在 vi(m) 就具有特殊意义,在一般的 regexp 中是 +,?,| 就可以了,只是提醒您一下,以免搞混了!
在 elvis 及 ed 中是使用 ? 来匹配出现 0 或 1 次,而不是 =,这里要非常小心!
[实例]
dg*
指 * 前所绑住的字元 g 出现 0 次或 0 次以上。也就是说 d(出现 0 次),dg,dgggg,dgggggggg 都是符合这个 pattern。如果您下寻找指令 /dg*,那符合这个 pattern 的字串都会被找出来。如果用在代换就要非常小心了,像 extended 中的 d 也是会被置换掉的。例如您下 :%s/dg*/test/g 的话,那 extended 这个字会换成 extentestetest。注 : shell 中使用的通用字元为 pattern matching notation 和 regexp 不同的。dg* 在 shell 中是解为以 dg 开头的任意字串,这就不包括 d 在内了,也就是说在 shell 中,* 是代表任一字元或字串。
[实例]
dg+
dg, dgg, dgggggg 皆符合,但 d 则不符合。如果是 dg= 的话,就只有 d、dg 这两个符合了。
[实例]
:%s/The|All/test/g
全文中只要是 The 或 All 都会被替换成 test。注意,如果文中有 There 也是会被替换成 testre!要如何避免这种情形呢?下面会另述及限定使用法。
[实例]
/123-=4567
这样会找出,123-4567 及 1234567。当然 123-456789 也是会被找出来。
[...] 字元集合,表示中括号中所有字元中的其中一个。
[^..] 这是上述 [...] 的补集,表非中括号内字元的其中一个。
. 除换行字元外的任一单一字元。指本身,非指前所绑之字元。就好像 shell 中的 ? 一样。如果要指定真正的英文句点,要用 来 escape,就是说 . 这时的 . 是代表真正句点,而不是 regexp 中的特殊意义。其他如 * 亦同。
[实例]
[Aa]
A 或 a 其中的一个。
[12345]
12345 其中的一个数目字。可用 [1-5] 来表示。连续性的数目字或字元可用 - 来隔开,写出头尾来代表就可以了。[0-9] 就表 0 到 9 的数目字,[a-d] 就代表 abcd 四个英文字母。
[实例]
W[0-9]*.cc
这个例子是说以 W 开头,后接 0-9 其中一个或多个数目字或不接什么,然后是一个句点,最后是 cc。所以 W.cc,W1.cc,W2.cc,W345.cc,W8976543287.cc 皆符合。如果要表示 W 及 .cc 间夹一个以上的数目字,要写成 W[0-9][0-9]*.cc。
[实例]
.*
这代表任意字元或字串,或什么都没有,脑筋急转弯,对照前面的定义想 一下。
[实例]
[^M]
表除 M 以外的任意字元。
[^Tt]
表 T 及 t 以外的任意字元。
[^0-9]
表非数目字之字元。
[^a-zA-Z]
表非英文字母之字元。
注:
注意,^ 要在中括号内,且在最开头的地方,否则另有含意。^ 匹配行首,指其后绑住的字串,出现在行首才符合。$ 匹配行尾,指其前绑住的字串,出现在行尾才符合。含换行字元。
不是在行首的 ^ 指的是 ^ 这个字元。不是在行尾的 $ 是指 $ 本身这个字元。
[实例]
/^What
这样只有在行首的 What 才会被找出来。注意! Whatever, What's 也是会被找出来。如果是 /What$ 则是在行尾的 What 才会被找出来。
[实例]
^$
这是什么东东?行首也是行尾的行。ㄚ,就是空白行嘛!当然也不能说这个行是没有什么东东啦!空白行至少也是会有个换行字元。在后面会详述如何消除全文的空白行。
(...) 记忆 pattern,可由 1, 2...9 来叫出。
[实例]
:%s/([a-z])1/test/g
这样 aa, bb, cc, dd, ..., zz 都会被 test 替换掉。这和 :%s/[a-z][a-z]/test/g 是不一样的意思,后者会把 aa, ab, ac... ba, bb, bc...zz 都换成 test。也就是说 (...) 由 1 叫出时会有对称性的配对出现。
[实例]
:%s/(.)(.)r21/test/g
会将中间为 r,前有二个任一字元,后有两个具对称性的字元所组成的字串替换成 test。例如:12r21,cfrfc,7grg7 等都会被替换成 test。
匹配字尾。这就是前所提及的限定用法,被 括住的 pattern 就会被限制住,使 regexp 不能再向右(左)扩充解释。
注: ed 及 perl 中可以 来表示这两个符号,但 perl 中只支援 ,ed 则 及 皆支援。在 vim 中 是表示 即
backspace 键。功能上而言,这是和 ^ $ 一样的定位样式(anchor pattern)指所绑住的字串必须是单字边界(word
boundary),前或后或前后除了空白字元及标点符号外不可再有其它字元。
[实例]
:%s//test/g
这样只有 abbbc 才会被替换成 test。如果没有这样限定, :%s/abbbc/test/g,那 deabbbcly 中的 "abbbc" 亦会被替换成 test。所以前面 :%s/The|All/test/g 可换成 :%s/|/test/g 这样一来,There 就不会被替换成 testre 了!
[实例]
:%s/]*$/d
在 vim 或 elvis 里您可以如此照打,也就是 代表空白字元, 代表按 Tab 键的结果。在原始 vi 则不行,得自行按出特殊字元出来,就是 Ctrl-v Space 及 Ctrl-v Tab。或采更简单的打法:
:g/^s*$/d
还记得中介中元吗?好用吧!少打了不少字。:-) 意思就是删除含 0 或 1 个以上空白字元的行。注: 有些书中写成 :%s/^$//g 可以删除空白行,这是错误的,因为 :s 这个指令只更动一行里的内容物,但不会做删除一行的动作。
& 替代变数
代表置换时合于 patern 的字元或字串。
[实例]
:%s/uddddddddd>/ID:&/g
这样全文中的身份证字号前就会加上 ID: 字样,也就是说 T123456789 会被换成 ID:T123456789。还记得吗? d 就是 [0-9],u 代表大写的英文字母。加个 > 是防止 T12345678999 也被换掉。当然前面再加个
就是删去行首的二个空白啦!
[实例] 将全文的 Edward 这个单字,前后加上中括号
:%s//[&]/g
[实例] 将全文的 Edward 这个单字,改成大写的。
:%s//U&/g
注: ㄟ!U 不是代表非大写字母吗?喔!您搞错位置了。U 在 pattern 的位置的时候是指非大写字母的样式,即 [^A-Z],但如果是在置换字串位置的时候是指将其后的字串通通改成大写。与其相对的是 L,会将其后的字串改为小写。详细请 :h sub-replace-special。
[实例] 将全文每行最后加上
这个 HTML tag。
:%s/.*/&/g
怎么样,是否已感觉到 regexp 威力无穷了呢?还是您已经快睡著了呢?:-) 不过也请您想想,如果是在没有 regexp 功能的编辑器里,范例中的一些动作您会怎么做呢?一个一个去改?
greedy 陷阱
regexp 会有贪心的倾向,什么意思呢?就是说在同一行内,如果有多个符合 pattern 的情形,会找最长的那一个。
注: 注意!greedy 的特性是针对会反覆比对的 regexp 而言,例如:*, =, +, {} 等。前面所举的 .* 的例子,由于 greedy 的关系,在整篇文章中做替换时,会被当成是每一行整行,因为 regexp 会去找每一行最长符合的那一个。
[实例] This is a test. Test for regexp. 如果您下
:%s/[Tt].*t/program/g
原意是想把所有的 Test 或 test换成 program 的,结果由于 regexp 的贪心,整个 "This is a
test. Test" 会换成 program。结果原文就变成了program for regexp.
因此在全文替换时要非常小心,避免使用弹性太大的 regexp。像此例,只要下
:%s//program/g
就可以了!
最后提醒您,这可不是 regexp 的全部,碍于篇幅及在下功力的问题,当然是没办法全面详尽的向各位做介绍,在下只是将各位领进门,修行就得看各位了!如果还想更深入的研究 regexp,可参考: Mastering Regular Expressions(O'Reilly & Associates) 一书。
__________________ 每临大事有静气 不信今时无古贤
This is very, very simple:
:noremap
I find this helpful when editing multiple files and I want to search for the word under the cursor in *another* file.
I then type F1, C-^, n.
Using Insert mode to insert a single character feels clumsy (you need
3 keypresses for one character), so here's a slightly easier way:
:nmap
Now, when in Normal mode, just press space followed by what
it is you want to insert.
BUG: Repeating the insertion with . doesn't work.
rate this tip Life Changing Helpful Unfulfilling
<
Additional Notes
, July 23, 2002 2:59
Very
good tip, but I prefer
reiss_david AT yahoo DOT com, July 29, 2002 10:30
I use
:map gt i$
:map gb a$
These macros were derived from one I found in a Vi FAQ.
Anonymous, May 20, 2003 10:44
yeah,
both comments get to the point, but the author was looking for a way to
save a keystroke. both solutions are 3 keystrokes long.
You can use the :redir command to redirect the output of an ex command to
a register and then paste the contents of the register into a Vim buffer.
For example:
:redir @a
:set all
:redir END
Now, register 'a' will have the output of the "set all" ex command. You
can paste this into a Vim buffer. You can also write a Vim function
to do the above.
For more information, read :help redir
I love using the visual block feature to move columns around (
However, this does not work conveniently on the last column
when lines are not of equal length.
is equal in width to the shortest line.
In order to pad all lines to a given width with trailing blanks
you can use the following functions:
" truncate line 'line' to no more than 'limit' width
function! Truncate( line, limit )
call cursor(a:line,a:limit)
norm d$
endfunc
" Pad all lines with trailing blanks to 'limit' length.
function! AtOnce( limit )
norm mm
g/^/norm 100A
g/^/call Truncate( getline('.'), a:limit )
let @/=""
norm 'm
endfunc
You may alternatively use the oneliner:
:g/^/exe "norm! 100A" | call cursor(getline('.'), 79) | norm d$
I even saw someone use a standard vi (non vim) oneliner to achieve the
same, but I forgot how. Any ideas?
【 在 neman (行胜于言) 的大作中提到: 】
: 标 题: Re: win Gvim不显示菜单和工具条
: 发信站: BBS 水木清华站 (Tue Jun 8 20:47:50 2004), 站内
:
:
: 【 在 qnx (OS) 的大作中提到: 】
: set guioptions=
: map
: function! SwitchShowMenus()
: if &guioptions=="gmrLtT"
: set guioptions=
: elseif &guioptions==""
: set guioptions=gm
: else
: set guioptions=gmrLtT
: endif
: endfunction
:
: "gmrLtT可以显示工具条和菜单,gm仅仅显示菜单
:
:
: 你的这个功能我的那个也是能实现的,
: 本来是介绍一个经验的,结果没有说明白,:)
:
: 我的问题是:
: 1、我不想要title条, set notitle 它只是把title的文字去掉了。
: 2、窗口最大化后最下边的无用空白条太大了,看起来不美观
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这个白边确实没有什么用, 不知道哪位niu能弄掉?
: 有办法解决没有? 谢谢 :)
精华区文章阅读
发信人: vale (浅谷·等待溪流), 信区: VIM
标 题: VIM中不易发现的强劲功能
发信站: BBS 水木清华站 (Mon May 31 10:54:41 2004), 站内
在我最初使用Vim时,有些功能并不知道,等发现后真后悔自己干了那么久的体力活。
1. * (super star)
向下查找光标下(或附近)的
在insert模式下,C-R (register) 插入register里的内容,一个有趣的reg是"=".
假设你想输入123K的具体字节数,不用打开计算器,试试这个“
“125952”就出来了!
另外在命令行里C-R C-W和C-R C-A是必用的技巧,它们将光标下的
考到命令行里,省了你无数的typing。
3. C-X (auto complete)
在insert模式下,C-X C-P/N/L/F等自动完成前面的词、行、文件名等,是编程时必用的
命令。其中C-P和C-N可以不用C-X。
4. [p & ]p (smart paste)
paste同时自动根据目标行的缩进调整来源行的缩进。在copy代码段的时候非常有用。
5. C-O (fast out, fast in)
在insert模式下,用C-O后可以执行一个normal命令,然后立即返回insert模式,省去了
用ESC的麻烦。
6. [I (fast grep )
[I显示文件中包含光标下
还有很多相关的命令::h include-search
7. object-select
iw, aw, ib, i], i} ... 都非常有用!看help吧
:h object-select
先写这么多,以后再补充吧。
例如你想把所有的"..."形式的串替换成'...'的形式
但引号里的内容不变
你就可以用
%s/"\(.*\)"/'\1'/来做
上面这个正则表达式"\(.*\)"里 \用来表示()是元字符
第一个在括号里的被匹配的串就可以被\1来代表, 以后依次是\2 \3。
顺便说一句,我到现在还不
知道怎么限制vim里正则表达匹配的贪婪算法。
------------------------------------
里面说的非贪婪匹配是 \{-},
也就是 %s/"\(.\{-}\)"/'\1'/g
\ 太多了可以用 \v,
%s/\v"(.{-})"/'\1'/g
详细
:h /\{-
:h \v
另外 和 perl 正则表达式的区别在 :h perl-patterns
把aaaaa.20300.2000.com 替换为aaaaa.com
~字符 ~~~~~数字和点
我用s/\(^.*)\(\.\d*.\)com/\1.com/
结果为 aaaaa.20300.com
请问有没有好点儿的办法?谢谢
☆─────────────────────────────────────☆
alphatan ( C ) 于 (Tue Aug 10 09:27:19 2004) 提到:
【 在 qiaolin (风儿) 的大作中提到: 】
: 把aaaaa.20300.2000.com 替换为aaaaa.com
: ~字符 ~~~~~数字和点
: 我用s/\(^.*)\(\.\d*.\)com/\1.com/
1. \(^.*\) 一下子把整个字符串吞进去了. \1 = aaaaa.20300.2000.com
2. 遇到com把 com从\1中吐出来. \1 = aaaaa.20300.2000.
3. 遇到.把com前面的\.吐出来 \1 = aaaaa.20300.2000
4. 遇到\d*, 再把随后的2000吐出来 \1 = aaaaa.20300.
5. 遇到\., 把.也呕出来了. \1 = aaaaa.20300
所以, 得到你要的结果.
可以用\{-}进行非贪婪匹配.
但为什么不直接把数字跟它们的点去掉呢?
s/[0-9.]\+//g
: 结果为 aaaaa.20300.com
: 请问有没有好点儿的办法?谢谢
☆─────────────────────────────────────☆
qiaolin (风儿) 于 (Tue Aug 10 09:36:27 2004) 提到:
谢谢大侠,有问题请教:
贪婪匹配的顺序是怎样的呢?
在这个例子中,先匹配第一个pattern,再从最后面的pattern一个一个“吐”出来?
【 在 alphatan ( C ) 的大作中提到: 】
: 1. \(^.*\) 一下子把整个字符串吞进去了. \1 = aaaaa.20300.2000.com
: 2. 遇到com把 com从\1中吐出来. \1 = aaaaa.20300.2000.
: 3. 遇到.把com前面的\.吐出来 \1 = aaaaa.20300.2000
: 4. 遇到\d*, 再把随后的2000吐出来 \1 = aaaaa.20300.
: 5. 遇到\., 把.也呕出来了. \1 = aaaaa.20300
: 所以, 得到你要的结果.
: 可以用\{-}进行非贪婪匹配.
: 但为什么不直接把数字跟它们的点去掉呢?
: s/[0-9.]\+//g
这里没有这样用是因为aaaaa也可能是a123a,可不可以用/w呢?
在查找、替换命令 使用以下正则表达式元字符,功能强大。
也可用在:g/命令中
& 代表最近匹配串
~ 代表最近替换串
. 任一字符
^ 行首 或 表示 非
$ 行末
\< 词首
\> 词尾
* 0次或多次
\( \) 分节指定与其中正则式匹配的部分,在替换时候可以用 \1 \2 \3 ... 引用匹配部
分
[] 表示选择
- 表示范围 ,例如 [0-9]代表数字,[a-z]代表小写字母 [^0-9a-zA-Z] 代表非数字和大小
写字母
\{m,n\} 前面部分的从 m 次 至 n 次出现,m n 为数值
\{m\} 精确m次出现
\{m,\} 大于等于m次出现
以下举几例子,欢迎大家提出问题来共同探讨。
1.在20列后插入串
:%s/^.\{20\}/&insert something here/g
2.把C++语言里 //注释 修改为 /* */ 格式
:%s/\/\/\(.*\)$/\/\*\1\*\//g
3.在建存储过程的sql文本里,在每个create procedure procname()
前加上drop procedure procname ; [ ]里输入的是一个空格和TAB键。
:%s/^[ ]*[cC][rR][eE][Aa][tT][eE][ ]*[pP][Rr][oO][cC][eE][dD][uU][rR][eE][ ]*
\([^(]*\)/drop procedure \1;Ctrl_VCtrl_Mcreate procedure \1/g
----------------
数字加减, CTRL-A, CTRL-X
----------------
vim里自动缩进一段
把光标移动到某个花括号,
按 =% 缩进整段。
把整段不按格式往外缩一个tab
>%
缩两个
>>%
往里缩
<%
注意%匹配很多东西,
如果你想从
#ifdef
缩到
#endif
也可如此
try :help c_CTRL-R
:help c_CTRL-D
....
常用命令:
------------------------------
CTRL-Z vim 切换到后台
:g/xxx 列出所有含 xxx 的行; 适合想到含 xxx 的某行, 但不知道行号,
/xxx 又太慢
q: q/ q? 编辑长命令时比较舒服, 执行按回车, 按 CTRL-C 再次进入
: / ? 原来的输入状态, 再按一次关闭.
CTRL-W= 所有窗口等高, 适合 diff 时自己移动了 window 大小
CTRL-Wo 等效于 :only
CTRL-Wc 等效于 :close!
gvim -u 用 NONE 的话必须大写, 可以用 nul 文件, gvim -u nul, 而且不
区分大小写
-s 执行脚本文件, 是 normal 时的指令, cmd 的命令要 :, 但不用加
-w 把所有按键记录 appedn 到指定文件中
-W overwrite
这 2 个适合不会 perl sed 的 vimer
--servername
--remote-silent 这 2 个搭配着用, 可以总在一个 vim 里打开新文件, 比如
gvim.exe --servername smarter --remote-silent test.text
命令太长, 可以自己 alias 一下(win32 下用 doskey 就可以)
再次选中 上次选中的内容, 用 gv
在选中的区域首尾跳动, 用 大写 O
:redi 把输出信息重定向, 比如 保存所有 set 选项到 剪切板
:redi @*
:se all
具体 :h redi
c\c++ 下常用的:
------------------------------
[[
]] 在 C 的 {} 形成的段落中移动 (在第一列 { 之间跳动,
一次一个函数,一个结构或类的定义)
[# 和 ]# 在 #if #else #endif 的上下位置间移动
[{ ]}
[( ])
[/ ]/ 在注释 /* */ 间移动
这样在这些块的中间位置, 就能迅速到块头和块尾
如果已经在这些行上, 如果不是到对应点,
会到上一级范围, 如 { 上按 [{ 到上一级
]} 则到对应点
(vim 里常用 [ 表示 "向上",
] 表示 "向下",
比如上面的例子, 以及 [i ]i, diff 时候的 [c ]c 等)
% 在 () {} [] #ifdef #endif /* */之间跳转
可以 :so $VIMRUNTIME/macros/matchit.vim
这样可以在 if endif
对 1 个块的操作, 具体 :h v_a
里面的 iX aX 什么的都很好用
ctags 用 -a 附加新 tags 到 ctags 文件后
--- 对 c
--- ctags -R --c-types=+px d:\mingw\include (etags)
--- 因为 ctags 确省不把函数声明作为 tag
--- 对 c++
--- ctags -R --language-force=c++ --c++-types=+px --verbose --extra=+q
extra=+q 用来增加生成 Class::member 的形式, 默认没有
这样就可以用 :ts CView::OnDraw 这种形式看
--- 因为 c++ 一些头文件不用 .h 所以要用 --language-force
--- 对 java
--- ctags -R --languages=java c:/jdk131/src
--- 要把 src.jar 展开
:che 检查 include 的文件在 path 中是否存在, 注意会递归验证
插入模式
------------------------------
insert 模式下的:
CTRL-W 回删一个 word, 具体 :h i_ctrl-w
CTRL-U 回删在当前行输入的内容
CTRL-R 用某个 reg 的内容
CTRL-E
CTRL-Y
0CTRL-D 这 2 个对缩进, 具体 :h i_0_CTRL-D
^CTRL-D
CTRL-C 退出 insert
另外, ascii 第 1 - 26 个对应的就是 CTRL-A 到 CTRL-Z
所以下面几个也常用
CTRL-H 对
CTRL-J 对
CTRL-M 对
不使用 ab: 输入 缩写 后, 按 ctrl-v 接着输入以后的字符
发信人: sysfree (虫), 信区: VIM
标 题: 插入模式下的命令汇总
发信站: BBS 水木清华站 (Wed Nov 17 14:36:29 2004), 站内
插入模式下有用的键盘命令:
(注意:以下命令都是在插入模式用的,也就是左下角要显示"--Insert--")
CTRL-[ or CTRL-C: 退出插入模式。如果嫌
CTRL-A: 插入先前插入过的内容。看起来比较有用,但是飘忽不定,很难把握。
CTRL-N/CTRL-P: 搜索匹配,自动完成单词(超级有用)。
CTRL-R: 插入寄存器内容。例如
CTRL-T/CTRL-D: 将本行缩进/去缩进,无论光标在什么位置
CTRL-Q: 当CTRL-V不能用时,可以试试这个。
CTRL-Y: 输入和上面一行相同的字符。有时候可能用的着。
CTRL-E: 输入和下面一行相同的字符。
CTRL-X: 进入CTRL-X模式。
CTRL-X模式基本上是用来自动完成的。vim的自动完成可以包含当前文件、头文件、tag文件、字典文件等。
CTRL-X模式中的主要命令:
CTRL-X CTRL-L: 整行自动完成
CTRL-P/CTRL-N: 在当前文件中自动完成单词
CTRL-I: 在头文件中查找匹配的单词
CTRL-]: 在tag中补全单词
CTRL-F: 自动完成文件名
CTRL-D: 在头文件中查找宏定义
以上命令都可以再紧跟CTRL-P或CTRL-N,表示继续向前或向后搜索。
例如:按CTRL-X CTRL-L补全了一行,但不是自己想要的,可以继续按CTRL-L查找,也可以按CTRL-P或CTRL-N继续查找。找到后如果再按CTRL-X CTRL-L将会把找到的那一行的下面的行也复制过来,很过瘾吧?
下面两个命令也在CTRL-X模式,但是不属于自动完成:
CTRL-X CTRL-E: 在插入模式下让屏幕往上滚一行
CTRL-X CTRL-Y: 同上,屏幕下滚一行
其它不常用的命令没有列出。欢迎补充。
去掉菜单 set go-=m
去掉工具条 set go-=T
去掉右边的滚动条 go-=r
去掉下边的滚动条 go-=b
4 最好的办法,编辑_vimrc.
加入set fileformats=unix,dos,mac
不管什么格式都可以识别了。按说vim可以自动转换的,不知道为什么
要自己加,我的是vim63 windows版。
你想要的是 'cscopequickfix' 这个选项吧?
首先,你要设置 'cscopequickfix' 这个变量,比如
set cscopequickfix=s-,c-,d-,i-,t-,e-
再打开 quickfix 窗口
copen
然后,比如你要找出所有出现 elephant 的地方,可以
cscope find s elephant
所有的结果都显示在 quickfix 窗口里面了,可以双击或者回车来选择。
发信人: ann77 (ann), 信区: VIM
标 题: Re: 请教如何将vim和编译器整合使用
发信站: BBS 水木清华站 (Wed Jul 7 12:49:16 2004), 站内
我做了一个试验,也许对你有帮助。
VIM和其他编译器一起工作的原理就是把
compiler 的stderr 重定向到一个临时文件中。
然后用 :cfile 打开这个临时文件,
用 errorformat 来解释临时文件的内容。
下面我的具体做法,
我是在 BASH 下。
$for i in * ; do echo "2:$i:$(head -n 1 $i)" ; done > x
生成一个错误文件,内容如下
2:scr:#!/bin/bash
2:screenshell:#!/bin/bash
2:view-data.py:#!/usr/bin/python
2:view-data.sh:#!/bin/bash
2:x:2:scr:#!/bin/bash
每一行的格式就是
行号:文将名称:错误信息。
然后用 vim
:set errorformat=%l:%f:%m
设定 errorformat 的格式, :help errorformat for more information
:cfile x
打开错误文件。
然后就可以想 make 出错的时候一样,打开每一个文件的第2行了。
我认为,你切换到了新的 compiler 后,你要做的事情就是
观察新的 compiler 的错误输出,编写一个新的 errorformat
就行了。
调试的时候,可以
$ make 2>temp-error-file
然后 vim 中
:set errorformat=?????
:cfile tmp-error-file
【 在 Charity (花无缺) 的大作中提到: 】
: 在RH下,我已经习惯了
: GCC + Vim + Make整合使用,
: Vim好像可以直接利用GCC编译器生成的Error List,
: ...................
标 题: Re: 如果查看一个10000000行的文件,如何提高速度?
发信站: BBS 水木清华站 (Fri Jul 23 11:03:37 2004), 站内
只要就是颜色高亮引起的, 只要syntax off 或是set filetype= 就可以了
这个在打开那些一行xml文件时尤其明显(xml可以set filetype=html)
【 在 thinelephant (严重消化不良) 的大作中提到: 】
: 主要是翻页的速度,如果向下一点一点的翻页速度还可以,但是向上翻页或者滚动就很慢,或者跳到文件末也要等一会。退出也要等一会。
: 呵呵,我已经找到解决方案了:只读打开,set compatible,syntax off。
: 速度不错,关闭也是瞬间。
: ...................
'd
d 表示0-9的数字,
代表最近打开的文件
发信人: windblown (......), 信区: VIM
标 题: Re: 问一个替换怎么写
发信站: BBS 水木清华站 (Tue Dec 14 10:08:39 2004), 站内
用sed吧
sed -e '
:REPEAT
s/\([[:alpha:]]*\) \([0-9]*\),/\1 \2\n\1 /
t REPEAT
' yourfile
【 在 thinelephant (严重消化不良) 的大作中提到: 】
: 每一行都是 \S\+ \(\d\+,\)*\d\+ 的形式,想把每行的逗号分割的数字展开成多行。
: 例如
: elephant 13,18,19
: ...................
vim 使用的一些小技巧。
在每行后面插入一行68个-号,用下面的命令:
:%s/\n/\r---------\r/
暂时没弄明白前面为什么用\n,而后面用\r。
vim的列模式。
在命令模式下,按v(or V)可进入可视模式,但是只能按行选择。要进入列模式,使用ctrl+v。
VI是VIsual
editor的意思,ex是他的“不可视”版本。如果多许多文件进行同样的编辑,用vim一个一个弄,就显得很麻烦。这种情况,我们可以采用ex进行自动
化处理。例如要把当前目录下所有的html文件编码由big5转换成gb2312,可以执行下面的脚本:
#!/bin/bash
for I in *.html;do
ex - $I<
:setfileencoding=gb2312
:wq
EOF
done
基于GTK2的gvim在gbk的locale下,菜单和编辑区中文字全乱码,而gb2312和utf-8 locale下均正常。解决办法:在自己的home目录下,创建一个.gvimrc文件,其中包括:
set encoding=gb2312
source $VIMRUNTIME/delmenu.vim
source $VIMRUNTIME/menu.vim
其原理似乎也是使用了gb2312的locale。gvim(GTK)本身不支持gbk?
vim具有的fold功能,可以把相连的某些行折叠起来,在需要的时候展开。
选中要折叠的行,zf命令创建一个fold并折叠起来,zr命令展开。z打头的很多命令都和fold操作有关,具体请:help z
假设你在编辑一篇html文件,可以使用如下命令对它进行排版:
:%!tidy -iq
tidy是一个html/xml格式化工具,同时还具有查错和转换功能。
vim对很多源文件提供彩色显示功能,能否把vim中显示的彩色发布到web上呢?下面的命令能帮你完成。
:TOhtml
使用y命令在vim中复制的时候,可以保存在a-z26个寄存器中,其实还有两个寄存器可以使用:*和+,放置在*寄存器中的文字
("*yy),可以通过鼠标中健粘贴到其它程序中,比如mozilla,+号寄存器中的文字("+yy),通过右健菜单中的paste粘贴出来。反之亦
然。(这一招学到smth上acura的,在此表示感谢!)
********************************************************************************
件,然后在里面加入一行就可以打开所有的编码的文件了(暗爽):
set fileencodings=ucs-bom,utf-8,cp936,big5,euc-jp,euc-kr,latin1
保存从新起动vim,打开文件 ok了。说到这里我感觉vim里面还有一个显示行号和语法高亮是我常用的功能,每次在 vim里面输入syntax on太他吗的烦了,我这种懒人是不能容忍这种事情发生的,算了,往里面在写两行字符,让他打开的时候自动的开启吧:
set nu #打开显示行号的功能
syntax on #打开语法高亮的功能
这样打
开一个源代码文件感觉就比较爽了,效果太好了,不好,这么正规的软件代码也有bug ,我改改,去除那个bug
section,我自己往里面写,输入代码,可是怎么不会自动缩进呀,这让我们这些人怎么能够忍受呀,好了,听说有个vim给写好的配置文件,是推荐的,
拷贝了直接使用,估计就可以了,在终端输入命令一条吧。
cp /etc/vim/vimrc /usr/share/vim/vim63/vimrc_example.vim
好了,就这样从新打开 vim,一切 ok 了,如果能有鼠标控制,有 menu 就更好了,我们继续添加,不就是网 .vimrc 里面加己行字吗,呵呵:
set mouse=a #加入鼠标支持
set wildmenu
这样就差不多了,基本上可以满足一般人的需求了,可
是我这种程序源的话可能在读源代码的时候会经常的在多个文件中间转换,如果每次都退出在用vim
打开的话很麻烦的,怎么办,分屏打开多个文件,这个可以,使用:new命令就可以,可以分屏的,但是我的可是15
的显示器,分分还有什么呀,还是想个其他的方法吧,能不能用一个简单的命令在不退出vim的情况下来回转换呀,答案是肯定的,伟大的
vim什么做不到呀。还是在.vimrc里面加入几句话,不过这才麻烦点,呵呵
if has(”unix”)
map ,e :e
else
map ,e :e
endif
保
存重新打开 vim,然后用 vim 打开一个源代码文件,在正常模式下输入,e 就会有一个框出来,上面罗列了当前目录下的所有文件,你用 tab
建来选择打开那个文件,太爽了。基本上 vim 的东西就这些了,还有的就是一些汉化的了,我在 linuxfans.org下载了 vim
的中文文档,解压安装了,使用的不错,我先去吃饭,回来继续。
********************************************************************************
vim tips 之五
vim设置自动格式化文本:
源码:--------------------------------------------------------------------------------
:set formatoptions=croamq
:help formatoptions 看帮助;
t 在文本宽度内,自动换行,对注释行无效;
c 对于注释,在文本宽度内自动换行,并自动插入注释前导;
r 在插入模式下,回车后自动插入当前注释前导;
o 在正常模式下,用o或O插入空行时,自动插入当前注释前导;
q 允许用"gq"格式化注释。但格式化不改变空行或只带注释前导的行。
m 对于255以上的多字节字符也进行断行。这对于每个字符就是一个字的亚洲文本特别
有用。
n 对于带. ) ] }的数字,如1., 1)等等,自动换行对齐;要求自动缩进选项ai打开。
例如:1. test
wraps.
2. test2...
********************************************************************************
具体的可以help看帮助
讨论到的自动缩进是 autoindent
主要是 c 代码等
拷贝粘贴 就在已经缩进的基础上再缩进 很不美
于是就可以 set noautoindent 解决
或者设置 set paste
具体 vim 网站有 Tips
Tip #330: how to stop auto indenting
********************************************************************************
摘要:vim的一个有趣的用法
如果想在vim里面达到这个效果,在vimrc中加入一下两行:
au BufWinEnter *. exe 'set list listchars=tab:\|\ '
au BufWinEnter *. exe 'command Seetab :set list listchars=tab:\|\ '
当你编程序时, 就会达到这个效果. 源自:
用法:
当你不想看到对齐线时 在vim的normal模式下 :set nolist
如果你想看到对齐线时 在vim的normal模式下 :Seetab
在
我们谈起Vim编辑器似乎只是觉得他只是一个类似于一个命令行方式的文本编辑器。而事实上不是这样的。Vim在窗口环境中也可以完美的完成我们的工作。在
窗口环境下,我们不仅可以使用那些在Vim文本方式下的命令来完成工作,而且还有许多的菜单和其他的选项。这些都使得我们可以完美的来完成我们的工作。
我
们要启动图形界面的Vim可以用下面的命令:gvim
file。这样就可以打开图形界面来编辑文本file。图形界面下的Vim编辑器的外观因你所用的操作系统的不同而有所不同,就是同样的操作系统也会因你
所使用的工具集不同(Motif,Athena,GTK)而会呈现不同的外观。而值得向大家推荐的是GTK版本的Vim编辑器,当然其他版本的也是可以来
完美的完成我们的工作的。
在Windows系统中我们可以在标准形式下用鼠标来选择文本,而在X
Window系统中我们也会有一个标准的系统来使用鼠标,但是这两种标准是不同的。然而比较幸运的是我们可以定制我们的Vim编辑器。我们可以使得我们的
Vim中的鼠标的行为看起来像是X Window系统中的鼠标的行为。下面的命令是设置鼠标的行为为X Window风格的鼠标行为::behave
xterm。而下面的命令则是使得鼠标的行为是Windows风格的行为::behave
mswin。在UNIX和Linux系统中的鼠标风格是xterm风格,而在Windows中的鼠标风格是在安装过程中选择的。为了控制鼠标的行为,命
令:behave有以下这些选项:
Setting for Setting for
Option :behave mswin :behave xterm
'selectmode' mouse,key (empty)
'mousemodel' popup extend
'keymodel' startsel,stopsel (empty)
'selection' exclusive inclusive
xterm的鼠标风格的行为主要有以下一些:
左键: 移动光标
拉动左键: 在可视化模式下选择文本
右键: 选中光标处到右键点击处的文本
中键: 在光标处粘贴选中的文本
Windows的鼠标风格的行为主要有以下一些:
左键: 移动光标
拉动左键: 在选择模式下选中文本
中键: 将系统剪切板中的文本粘贴到文件
(注:其中的S为Shift键)
其他的一些特殊的用法:
Shift+左键: 向前搜索光标处的文本
Shift+右键: 向后搜索光标处的文本
Ctrl+左键: 跳转到以光标处的文本为名字的标记(tag)处
Ctrl+右键: 跳转到前一个标记处
在
图形界面的Vim编辑器还有一个有趣的特征,那就是当我们点开一个菜单时就会发在子菜单的第一行有一条虚线,点击此虚线就可以将这个菜单移其他的地方。关
闭后Vim的菜单结构又恢复到正常的状态了。在GTK版本和Windows版本中的图形界面的Vim还有一个工具栏,这些工具可以快速的完成我们的工作。
vi编辑器的学习使用(一)
vi编辑器是Unix的世界中一个相当强大的可视化编辑器,有人曾这样的说过在世界上有三种人:一种
是使用Vi的,另一种是使用是Emacs的,剩下的是第三种人。由此可以看出Vi和Emacs的强大。在有关Linux的论坛中关于Vi和Emacs的论
争也是一直不断的。现在看来这样的论争也实在是没有办法的,这两个编辑器是同样的强大,同样有不同的人在支持。在个人看来就是同时喜欢这两个的。然而他的
这种强大也是要会付出一定的代价,他的学习和使用也是相当的复杂的,在学习的起点常常会面临着一个巨大的学习困难。但是只要过了这样的一段时间你就可以来
体会Vi的强大了。
一 Vi的启动与退出在现在的Linux世界中还有一个发行版本被称为是Vi的改进版本,所以被称为是Vim,也就是Vi Improved的意思。在现在的一般的Linux的发行版本中常常是Vim的。要启动Vi可以终端窗口输入vi或是vim,这样就可以终端窗口打开一个 Vi的编辑窗口。或者是输入gvim,这样就可以打开一个类似于gedit这样的文本编辑器,他有一些菜单,但是大部分的功能仍是通过命令行的方式来完成 的。在vi中有两种模式:一是命令模式,一是编辑模式。命令模式是用来输入命令行来完成工作的。而编辑模式是用来编辑文本的。在两种模式中切换可以通过 Esc来完成。在我们完成了文本编辑以后可以这样的来退出:
:q 这是退出的命令,如果你已经做过了改动,那么就会提示错误。
:q! 这也是一个退出命令,与上一个不同的是,我已经做过了改动,但是我想放弃这些改动,从而用这样的命令。
:w 这是文件写入的命令,但是执行完这个命令后并没有退出vi.
:wq 这个命令的意思是保存并退出
二 Vi的基本编辑命令在启动了Vi以后是在命令模式的,这是可以输入i(insert)进入插入模式。这时会在Vi窗口的下端显示出你这时的状态。这时你就 可以来输入文本了。在这样的情况下,你可以用Backspace来Delete来删除一个字符。用方向键来控制光标。其实在知道了这样的几个命令后就可以 用来编辑文档了。但是这样的几个命令并不能保证你能高效的来完成你的工作。而事实上在命令模式下我们用键盘来移动光标而不用将手离开键盘去按方向键,这样 就可以大大的增强你的编辑速度。
我们可以用h(left),j(down),k(up),l(right)这几个键来移动光标。我们可以将光标放在一个字符上同时按下x键来删除这个字符。
我们可以将光标放在某一行同时按下dd,这样就可以将这一行删除。
当然有的时候也许我们做了一些事情,不过我我们觉得以前的要更好一些,我们想要恢复到以前的状态,在这样的情况下我们可以u和U这两个命令。u要撤销上一次的修改,而U将是撤销所记录的所有的修改。
而有的时候我们觉得现在的工作要好一些,我们希望撤销刚才所做的撤销工作,也就是我们要重做这些工作,这时我们可以使用CTRL_R命令来达到我们的目的。
有时我们可以使用新增的命令,使用a和A来完成这样的工作。a在当前光标所在的字符后面进入插入状态,而A是在一行的末尾进入插入状态。使用这两个命令可以方便我们进行文本的插入操作。
在vi的编辑模式中,是将回车换行看作新的一行的开始。有时我们希望新插入一行,这时可以使用o和O这两个命令来完成。o是在文本的下面新增一行并进入插入模式,而O是在文本的上一行新增一行并进入插入模式。
有了这些命令,现在的我们就可以比较方便的来完成我们的文本编辑工作了。但是有时候得到在线的帮助对于我们来说显得更为重要,要得到vi的帮助,可以在命令的模式下输入:help,这样就可以得到vi的在线帮助了。要想退出帮助,可以输入退出命令,:q.
为得到更明确的帮助,我们可以明确的指明我们所需要知道的内容。例如我们想知道关于x一些更详细的内容我们可以输入:help x.我们要想得到其他的帮助,我们就可以这样来得到我们想要的帮助。
在vi中可以使用数字和命令组合的方式得到新的命令,例如3h,这样就可向左移动3个字符。同样可以使用数字和其他的移动键进行组合来达到快速移到 的目的。也可以是数字和其他的命令组合形成新的命令,例如3x就可一次删除3个字符。为了我们更快速的掌握vi的使用,vi本身也提供了一个学习的教程, 只要你能耐心的做下来,我想使用vi对你来说应不再是一件难事了。进入vi的学习教程,可以在终端输入vitutor.这样就可以进入vi的学习教程,为 了得到更多的帮助信息,可以在vi的窗口内输入:help tutor.这样就会得到更多的关开Tutor的帮助信息的。