顯示具有 vim 標籤的文章。 顯示所有文章
顯示具有 vim 標籤的文章。 顯示所有文章

2015年8月4日 星期二

Vim plugin - YouCompleteMe

Ubuntu 15.04下安裝完youcompleteme之後通常會遇到兩個如同月經般的老問題:
1. YCM要求手動編譯(使用cmake)
"ycm_client_support.[so|pyd|dll] and ycm_core.[so|pyd|dll] not detected; you need to compile YCM before using it. Read the docs!"
$ (Optional) sudo apt-get install cmake
$ cd ~/.vim/bundle/YouCompleteMe
$ ./install.sh --clang-completer

2. cmake找不到python lib
"  STDERR:
Your C++ compiler supports C++11, compiling in that mode.
CMake Error at /usr/share/cmake-3.0/Modules/FindPackageHandleStandardArgs.cmake:136 (message):
  Could NOT find PythonLibs (missing: PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS)
  (Required is at least version "2.6")
Call Stack (most recent call first):
  /usr/share/cmake-3.0/Modules/FindPackageHandleStandardArgs.cmake:343 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-3.0/Modules/FindPythonLibs.cmake:197 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  BoostParts/CMakeLists.txt:30 (find_package)"
安裝python-dev即可解決
$ sudo apt-get install python-dev

3. clang不提供32位元的版本
"  STDERR:
Your C++ compiler supports C++11, compiling in that mode.
CMake Error at ycm/CMakeLists.txt:64 (message):
  No pre-built Clang 3.6 binaries for 32 bit linux.  You'll have to compile
  Clang 3.6 from source.  See the YCM docs for details on how to use a
  user-compiled libclang.
 
如果系統上確定已經安裝好libclang,試看看以下參數:
$./install.sh --clang-completer --system-libclang

或是參考這些地方自己編
1.https://solarianprogrammer.com/2013/01/17/building-clang-libcpp-ubuntu-linux/
2.http://www.cnblogs.com/csuftzzk/p/3435710.html
3.http://www.linuxzen.com/vim-dai-ma-bu-quan-he-jian-cha-youcompleteme-syntastic.html

2015年7月12日 星期日

VIM: Buffers vs Tabs

Vim在7.0開始的分頁(Tabs)功能對於依靠直覺使用工具的人來說應該不難理解,就像Firefox、Chrome、Ultraedit之類上的應用一般,開一個新檔案就開一個新頁籤(tab)去放,
 一個tab一個檔案,很清楚。

但是對於老用戶如我來說,新出現的分頁功能要我照Windows下的慣用用法來用實在是有夠彆扭,因為Vim本來就有運作良好的buffer機制可以進行多檔編輯,
交互參考還可以搭配vs(plit)開兩個視窗來做,chrome上的分頁用法套在這裡貌似不太適用。

事實上Vim的頁籤功能原本的設計意圖的確不是這樣用,開始說明之前先回顧一下Vim的buffer與window:

Vim所謂的buffer,指的就是編輯中的文檔(Text),有一個比較傳神的形容叫做instance of file,
當Vim打開一個檔案要編輯的時候,他事實上是將整個檔案讀到記憶體中的一塊空間,
我們編輯的是記憶體裡的副本,因此改完了要:w寫回去,
而當Vim同時編輯兩個檔案的時候,所作的就是將第二個檔案讀到另一塊記憶體的空間中,我們隨後可以使用bnext/bprev在兩管buffer中切換。

而 Vim中的window指的是一種顯示buffer內容的方法,是"任何"buffer,一次一個,
當我們正在編輯一個檔案,我們可以split開啟另一 個window,此時另一個window顯示的還是原本在編輯的buffer,
隨後我們bnext切換到另一個buffer,前面提到的交互參考就做出來 了。

以上是buffer與window,根據Vim的文件,buffer、window與tab的定義是這樣:
buffer: the in-memory text of a file.
window: viewpoint of a buffer.
tab: a collection of windows.

來 做個實驗,我們打開兩個檔案,使用垂直分割讓他們能同時顯示,然後:tabnew開一個新的tab,這次水平分割兩個window讓他們讀進方才的兩個檔 案,:tabnext來回切換tab, 
你會發現tab就真的只是讓window以不同形式layout,他們事實上還是共用同一組buffers。

具 體上tab的用法其實也就是這樣,讓你可以切換不同的layout,可以一個tab開啟.c與.h做交互參照,然後另外一個tab單開.c檔專心做編輯,
也可以一個tab編輯一個專案,另一個tab分開另一個專案,當然要一個tab開一個不同的檔案還是可以的,只是我會說那不是原本設計的意圖 (intention)。

2015年7月11日 星期六

VIM的剪貼簿(register)

