天天看點

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

掌握normal模式下常用操作的文法和概念,這些操作對應的應用場景以及實用技巧。

通過normal模式舉一反三掌握cmd-line和visual的常用文本操作。

  文本操作的理想狀态為:一個操作符+一個動作指令。

  normal、visual、cmd-line都具有操作文本的基本功能。

normal    操作符+動作指令。

visual      動作指令+操作符。

cmd-line     比對範圍+操作符。

  這三個在文本的基礎操作時實作的功能是一樣的。主要圍繞着normal來講,其他的舉一反三即可。

  學習新的動作指令及操作符,就像是在學習Vim 的詞彙一樣。如果掌握了這一簡單的文法規則,通過組合,在詞彙量增長時,就能表達更多的想法。是以必須明确每個操作的真實對應的概念,因為這些概念在整個vim都是通用的。

指令一般都是成對出現的,是以可以合起來記,這樣記憶場景量能少一半。例如:

單詞移動,從左向右和從右向左都有對應的動作指令。從左到右:w|W,e|E。從右向左:b|b,ge|gE.....

螢幕滾動, 向前和向後。Ctrl+F|Ctrl+B, Ctrl+U|Ctrl+D

大小寫。gu |gU

指令是象形。了解這個象形,有助于記憶。例如:

符号本身即表示向前還是向後的概念。),},],>

小寫的時候代表 word,大寫的代表WORD。 單詞移動:w(word),W(WORD)

比如在方向前加g,表示實體行和螢幕行。 k(移動到下一個實體行),gk(移動到下一個螢幕行)

大寫代表到行尾。C相當于c$,D相當于d$。

大小寫表示方向的。f{char} 從左向右查找,F{char}從右向左查找。

一個操作符指令被連續調用兩次時,它會作用于目前行。比如:dd:删除目前行,yy:複制目前行,>>:縮進目前行......

  由非空白字元組成的連貫的集合,由空白字元分隔。字元不包括關鍵字(iskeyword)。

  詳情可以檢視:h word ,:h iskeyword。

  由非空白字元組成的連貫的集合,由空白字元分隔。字元包括關鍵字(iskeyword)。

  例如:

  This is mine/yours

  其中的"mine"是word,而"mine/yours"是一個WORD,這裡"mine","/","yours"是三個word。這裡的"/"就是iskeyword。

  詳情可以檢視:h WORD,:h iskeyword。

  一個句子,以".","!","?"結尾。需要注意的是,是英文狀态中的符号,中文狀态下是無效的,比如"。"。

  詳情可以檢視:h sentence。

  實際行與螢幕行的差別。

  與許多文本編輯器不同,Vim 會區分實際行與螢幕行。當‘wrap’ 設定被啟用時 (預設啟用),每個超出視窗寬度的文本行都會被回繞顯示,以保證沒有文本顯示不出 來。這樣一來,檔案中的一行也許會被顯示為螢幕上的若幹行。要想知道實際行與螢幕行之間的不同,最簡單的方法是啟用‘number’ 設定。

  

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

  了解實際行與螢幕行間的差别很重要,因為 Vim 提供了不同的動作指令來操作 這兩者。j 和k 指令會根據實際行向下及向上移動,而gj 和gk 則是按螢幕行向下 及向上移動。即隻要有加g就表示的是螢幕行,沒有加g就表示的是實際行。

  以空行區分開段落。

  詳情可以檢視:h paragraph。

  類似于java的程式設計語言的一個方法。

  詳情可以檢視:h various-motions裡的]m。

  有兩種情況:

  1、以一個符号開始,又以這個符号結束的。比如(),[],{},<>,"",''。

  2、以标簽開始,又以這個标簽結束的。比如 <aaa> </aaa>

  這個主要是文本選擇的時候用的比較多。一般會區分a和i(inner)。a表示整個結構,i表示這個結構内部的文本。

  詳情可以檢視:h object-select ,:h tag-blocks。

  約定:如果後面需要跟動作指令的用{motion}表示。

  詳情可以檢視 :h operator ,:h xx(操作符)。

  定義:删除指定的文本并且進入insert模式。

  文法:

操作符

實作功能

c{motion}

删除指定動作指令選擇代表的文本并且進入insert模式

cc

删除目前行并且進入insert模式

C

删除到光标到行尾的文本并且進入insert模式。相當于c$

s

删除光标下的字元并且進入insert模式。相當于cl

S

删除目前行。相當于cc。  能不按shift鍵我都不願意用shift。是以一般直接用cc

  定義:删除指定的文本。

 x

 删除光标下的字元

 X

 删除光标前一個字元

 d{motion}

 删除指定動作指令代表的文本

 dd

 删除目前行

 D

 删除光标到目前行行尾。相當于d$

  定義:指定的文本大小寫切換。

