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

2017年2月22日 星期三

用vim 巨集整理文件格式

曾經有一次,從外面匯入一個project 的程式碼,林林總總大概10 幾個C 的source跟header,每個檔案幾十行到幾百行不等。
打開一看,關掉,哎呀我的眼睛業障重呀
唔…是沒這麼誇張,但裡面充斥著行末空白、排版有點糟糕,然後有些tab 跟空白混用,研究了一下,可以用vim 把這些程式都整理整理。

在刪掉trailing space 的部分用vim-better-whitespace:
https://github.com/ntpeters/vim-better-whitespace
這樣就能在文件中使用StripWhitespace 指令刪掉所有行末空白。
排版用vim 本身的排版功能,一般文件可以用 = 就會排好了,不過如果是python 的話就沒辦法,它不像C 有明確的分號跟大括號來表示縮排結束,所以這招對python 是沒用的,用了只會一直不斷的縮排下去。
把tab 換掉的部分,我基本上是space 派的(戰,這也可以用vim 的取代功能很快做完,不過我們要用ge 來suppress error ,以免文件中不存在tab 的狀況停掉巨集執行。

我們利用vim 的巨集功能,把上面幾個結果串在一塊,選一個喜歡的英文字母(這裡用y,因為我最喜歡y了),依序輸入下面的指令,打完一行就按一下enter,#後面的表示註解:

q
y #將巨集存在 y 暫存區
:StripWhitespace  #清除trailing space
:%s/\t/ /ge  #全文件取代tab 為雙空白
=G  #全文件重新排版
:w  #記得存檔,神明保佑(X
:n  #編輯下一份文件
q
然後關鍵的一步來了,我們的巨集在執行完就會跳到vim 暫存區的下一個檔案,現在,我們在project 目錄裡面,可以用 vim *.h *.c 一次打開所有程式檔案到暫存區。
接著只要 100@y,執行這個巨集100 次(好吧如果你檔案更多就選個更大的數字),巨集的執行會在 :n 沒有下一個檔案的時候停止,這樣就能把所有檔案的格式都整理得漂漂亮亮了。

2016年10月22日 星期六

使用vim script 改進blogger 寫作流程

故事是這樣子的,今年不知道為什麼靈感大爆發,一直不斷的寫blog。

用blogger 最麻煩的就是它的介面,不太能像jekyll 之類的由文字檔轉成blog,要直接用它的編輯器介面寫文章,如果是一般的文章就很方便,插圖、連結都能一鍵完成,但要插入tag 就麻煩大了。
像我的blog 常會有程式碼或一些執行結果要highlight,我通常會插入兩種不同的tag,一種是單純的highlight <div class="hl"></div>;另一個是包住程式碼用的 <pre class="prettyprint lang-xx">,要在blogger 上面加上這兩個tag ,就必須切換到html 編輯模式,自己到適當的地方加上open tag,然後找到末尾加上close tag,這是一個很累人的過程。

特別像是上一篇rust helloworld 的文章,充滿許多程式碼跟執行結果,編輯起來要十幾分鐘,還要不斷的交稿,每每寫到這種文章就想要放棄blogger換到其他平台…但想想還是不太想放棄blogger 平台,雖然有無痛轉移到其他平台wordpress,但其實blogger 上傳圖片等等還是滿好用的。

那編輯耗時這點總不能這樣下去吧…最近死腦筋終於想到:可以利用vim script 改善這個流程。
首先是HTML跳脫的部分,其實這個可以把文字貼去blogger 再從HTML 抓回來就行了,也可以用vim script 代勞,例如這個指令:
http://vim.wikia.com/wiki/HTML_entities

另外自幹一個Make Blogger funciton,會用這個function對整份文件執行EscapeHTML 取代,並在每個行尾插入<br /> 換行tag:
function! Blogger()
  let range = 'silent ' . 0 . ',' . line("$")
  call EscapeHTML(0, line("$"))
  execute range . 'sno/$/<br \/>/eg'
  endfunction

command! MakeBlogger call Blogger()
另外有兩個help funciton MakePre 跟MakeDiv,功用是可以用vim 執行range 指令,在前後加上tag,如果是Pre的話會把當中的<br /> 給代換掉,利用vim 優秀的整行選取,方便加入各種tag。
//Pre, add <pre class="prettyprint"> and </pre>
function! MakePre(line1, line2)
  call cursor(a:line2, 0)
  :normal o</pre><ESC>
  call cursor(a:line1, 0)
  :normal O<pre class="prettyprint">\r<ESC>
endfunction

command! -range Pre call MakePre(<line1>, <line2>)
//Div, add <div class="hl"> and </pre>
function! Div(line1, line2)
  call cursor(a:line2, 0)
  :normal o</div> <ESC>
  call cursor(a:line1, 0)
  :normal O<div class="hl"> <ESC>
endfunction

command! -range MakeDiv call Div(<line1>, <line2>)
如此一來就能有效的加速blog 發文的流程了,使用時先把libreoffice 裡的文件貼到文字檔裡面,然後用vim script 編輯過,就能整篇由blogger的文字介面中貼入,這篇文用這個方式發,不到十分鐘就發完了。 話說在這個FB, LINE, HackMD 當道的年代,這樣一直寫blogger 感覺怪土裡土氣的,不知各位看倌怎麼想呢?

2016年9月5日 星期一

使用 ctags 增強vim 的功能

vim 搭配 ctags 是一款生猛的工具組,可以快速在trace 專案尋找定義和實作,大幅增加vim 瀏覽程式碼的效率。
安裝方法,首先要安裝ctags ,archlinux 的話是ctags,ubuntu 的話是exuberant-ctags,其他的就…自己找。
在專案的根目錄中使用:
ctags -R

產生tags 檔,在瀏覽原始碼的時候,就能用:
Ctrl + ] 跳到該名稱的定義
Ctrl + t 跳回到剛離開的位置