關於在Vim裡的複製與貼上,help copy-move 可以得到詳細的說明。
較為特別之處是Vim提供了暫存器(register)的觀念,可以將他想成buffer的概念,
剪下來的東西分別以自動或手動的方式放置到不同的register,稍後就可以統一處理。

想像一個場景,用Windows的筆記本編輯一個檔案,你發現想要複製的內容分佈在檔案的不同部位,甚至是不同的檔案中,
通常的操作就是捲到目標處,複製,回來貼上,捲到下個目標處,回來再貼上,打開另一個檔案,重複本行的行為。

使用Vim的情景會是找到目標,複製到某暫存器,繼續找下一個目標,複製到另一個暫存器,打開別的檔案找到目標,複製到另一個暫存器,一直到暫存器用完或是全部複製作業結束,然後回來原先的編輯處按需要一個一個貼出來,以下是常用的register及功能介紹。

Vim總共有九種類型的暫存器, 共74個,
使用時按"接著要使用的暫存器,需要配合d、c、s、x、p等指令,
例如"a2x表示剪下游標後的兩個字元存入"a暫存器, "ap表示將a暫存器內容貼在游標處,
1. unmamed register ""
2. number register "0 ~ "9
3. small delete register "-
4. 26 named register "a ~ "z 或 "A ~ "Z
5. 4 read-only register ":  ".  "%  "#
6. expression register "=
7. selection and drop register "* "+ "~
8. black hold register "_
9. last search pattern register "/

1. unnamed register:
     Vim執行d, c, s, x, 等刪除行為, 或是複製行為y時就會將被剪下來或是複製下來的內容放進這個暫存器, 不管有沒有指定要使用那一個暫存器, 也可以說這個暫存器就是指向最後一個使用的暫存器, 在Vim內使用複製、剪下與貼上時,如果沒有指定使用哪個暫存器,東西就是存在unnamed register,順帶一題指定存入""的話,實際會寫入"0。

2. number register:
     number register也是屬於自動使用,沒指定暫存器的話,最近一次的複製(yank)內容會存到"0, 而最後一次的刪除(x|d)或變更(c)會將被去掉的內容放在"1 ,每次"1被換成新的內容時,前一次存著的內容就會推到"2,以此類推,最後的"9放的內容會自動丟掉。

3. small register:
     類似"1, 差別在少於一行的內容會放在"-, 大於一行的內容放在"1

4. named register:
     給你手動使用的register, 指定存到小寫暫存器("a ~ "z)時以新的內容置換掉原來暫存器的存放內容,指定存到大寫暫存器("A ~ "Z)時新的內容會被附加在原來內容的後面。

5. 4 read-only register:
     這四個暫存器值是Vim自己填的,你只能用p或P貼出去。
     ".     -     最後以i或o命令插入的文字, 打了1234abcd, ".裡面放的就是1234abcd
     "%     -     當前編輯的檔名
     "#     -     替代用檔名(alternate name)
     ":     -     最後執行的命令, 例如執行shell命令:! ls, ":裡放的就是! ls

6. expression register:
     read only register, 這個暫存器的用法有點不容易搞清楚,說明文字裡說的是讓我們評估Vim的表示式(expression),如果表示式的結果能被轉換成字串,字串就可以被插入當前游標所在地,很拗口的說法。
     實際上的使用可以當作一個簡易的計算機,在輸入模式時按下Ctrl+r及=,游標會顯示在命令行讓你鍵入命令,我們輸入一個算式例如4*2,按下enter後,結果8就會被插入文件中游標最後位置。
     所謂的表示式並不限於數學的運算式,只要是按下:後能在命令列輸入的命令就可以用,暫存器會存下執行的最後結果供你隨後使用。

7. selection and drop register:
     用在圖形界面中與其他應用程式共用剪貼板,一般來說會被WM或是Windows的內建功能接管剪貼簿,這個功能實驗不出來。

8. black hols register:
     像是/dev/null,寫進去之後就不見了,也貼不出東西,當不想打亂register的時候用

9. Last search register:
     這個register存放最後執行的search pattern,主要影響到n及hlsearch,意思是說當你想更換n及hlsearch的對象,但是又不想真的執行search時,使用:let設定這個register的值, ex: let@/='search_target'

#順道一提,:reg {arg}與:dis {arg}列出指定的register及值,:reg沒指定對象的話就列出全部register。

2014年12月13日 星期六

自訂VIM

# vm /etc/skel/.vimrc
set background=dark
set number                          #顯示行號
set cursorline                      #啟用行游標提示
set mouse=nv                     #只有Normal及Visual支援滑鼠, 取消Insert模式時的滑鼠支援
set hls                                   #High light search
set ic                                     #search忽略大小寫
set ai                                     #自動縮排
set tabstop=4                      #設定縮排位元數
set shiftwidth=4
set enc=utf8                        #vim所使用的內部編碼
set fileencoding=utf-8        #建立新檔時以utf-8編碼建立,
                                                 fileencodings成功判斷出文件編碼後
                                                 會將fileencoding改為判斷出的編碼好保持編碼一致
