Chinaunix首页 | 论坛 | 博客
  • 博客访问: 576997
  • 博文数量: 226
  • 博客积分: 10080
  • 博客等级: 上将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-26 11:15
文章分类

全部博文(226)

文章存档

2011年(5)

2010年(64)

2009年(99)

2008年(37)

2007年(21)

我的朋友

分类: 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 :s///c for replacing only confirmed pattern locations.

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/$/./|'';/./-1j|$d
         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/$/./|'';/./-1j|$d

|是两个命令风格符号

:v/./$s/$/enter./
'';/./-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 :silent noh,这样就可以使用Ctrl-N来关闭高亮显示。

posted on 2004年10月05日 5:19 PM
1. 已经在编辑状态(insert mode)了,如何快速执行 normal mode 的命令?
在编辑文本时,需要快速定位到某个位置,如下一个 d 的位置,难道要
、fd、i 这般繁琐吗?
其实,使用 Ctrl-O 就可以临时切换到 normal mode, 执行一个命令后自动返回 insert mode。
于是上述命令序列可以改为:
Ctrl-O、fd 即可。
Ctrl-O 要按两个键呢,很麻烦,于是来个 keymap
" make ` functions in insert mode
inoremap `
nnoremap ` i`

在 normal mode 下按 ` (左上角那个),会正常插入 `,
而在 insert mode 下则相当于按 Ctrl-O,
于是上述命令序列又可简化为
`fd 即可。
在 insert mode 想粘贴剪贴板内容时,可以输入 `P,爽吧?
这样就可以在 insert mode 下天马行空,不用再按 和a 切来切去了。

2. vim 的剪贴板怎么怪怪的?
用 y 命令拷贝的文本怎么不能在 X/Windows 的其它应用中使用呢?
事实上,vim 有多个所谓寄存器来寄存剪切的内容。
平时是不是只用 y 和 p 命令呢?
其实这时使用的是 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 :exe "norm! kly0jPD"

这是在编辑模式中使用的,怎么个用法?举个例子吧(括号内是我的注释):

(在编辑模式下,先输入这句:)
     this_object.set_height(1.80);
(                    ^)
(                    |)
(用啊,空格啊移到箭头所示处,即h处,然后按Ctrl-F)
(自动补全成:)
     this_object.set_
(于是你可以继续输入"weight(100);" 了)

不知大家明白没有,不明白的先试试:)

4. 我想注释一堆 C++ 代码
当然,这有许多种我不知道的方法,我的通用方法为,先在配置文件里添加:
vnoremap . :normal .

呵,一句就够了,示例如下:

假设你有如下几行代码需要注释:
this_object.set_height(1.60);
this_object.set_weight(100);
this_object.run();

你先移到第一行,输入 I// (就是ESC键),将第一行注释。
然后移到第二行,按 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-N, cont-N

(请大家不吝赐教,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 i_r

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 as a {lhs}.  It is unused and fits better to the insert logic of VIM, although it saves less key strokes.
reiss_david AT yahoo DOT com, July 29, 2002 10:30
I use
:map gt i$r
:map gb a$r
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 (, blockwise-visual).
However, this does not work conveniently on the last column
when  lines are not of equal length. marks then a block which
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 :call SwitchShowMenus()
: 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)
向下查找光标下(或附近)的。向上找用#。g*查找则不限制whole word。

2. C-R (magic insert)

在insert模式下,C-R (register) 插入register里的内容,一个有趣的reg是"=".
假设你想输入123K的具体字节数,不用打开计算器,试试这个“=1024*123”,
“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显示文件中包含光标下的所有行。我常用来浏览某个id在程序中的引用情况。
还有很多相关的命令::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

: 将光标下的keyword拷贝到命令行缓冲区中
*: 从系统剪贴版中拷贝内容
=: 表达式求值
": 拷贝buffer中的内容
....

: 命令和文件提示
常用命令:
------------------------------
    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 <\tr> 之间使用

    对 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  对 vim 里叫
        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: 插入寄存器内容。例如*会插入windows剪贴板的内容。:reg命令查看全部寄存器。
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<:set encoding=big5
: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 =expand(”%:p:h”) . “/”
else
    map ,e :e =expand(”%:p:h”) . “\”
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的帮助信息的。


vi编辑器的学习使用(二)
vi学习笔记之二在上一节的学习中,我们只是学习一些使用vi进行文本编辑的基本的命令。有了这些的 基本命令我们就可以完成一般的文本编辑任务。在这一节中我们要学习一些其他的一些编辑命令,这些命令将包括其他的一些光标移动命令,如何在一行中快速的查 找我们想要的东西,其他的一些文本删除和更改的命令,键盘宏和特殊字符的输入。在vi的编辑中,我们可以有多种的光标移动命令:我们可以用w命令向前移动 一个字符,用b命令向后移动一个字符。就像其他的vi命令一样,我们也可以用数字来做前缀从而组成新的命令,来快速的移动。例如4w就是向前移动4个单 词,而5b则是向后移动5个单词。而我们在编辑的过程中又如何来快速的移到一行的开始或是结尾处呢?在vi中$和^可以来完成这样的工作。$可以使光标移 到一行的结尾处,而^可以使光标移到一行的开始处。$命令可以和数字进行组合形成新的移动命令,而^也可以和数字进行组合,但是组合后组成的新的命令中数 字却不起任何的作用。在我们的文本编辑中我们就会移动光标是我们经常要做的事情,但是我们很快就会发现查找我们要找的字符串也是我们经常要做的一件事。那 么如何在文本编辑中快速的查找到我们想要的字符呢?在vi的编辑命令有几个这样的小命令可以帮助我们来完成这样的工作:f是向前搜索的命令。例如fx是向 前搜索字母x.利用f向前搜索的命令我们也可以快速的移动到指定的位置。而F是向左搜索的命令,也就是向后搜索。例如Fx是向后搜索字母x。与f和F这两 个命令相类似的是t和T这两个命令。t命令类似于f向前搜索命令,所不同的是t搜索到时并不是将光标停在目标字符上,而是停在目标字符的前一个字符上。和 他相反的就是这个F命令。当然这几个命令都可以和数字组合来形成新的命令来完成我们的工作。在搜索的工作过过程我们可以使用ESC来退出搜索而开始我们新 的工作。在我们的工作中常常要求我们移动到指定的行,那么我们如何来做到这一点呢?我们当然可以使用数字和方向键组合来完成。虽然这种方式不够快速,但是 确实可以来实现。而在vi中提供了一个新的命令来完成,那就是G。例如3G可以使我们快速的移到第3行。而1G则可以使我们移到文章的最顶端,而G则是定 位到文章的最后一行。那么在vi的编辑中我们又如何来知道我们在第几行呢?我们可以使用:set number来叫vi加上行号,这样我们就可以很容易的知道我们所在的行号了,取消行号的命令为:set nonumber。那么在没有行号的文章中我们又如何来知道我们所处在的位置呢?我们可以使用ctrl+G命令来知道。这个命令可以清楚到告诉我们总共有 多少行,而当前我们又在多少行,以及所占的百分比等信息。在我们进行编辑的过程中我们可以使用CTRL-U和CTRF-D来进行上下的翻页。当然这样的功 能也可以通过功能键来实现。在我们的文本编辑过程中另一件我们要常做的事情就是文本的删除了。我们可以使用dd来删除一行,我们还可以使用dw来删除一个 字符。删除的命令操作d是一个相当灵活的命令,我们可以用他来进组合来完成工作。例如d3w则是一次删除3个字符,而3dw则是指一次删除一个字符,而这 样的操作进行3次,即总的是也是删掉3个字符。而在d$则是删除从当前位置到本行结束的所有字符.也d命令相类似是的c命令,这是一个更改的命令,所不同 的是他在删除一个字符的同时进入插入状态,这样我们就可以进行另外的文本操作了。另一个有兴趣的命令则是.命令。.命令可以使vi重复执行刚才执行的命 令。在我们进行文本编辑的时候,有时要用到合并行的命令,也就是将几行合并为一行,这时我们可以使用J命令。这个命令可以将本行和下一行合并为一行。当 然,就像大多数的Linux命令一样,我们可以使用数字来使几行合并为一行。例如3J就可以将当前行下的三行(包括当前行)合并为一行。那么我们又如何时 来做替换文本的工作呢?我们可以使用r的命令。例如rx就可以当前光标下的字符替换为x。我们当然也是可以用数字来组合以形成新的命令来进行工作,例如 5rd就是将当前光标以后的5个字符替换为d。有时我们要进行大小写的转换,这时我们就可以用~命令。这个命令可以实现在大小写的转换。在vi中一个比较 有趣的东西便是键盘宏了,这个可以使我们实现多个命令的记录,有时这样可以高效的完成我们的工作。例如我们现在的文本是 stdio.h stdlib.h math.h 但是我们都知道在C语言的编辑中我们所需要的是 #i nclude #i nclude #i nclude 如何来做到?如果你有足够的耐心可以一句一句的来加,但是在这里我们可以使用键盘宏来完成我们的工作,这样我们就可以体会到他的强大之处了。开始输入 qa.其中的a是一个宏的名字,我们可以用任何我们喜欢的字母来代替,q是开始录制宏的命令标志。这样我们就可以开始我们的宏输入了: ^ 移到一行的开始 i#i nclude < 在一行的开始插入#i nclude < $ 移到一行的结束 a> 在结束处加入> j 移到下一行 q 结束宏的录制这样当我们要使用宏时就可以输入@a,这样就可以执行这个宏了。我们还可以在执行命令前加上数字来告诉vi执行几次。这样我们就可以快速的完 成我们的一些工作了。在vi的编辑中我们还可以输入一些由平常的键盘不可以输入的字符,有关这样的信息我们可以输入:help digraphs得到更多的信息。 (注:在vi中我们通常所指的一行是以回车做为标志的,即只有输入回车才算是一行的结束,从而开始新的一行)
vi编辑器的学习使用(三)
vi 学习使用笔记之三我们在使用vi进行编辑文本的时候常作的一件事就是要在所编辑的文本中进行查找。如何快速的查找到我们想要的东西呢?在vi中我们可以使 用f,F和t,T来进行向前或是向后查找。除了这些命令,我们还可以使用其他的一些命令来快速高效的完成我们的工作。在vi的编辑操作中,我们可以使用 /string命令来查找字符串string,打下回车后,光标就能跳到正确的地方。在这个命令中/后的字符是我们想要查打的字符,而回车键则表明了命令 的结束。但是有时我们所想要查找的字符具有特殊的意义,例如.*[]^%?$~等等,那么我们又如何来查找这些具有特殊意义的字符呢?这时我们可以使用\ 放在所要查找的字符前,这样再使用/来查找就可以正确的查找了。有时我们在进行查找操作时想要查找的内容并不仅在一处,我们想要做的是在整个文章中进行查 找。那么我们又如何来进行我们刚才的查找命令呢?我们可以这样的来做:/。这样我们就可以继续我们刚才的查找操作了。在这里回车是命令结束的标志。我们还 可以使用n命令来继续刚才的查找命令。这两个命令都能达到同样的效果,但是显然用n可以有更少的键盘操作。偷懒嘛:)在vi中他还具有记录查找命令历史的 作用,这样我们就不用输入刚才输入的查找命令了,而是只需要在他所记录的查找命令进行一下查找就可以了。例如你刚才做过的三次查找分别是:/one, /two,/three.而现在输入/,然后按方向键的上或是下我们就看到刚才查找的内容显示在vi的下面,这时只要打下回车我们就会找到我们要找的内容 了。当然在vi中还在一些其他的查找选项,例如我们可选择高亮的显示查找的文本,命令为::set hlsearch,关闭高亮显示的命令为::set nohlsearch.如果也想同时关掉刚才高亮显示的结果,可以用这样的命令::nohlsearch。在我们进行查找的选项中,我们还可以有这样的命 令::set incsearch。在我们打开这个选项以后,我们在进行查找时就会显示出不断匹配的过程。例如你想查找的内容是include,在打开这个选项后你可以 输入/i,光标定位在i上,再继续输入n光标定位在in上,如此直到查打到我们所要求的。关闭这个选项的命令为::set noincsearch。一般来说我们在进行查找时总是在向前查找,那么又如何来向后查找呢?我们可以使用?命令。这个命令就是向后查找的命令。而还有一 个命令N是逆向查找的命令,他可以实现立即反向查找。(注:在查找的时候我们还可以用一些其他的表达式来进行查找,例如/^string是在开头进行查 找,而/string$是在一行的末尾进行查找。不过看书我的理解是这样的,不过总是试验不成。而/c.m则是查找所有第一个字母为c,而第三个字母为m 的字串,由此可以实现一些查找的匹配
vi编辑器的学习使用(四)
vi学习使用笔记之四我想我们在接触了vi以前一定会用一些其他的 编辑器,在那些的编辑器里复制,剪切和粘贴都是最平常的操作,而在vi中这些操作也是同样的存在的。在vi编辑器有一个注册的概念(concept of register),正是这个概念使我们可以时行多次的剪切和粘贴等的操作。在一般的编辑器中我们被限制只有一个剪切板可以用,而在vi中我们最多时可以 有26个剪切板可以来使用,这样就会大大的提高我们的完成工作的效率。而在vi中更是有一个相当强大的功能那就是他可以同时处理多个文件。如此强大的功能 我们又来如何的操作呢?在vi的编辑中我们可以使用d或是x来删除文本,但是经过这样的操作所删除掉的文本并没有被vi所丢弃,而是被保存起来。我们可以 使用p命令来粘贴刚刚所删掉的内容。下面我们可以来试一下看一下他是如何工作的。我们可以在vi中随意的输入几行,然后我们移动到其中的一行,用dd命令 来删掉其中的一行,这时我们就不会再在vi中看见他。如何叫他再回来?我们可以将光标移到任意的地方,然后用p命令,我们就会看到刚才被删除掉的内容又回 来了。同样我们使用x命令来删除的东西也可以这样的粘贴回来。所不同的就是我们用dd来删除一行再用p命令时是在当前光标的下一行粘贴,而删除一个单词再 用p命令来粘贴时是在当光标处粘贴。有了这样的命令有时我们就可以来处理我们输入错误的单词了。例如我们不小心将the输入成了teh,这时我们可以将光 标移到e的位置,用x命令删掉,再用p命令粘贴回来,这时我们就会发现现在的输入正是我们想要的输入了。p命令可以在一个文件中使用几次,每一次都可以将 刚删除的内容重新粘贴在我们所希望的地方。当然这个命令也可以使用数字做前缀来明确的指出所要执行的次数。在使用vi进行文本编辑的过程中我们还可以对某 一行进行标记,做法为我们将光标移到某一行,用命令ma来进行标记。在这里m是标记的命令,a是我们对这一行所做的标记的名称,当然我们也可以使用其他的 标记名称,必竟我们是有26个字母可以用的嘛:)。在做了这样的标记以后我们可以快速的移到被标记的地方,‘a就可以使我们快速的移到刚才我们所做标记的 地方。这里’是单引号,这时我们就会移到被做标记那一行的行首。我们也可以使用`a来移到我们所做标记的地方,这里`是反引号,也就是数字键1左边的那一 个,不要弄错了噢:),这时我们就会移到所做标记时光标所在的位置,可以说是更精确啊。这也是这两个命令的不同之处。在进行文本编辑时我们可以列出当前所 做的所有的标记。命令为 ::marks。这时vi就会列出当前的所有的标记。当然如果我们将做了标记的那一行删除的话所做的标记也就不存了。我们用标记不仅可以快速的移到做了标 记的行,而且还可以用标记来删除掉一行,例如我们在某一行用ma做了标记,然后我们移到这一行的底部,这样我们就可以用在d‘a来删掉这一行。可以说这也 是标记命令提供给我们的方便吧。在vi中还有一个命令可以提供复制的操作,那就是y命令。yy命令可以复制一行,然后我们可以用p命令来粘贴。这时我们也 可用标记命令来组合使用,我们可以在一行用ma标记此行,然后将光标移到这一行的底部,用y’a命令就可以来复制这一行了。然后到我们所希望的地方用p命 令来粘贴。我们也可以使用Y命令来复制一行,或是用数字做前缀来明确的指明复制几行,然后用p命令粘贴到我们所希望的地方。在vi中还有一个比较有趣的命 令便是!命令。这个命令告诉vi编辑器我们要来运行一个系统命令,这时vi就会将以后的输入做为一个命令来运行,运行的结果也就是输出将替代当前光标所在 的行的内容。例如我们在 Linux中知道sort是一个排序的命令,他是将一个文件或是一些输入进行排序后输出到屏幕或是其他的文件。那么我们想对vi中的内容进行排序来如何做 呢?这时我们可以将光标放在文本的开头的一行,输入!10G,这时vi就知道要到10行,也就是我们要操作的内容是第1行到第10行,这时在vi的下端就 会显示出!,这时我们就可以输入命令了,sort。也就是我们要输入的完整的命令应为:!10Gsort。这样回车以后vi就会对文本中的10行进行操 作,将操作的结果替换掉现在vi中的文本来显示。而!!是在一行运行命令,并且输入的结果为当前行的内容。例如我们输入!!ls,就会将ls的执行结果显 示在vi中,并且是当前的内容,如果此行原先有内容将会被替换掉。如果我们完成一个文件的编辑而要开始一个新的编辑时我们最平常的做法就是退出当前的文件 而重启vi开始一个新的编辑。事实我们可以直接在vi中输入:vi file而开始一个新文件的编辑。如果当前的文件你没有保存,vi会给出警告的信息,这时你可以输入:write来保存当前的文件。你也可以 用:vi!file强制开始一个新文件的编辑。与vi相类似的一个命令是:view,所不同的是他以只读的方式打开一个文件,这时vi会给出警告信息,但 是你也可以进行修改,只是你不能进行保存,如果你要保存,vi就会给出提示。当然在这样的情况下你可以用命令:write!来强制保存。我们还可以使用 vi来编辑多个文件。我们可以在终端输入vi file1 file2 file3,这样我们就可以来编辑多个文件了,在默认的情况下vi来显示第一个文件,如果要切换到下一个文件我们可以输入:next,这样我们就可以切换 到第二个文件了。如果你没有保存,vi会给出提示信息,这时也就不可能切换到第二个文件了。这时我们可以输入:write进行保存然后再切换到第二个文 件,或者是我们输入:write:next.来保存后再切换到第二个文件。或者是我们可以用:wnext来简写这个命令。当然我们也可以用命 令:next!来强制切换到第二个文件。当然这样你所做的改动也就会丢失掉。为了避免这样的情况,我们可以打开vi的自动保存功能。:set autowrite.这样我们就不会为没有保存而收到提示信息了。关闭自动保存的命令为::set noautowrite.当然next命令也可以用数字做前缀来指明所要执行的次数。如何来确定我们在编辑哪一个文件呢?我们可以用这样的命令来明确我们 所编辑的文件::args.这个命令会显示出我们所打开的文件,同时会显示我们正在编辑的文件。如果我们想要回到上一个文件我们可以用这样的命 令::previous或是:Next.如果你要保存当前的文件并切换到前一个文件可以用这样的命令::wprevious或是:wNext.如果我们要 编辑第一个文件我们可以用:first或是:rewind来快速的切换到第一个文件,同理如果我们要编辑最后一个文件我们可以用:last来快速切换。如 果我们在一个文件中进行一些改动,再切换到另一个文件中进编辑,这时我们就可以用CTRL_^来切换这两个文件。
vi编辑器的学习使用(五)
在 使用vi进行文本编辑的时候我们也可以打开多个窗口进行编辑。这也正是vi编辑器的强大这处。那么我们如何来打开多个窗口进行文本编辑呢?我们又如何在多 个文本窗口中进行切换呢?如何来控制窗口的大小呢?在vi编辑器还有一个缓冲区的概念,利用缓冲区我们可以进行多文本的编辑。打开一个窗口最简单的方法就 是下面的命令::split。输入这样的命令后vi就会将当前的窗口平分为两个。并且在这两个窗口中显示的是同一篇文章。如果你在其中的一个窗口进行文编 辑,那么另一个窗口也会同步的显示出你所做的工作。如何在两个窗口中进行切换呢?在gvim中要方便得多,只要用鼠标就可以进行窗口的切换。而在vim中 则需要用命令来实现。CTRL_Ww这个命令可以实现在两个文本窗口中进行切换。切换窗口还有另外的命令:CTRL_Wj 可以将光标定位在下一个窗口中,而CTRL_Wk可以将光标定位在上一个窗口中。如果想关闭 一个窗口可以用命令ZZ或是:q.当然了CTRL_Wc也可以做到同样的事情。我们打开一个窗口一般并不是要在两个窗口中显示同一个文件,我们常常需要的 是在两个窗口中显示两个文件来加快文件编辑的工作。如何在新窗口中打开一个文件来进行编辑呢?我们可以用这样的命令::split file.这样我们就可以在另一个窗口中打开文件file开始我们的编辑工作了:)。那么我们如何来控制窗口的大小呢?我们在输入split命令时可以带 上一个参数,这个参数 也就指定了打开的窗口的大小。例如我们可以这样的输入::3 split file。这样我们就可 以在一个新窗口中打开文件file,而这个窗口的大小有三行。当然我们也可以将这个命令中的空格去掉,也就是写成::3split file这样也可以达到同样的作用。与split命令相类似的一个命令就是:new命令。所不同的就是split命令打开一个新窗口,但是在两个窗口中显 示同一个文件,而new命令则是打开一个新窗口开始一个新文件的编辑.我们还可以打开一个新窗口,在这个窗口中打开一个文件来读。命令为:sview。这 个命令是:split和:view这两个命令的组合。在这样的多文本窗口中进行操作时我们常做一个工作就是要改变窗口的大小。可以使我们来改变窗口大小的 命令为: CTRL_W+这个命令增大窗口,默认增量为1 CTRL_W-这个命令减小窗口,默认值为1 CTRL_W=这个命令可以将几个窗口的大小变得相等。另外还有一个命令countCTRL_W_可以使得当前窗口变得count这样的高。如果没有指定 count将会使得当前窗口变得尽可能的最大。 :buffers 这个命令就会列出当前的编辑中所有的缓冲区状态。在这个状态列表中,前面的数字就是缓冲区的数字标记,第二个标记就是缓冲区当前的状态,而后一个则表明与 空上缓冲区所关联的文件名。他的一些状态是这样的: - 非活动的缓冲区(Inactive Buffer) h 隐藏的缓冲区(Buffer is hidden) % 当前的缓冲区(current buffer) # 交换缓冲区(Alternate buffer) + 文件已经被修改如果我们要选择一个缓冲区我们可以用这样的命令::buffer number number就是缓冲区状态列表中所显示出来的数字。我们也可以用文件名字来选择缓冲区: :buffer file 关于缓冲区有一些有用的命令可以快速的完成我们的工作:我们可以用下面的命令来分割当前的窗口开始编辑一个缓冲区::sbuffer number 如果我们指明了数字,那么当前窗口就会显示数字所标记的那缓冲区中的内容,而如果没有指明数字,那么就会利用当前的缓冲区。当然这个命令我们也可以用文件 名来做为参数进行操作。对于缓冲区还有一些其他相关的命令: :bnext 到下一个缓冲区 :count bnext 到下一个缓冲区执行count次 :count sbnext 命令:split 和 :count bnext组合形成的命令 :count bprevious 到前一个缓冲区count次 :count sbprevious :count bNext 与:bprevious作用相同 :blast 到最后一个缓冲区 :brewind 到第一个缓冲区
vi编辑器的学习使用(六)
vi编辑器学习使用之六在现在的 vi版本,或者是说是在vim中,与其先辈区分开来的一个特征就是现在的版本中有一个可视模式。这种可视模式可以使你加亮一个文本块然后整体进行命令操 作。例如你可以用高亮显示出一个文本块,然后用d命令来删除这个文本块。这种可视模式与其他的编辑相比的一个好处就是你可以在做改动以前看到你的操作对于 所编辑的文本产生的影响。那么我们如何为用这种有趣的可视化模式来进行我们的文本编辑工作呢?要进入可视化模式,我们可以输主命令v,这样在vi的状态行 就会显示我们已经进行可视化模式了。在这样的模式下,我们移动光标,那么在光标起始的位置和光标现在的位置之间的文本都会以高亮显示的。这时我们可以对这 些高亮显示的文本整体进行命令操作,例如这时我们可以输入d命令,那么这些高亮显示的文本就会被删除掉。一般来说可以化模式可以具体的分为三种可视化模 式,一种就是我们刚才用v命令进入的所谓的字符式可视模式(character-by-character visual mode)。在这种模式下,我们在进行文本选择以高亮显示时是以字符为单位的,我们可以一个字符字符的来选择。而第二种就是所谓的行可视化模式 (linewise visual mode),这时我们可以输入V命令来进入这种可视化模式。这时我们所进行的操作是在以行为单位来进行的。还有一个命令可以使我们进入可视化模式,这就是 CTRL_v,这就是我们所要说到第三种可视化模式,他可以使一个矩形内的文本高亮显示,然后以这些文本为整体进行编辑操作。在可视模式下我们也可以得到 一些相关的帮助信息。当然在输入命令时要在所希望帮助的名称前有v_做为前缀。例如我们想得到一些关于在可视模式下进行删除操作的命令,我们可以这样的来 得到帮助信息::help v_d 当我们要退出可视化模式时,我们可以按ESC键退出。当然CTRL_c也可达到同样的作用。与ESC作用相同的还有CTRL_和CTRL_N. 在可视化模式下我们可以进行各种各样的编辑操作。如d命令可以删除那些高亮显示的文本内容,而D命令只是来删除一行,哪怕这一行中只有部分文本是高亮显示 的。与d和D命令类似的是复制y和Y命令。y命令是将高亮显示的文本复制下来,而Y只是将一行文本复制下来。c命令可以将以高亮显示的文本删除掉然后进入 编辑模式,而C命令的作用与其相类似,所不同的只是C命令只是删除一行文本。我们还可以利用可视化模式将几行文本合并为一行。J命令可以将高亮显示的文本 内容合并为一行,同时以空格来区分各行,而如果我们不希望看到这些空格,我们可以使用gJ命令。我们在可视模式下进行文本编辑时也可以进行可视化模式的选 择和切换。你可以在任何情况下进行这种切换,而切换的做法只是简单的输入那种可视化的命令操作。例如现在我们在字符模式的可视化模式下进行操作,而现在我 们想切换到块模式的可视化模式,这时我们只是要简单的输入CTRL_v可以了。当然我们也可以先用ESC来关闭当前的可视化模式,然后再选择我们所希望的 可视化模式. 对于程序员来说似乎这种可视化模式会有更大的用处,我们可以用一种可视化模式来高亮显示文本,然后用>命令来进行文本的缩进,我们还可以用< 命令来进行相反的缩进。我们更可以用CTRL_]跳转到某一个函数定义的地方。我们还可以利用可视化模式的高亮文本进行做法关键字用man命令来得到更多 的信息。当然这必须是man可以查找得到的内容对于可视化模式的文本编辑还有一个有趣的现象,这个主要的表现在CTRL_v所定义的文本块内。例如我们用 这个命令来定义了一个文本块,然后输入Istring,这个命令中I是插入文本的命令,string是我们要插的文本,而Esc则是结束插入操作的命令。 这时就会看到我们所输入的文本显示在文本块的左侧,也就是开头的地方,当我们结束插入操作时我们就会惊奇的发现我们所输入的文本也会同时出现我们所定义的 文本块内所包含的其他行的开头部分。同样当我们用c命令来操作时我们也会发现类似的情况。当然了,在用c这个命令进行操作时你所输入的文本应不超过一行, 否则的话将会只有第一行的文本会被改动。而C命令也会有相类似的情况。我们也可以类似的来得到一些关于块操作的命令帮助:例如::help v_b_r
vi编辑器的学习使用(七)
vi编辑器学习使用之七
vi是一个强大的编辑器,他不仅可以用来处理我们平时的文本工作,他还可以 用写程序文件。在vi中有许多命令可以方便的完成我们的程序处理工作。在用vi进行程序处理时,vi充分的显示出来了他的强大之处,他可以实现在语法加亮 显示,实现自动缩进,实现括号匹配,还可以在程序中实现查找和跳转。
我们可以用这样的命令在vi中打开语法加亮显示的功能::syntax on。这样以后我们在输入的字符中,vi就会自动的识别出关键字,字符串以及其他的一些语法元素,并以不同的颜色来显示出来。这对于程序员来说是一个巨大的帮助。当然你可以自定义语法加亮显示的颜色。
一 般情况下,vi的这种语法加亮显示的功能可以工作的很好,但是有时我们也遇到一些小小的麻烦。也许我们都遇到过背景是白色而字体是浅黄色的情况,在这样的 情况下是非常难读的。vi编辑器有两种语法加亮的办法,一种是当背景为浅色时用,而另一种是当背景为深色时用的。当我们启动vi时,他会检测我们所使用的 端是哪一种背景颜色,是浅色还是深色,然后再应用语法加亮的颜色方案。当然了,有的时候vi也是可以检测出错的。我们可以用这样的命令来知道我们的背景的 情况::set background?。这样vi就会在底端给出我们具体的显示。如果vi检测的并不正确,我们可以用这样的命令来为他赋下正确的值::set background="/light"或是:set background="/dark."当然我们要清楚的知道,这样的操作要在打开语法加亮的命令之前来执行。vi实现语法加亮显示的功能是通文件的扩展 名来文件的类型从而实现功能的。但是有时我们在编辑一个C程序文件时并没有使用传统的扩展名,那么我们如何来告诉vi我们正在编辑的文件的类型呢?解决的 办法就是用filetype这个选项。例如我们要告诉vi我们正在编辑的是一个C程序文件我们可以这样的来做::set filetype=c。这样以后vi就会知道我们正在编辑的是一个C程序文件并正确的加亮语法显示。
除了语法加亮显示的功能以外,vi还提供了缩 进的功能。命令<<将使当前行向左移动一个移位宽度,而命令>>将使当前向右移动一个移位宽度。这个所谓的是移位宽度具体是多少 呢?在vi中默认的是八个空格的宽度。然而平时的经验可以表明当缩进是四个空格宽度时最有利于程序的阅读。那么我们如何将这个移动宽度定为四个空格的长度 呢?这时我们就可以用下面的命令来做到::set shiftwidth=4.而这时的命令仅是对当前的一行有效,我们也可以像其他的vi命令一样的在命令前用数字做为前缀还指定命令作用的范围。如5& lt;<就将缩进五行。
在vi中还有许多自动进行缩进的选项,一般有以下的几种:C缩进(cindent):这是C语言的缩进形式,采用这 样的缩进方式的程序语言有:C,C++,Java等。当采用这种缩进格式时,vi就会自动的采用标准的C语言形式。还有一种形式是 smartindent:在这种缩进模式中,每一行都和前一行有相同的缩进量,同时这种缩进形式能正确的识别出花括号,当遇到右花括号(}),则取消了缩 进形式。另外的一种缩进形式便是所谓的自动缩进(autoindent):在这种缩进形式中,新增加的行和前一行有相同的缩进形式。vi编辑器可以很好的 识别出C,C++,Java以及其他的一些结构化程序设计语言,并且能用C语言的缩进格式来很好的处理程序的缩进结构。我们可以用这样的命令来打开C语言 形式的缩进结构::set cindent.这样以后vi编辑器就会用C语言的缩进形式来正确的处理程序文件。一般而言C缩进结构可以满中绝大多数人的需要,当然了不同的人有不同的 编程风格,如果你不喜欢这样的缩进结构,你可以自己定义自己的缩进形式。也许我们做程序设计的人并不想每一次想要编辑C程序文件时都要用命令:set cindent来打开C缩进形式,为了解决这样的问题,我们可以改写vi的配置文件来使vi能够自动的完成这样的工作。我们 在.vimrc(UNIX/LINUX)或是_vimrc(WINDOWS)中加入下面的几句:
:filetype on
:autocmd FileType c,cpp:set cindent
第一行是打开vi文件类型识别功能,第二行是如果所识别的文件类型为C或是C++文件那么便打C缩进形式。
在 vi中除了C缩进形式以外我们还有smartindent缩进形式可以来用。在smartindent这种缩进模式中能够正确的识别出{和}。同时增加了 识C语言关键字的功能。如果一行是以#开头的,那么这种格式将会被特殊对待而不采用缩进格式。这种缩进格式不如cindent,但是却强于 autoindent。另外的一种缩进形式便函是autoindent。在其他的一些结构化程序设计语言如Pascal,Per或是Python语言中, 我们所希望的是新的一行能和上一行有相同的缩进形式,这时我们便可以打开autoindent缩进形式,:set autoindent。这样就可以很好的来满足我们的要求了。
vi不仅有这些功能,而且还有更多的功能来快速的处理程序文件。其中一个便是可以快速的在文件中定位变量及宏定义等。其中一些常用到的命令有:
[CTRL_I/]CTRL_I    在本文件中以及在由#i nclude命令包含进来的文件中进行查找光标下面的文字
gd/gD    查找变量的定义
[CTRL_D/]CTRL_D    跳到宏定义的地方
[d/]d/[D/]D    显示宏定义
阅读(3210) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~