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

2016年4月16日 星期六

用 vimdiff 作 git merge

參考文章

以前我用 kdiff3, 後來需要在 terminal merge, 改試 vimdiff, 也很好用。

設定:

$ git config --global merge.tool vimdiff

執行 (在 git merge 有 unsolved conflict 後):

$ git mergetool

UI 顯示:

  • 左上: LOCAL
  • 中上: BASE
  • 右上: REMOTE
  • 下面: 編輯區

vim 指令:

  • [c, ]c: 在 hunk 間移動, 和 vim-gitgutter 一樣
  • 搜 "<<<<" 找 conflict
  • :diffget LOCAL: 目前的 hunk 選用 LOCAL
  • :diffget REMOTE: 目前的 hunk 選用 REMOTE
  • :diffupdate: 更新 diff 畫面

修改後存檔離開, 會自動 resolved conflict。無修改離開會跳過 merge, 維持原本狀態。

其它

查看 merge 狀態:

$ git status

如果整份檔案都要選用 LOCAL, 改用 git 指令:

$ git checkout --ours

全用 REMOTE:

$ git checkout --theirs

2015年5月24日 星期日

大幅提升開發時間的 vim 必備 plugin: syntastic

用 IDE 開發的一大好處是: 寫程式的當下, IDE 會即時編譯程式碼, 指出編譯錯誤的地方。可以大幅縮短「寫碼 -> 編譯失敗 -> 寫碼 -> 編譯失敗 -> ...」的流程。VIM 可透過 syntastic 達到一樣的效果, 存檔後立即編譯, 然後指出編譯錯誤的地方。Script language 也有同樣效果。安裝後我不需改任何設定就可以愉快地寫 C++ 和 Python。

通常寫 C/C++ 時, 會在編譯時加上 "-I/path/to/header", 這樣編譯器才知道上那找標頭檔。syntastic 同樣地也需要這個設定。設定方法是在程式碼的目錄下 (或父目錄, 或父父目錄...) 建立 .syntastic_cpp_config , 裡面直接寫 "-I/path/to/header", syntastic 就知道上那找標頭檔了。

參考資料: http://stackoverflow.com/a/19143873/278456

2014年8月5日 星期二

在 vim 內 indent JSON

太容易忘了,乾脆寫篇文章加強記憶:

:%!python -m json.tool

是的,其實就是呼叫 python module 來處理

2014年2月21日 星期五

用 vim tab 批次處理多個檔案

最近才發覺 vim 有強大的批次處理功能, 相見恨晚啊。

在命令列同時開啟多個檔案到多個 tab

