使用者工具

網站工具


editor:vim

這是本文件的舊版!


圖解鍵盤指令

Text Entry Mode

進去 vim 最開始的狀態(按 Esc 可從其他狀態跳過來)

Key Action
i 在游標前面插入文字
I 在行首插入文字
a 在游標後面插入文字
A 在行尾插入文字
o 在游標下一行插入文字
O 在游標前一行插入文字
r 取代一個字元
R 進入取代模式
J 將下一行合併到此行結尾
V 選取模式(反白)
!<command> 執行 shell 指令
Key Movement
k
j
l
h
︿ 行首
$ 行尾
b 往前一個單字
w 往後一個單字
e 前一個單字的尾端
H 螢幕頂端
M 螢幕中間
L 螢幕底端
Ctrl+d 下移半個螢幕
Ctrl+u 上移半個螢幕
Ctrl+f 下移一個螢幕
Ctrl+b 上移一個螢幕
:nn 跳到第 nn 行
gg 跳到檔案開頭
G 跳到檔案結尾
Key Delete
x 刪除一個字元
dw 刪除一個單字
dd 刪除一整行
:<range>d 刪除範圍(Command mode)
Key Replace
cw 刪除一個單字,並進入插入模式
cc 刪除一整行,並進入插入模式
Key Copy
:<range>y複製範圍
Y 複製此行
p 在下一行貼上
:nnpu 在第nn行後貼上

套裝鍵

gg=G 程式碼重新縮排
ggVGy 全選+複製

Command Mode

先輸入一個冒號(:)即可進入指令模式

動作範圍

: 1 , 3 d     #刪除第一到三行
: . , . +2 d    # 刪除游標所在行到後兩行(共三行)
Range Selects
.(句點) 游標所在行
$ 檔案的最後一行
1 , $ 第一行到最後一行
1 , . 第一行到游標所在行
. , $ 游標所在行到最後一行
. -2 游標所在行的兩行前(5 → 3)
Key1) Search and replace
:<range>s/aaa/bbb/ 將範圍內每行開頭出現的 aaa 字串替換成 bbb
:<range>s/aaa/bbb/g 將範圍內所有 aaa 字串替換成 bbb
:%s/aaa/bbb/ 將整個文件所有 aaa 字串替換成 bbb
: % s/︿v︿m/ /g 將 dos 格式的文章轉成 Linux 格式,先按 Ctrl+v 然後按 Ctrl+m
Key Save/Load
:<range> w <name> 將範圍內資料另存新檔
:r <name> 插入指定檔案的內容
:n 下個檔案

tabs

一次用 tab 打開很多檔案

$ vim -p file1 file2 file3 ...
Command Action
:tabnew [filename] 開新分頁[指定分頁名稱 filename]
:tabf filename 用 tab 打開現在所在目錄下的檔案filename
:tabm [num] 將目前的 tab 移到指定數字位置(0為最前面,若沒輸入 num,則移到最後面)
:tabn 切換到下一個分頁
:tabp 切換到前一個分頁
:tabs 顯示所有分頁資訊
:tabfir 跳到第一個分頁
:tablast 跳到最後一個分頁
:tabdo [指令] 對所有 tabs 執行指令2)

說明文件

:help tab-page-intro

畫面切割

:sp filename 橫向切割
:vsp filename 是縱向切割
Ctrl+w Ctrl+w 切換到另一個視窗

環境設定

支援 UTF8

:set enc=utf8
:set fileencoding=utf8 

Mapping

程式碼轉成 HTML

命令模式下輸入

:so \$VIMRUNTIME/syntax/2html.vim

可將螢幕上高亮度顯示的文字轉化為HTML 文字, 然後用 :w file.html 存檔, :q 退出

另一種,會出現分割視窗。

:TOhtml

在文件前加上行號

:%s/^.*$/\=line(”.”) . ” ” . submatch(0)/g

將網頁字碼轉成中文字

:set enc=utf8
:%s/&#\([0-9]\+\);/\=nr2char(submatch(1))/g

Plugins

snipMate

http://www.vim.org/scripts/script.php?script_id=2540

類色 TextMate 的自動完成功能。

javacomplete

taglist

Source code browser (supports C/C++, java, perl, python, tcl, sql, php, etc)

http://www.vim.org/scripts/script.php?script_id=273

cppcomplete

cTag

Reference

COSCUP 2009 by c9s

by 紅塵一隅間拾得

http://greenisland.csie.nctu.edu.tw/wp/category/comuter/vim/