另外在搜尋的時候,找到了一個taglist 的替代品tagbar,可以使用Vundle 安裝:
https://github.com/majutsushi/tagbar
在vimrc 裡面加上:
Plugin 'majutsushi/tagbar'
map <F12> :TagbarToggle<CR>
就能用F12 開關Tagbar 的視窗,第一眼看來還不錯,比taglist 還要漂亮跟清楚很多,據說相對taglist 對Cpp 的支援也更好;雖然以個人之前的經驗,taglist 沒有想像中的好用…也可能是我不會用吧。

有關Vundle 的相關資訊,請參考之前的文章:
http://yodalee.blogspot.tw/2015/03/vundle-vim.html

其實ctags 上使用一直有個問題,導致我之前都不太使用它:一般稍大一點專案都不會是一層,而是程式碼分到樹狀的資料夾中,用ctags -R 只會在根目錄上產生tags 檔,而通常寫code 的時候都不會在根目標上作業,否則要開檔的時候光打目錄就飽了;但如此一來vim 就抓不到tags 檔了。
後來查了一下vim wiki,發現只需要在.vimrc 裡面加上一行文就可以解決這個問題……
http://vim.wikia.com/wiki/Single_tags_file_for_a_source_tree
set tags=tags;
這樣vim 就會一路往上找tags 檔。

ps. 這樣就能修掉也太詭異了吧…

2015年3月21日 星期六

使用Vundle 維護的新vim 設定

離上一篇「我的vim設定」已經過了一段時間
http://yodalee.blogspot.tw/2012/09/vim.html
其實這個設定已經過時,大約去年九月左右就已經整個換掉了。

現在的設定是由阿蹦大神推薦的,包括:
* Vundle: https://github.com/gmarik/Vundle.vim
自動安裝插件的插件
* ultisnips: https://github.com/SirVer/ultisnips
強大的原始碼片段展開
* vim-snippets: https://github.com/honza/vim-snippets
各種snippets的集合
* YouCompleteMe: https://github.com/Valloric/YouCompleteMe
補齊插件,包括C語言、Java(雖然我沒寫)跟python 的補齊
* Cscope: https://github.com/steffanc/cscopemaps.vim
Cscope,利用Ctags 幫助原始碼查找的工具
* vim-better-whitespace: https://github.com/ntpeters/vim-better-whitespace
vim-better-whitespace,自動幫你把trailing whitespace 給幹掉的插件

另外還有一個,不過這不是很重要(=w=)
Rust.vim: https://github.com/rust-lang/rust.vim