#依序按設定編碼打開文件, 編碼嚴謹的放前面, 編碼寬鬆容易誤判的放後面,
   不常用的也放後面
set fileencodings=ucs-bom,utf-8,big5,euc-jp,gbk,latin1

#其實可以不用設, 只影響顯示在螢幕上的編碼, 大部分影響到的是透過終端機(putty之類)連入
   的vim編輯行為
set termencoding=utf-8

2014年3月26日 星期三

Vim - 字元(Char), 詞(Word), 句(Sentence) 與 段落(Paragraph)的差別與移動方式

Vim也能像Emacs一樣以文章結構(字, 詞, 句, 段)為單位進行處理.

Column(欄)
表示vim中每一行有幾個字, 如果打了80個字母後就到了畫面邊緣, 那麼column就是80.

Char(字元)
表示單一個ASCII字元
h|l, 游標前進及後退到下一個字元

Word(詞)
由連續的非空白字元組成, 由空白隔開(space)

w|b 與 W|B , 游標前進及後退到下一個Word的第一個字母, 差別在w|b會考慮到標點符號, 因此游標會在兩個標點符號間移動, W|B只接受以空白為Word的分隔.

e|ge與 E|gE, 游標前進及後退到下一個Word的最後一個字母, 而不是第一個, ge是組合鍵, 表示先按g再按e

Sentence(句)
以".",  "!",  "?"結尾, 後面跟著換行符號, 空白 或是 tab
(|), 游標前進及後退到下一句的第一個字

Paragraph(段)
由句子(Sentence)組成, 以空一行(Empty Line)隔開, 以空白鍵按出的空白行並不會被考慮成段落的分隔,
{|}, 游標前進及後退到下一段落的第一個字

Vim - 在畫面中移動

Vim中把整篇文章當作一個超長字串來看的時候, 有這些編輯移動方式

四方向移動(hjkl)
hjkl, 用直覺聯想 h 與 l 分別將游標往左與右移動一個字元, j 往下一行, k 往上一行, 如果習慣用標準鍵位打字會發現在文章中上下移動不過就是右手食指與中指的事, 很方便.

行內移動(0^$)
0|$, 將游標移動到行內第一及最後一個字元, ^則是移動到行內第一個不是空白的字元

尋找同行字元x(fx|tx)
fx|Fx 與 tx|Tx, 游標移動到同一行中的下一個x字元, Fx與Tx則是往回移動,
fx|Fx 與 tx|Tx 的差別是fx|Fx(Find)將游標停在字元上, tx|Tx(To)則是停在字元前

括號間移動
% - 尋找下一個出現的括號 例如(), [] 或 {} 並將游標停在上面, 繼續按游標會在與之成對的括號間來回移動
[( | [{ - 往回找沒關好的(或是{
]) | ]} - 往前找沒關好的)或是}

文章內移動
?G - 移動到文章內第?行
gg - 移動到文章頭
G - 移動到文章尾
?% - 移動到文章百分之?處

跳躍點(Jump)間移動
命令能造成游標移動出本行稱之為一個Jump(字元搜尋fx|tx 與四方向移動造成的
不算跳躍),
此時的位置會被記錄下來成為跳躍點
`` - 在當前位置與上一跳躍點間移動
Ctrl+O|I - 跳回上|下一個跳躍點
:jumps - 列出跳躍點
:marks - 列出位置標記
m[a-z] - 標記當前位置, 總共可以記錄26個
`[a-z] - 跳回先前紀錄的跳躍點
'[a-z] - 跳回先前紀錄的紀錄點所在行首
特殊mark:
' - Jump前的游標位置
" - 上次編輯檔案時的游標位置
[ - 上次變動的開頭
] - 上次變動的結尾

同畫面內移動
H - 移動到畫面內第一行
M - 移動到畫面內中間行
L - 移動到畫面內最下一行

翻頁(Scrolling)
Ctrl+E|Y - 上下翻一行
Ctrl+U|D - 上下翻半頁
Ctrl+F|B - 上下翻一頁
zt - 畫面往下翻直到游標所在行變成第一行
zz - 捲動畫面畫面直到游標所在行位於畫面中間
zb - 畫面往上翻直到游標所在行變成最後一行

了解現在游標相對於全部文章的位置
.Ctrl+G - 顯示在螢幕下方, 順序為 檔名 行數 總行數 位於文章內%處 第幾個字
.:set number - 每行前方顯示行數的開關
.:set ruler - 常駐顯示在右下角, 順序為 行數 第幾個字 位於文章內%處