http://greenisland.csie.nctu.edu.tw/wp/2005/09/02/302/

作者: chrisliu (ChrisLiu*) 站內: Unix
標題: [vim] vim 的取代置換功能「s」
時間: 2006/08/07 Mon 03:16:46

在前面我們所談的那些可以說是比較基本的東西,但是對於一份文件來說,光有前面所介紹的游標移動、刪除等等功能是不足夠的。面對一份文件我們通常會因為某些緣故而使得我們必須去修改當中固定出現的字串樣式(pattern)成我們想要的樣子。最常遇到的就像中文文件的標點符號問題,或是 unix 和 DOS 文件格式之間轉換常會有個 ^M 結尾會讓人覺得很討厭,又或是我們想要把一份 HTML 格式的文件去除掉它的 HTML tag。

對於這些事情來說,拿中文標點符號置換這個很多編輯器都做得到,簡單地說如果想更動的 pattern 是一個固定的字串,那對於一般編輯器來說都不會太困難,但是對於具有固定格式,但字串內容卻不一定的該怎麼辦?就像要去掉 HTML 格式中的所有 HTML tag?這就是 vim 開始大顯身手的地方了。

今天我們不談別的其他指令,就光談在 vim 中的「 :s 」指令。小寫 :s 表示置換(substitute)的意思,不過通常你用 vim 下 :h :s 指令的時候會看到這樣的畫面:

vim help for :s substitute

其實這一串東西就是在說 :s 這個指令的格式要怎麼下。

Range:

一般對於整份文件都要作置換的話,我都會下像這樣的指令:

:%s/, /,/g

最前面的「%」就是表示全域,也就是現在編輯的這一份文件都要作後面取代的工作。那這個指令就是說要把半形的逗點「,」變成全形「,」。那後面「g」又代表什麼意思呢?在 g 這個欄位上的東西是用來表示對目前這個指令所做的額外的選項。就拿 g 來說,g 代表在文件中每一個出現的半形逗點都要置換成全形。或許你會問剛剛不是已經用「%」表示全域了嗎,怎麼又要用 g 呢?我應該這樣說,「%」用來表示從文件的第一行到最後一行。但是在比對(match)的時候,如果不加「g」這個額外選項的話, vim 只會把每一行比對到的第一個作取代,同行其他也 match 到的就不管了。所以用「g」表示每一行中每一個比對到的都要置換。

所以同理,如果你要把那些因為 un*ix 和 DOS 之間格式不合所造成的^M消掉的話,也只需要下成這樣就可以了:

  :%s/^M//g

可是有時候你想要作置換的只是文件中的某一部份的話怎麼辦?不要緊,還記得選取模式嗎?在你想置換部分的開頭按下大寫「V」然後用移動游標(我們之前講的 vim 移動游標的方法在選取模式下都可以用)到你想要的位置之後按「:」就會跳到輸入指令的狀態,如下圖最下面那行看到的一樣:

vim selection for substitute

當然你很確定行數,你也可以這樣下:

:1,300s/vim/VIM/g

或者是如果你很確定要從現在游標所在行之後的所有行都置換,可以下成:

:.,$s/vim/VIM/g

冒號一開頭的那一小點「 . 」就代表游標現在所在行,「$」則用來表示最後一行。

或許聰明的你已經想到怎麼樣可以從現在所在行之前的都要置換了,

:.,1s/vim/VIM/g

不過當你這樣打的時候, vim 會跳出來一個訊息:

Backwards range given, OK to swap (y/n)?

這就是說你給了一個起始行數比結束行數還要大的範圍。這是因為 vim 所定的範圍都是從小到大,如果你要從大到小不是不行,只是多個訊息確認你沒有打錯罷了。

Pattern:

像前面說,固定字串像把半形逗點換成全形逗點這都還容易,如果只是格式固定,但是字串內容會變動怎麼辦?就像去 HTML tag 的時候就很麻煩。

還記得我們在淺談vim那時候提過的指令嗎?

  * :%s/\n/^V/g
  * :%s/< [^<>]*>//g
  * :%s/^V/\n/g

在中間的那一些 [^<>]*看起來像外星文字的,就是 pattern 比對的主力。事實上關於這些東西,我們在談 vim 的 search 搜尋功能的時候也有提到過一些。所以我們今天就來補一些上次沒有講到的東西。