~

切換光标下的字元大小寫

~~

切換目前行的大小寫

g~{motion}

切換動作指令代表的文本的大小寫  

gu{motion}

把動作指令代表的文本變為小寫

gugu

目前行變為小寫

gU{motiong}

把動作指令代表的文本變為大寫

gUgU

目前行變為大寫

  定義:複制文本到寄存器。

y{motion}

複制動作指令代表的文本到寄存器

yy

複制目前行到寄存器

Y

複制目前行到寄存器,相當于yy。能不按shift鍵我都不願意用shift。是以一般直接用yy  

  定義:把複制的文本粘貼出來。

p

把複制的文本粘貼到光标之後。如果複制的是行,則放在目前行的下面,并且光标停留在複制文本的第一行位置

P(Shift+p)

把複制的文本粘貼到光标之前。如果複制的是行,則放在目前行的上面,并且光标停留在複制文本的下一行位置

gp

gP(Shift+p)

   注意事項 :

有加g的操作符,如果是行複制需要注意。有加g最後光标停留在複制的文本的下一行,沒加g最後光标停留在複制的文本第一行。

  定義:針對文本進行縮進。縮進針對的是行,是以是文本動作選擇對應的行的縮進。

>{motion}

向右縮進動作指令文本代表的行

>>

向左縮進目前行

<{motion}

向左縮進動作指令文本代表的行

<<

  把文本折疊起來。此時操作折疊相當于操作一行。

  這個現在暫時不涉及,感覺暫時應用不會太多,如果有用到後續會補充。 

  用來標明要操作的文本的範圍。

  基本所有的動作指令前都可以加上量詞{count}表示重複,就不在一一做說明。

  詳情可以檢視 :h motion,:h usr_03.txt,:h xx(動作指令)。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

動作指令

動作說明

h

向左移動一個字元

l

向右移動一個字元

j

向下移動一個實際行

gj

向下移動一個螢幕行

k

向上移動一個實際行

gk

向上移動一個螢幕行

 注意事項:

g用于差別實際行和螢幕行

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

移動到實際行的行首

g0

移動到螢幕行的行首

^

移動到實際行的第一個非空白字元

g^

移動到螢幕行的第一個非空白字元

$

移動到實際行的行尾

g$

移動到螢幕行的行尾

gm

移動到螢幕行的中間

+

移動到下一行行首第一個非空白字元

-

移動到上一行行首一個非空白字元

注意事項:

0與^的差別在于非空白字元。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

F{char}

從右向左查找字元。光标停留在找到的字元上面。

f{char}

從左向右查找字元。光标停留在找到的字元上面。

T{char}

從左向右查找字元。光标停留在找到的字元後一個字元。

t{char}

從左向右查找字元。光标停留在找到的字元前一個字元。

;

重複上一次的行查找(f,F,t,T)

,

回到上一次的行查找的位置

大寫字母是從右向左,小寫字母是從右向右

f系統是光标停留在查找到的字元上面,t系列是光标停留在查找到的字元臨近一個字元。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

G

檔案的最後一行

nG

跳到檔案的第n行。

gg

檔案第一行,相當于1G

n%

跳到檔案的百分之n行。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

w

從左向右,移動到下一個單詞詞首

W

從左向右,移動到下一個大單詞詞首。

b

從右向左,如果光标不是在詞首。則移動到本單詞詞首。如果在詞首移動到下一個單詞詞首。

B

從右向左,如果光标不是在詞首。則移動到本單詞詞首。如果在詞首移動到下一個大單詞詞首。

e

從左向右,如果光标不是在詞尾,則移動到本單詞詞尾。如果在詞尾移動到下一個單詞詞尾

E

從左向右,如果光标不是在詞尾,則移動到本單詞詞尾。如果在詞尾移動到下一個大單詞詞尾

ge

從右向左,移動到下一個單詞詞尾

gE

從右向左,移動到下一個大單詞詞尾

注意事項

 大寫代表WORD,小寫代表word

)

移動下一個句子句首。

(

移動上一個句子句首。

}

移動下一個段落段首前的空行上

{

移動上一個段落段首前的空行上

]]