vim -p module/*.h

開啟 module 目錄下全部 .h 檔, 用一個 tab 編輯一個檔案。

需配合 tabpagemax 使用 (set tabpagemax=1000), 預設 tabpagemax=10, 不太夠用。

在 vim 內開啟多個檔案到多個 tab

:args module/*.h
:argdo :tabe

效果同上一個作法。但 argdo 為了加速讀檔會先關掉 syntax, 要自己加指令開啟 syntax:

:args module/*.h | execute 'argdo tabe %' | syntax on

在 vim 內更改全部 tab 內容並存檔

:tabdo :% s/xxx/ooo/
:tabdo :w

第一行對全部 tab 逐一執行 :% s/xxx/ooo/, 第二行則是逐一執行 :w。一但有 tab 無法執行指令, 就會停下來。

:tabdo 可用的場合很多, 比方說我習慣用 vim -p 一次開啟多個 core dump 的 backtrace, 然後用:tabdo normal zR unfold 全部檔案, 還有用 :tabdo 下指令 highlight 關鍵字:

:tabdo hi KeywordTemp ctermfg=red
:tabdo syn match KeywordTemp /SOME_KEYWORD/
方便閱讀不同 core dump 中共通的部份。

2013年11月3日 星期日

gj: 閱讀 C/C++ 原始碼的好幫手

兩年前剛開始接觸大型 C++ 專案時, 研究了一下尋找 symbol 相關位置的工具。最後依自己的需求, 做了一個小工具 gj。經歷了近兩年的使用和改進, gj 已成為我工作環境裡不可或缺的一塊了。

gj 的特點是:

  • 建立索引和找尋 symbol 的時間極短, 沾 ID Utils 的光, 不費任何力氣就有這樣的成果。
  • 盡可能不要漏掉可能的相關檔案, 並提供互動過濾的機制, 方便找出目標。
  • 和 vim 整合一起使用。

這裡有 gj demo 的畫面。

雖說目前已可應付我自己的九成需求, 還是有不少可改進的地方, 只是用到的情境較少就懶得補了。大家若有興趣使用, 歡迎提供建議。愈多人有需求, 愈有動力來改。或是用過 gj 後, 覺得有其它和 vim 整合得好工具, 也歡迎推薦。

2013年10月12日 星期六

screen 和 vim 切換以及移動分頁的方法

在 screen 或 vim 內開太多分頁後, 常常會忘記先前在那個分頁做什麼, 雖然可以設快速鍵在分頁間切換, 還是不太方便。實驗一陣子後, 適度地重新排列分頁, 可以加快不少操作速度。備忘一下兩者的用法。

screen

$HOME/.screenrc 裡加上快速鍵 F7/F8 替代 ctrl+a p/ctrl+a n:

  • bindkey -k k7 prev
  • bindkey -k k8 next

另外, 移動分頁的方法是 ctrl+a :number N, 其中 N 表示要移往的位置。

vim

$HOME/.vimrc 裡加上快速鍵

  • nmap <leader>h gT
  • nmap <leader>l gt
  • nmap t <C-w>

前兩項對應到切換 vim tab page, 預設 leader key 是 \, 不過我習慣用 e, 比較好按。參考 vim :help mapleader 了解 leader key 更多訊息。

第三個方便在 vim window 間切換 (如 tl 表示切到右側 window), 可以少按 ctrl。

另外, 移動分頁的方法是 :tabm N, 其中 N 表示要移往的位置。

2013年7月27日 星期六

vim 快速開啟目錄下的檔案

用過 XCode 的 "shift+command+o" 快速開啟檔案後, 一直很想在 vim 內用同樣的功能。按個快速鍵會跳出一個輸入框, 接著只要打部份字串, 就會濾出有可能的檔案。

看到 DKcmd 推薦用 ctrlp, 就來試用一下。試用後感覺相當不錯, 用法如下:

  1. 在 command mode 打 ctrl+p
  2. 打檔名
  3. 選定檔案, 按 ctrl+t 開在新分頁; 按 ctrl+v 開在目前分頁的新 window; 按 enter 開在目前分頁

ctrlp 除介面好用外, 另一大優點是使用 pure vim script, 理論上有 vim 的平台都能用 ctrlp。不過最近用一陣子後發覺一些小問題, 微調之後才會更好用。

在 $HOME/.vimrc 中加上這幾行:

  • let g:ctrlp_clear_cache_on_exit = 0 " 離開 vim 後不要清 cache
  • let g:ctrlp_max_files = 1000000 " 加大 cache 索引的檔案數, 否則會漏找檔案
  • let g:ctrlp_user_command = 'find %s -type f' " 使用 find 加速建索引的速度

備註: 無用的實驗觀察

之前沒讀完官網, 漏看了參數 g:ctrlp_user_command, 只好自己手動建索引加速, 下面的心得就當紀念吧。

另外 cache 預設存放在 $HOME/.cache/ctrlp 下, 若嫌 ctrlp 建 cache 太慢, 可以自己手動建:

$ cd /path/to/target
$ index=$(echo `pwd` | sed 's#/#%#g' | sed 's#$#.txt#')
$ find . | cut -b 3- | LC_ALL=C sort > $HOME/.cache/ctrlp/$index

自己建會快超多, 不過會比較不乾淨一點, ctrlp 似乎有濾掉不能開的檔案, 像是目錄或圖檔之類的。

2013年6月6日 星期四

vim-protodef: 從 C++ header 產生實作樣板的好幫手

C++ 寫一陣時間後, 覺得每次在標頭檔寫完宣告又要在實作檔裡重打一次類似的函式名稱, 有點麻煩。原本想說自己寫個 vim script 處理這件事, 轉念一想, 應該有人做過了。結果找到別人滿完整的實作: derekwyatt/vim-protodef

作法滿聰明的, 用 ctags 讀標頭檔產生索引, 然後用 perl script 清理 ctags 產生的結果, 最後用 vim script 搜尋目標函式是否已出現在實作檔裡, 沒有的話就輸出到實作檔裡。日後有需要寫比較複雜的 vim script 時, 可以回頭來參考語法。

2013年5月30日 星期四

使用 vim script 自動開啟 C/C++ 程式的標頭檔或程式碼

先附上完整 script:

" Open .h if it's a cpp file, and vice versa.
function! OpenComplementFile()
  let f = expand('%')   " (1)
  let suffix = matchstr(f, '\.\a\+$')
  let pattern = suffix . "$"
  if suffix == '.h'
    let suffixes = ['.cpp', '.cc', '.mm', '.m', '.h']
    for suf in suffixes
      let target = substitute(f, pattern, suf, '')   " (2)
      if filereadable(target)
        break
      endif
    endfor
  elseif suffix == '.cpp' || suffix == '.cc' || suffix == '.m' || suffix == '.mm'
    let target = substitute(f, pattern, '.h', '')
    if !filereadable(target)
      let tmp = target
      let target = substitute(tmp, '\v(.+)\..+', 'public/\1.h', '')  " (3)
      if !filereadable(target)
        let target = substitute(tmp, '\v(.+)/(.+)\.(.+)', '\1/public/\2.h', '')
      endif
    endif
  else
    let target = ''
  endif

  if filereadable(target)
    exec 'vsplit ' target
  else
    echo "Complement file not found"
  endif
endfunction
nnoremap <silent> <F4> :call OpenComplementFile()<CR>

在 vimrc 裡放入上述程式, 然後在 normal mode 裡按 F4 會有如下的反應:

  • 若是在 X.h 裡面, 會試著在垂直分開的視窗裡開啟 X.cpp, 若沒有 X.cpp, 則會依序改試 X.cc, X.mm, X.m。
  • 若是在 X.cpp (或 .cc, .mm, .m) 裡, 會先試開 X.h, 若沒有 X.h, 再試 public/X.h。有需要的話, 可以配合自己的習慣往更深的目錄找。

1.

  • 詳見 :h expand。
  • % 表示目前的檔名。
  • 簡單的檔名轉換可以用 expand 就做完, 比方說如下的例子:
"open A_test.X if current file name is A.X
"open A.X if current file name is A_test.X
function OpenCorrespondingFile()
    let d = split(expand("%"), '_test')
    if len(d) == 1
        let name = expand("%:r") . "_test." . expand("%:e")
    else
        let name = d[0] . d[1]
    endif
    exec 'vsplit ' name
endfunction

2.

  • 寫上述 script 的時候, 花最多時間查詢如何使用函式 substitue()。參考 vim 內部的說明 :h substitute() 即可。
  • 注意要加 () 表示查詢函式的文件, 而不是查 Ex command 的 :substitute

3.

  • :h magic 說明 vim 對待特殊字元的方法。在 pattern 前面加上 "\v" 會和其它 script 的用法一致, 比較方便。

2013年2月11日 星期一

vim 顯示目前函式的名稱

我平常習慣用 gj 跳到某個 symbol 位置, 但接下來上下讀程式時, 有時需要知道目前在那個函式裡, 幸好有前人提供 script 做這件事。省了自己摸索的時間。

藉這機會順便學一些 vim script 的語法:

fun! ShowFuncName()
  let lnum = line(".")  " (1)
  let col = col(".")
  echohl ModeMsg        " (2)
  echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bW'))  " (3)
  echohl None
  call search("\\%" . lnum . "l" . "\\%" . col . "c")  "(4)
endfun
map F :call ShowFuncName() <CR>  " (5)

注意 vim 是用 「"」 表示後面的字為註解

1.

  • let VAR = VALUE: vim 的設值
  • line("."): expression, 取回目前行數
  • col("."): expression, 取回目前欄數

這裡存下目前的位置, 在 (4) 的時候可以跳回原位 (後述)。

2.

  • 切換 echo 字串 highlight 的方式, 比方 echohl WarningMsg 預設會顯示紅字

3.

  • :call FUNCTION(...): 呼叫函式 FUNCTION
  • getline(N): 顯示檔案內第 N 行字串
  • search(REGEXP, FLAG): 搜尋字串, 跳到符合的位置並傳回顯示符合的行數
  • :call search(REGEXP, 'bW'): b 表示往上搜; W 表示搜到底的時候, 不用從頭 (或尾) 繼續搜。見 Searching - Vim Tips Wiki 了解更多 search 技巧
  • 所以這一行的意思是往上找到開頭「兩個字不為空白字元和註解開頭」的行, 並且此行結尾不能是':'
  • 由於 search() 會傳回行數, 搭配 getline() 完成目的

若希望此函式一併支援 Objective-C 的函式, 更改 REGEXP 即可, 雖說會有一些辛苦就是了。

4.

  • 由於 search() 會更動游標位置, 再用 search("\\%Yl\\%Xc") 跳回原本的位置, 其中 (X, Y) 表示原本的游標位置

5.

  • 我平時會用到 f, 所以改用 F 觸發這個函式。

2012年10月5日 星期五

在 vim 內直接搜尋專案目錄下的字串

以前用 id-utils 為底, 寫了個小程式 gj, 用來搜索目錄下的關鍵字。基本上 gj 已滿足我八成的需求, 不過有時還是覺得若能在vim 內搜尋就更方便, 不用複製目前游標下的字串、開新視窗、貼上字串、執行 gj

最近找到 ack.vim, 發現完全符合我的需求, 只不過它是用 ack 搜尋, 不是用 id-utils, 檔案多的時候搜尋速度較慢。ack.vim 用 vim 的 grep + quickfix 達成目的, 只要改用 id-utils 作索引和搜尋即可, 剩下部份可直接拿來用, 沒花多少工夫就改好了。

安裝方式如下:

  1. sudo apt-get install id-utils
  2. wget https://raw.github.com/fcamel/configs/master/.vim/plugin/ack.vim && mv ack.vim /.vim/plugin/
  3. wget https://raw.github.com/fcamel/configs/master/bin/gid_with_col.py && chmod +x gid_with_col.py && mv gid_with_col.py /bin
  4. $ cat << EOF >> ~/.vimrc
    let g:ackprg="gid_with_col.py"
    nnoremap <silent> <Leader>g :Ack<CR>
    EOF
    

  5. $ cd /path/to/project && mkid # 建立索引
接下來在專案目錄下用 vim 編輯檔案, 按 \g 就會搜索目前游目標下的字串, 在下方開啟索尋結果。或是用 :Ack <pattern> <pattern2> ... 做更細的搜尋。

用法參見 ack.vim:

o    to open (same as enter)
go   to preview file (open but maintain focus on ack.vim results)
t    to open in new tab
T    to open in new tab silently
v    to open in vertical split
gv   to open in vertical split silently
q    to close the quickfix window
不過我將 t 的功能註解掉了, 需要的人請自行修改 ack.vim 去掉註解。

2012年4月8日 星期日

使用 vim script 協助閱讀程式碼

開啟多個 window 顯示各個符合搜尋結果的位置

在讀原始碼時, 我常常想知道某個變數或函式, 在這個檔案裡被用在那些地方, 而且希望在 vim 裡一次開多個 window, 每個 window 顯示一個位置, 方便同時觀看。若能一併尋找其它檔案更好, 不過那會難許多, 第一步先在同一檔案做到這點, 應該就很有幫助。

針對這個需求, 順便研究一下寫 vim function 需要知道的一些基本知識, 寫好的東西見 ShowMatched(pattern) 相關的程式

以編輯 eglibc 的 stdlib/setenv.c 為例, 將游標移到 LOCK 後, 按下 \f, 會開個新 tab, 並呈現如下的畫面:

\f 最多會開兩個 tab, 一個 tab 最多六個 window, 待試用一陣子後再來調整它的行為。可用 :wind q 關掉目前 tab 內所有 window。由於很常用到這功能, 我會設個巨集做這件事:

map qq :q      # 關掉目前 window
map qa :wind q # 關掉目前 tab 的全部 window

vim script

在這裡整理一下寫 vim script 時需要知道的基本常識。

基本上 script 的每一行如同在 ex mode 執行:

g/^$/d  # 等同於 :g/^$/d, 砍掉空行

若需要使用 normal mode 的指令, 要配合使用指令 normal:

normal ggdd  # 砍掉第一行
execute "normal \<c-w>l"  # 切到右邊的 window

若需要讀取指令的輸出結果, 可用 redir 導到 register:

redir @a
:g/printf/p
reidr END
put a  # 將搜到 printf 的顯示結果寫到目前的檔案裡

若在導到 register 時, 不希望同時輸出到螢幕, 得將指令先包在函式裡, 再用 silent call FUNCTION:

silent call MyFunc

知道以上幾件事後, 剩下的就是熟悉語法、找些小範例、查查內建的函式, 就可以延伸原本熟悉的 vim 指令成為 script:

如此一來, 不用花多少力氣, 即可讓 vim 的威力增加數倍。

2012年3月25日 星期日

vim 快速開啟 .c / .cpp / .h 的相對檔案

搜尋這個需求的話, 會看到網路上一個廣為流傳的版本:

map <f4> :p,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,

開 .cpp 後按 F4 就可以開啟同目錄下的 .h; 反之亦然。只要一行就搞定, 沒有 if-else, 頗為神奇的。

但是有時候我開 .cc 或 .c 時, 就沒辦法叫出 .h 檔, 所以剛才花了點時間研究一下, 才搞懂它怎麼做的。

修改後的版本如下, 這個版本在 .cpp / .c / .cc / .C 檔案裡按 F4 會開 .h; 在 .h 裡開 F4 會開 .cpp:

map <F4> :vs %:s#\.cpp$#.XY_CPP_XY#:s#\.h$#.cpp#:s#.XY_CPP_XY#.h#:s#\.cc$#.h#:s#\.[cC]$#.h#<CR>

% 表示目前的檔名, 在 vim 打 :help :%s, 可看到 :%s 的用處, 它是用來取代檔名的指令, 功能同 s/.../.../, 特別的是, 它可以重覆使用。

原作者的巧思在於, 先將 .h 轉成一個大概不會出現的字串 (.X123X), 然後放心的將 .cpp 轉為 .h, 再將那個不會出現的字串轉回 .cpp。由於是字串代換, 代換的目標沒有出現, 也不會有不良影響。這裡的順序很重要, 替代字串的順序對的話, 就可應付各種情況。

所以要支援其它副檔名轉為 .h, 只要在後面直接多加 :s 即可。其它就只是細部小修改, 沒改也沒什麼影響。

2012年2月7日 星期二

在 gvim 內顯示中文

若你像我一樣習慣看英文名稱的選單, 想說也可以順便練英文, 因此裝了 win7 64bit 英文版, 才會有這需求。

除了本來就該做的:

set encoding=utf-8
set fileencoding=utf-8

之外, 還要設 guifont:

if has("gui_running")
    set guifont=MingLiU:h14
endif

要怎麼知道 guifont 的值呢? 只要按 Edit -> Select Font ..., 選好字型後再打 :set guifont, 就會看到設好的字型, 將它寫入 $HOME/_vimrc 下即可。

特別的是, 在 win32 下和 win64 的設法有點不同, 不能直接照著選完字型的值打, 得去掉最後的 :cCHINESEBIG5。在 vim 內輸入 help guifont 會看到完整說明, 不過好像沒看到 win64 的說明。

2011年5月17日 星期二

讓 vim 暫時 highlight 指定的關鍵字

在讀程式碼時, 常需要暫時追踪特定變數, 比方說 class Foo 裡有個 self.client 用做連線, 想追踪 self.client 是如何被產生、設定、使用。以前我會在 client 上按 * 搜尋這個字, vim 裡有設 set hlsearch, 自然會被 hilight。這個作法有兩個缺點:
  1. 一次只能特別標記一個字。
  2. 游標會跑掉, 得再按 ? 跑回來。
剛才想到, 其實可以寫個 nmap, 按個鍵就自動 highlight 目前的關鍵字。參考 cscope 的巨集指令, 總算試出來了, 結果如下:

~/.vimrc

nmap <leader>* :syn match TempKeyword /\<<C-R>=expand("<cword>")<CR>\>/<CR>
nmap <leader>c :syn clear TempKeyword<CR>
hi TempKeyword ctermfg=red
注意, 若你載入的 syntax file 或其它 vim script 有執行 :syntax clear 的話, 要將 hi TermKeyword 那行移到 :syntax clear 之後。像我用的 syntax/python.vim 就有執行 :syntax clear。

用法

<leader> 預設是對到反斜線 ("\"), 若沒設 <leader> 的話, 就是在想 highlight 的字上按 \*, 就會用紅色顯示這個字, 可以在多個字上按 \*, 效果會累加。不想看的時候, 按 \c 清掉所有 highlight 的字。

下面是使用前後的對照圖 ( 游標移到 auth_type 後按 \* ):



備註

<C-R>=expand("<cword>")<CR> 是關鍵, 這段程式碼會取出目前游標所在的字, 展開後填在命令列上。之後再來詳細研究它的結構。<C-R>= 、 expand 、 <cword> 和 <CR> 四個拆開看我都懂, 但合在一起為何有這個效果, 就看不懂了。

2011-05-17 更新: 經 BlueCat 提醒, 重看 <C-R> 的說明, 發現它的功能是填入特定 register 的值。而 = 這個 register 的功用比較特別, 執行後才會讓使用者填入 expression, 再回傳 expression 運算的結果。這樣這串指令合起來的意思就不難懂了。

2011年2月17日 星期四

讓 vim 的複製貼上和其它 terminal 以及 Windows 共用 clipboard

今天從同事 P 那學到的。

目的是用 Windows 開 putty 連 Linux 工作站時, 可以在 screen 內跨 window 共用 clipboard, 也可以和 Windows 共用。比方說將程式碼貼到 Windows 下的 Gmail 時, 原本要先關掉 vsplit 並 set nonu, 才能用滑鼠正確選出要的內容, 接著貼到 Gmail。若能共享 clipboard 的話, 就能在 Linux 的 vim 內按個 20yy 複製, 回到 Gmail 裡按 ctrl+V 貼上 20 行內容。

作法如下:
  1. Windows 下要安裝 Xming X Server for Windows。裝好啟動後, 功能表旁會有個 X 的小圖示。
  2. 設定 putty: connections -> SSH -> X11 -> Enable X11 forwarding。
  3. 在 bash 下執行 xterm 測試看看, 成功的話會在 Windows 跑出一個 xterm。
  4. 重開新的 screen, 這時應該可以透過 "+ 複製貼上了。也就是說, "+yy 後, 可以到別的 screen 下其它 window 下用 "+p 貼上。也能在 Windows 下用 ctrl+c / ctrl+v 互通。
  5. 若要省掉 "+ 的步驟, 要將 clipboard 和 vim 預設 register 設成一樣的, 設法是 :set clipboard=unnamed
另外, 可以用 :reg 或 :di 顯示目前所有 register 裡存的東西, 搜 vim register 可看到一些相關介紹。

2011/02/18 更新

補充 Vim tip: Accessing the system clipboard

2011/07/13 更新

注意: vim 編譯時要支援 +clipboard 才行, 可用以下的方法檢查:
$ vim --version | grep clipboard
若有看到 +clipboard 表示有支援, -clipboard 表示沒有。Ubuntu 下要裝 vim-gui-common 才會支援, 光裝 vim-common 不會包含 +clipboard。或是 :set showcmd 時, 看看按了 "+ 後右下角有沒有出來 "+, 沒有的話表示沒打開 clipboard。

2010年3月27日 星期六

用 vim 將 camel case 改成 underscore-based

昨天改這改到很累, 想到可以用 map 處理:
:map e a_<ESC>l~

接著用 /[a-z][A-Z] 搜可能是 camel case 的部份, 確定是的話就按 e 修正。接著按 n 跳到下個地方。遇到一片連續的 camel case, 就 nenenenenen ..... 用力的敲下去, 很有快感!

或是用 record 也 OK, 操作如下:
  1. qe  # 錄到 e 裡
  2. a_<ESC>l~ # 這裡是真的按 ESC 鍵
  3. q
之後一樣先搜到可疑之處, 若是的話按 @e 重播剛才錄下的操作。

2010-03-28 更新

感謝 keitheis 提供直接用 ex mode substitution 的作法, 簡化後的寫法如下:
:% s/\(\l\)\(\u\)/\1_\l\2/gc

關鍵在於後面的 \l (小寫 L) 會把下一個字元轉成小寫 (\u 則是轉大寫), 所以先用 regular expression (regexp) 記好前面的小寫 (\1) 和後面的大寫 (\2), 就很容易啦。之所以看起來這麼亂, 是因為 vim 的 regexp  語法大多要多加反斜線 。詳見 substitute 和 sub-replace-special

2010年3月6日 星期六

學習和開發 Python 的好幫手

慣用 IDE 的人會推 Eclipse + PyDev, 網路上有不少教學文章。我則是慣用 VIM + IPython

這裡有我針對 Python 設的 vim 設定檔, 有興趣用的人可以撿需要的部份用, 或是直接複制整個 .vim 和 .vimrc 也行 (若你原本沒設 .vim 和 .vimrc):

$ git clone git://github.com/fcamel/configs.git
$ cp -r configs/.vim ~
$ cp configs/.vimrc ~

推薦讀 IPython Tip Sheet 學習使用 IPython, 花個十分鐘將可獲得兩倍以上的學習速度。我常最用的指令是 ? 和 ??, 分別會秀出物件 (函式) 說明和原始碼。它的運作原理很簡單, 因為在 Python 的世界裡, 所有東西都是物件, 而物件的 __doc__ 欄位存有文件, __file__ 欄位則存有載入的檔案路徑。因此 IPython 可以輕易地讀入文件和原始碼。

如此一來, 在 screen 裡開兩個 terminal, 一個開 IPython; 一個開 VIM。想試什麼簡單程式就在 IPython 裡試, 有疑問就用 ? 和 ?? 查。在 VIM 裡可按 F10 執行內容, 方便試較長一些的程式。實際開發時則在 VIM 裡切兩個視窗, 一個寫 unit test, 一個寫 software-under-test。在 unit test 的視窗裡按 F10 執行程式, 有錯就切到 software-under-test 的視窗改。若有錯不知錯在那想了解物件內容, 則在 unit test 裡呼叫 IPython [1], 進入 IPython 內了解詳情, 寫起來很有效率。

備註

  1. 由於在 VIM 內執行 Python 已用掉 stdin, 叫起 IPython 後 IPython 會立即結束。這時得改在 shell 上執行程式, 才能從 unit test 中叫出 IPython 並繼續操作 IPython。
  2. fcamel's blog: 強化 Python 在 Vim 裡的顏色

2010年2月19日 星期五

在 VIM 中執行選取區塊內的程式

用 Limp 時發現可以選取區塊後直接執行, 轉念一想, 這應該可以用在任何有直譯器的語言。首先在 ~/.vimrc 內加入這兩行 (以 Python 為例):
autocmd BufRead,BufNewFile *.py map <F10> :% w !python
autocmd BufRead,BufNewFile *.py vmap f :w !python
這裡的意思是編輯副檔名為 py 的檔案時才套用後面的命令。第一行表示按 F10 就將內文全部透過 pipe 丟給 python。相當於在 shell 下這麼做:
cat MY_SCRIPT.py | python
第二行將指令對應到 visual mode (按 V, v, Ctrl+v 選取區塊), 選好區塊後按 f 會執行被選到的那幾行程式。假設選到的是第三到五行, 相當於在 shell 下這麼做:
head -5 MY_SCRIPT.py | tail -3 | python
選用 f 只是我個人習慣 (最不費力的鍵), 大家可以換成自己喜歡的鍵。其它語言只要有直譯器, 把設定中的 python 換成該直譯器 (比方 ruby), *.py 換成對應的副檔名 (比方 *.rb) 即可。

本文作法比較陽春, 希望足以應付大部份的情況。

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...