用上Vundle 的好處是,安裝plugin 變得簡單很多,不像以前要用dropbox同步所有設定檔,同時Vundle 可以透過github 安裝,能直接update plugin,像我剛裝的時候還沒有Rustlang 的snippets,後來update 一下就有了。

設定:

首先設定Vundle,照著Vundle 的設定打就行了,先用git 把Vundle.vim 載到~/.vim/bundle 資料
夾裡:
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

然後在設定檔加入
filetype off
set runtimepath+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'gmarik/Vundle.vim'
Plugin 'SirVer/ultisnips'
Plugin 'honza/vim-snippets'
Plugin 'Valloric/YouCompleteMe'
Plugin 'steffanc/cscopemaps'
Plugin 'wting/rust.vim'
Plugin 'ntpeters/vim-better-whitespace'
call vundle#end()
想要裝的plugin就像這樣,在vimrc 裡面插入Plugin,後接git repository 的url 或是author/pluginname;接著在vim 裡面下達:PluginInstall 讓Vundle 猛攪一陣就可以了。
再來是設定其他兩個plugin
首先是Ultisnips,這個比較簡單,因為我們vim-snippets 裡的檔案會存在
.vim/bundle/vim-snippets
裡面;另外是觸發snippet 的按鍵,設定Ultisnips的參數,xxxxxxx請改自己的家目錄:
let g:UltiSnipsSnippetsDir=["/home/xxxxxxx/.vim/bundle/vim-snippets/UltiSnips"]
let g:UltiSnipsExpandTrigger="<c-j>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"

youcompleteme比較麻煩,在C語言系統它要先編過一些東西,先設定vimrc:
let g:ycm_global_ycm_extra_conf = '/home/xxxxxxx/.vim/plugin/.ycm_extra_conf.py'
let g:ycm_extra_conf_vim_data = ['&filetype']
上面這個.ycm_extra_conf.py可以在.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/
裡面找到(講到這裡我就要靠北一下,我記得這個py檔不設定的話YouCompleteMe會跟我一直叫叫叫,然後一堆人都遇到這個問題丟去github 上問,作者只會回「去看文件」啊你文件就沒有講吼!)
這裡面是YouCompleteMe 的設定檔,我只有把裡面的 -Wc++98-compat 改成 -Wno-c++98-compat,使用一些 C++11 的語法時才不會一直警告和 C++98不相容。

然後YouCompleteMe需要編譯,需要安裝編譯工具、Cmake跟python-dev,然後:
cd ~/.vim/bundle/YouCompleteMe
./install.sh --clang-completer

Cscope的話,首先要安裝ctags 跟cscope,在Linux 用套件管理程式都可以安裝。
接著在原始碼根目錄的地方,先用ctags -R 產生tag 檔,之後打開vim後,在關鍵字上使用Ctrl + ] 就可以進行跳躍,用Ctrl + t跳回。

大概就是這樣,現在你的Vim 應該已經變成相當強大的工具了,Happy Vim。

2013年3月29日 星期五

使用vimdiff來解決git merge conflict

使用vimdiff來解決git merge conflict 最近同時家裡用筆電跟辦公室用桌電,在兩個地方使用git/github來管理程式作業,這兩個東西加起來根本神物,本來要用隨身碟同步的東西,現在可以用git直接完成。
關於git的基本介紹我就不解釋了,網路上隨便一找就有一堆資源,例如右邊友站連結,作者比我強30dB的JJL blog,裡面有git的基本使用方式;作者當初則是看參考資料一的progit來學git。

作者遇到的問題是:有時候檔案在github上的檔案已經更新,本地的檔案也有修改過,這時候若想要git pull的話會產生conflict,這時候就需要把本地的檔案刪掉重新clone使用merge來解決衝突,偏偏作者手殘常常把檔案merge成連<<<, >>>都保留下來的檔案,相當麻煩;這次好好的研究一下怎麼用vimdiff作為merge的工具,在這裡記錄一下。

首先呢,我們可以先設定vimdiff為git default的mergetool
git config --global merge.tool vimdiff
為什麼?沒辦法,用vim就是潮(誤)