移動到下一個以“{"為第一個字元的行首。如果結合操作符,則停留下一個"{"的上一行。

[[

移動到上一個以“{"為第一個字元的行首。如果結合操作符,則停留上一個"{"的那一行

][

移動到下一個以“}"為第一個字元行首。如果結合操作符,則停留下一個"}"上一行

[]

移動到上一個以“}"為第一個字元行首。如果結合操作符,則停留上一個"}"那一行

  标記有兩類型的符号'(單引号),`(反撇鍵)。',表示定位到行首。`,表示定位到行首的第一個非空白地方。後面跟的任何指令,兩個類型都有,是以就不一一說明了隻取'來做文法說明。

m{a-zA-Z}

設定标記

'[

跳到最近一次修改或者複制文本的第一行位置

'] 

跳到最近一次修改或者複制文本的最後一行位置

'> 

跳到最近一次visual選擇的最後一行位置

'<

跳到最近一次visual選擇的第一行位置

''(兩個單引号)

跳到最近一次上方位置

'"

跳到檔案上一次打開的最後位置

'^

跳到光标退出插入模式的地方

'.

跳到最後一次檔案修改的地方   

]'

跳到上一個小寫字母标記(用:marks檢視)的地方

['

跳到下一個小寫字母标記的地方

   注意事項:

還有一些沒有實際意義的,不列出來了。'),'},'(,'{  相當于(,),{,}。

需要注意的是:配合cmd-line下的:marks。檢視所有标記 。

  詳情可以檢視:h marks。

  一個跳越,指定的是使用以下指令: "'", "`", "G", "/", "?", "n","N", "%", "(", ")", "[[", "]]", "{", "}", ":s", ":tag", "L", "M", "H" 等指令

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

Ctrl+o

跳到上一個光标位置

Ctrl+i

跳到下一個光标位置

ng,

向之前n次修改跳越

ng;

向之後n次修改跨越

  注意事項:

配合cmd-line下的:jumps,檢視所有跳越。

配合cmd-line下的:changes,檢視所有修改的跳越。

  詳情可以檢視:h jumps ,:h changes 。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

%

找到比對的([{}])

[(

找到不比對的(

[{

找到上一個不比對的{

]m

跳到下一個方法  

]符号( #,*,/)

跳到下一個符号的位置

  一旦執行這個動作指令,就相當于執行這個選擇的區域。

  a和i的差別。 i:表示的是inner,指的是區域内的文本;a:表示的是a,指的是一個完整的區域文本内容。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

 

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

  後面就隻寫區域名稱,不一一寫出來了,都是成對出現的。

代表的文本區域

句子

段落

]或[

一個"]"塊 

)或(

一個"("塊

}或{

一個"{"塊

相當于一個"("塊

相當于一個"{"塊

>或<

一個"<"塊

t

一個tag blocks,相當于<aa></aa>

"

一個"""塊

'

一個"'"塊

  詳情可以檢視:h object-select。

  目前視窗滾動文本内容顯示。

  z{count}CR(Enter鍵)。設定視窗高度。

  詳情可以檢視:h scroll.text ,:h xx。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

CTRL+E 

向下一行。光标一直往上走,直到頂到螢幕第一行,滾動的是内容

CTRL+Y 

向上一行.光标一直往下走,直到頂到螢幕最後一行,滾動的是内容

Ctrl+D  

向下半屏。光标在螢幕的相對位置不變,滾動的是内容

Ctrl+U  

向上半屏。光标在螢幕的相對位置不變,滾動的是内容

CTRL+F  

向下一屏。光标一直在第一行,滾動的是内容。

CTRL+B

 向上一屏.光标一直在最後一行,滾動的是内容。

  說明:螢幕裡的内容不滾動,光标移動。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

H

光标定位到目前螢幕最上行

M

光标定位到目前螢幕的中間行

L

光标定位到目前螢幕的最下行

  說明:光标在原來的實體行位置不動,螢幕裡的内容滾動最大值一屏。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

zt

光标置于螢幕第一行,光标的列還是和移動之前一緻。

z+

光标置于螢幕第一行。相當于z<CR(Enter鍵)>,光标在于行首

zz

光标置于螢幕中文,光标的列還是和移動之前一緻。

z.

光标置于螢幕中文,光标在于行首

zb

光标置于螢幕下方,光标的列還是和移動之前一緻。

z-

光标置于螢幕最後一行,光标在于行首

z後面如果跟的是字母則停留在原來的位置,如果跟的是字元停留在行首

  詳情可以檢視,:h z

{count}ctrl+a  加法

{count}ctrl+x  減法

在做一些數字處理和校正時有用。例如

文法:

  定義宏:

1、q{name}

2、錄制的指令

3、q

  使用宏:

    ${count}@{name}

  這些小技巧都出處于《vim實用技巧》,大家如果有興趣可以進一步閱讀學習。

   我們嘗試了3 種不同的方式來删除一個詞:dbx、bdw 以及daw。他們高爾夫數(按鍵操作數)都是3,哪種方式最具重複性?我們針對這三種情況,都使用.指令操作一下。

  dbx包含兩步操作:db 指令删除至單詞的開頭,而後x 指令删除一個字元。如果我們跟着執行一次. 指令,它會重複删除一個字元( . = = x )。我不覺得這有什麼價值。

  bdw包含兩步。這一次,b 隻是一次普通的移動,而dw 完成修改。此時用. 指令會重複dw,删除從光标位置到下個單詞開頭的内容。不過因為我們剛好已經在行尾了,并沒有“下一個單詞”,是以在這個場景裡. 指令沒什麼用。不過,至少它代表了一個更長點的操作(. = = dw)

  daw隻調用一個操作:daw。這個操作不僅僅删除了該單詞,它還會删除一個空格,是以光标最終會停在單詞“is”的最後一個字元上。如果此時我們使用. 指令,它會重複上次删除單詞的指令。這一次, . 指令會做真正有用的事情(. = = daw)。

  結論:daw 可以發揮. 指令的最大威力,是以我宣布它是本輪的獲勝者。

  如果你發現自己要在幾個地方做同樣的小修改,就可以嘗試構造你的修改,讓它們能夠被. 指令重複執行。要識别出這類機會需要進行一定的實踐,不過一旦你養成了使修改可重複的習慣,那麼你就會從 Vim 這裡得到“獎賞”。

  在處理某些特定工作時,使用次數可以使按鍵次數變得最少,不過我們并不是非得這樣不可。我們需要認真考慮次數與重複各自的優缺點。

   我們的3 種選擇d2w、2dw 或者dw. 都是3 次按鍵,不過哪一種最好呢? 

  根據我們的讨論,d2w 和2dw 是相同的,在執行完兩者中的任一個後,我們可以按u 鍵撤銷,這樣兩個被删除的單詞又會回來。或者,我們不是用撤銷,而是用.指令重複執行它,這就會删除後面的兩個單詞。

  對于dw. 的情形,按u 或. 的結果會有細微的差别。這裡的修改是dw,即删除一個單詞。是以,如果想恢複這兩個被删除的單詞,必須撤銷兩次,按uu(或者,如果你願意,也可以按2u)。按. 則隻删除後面的一個單詞,而不是兩個。

  現在假設我們原本是想删除3 個單詞,而不是2 個。由于判斷出了點差錯,我們執行了d2w 而不是d3w,那接下來怎麼做?我們不能使用. 指令,因為那會總共删除4個單詞。是以,我們或是先撤銷而後修正次數(ud3w),或是繼續删除下一個單詞(dw)。

  現在考慮另一種方案,如果我們在第一處地方用的是dw. 指令,那麼我們隻要再多重複一次. 指令就行了。因為我們最初的修改隻是簡單的dw,是以u 指令和. 指令都具有更細的粒度,每次隻作用于一個單詞。

  現在假設我們想删除7 個單詞,我們可以運作d7w,或是dw......(即dw 後面跟6 次. 指令)。計算一下按鍵的次數,哪個指令勝出是很顯而易見的。不過你真地确信自己數對了次數嗎?計算次數很是讨厭,是以我甯願按6 次. 指令,也不願意隻為減少按鍵的次數,

  而浪費同樣的時間去統計次數。如果我多按了一次. 指令怎麼辦?沒關系,隻要按一次u 鍵就可以回退回來。

   

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

  在此場景中,使用. 指令的意義不大,我們可以删除一個單詞,然後再用. 指令删除另一個,但随後我們還得切換到插入模式(例如,使用i 或cw)。對我來說這麼做很不順手,我反而更願意用次數。

  使用次數的另一個好處是:它保留了一個幹淨、連貫的撤銷曆史記錄。完成這次修改後,我們按一下u 鍵就可以撤銷整個修改。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

  這條指令會删除此單詞,外加一個空格,是以結果會很幹淨。如果我們用的是diw的話,那删完後就會有兩個連在一起的空格,這或許并不是我們想要的。

菜鳥vimer成長記——第2.1章、normal模式目的簡介統一規則 基本概念  操作符動作指令滾屏算術運算宏小技巧

  ciw 指令隻删除該單詞,而不删除其前後的空白字元,随後它會進入插入模式,這剛好是我們想要的效果。如果用的是caw 的話,那最後兩個單詞就會連在一起,變成“mostadjectives”。雖然這很容易修正,但如果一開始就能避免此問題,那豈不是更好麼。

  一般來說,d{motion} 指令和aw、as 和ap 配合起來使用比較好,而c{motion}指令和iw 及類似的文本對象一起用效果會更好。