假如我現在有一筆人名、電話的資料,由於是隨手記的,上面自然就是沒有排序過。那沒排序過對於想要在上面找資料的人就很麻煩。萬一人名記不太清楚,電話號碼也記得七七八八,雖然說有 vim 方便的 search 功能,但總是感覺不足。(當然這只是假設情況,因為實際上可能大家都已經建立某種方便搜尋的資料庫了)

我們先假設人名、電話的對應長成這樣:

趙大明 1235478982
錢小名 1223450012
王孫李 5938123812
周渚衛 1384914191
沈以情 2345934981

那我可不可以讓它變成這樣子?

1235478982 趙大明
1223450012 錢小名
5938123812 王孫李
1384914191 周渚衛
2345934981 沈以情

我可以下這樣的指令完成這個工作:

:%s/\([^0-9]\{1,}\)\([0-9]\{1,}\)/\2 \1/g

前面橘色的部分 \([^0-9]\{1,}\) 用 \( \) 括起來的,表示這是一個的單元,之後就可以依照它出現的順序而使用 \1, \2,… ,來代表它。所以我們可以看到 [^0-9] 就表示非數字的部分,後面的\{1,} 如果你還記得的話,就是代表出現至少一次。不過這個時候DK長輩會跟你說用 vim 要文明一點,要用「\+」來代表至少出現一次。看個人喜好了,如果你願意多記一些代替的符號就多記一點,你可以用 :h /multi 看到更多這些替代符號。

所以把 pattern 用 \( \) 分開之後,我們就可以用 \1,\2 來把他們交換位置。

不過你可能會說這樣還沒排序啊。我們可以用選取模式把整份文件選起來,或是你懶得用上下左右改變,你可以用 ggVG (gg 跳到第一行之後,用大寫V進入選擇模式,以大寫G跳到最後一行)把整份文件選起來之後按 :!sort,這時候在你 vim 視窗的最底下就會變成這樣:

:』< [^<>]*>!sort

按下去就會變成根據每一行的最前頭作排序的結果。所以結果就會變成:

1223450012 錢小名
1235478982 趙大明
1384914191 周渚衛
2345934981 沈以情
5938123812 王孫李

很簡單吧? :p

如果你願意配合暫存器( registers )的話,有時候也能省點力氣。在講 vim search 的時候,我們曾經提了用 搭配數字鍵 0 來把暫存器 0 的東西叫出來。同樣的,我們不管用 / 或是 ? 等等輸入字串的時候,事實上都已經把要搜尋的字串寫入「/」的暫存器裡面,所以當我們只是想置換的字串就是搜尋的字串的話,我們可以這樣做:

:%s//用來取代的字串/g

表示在按 之後按下「/」這個按鍵。這樣就可以把搜尋的字串叫出來並用之於置換指令上。

額外指令:

我們剛剛在前面談到可以作像「g」這些的額外控制。那有哪些控制可以作呢?

比方說在我們作置換的時候,由於 vim 預設是有大小寫的差別,如果你不管大小寫都要取代的話,那可以用「i」這個額外參數來控制 vim 取代的時候就不管大小寫都會作取代的工作。

不過有時候,我們可能不太能確定是不是整份文件中的每一個都要取代,那我們就可以加「c」 confirm 確認參數來控制,那使用上也很容易。 vim 會在比對到之後問

(y/n/a/q/l/^E/^Y)?
  • y 是代表執行目前的取代。
  • n 是跳過。
  • a 代表 always ,就是從目前以後的取代都會執行。
  • q 則是不要作取代,並且離開詢問要不要取代的狀態,並回到指令模式或原來的模式下。
  • l 則是 last 的意思,就是目前這個取代執行後就離開詢問的取代模式,回到指令模式或原來的模式下。
  • ^E 表示往前一頁。
  • ^Y 表示往後一頁。

對於 :s 的用法到這裡我們就已經把常用的幾個方式都說完了。礙於篇幅,我也決定先寫到這裡就好,不然寫一大篇,可能連有興趣進來瞭解 vim 的人光看到就害怕了,怎麼還有辦法體會 vim 的好呢?其實關於 :s 的用法,還有 pattern 還有很多的方式在本篇中沒有提到,你可以在 vim 中用 :h :s 看到更多詳細的資料。今天就來 vim 吧!

Vrapper

Vim-like editing in Eclipse

http://vrapper.sourceforge.net/home/

1) 若字串中出現 '/',使用 '\/' 跳脫
2) 例:「:tabdo %s/foo/bar/g」
editor/vim.1262869733.txt.gz · 上一次變更: 2010/01/07 21:08 由 wenpei