那麼來merge吧,輸入
git mergetool
這時候應該會打開vimdiff,然後產生左上角、中上、右上、下四個視窗,說明如下:
左上:local:顯示本機的檔案內容,現在這個git資料夾的版本
右上:remote:顯示遠端,你要merge的分枝
中上:base:顯示上面兩個分枝的基部的內容
下:merged:顯示merge的內容,也是是包含了那堆<<<<<<, >>>>>> 的版本,我們的目標就是把下面這個修到我們希望的版本。
截圖:













到了這裡就開始解衝突啦,事實上不單是git,平時如果有兩個很像的檔案要合併,也可以用vimdiff開啟來解,使用的指令是這些:
[c:跳到上一個衝突點
]c:跳到下一個衝突點
:diffget,從某個視窗取得內容
:diffput,把內容丟去某個視窗
可以用:help do, :help dp查怎麼用,不過兩個指令的基本格式是:
:[range]dp|do bufspec

如果是雙方比較,那就沒什麼好說的,do/dp的對象就是另一個視窗的內容,這時候只要在衝突點在一般模式下用dp,do即可。但如果是現在這種3方比較時,就沒辦法這麼方便,而是要直接輸入:diffget/put bufspec來操作(可以打diffg, diffpu來少打幾個字,不過有差嗎=w=)
以上圖為例,我們游標停在下面的衝突點上,要使用remote的視窗內容。
這裡bufspec(用哪個視窗的內容)有兩種指定方式:
1. 先用:buffes,確認remote那個視窗編號,我是4號,因此用 :diffget 4
2. 用關鍵字,這個超強,用 :diffget REMOTE (因為git自動命名暫時檔名為 XXXX.REMOTE.yyy, XXXX.BASE.yyy, XXXX.LOCAL.yyy)即可。
如此就會套用remote的內容了,經過幾次套用之後,畫面可能會變得有點亂,這時候可以用 :diffupdate來重新產生diff的格式。













用上面的步驟,就可以快速的完成解衝突的工作,做完之後,在下面的合併檔存個檔離開吧。

參考資料:
1. progit download:
2. vim wiki about git vimdiff:
3. vim help:
Type in vim :help diff

2012年9月22日 星期六

我的vim設定

最近梗比較少,寫不出什麼有用的東西
整理了一下自己的vim設定,就把自己的設定跟plugin分享一下好了

1. plugin
裝的plugin主要有幾個:
autoComlPop: 輔助omnicomplete的文件單字補齊
http://www.vim.org/scripts/script.php?script_id=1879
LargeFile: 開大檔用,其實比較少用到
http://www.vim.org/scripts/script.php?script_id=1506
surround: 快速修改相對應的標籤
http://www.vim.org/scripts/script.php?script_id=1697
NERDtree: 快速瀏覽目錄
http://www.vim.org/scripts/script.php?script_id=1658
snipMate: 自訂關鍵字補齊功能,缺點是會變笨
http://www.vim.org/scripts/script.php?script_id=2540
taglist: 程式碼概略瀏覽
http://www.vim.org/scripts/script.php?script_id=273

附帶一提,這些plugins全部都裝在~/.vim裡面
我發現可以用dropbox,建一個setting的資料夾
把.vim sync到dropbox上,這樣以後重裝電腦
只要把這個資料夾再複製回來,這些plugin就都裝好了

2. vimrc
我的vimrc如下:
paste.plurk.com/show/1313103
一開始是編碼和layout的設定,然後是各個plugin的設定
用F12可以開taglist
用F7可以用當前的makefile進行make
之後可以用F8列出quickfix所有的錯誤編譯訊息
Ctrl+n Ctrl+p在錯誤內容進行跳躍

omnicomplete的部分是針對各種檔案格式,去設定omnifunc要用哪一種
比較奇怪的是,在vim73上面,omnicomplete的功能被嚴重限縮了
目前還不知道原因Orz

最後就是一些filetype的link
比如說把php, html的filegype交互設定,這樣在php檔裡面也可以使用html 的snipMate快速補齊;cuda 和lex也是相同的道理
3. 結論
這是一篇廢文
其實vim功能相當的強大,能安裝的plugin也多的很
這個設定只是分享,使用習慣還是大家平時用習慣最重要