vim windows版本_大概是篇Vim入门教程(1): 基本的一些东西
雖然其實已經有了很多很好的Vim教程了... 但是... senioria也來試著寫寫吧...
首先, 放一些senioria當年入門的時候看的教程:
- vimtutor, 這個是隨Vim安裝的一篇小教程腳本, 在*NIX系統上可以在shell中鍵入命令vimtutor啟動, 在Windows上(大概)可以在Vim的安裝目錄下找到vimtutor.bat.
- coolshell上的教程
vim速查表什么的大概到處都可以找到, 所以senioria就不放了(((
安裝的話, 絕大多數*NIX發行版的軟件源里應該都有gvim或者類似的包; Windows上, 官網里有一個32位的版本, github上有64位的. 一般來說, 除非實在沒辦法下載, 否則都建議用64位版本: 32位版本無法鏈接64位的python, lua之類的dll[1], 所以要不就也用它們的32位版本, 要不就裝一個vim用的版本, 一個自己用的版本...
不過, 因為Vim和其它編輯器有點不同, 所以, 建議在讀到senioria說去Vim里試試之前不要在vim里亂玩免得失去信心(((
模式
首先, Vim的一個基本思想是"模式"的劃分. 在介紹Vim的模式系統之前, senioria想先介紹一下其它編輯器的"模式"(比如, Windows自帶的那個記事本). 在默認的情況下, ~~拿臉~~在鍵盤上滾一下, 我們可以看到編輯框里出現了一些字符. 然后, 我們按著ctrl不放~~比如放塊磚在上面之類的~~, 會發現, 我們滾鍵盤的時候不會輸入字符, 而是會觸發一堆奇怪的操作了. 這樣, 我們可以根據有沒有按住ctrl來把記事本分成兩種模式: 沒打開的時候是插入模式, 打開的時候是操作模式.
在平時的編輯之中, 我們會發現, 我們很多時候其實并不是在單純的打字/瀏覽, 而是把光標移到一個地方, 刪/加一點東西, 然后繼續移光標. 然后我們會發現, 加一些用來移動光標的快捷鍵會很方便. 加了一堆這樣的快捷鍵之后, 可以注意到的是, 我們實際上會有相當長的一段時間是按著ctrl的; 這樣, 一個相當自然的想法是, 給編輯器加上一個類似"ctrl是否按下"的狀態, 在這兩個狀態之間切換可以用很少的一些快捷鍵來完成, 這樣就可以把我們的左手從ctrl鍵上解放出來了. 這個狀態系統, 就是Vim的模式系統的一個簡略的雛形.
普通和插入模式
我們上面構造的"按下ctrl"和"松開ctrl"兩個狀態, 就正好[2]對應著Vim的普通(Normal)模式和插入(Insert)模式. 而普通模式下的那些單字母的快捷鍵, 我們可以稱為"命令"(因為它就是在"命令"Vim做一點事情). 進入Vim的時候, 我們是處于普通模式下的. Senioria先列出普通模式下的一些命令:
- 移動: 用來動光標的, j, k, h, l分別對應著向下, 向上, 向左, 向右. 用這么幾個鍵并沒有什么特殊的原因: 這幾個按鍵是我們在(QWERTY)鍵盤上最方便按到的幾個鍵, 所以就被用來執行這些非常常用的操作了.
- 插入: 用來從Normal模式進入Insert模式瞎寫東西的.
- i, a: 在當前光標之前/之后插入;
- o, O: 在當前行之下/之上創建新行并插入.
- 刪除: x用來刪掉當前光標下的字符.
- 在插入模式下, 按Esc來回到普通模式(其實更常用的按鍵是C-[( 順便說一下, Vim/Emacs中表示快捷鍵(一般叫"鍵綁定")的方法是這樣的: 先列出這個鍵的修飾鍵(ctrl, shift, meta/alt之類的, C表示ctrl, S表示shift, M/A表示meta/alt), 然后再寫出這個鍵本身. 這些要一起按的鍵之間用-連接, 如果要依次按, 就在兩個這樣的鍵序列之間加上空格))
一般來說, 要從其它模式回到普通模式, 按多幾次Esc/C-[總是沒錯的.(
命令模式
當然Vim的命令不止這點, 但是一開始的話這點大概已經算很多了(而且也夠用了()); 用多了這些單字符的命令之后, 我們會發現, 一些操作用這些簡單的命令來表示并不夠, 比如字符串替換, 文件的打開和另存為之類的. 自然, 我們可以設計一些鍵綁定來完成這些, 但是在Vim的前身Vi被發明出來的時候, 世界上并沒有彈出窗口這種設計, 所以我們必須找到一種方法來直觀地完成這些交互式的操作.[3]
讓我們來插播一些歷史~~(雖然能看到這篇文章的大概都了解這些)~~: 現在被人們認為"理所當然"的GUI, 實際上并不是一開始就存在的, 在Vim/Emacs那個年代, 操作系統的"界面"只是shell(shell這個詞"殼"的意思本來就是用來指"界面"的). 所以, 我們上面問題的解決方案就很明顯了: 加入一個命令模式, 用類似shell的命令來執行這些不好用單字母命令表示的操作.
進入命令模式的命令是:(S-;), 光標會移到Vim窗口的下端用于輸入命令, 這個冒號也會隨著命令一起顯示. 這里是一些命令模式下常用的命令(列出命令的時候, 一般的習慣是連冒號一起列出, 這樣就不會與普通模式下的命令混淆):
- :w file, 其中file是一個文件名. 將當前文件另存為file, 如果還沒有打開文件, 那就在保存之后也打開file(或者說, 將當前文件設為file). file也可以不寫, 這時候就只是保存當前文件.
- :e file, 其中file是一個文件名. 打開file, 如果不加file, 重新打開當前文件.
- :q: 退出Vim; :wq保存并退出Vim; :q!強行退出(不保存);
(不要看:wq似乎是:w和:q的組合就以為Vim的命令可以這么組合了: 它只是Vim給這兩個命令連用加的糖而已, :qw和:qwq就都不能用())
替換的命令稍微有點復雜... 所以... 為什么不自己查文檔呢(bushi(((
要從命令模式回到插入模式, 除了按Esc之外, 也可以把那行命令連著前面的冒號整個刪光, 雖然聽起來很麻煩, 但是在只按了一個冒號的時候, 至少退格比Esc近了很多, 不是嗎:)
文本對象和可視模式
我們一開始用"快捷鍵"來引入模式的時候, 是說過要刪除操作的. 一件可以注意到的事情是, 文本本身并不是"字符的集合", 很多情況下, 字符都會以一定的邏輯組合成一個"對象", 比如, 自然語言文本里的詞, 句子, 段落; 程序中的定義, 語句塊. 因為是出現在文本中的, 我們稱這些對象為文本對象(((; Vim中的刪除, 替換等操作, 正是基于這些對象進行的. 首先介紹一些命令以便進行下面的討論:
- 刪除: d, c, 刪除一個文本對象, 區別在于d刪除一個文本對象之后仍然留在普通模式, 而c刪除之后會進入插入模式. (所以后者一般被叫做修改)
- 復制: y, 將一個文本對象復制到Vim自己的剪貼板, 與系統的剪貼板不通用. (其實刪除命令刪除的文本也會進入Vim的剪貼板, 但是y是不刪除內容的)
- 粘貼: p, 將(Vim的)剪貼板里的內容粘貼到光標下.
- 一些移動命令:
- f, F: 后面加一個字符, 向行尾/行首方向找到, 并移動到這個字符, 如果沒有找到, 則不移動.
- w, b: 移動到下一個單詞/前一個單詞(b的規則要稍微復雜一點: 如果光標不在當前單詞的開頭, 則移動到開頭; 如果在, 則移動到上一個單詞的開頭) (因為這里的單詞是按照標點/空格 (實際上是由一個配置中的選項控制, 反正都做不好中文分詞就是了) 來劃分的, 所以在中文環境里, 這個命令實際上會按照分句來跳轉)
實際上, Vim中的每個移動都可以被視作一個文本對象(因為實際上并不是): dl會刪除當前光標下的字符, df)會刪除從當前光標下的字符到)之間(包括))的所有字符. 要解釋這一行為, 首先要知道, Vim中的移動操作是有包含和不包含兩種(inclusive & exclusive)的, 對于包含的移動, 光標開始移動和最后移動到的位置都包含在了文本對象中; 而對于不包含的移動, 最靠后(i.e. 靠近文件結尾)的那個字符是不包含在文本對象中的.[4]h, l就屬于不包含的移動, 而f是包含的[5].
然后是一些真正的文本對象(i.e. 在Vim的文檔中也被定義成了文本對象). 這些文本對象都以i或a開頭, 用以提示這個操作的范圍(其實這種說法并不合適: 真正的"對象"是i或a之后的那個字符所表示的, i和a只是用來表示"這是個文本對象"). i表示對象的"內部", 而a表示整個對象(inner和"an", 這是文檔里的說法):
- i(, i), a[, a>之類的: 對所有的括號式結構都適用(當然rust closure的|x|不行), 表示最近的一層括號擴住的內容/包括括號在內的內容. 開括號((, [之類)和閉括號(), ]之類)的作用是相同的.
這是一個例子:對于(hello(world)hi), 假設當前光標在world里的字母o上, 那么da(會刪除(world), 但di(只會刪除world; 如果光標在hi的字母i上, 那么da(會刪除這整個字符串(但不會刪掉更多東西), di(會刪剩兩邊的().
- iw, aw: 表示當前的單詞(同樣, 在中文語境下大多其實都指的是當前分句).[6]
很明顯, 只有這些文本對象是肯定不夠的: 我們需要有能夠選中更復雜的文本的能力. 誠然, 這可以通過插件添加更多的文本對象[7]來實現; 但是我們總是會有選中各種奇形怪狀的文本的需求的. 這時候, 我們就需要一個能夠動態根據自己的需要來決定文本對象的模式了. 在Vim里, 這個模式叫可視模式(當然如果愿意的話, 叫選擇模式似乎也沒有什么不行的), 進入的命令是v. 因為在可視模式里我們已經有了一個文本對象了(就是當前選中的文本), 所以c, d這樣需要一個對象的命令會直接執行在選中的文本上, 不需要任何額外參數.
寄存器和宏
我們上面說過, Vim的復制命令會復制到Vim自己的剪貼板而不是系統的剪貼板. 這么做大概是有些歷史原因的: Vi的年代里還不存在系統剪貼板這回事, 畢竟在shell里我們可以用變量/文件來保存一段文本, 然后再在任何地方使用它們. 這確實不方便, 但是要是命令行界面確實做什么都能比GUI方便的話, 為什么還會有那么多GUI下的生產力軟件呢:) 不好揣測Vi作者的心思, 但是Vi里于是有了一套類似shell變量的寄存器系統.[8]有些命令, 比如y, d, 可以用默認寄存器, 也可以在命令之前指定"x(其中x是一個單鍵盤按鍵對應的字符)來指定一個寄存器.[9]寄存器有這么幾類(同樣, 寄存器名之前加上了"來與命令區分):
- "": 默認寄存器; "+: 系統剪貼板; "*: 系統選區(就是當前選中的內容).
- "1到"9: 由新("1)到舊("9)保存了最近刪除的內容(如果沒有指定其它寄存器). 每次刪除文本之后, 原有寄存器里的內容會被移到"下一個"寄存器, 而"9里的內容被刪除. "0保存了最近復制的內容.
- "a"到"z: 這些寄存器沒有任何特殊意義, 可以自由使用. 對于這些寄存器, 大小寫是有意義的: 小寫時覆蓋寄存器里原有的內容, 而大寫時會添加到原有的內容之后.
宏
我們總是會遇到一些需要機械重復的場景, 這時候, 一個能夠自動幫我們敲鍵盤的機器人就顯得很有用了. 而鍵盤宏就是Vim自帶的這么個機器人.
錄制宏的命令是qx, 其中x是一個寄存器; 停止錄制的命令是q. 自然, 錄制到"8這樣的寄存器里雖然也可以, 但意義似乎并不是很大... 如果用"ap粘貼出一個錄制了宏的寄存器, 我們會發現錄制宏其實只是把我們的鍵盤操作放到了寄存器里而已. 因此, 我們可以用qA這樣的方式, 在一個已經錄制好的宏里加入一些內容. 也可以"ap來查看和編輯一個宏, 并且"ad來把它保存回去. (順便說一句, :reg命令可以查看寄存器)
執行宏的命令是@x, 其中x是一個寄存器 ~~(這種時候其實按著shift不放也沒事, 并且會更方便一點)~~. 如果要執行上一個執行的宏的話, 還有一個更方便的糖: @@.
更多
為了敘述方便, Senioria在上面沒有列出很多東西, 這里列一下. 正如很多文章里都說的, Vim的很多東西都要背呢><
Normal模式命令
s用于替換當前光標下的字符(等價于cl).
r也是替換當前光標下的字符, 但是不會進入插入模式. 相應的, R會進入一個替換(replace)模式, 鍵入的每一個字符都會替換之前已有的一個字符 (就像Windows下按了insert鍵之后的編輯器一樣: 到了行尾的話就在行尾之后插入, 按回車開始下一行的話也不會替換下一行).
gg跳轉到文件開頭; G跳轉到文件末尾; nG, 其中n是一個數字, 跳轉到第n行. (不過更常用的大概是:n(見下文))
0跳轉到當前行的開頭, 是不包含的; $跳轉到當前行的結尾, 是包含的. (因為0不會向后跳轉, $不會向前跳轉)
很多命令都可以用重復命令自身的字符(如cc, dd)來操作整行, 比如dd是刪掉整行(包括了換行符); 常用的這些命令大概有cc, dd, yy. 對于這些命令, 它們的大寫版本(比如C, D)是從當前位置操作到當前行的結尾. (對于Y, 行末的換行符也會被復制)
{和}可以跳到上一段/下一段, 這里的“段”一般是按照空行來分隔的.
I, A可以在當前行的第一個非空白字符之前/最后一個非空白字符之后插入.
q:可以像編輯普通文件一樣編輯命令及其歷史. 按enter會(且僅會)執行當前這一行的命令.
%可以跳轉到匹配的另一個括號(如果光標不在括號上, 就跳到最近的回括號(大概))
命令前還可以加一個數字n來表示重復這個命令n次, 一個例外是nG( 對于插入命令, “重復”就是把插入的內容插入n遍((( (實際上這個功能用來畫分割線還蠻好用的())
命令
:n, 其中n是一個行號, 會跳轉到這一行.(和nG)一樣
:help topic, :h topic, 其中topic是一個… 幫助話題, 用來查詢幫助, 可以用tab來補全. (不帶參數的話, 也會打開一個默認的幫助頁面)
:!shell, 其中shell是一個shell命令, 用來執行shell命令. 需要注意的是Vim會對其中的一些字符轉義. (其實很多時候不如直接用:term開一個shell好用)
:cd, :pwd切換和輸出當前工作目錄, 和shell里的用法一樣.
搜索/替換
Vim的所有搜索/替換幾乎都是默認使用正則表達式的. 正則表達式的語法… 大概還算平凡, 可以用:help regexp來查看.
用于搜索的命令是/, 會進入命令模式, /之后的字符都是搜索正則, 不過/這個字符本身要轉義: Vim提供了一些控制選項, 可以用/exp/opt(其中exp是正則, opt是選項)來控制. ?命令基本類似, 不過是向前搜索. 如果只是/或者?, 那么會使用和上次相同的正則. 可以用n和N命令來快速向后(方向相同)/向前(方向相反)重復上次的搜索. 類似于q:, 也可以用q/來像操作普通文件一樣操作搜索歷史.
替換的命令是:s(完整的命令名稱是:substitute), 語法是:s/reg/replace/opt, 其中reg是搜索的正則, replace是要替換成的文本, opt是一些選項. 默認情況下, :s只會在當前行執行替換, 并且只會替換第一個搜索結果; 可以用g選項來替換所有搜索結果, 用可視模式選擇一些行之后按:s可以在這些行上執行替換. 多說一句: 選擇一些行之后再按:, 命令行里會出現:'<,'>而非:, 這是Vi的range語法, 用于在某個范圍里執行一個命令, '<和'>表示可視模式開始和結束的行, ,是范圍下界和上界的分隔符, 可以用行號來代替它們, 用%表示整個文件.
進一步的, 替換中還有另一些正則細節可以用: (和)在正則表達式里被用作匹配的子表達式的選擇 (i.e. 把括號里括住的表達式匹配到的內容保存為一個“匹配”以后使用) (除了Vim正則之外還有另一些其它正則也一樣), 在只有查找的情況下, 這個功能比較少用, 但是在替換的情況下, 可以在替換文本里用n, 其中n是一個數字, 來引用第n個匹配.
下一篇肯定會有的![10]
參考
總結
以上是生活随笔為你收集整理的vim windows版本_大概是篇Vim入门教程(1): 基本的一些东西的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python versions comp
- 下一篇: python中函数修饰符_python中