如何用 Vim 重構代碼?
例如:我現在有一個 cpp 類的成員函數的參數列表發生了變化,如何快速的更新整個工程中聲明,定義以及調用?
就我所知,Vim的重構工具並不太多,與Eclipse等集成IDE不一樣,Vim本身不集成語言相關、語義層面(semantic level)的複雜重構功能。而另一方面Vim提供非常方便好用的基於正則表達式的替換工具,我經常使用它來進行各種文件(包括各種語言的代碼、配置、文檔等)的批量處理(包括「重構」,也包括各種批量插入、刪除甚至生成代碼等)。以下是幾種常見情形的解決辦法:
如何對當前文件進行統一替換?舉個例子,現在你希望把所有的foo()函數調用最後都加上一個NULL參數(當然,你可以優先考慮為該函數定義加上一個默認參數或者函數重載,這樣有更好的向後兼容性),你只需在normal mode輸入::%s/(foo([^)]*))/1, NULL)/g
即可將當前文件的所有調用進行替換。想了解更多,在normal mode輸入:
:h :s
如何對當前文件的一部分進行替換?
方法類似,只需要之前先用字元選取命令(v)或行選取命令(V)選取替換範圍即可(小提示:v/V可以配合查找一起使用,比如替換到下一次出現頂行右大括弧,你可以在normal mode輸入:V/^}
:args *.txt
:argdo %s/(foo([^)]*))/1, NULL)/g | update
update命令用於保存修改。
如何在進行每一個替換前先確認?
很簡單,在每一個s命令的/g之後都加上c(表示confirm)即可。如何只替換符合某種條件的行?如果你的條件可以用正則表達式表達,則可以結合:g命令來使用。:g表示全局替換。比如,如果你想在所有出現bar的行進行替換,則可以在normal mode輸入::%g/bar/s/(foo([^)]*))/1, NULL)/g
:%g!/bar/s/(foo([^)]*))/1, NULL)/g
:h :g
我就是想要重構工具,可以有嗎?
可以有的,別忘了vim還有各式各樣的插件,比如這個:lhRefactor -lh-vim -
lh-refactor: Generic refactoring plugin
若有其它問題,歡迎提問。作為 exVim 的作者,我會推薦使用 exVim 來解決重構問題。
當然,客觀地說,在 Vim 里重構代碼,是非常艱巨的任務。因為Vim的工具鏈更偏重於靜態分析,文本分析。而對於好的重構工具,他需要一定的語義分析能力,並且不同的編程語言也會面臨不一樣的挑戰。簡單的說,靜態語言重構相對動態語言而言要輕鬆一些。
一般我會通過 exVim 中的 gg 或者 :GS &
在完成檢索結果後,就是比較麻煩的替換操作。在 exVim 中,可以對 exGlobalSearch 中的查找結果做全局替換,通過指令 :SUB name1/name2/option 。這個指令和 Vim 中的 :s/name1/name2/opt 格式是一樣,只不過他做的事情是對每一條 exGlobalSearch 中過濾出得檢索結果做一次 Vim 的 :s 操作。
當然,由於執行的是文本替換,我個人並不是非常放心替換結果,所以,每次完成名字替換的重構操作後,我還會根據 exGlobalSearch 的檢索條目,一一檢查替換結果。
誠然Vim不是重構利器,但是在做諸如以上的文本操作時,工作量還是屬於可控的。對於靜態語言編程,這樣的方法已經足夠,如果是C語言編程,更有cscope這樣的靜態分析利器(對應exVim的 exCscope) 來幫助重構和代碼分析。
讓我比較迷茫的是動態語言(Lua, Javascript)的重構過程,目前我並沒有特別好的方法。所以也想借這個問題詢問。在同一個文件里,使用多游標,這個很給力。terryma/vim-multiple-cursors · GitHub
在多個文件查找的情況,主要是有一個靠譜的文本搜索工具。推薦使用The Silver Searcher這個超快的搜過工具,和vim結合,需要用到一個更牛叉的插件Shougo/unite.vim · GitHub 。Unite.vim實現一套搜索的介面,實現有點像sublime的goto anywhere,不夠沒那麼強,可以直接接入ag。使用命令,:Unite grep
" For ag
if executable("ag")
" Use ag in unite grep source.
let g:unite_source_grep_command = "ag"
let g:unite_source_grep_default_opts =
"--line-numbers --nocolor --nogroup --hidden --ignore " .
""".hg"" --ignore "".svn"" --ignore "".git"" --ignore "".bzr"""
let g:unite_source_grep_recursive_opt = ""
endif
easygrep插件不錯喲~
推薦一個插件 dyng/ctrlsf.vim · GitHub
使用ag, 在其editor模式中, 可以配合terryma/vim-multiple-cursors · GitHub 選中直接編輯保存, 批量修改所有文件一些鍵位修改, 可以參考 wklken/k-vim · GitHubvim連定位個symbol都困難,碰見複雜點template更是直接完犢子了,所以還是用大番茄+VS重構吧
cscope?
https://github.com/wsdjeg/DotFiles
補充一個,exVim,用過的最好用的VIM環境, exVim | exDev Studio
直接在vim使用!調用系統命令。重構js推薦工具 grasp 很方便,支持各種語法和局部,選擇替換,整個項目替換等功能……
推薦閱讀:
※Mac OS X Lion 下 Vi 怎麼回到行首/行尾以及 page up/page down 呢?
※在 Vim 中移動游標需要先切換模式,是否很麻煩?
※如何優雅地使用 Vim?
※到底 VIM 能配置到多強大的程度?
※你最愛的一個 Vim 命令是什麼?
TAG:Vim |