誤打誤撞研究了 Vim 的顏色設定

緣由


不知道為什麼我的顏色設定在 vimdiff 時,剛好 highlight 的背景色與某種 syntax 的前景色一樣,導致整個字像透明一樣,diff 時看不到字,一整個就是搞笑,所以我決定一定要修好他。

在決定要修他之前,我的妥協作法是,在 diff 時手動設成別種 colorscheme。上網查發現也有人有這問題,一個解法是在 vimrc 裡設定,偵測跑 vimdiff 時就自動套別種顏色,不過根本的解法還是把顏色調好,這才是一勞永逸。

就在我調顏色時,突然發現了一個關鍵點,我的 Vim 怎麼不是 256 色!!!,我明明就設了,Oh NO。

最後終於找到,原來是 tmux,我的 Vim 是透過 gnome terminal => tmux => vim,tmux 那層沒設好,顏色就不見了,哭哭。

所以我決定把我的心路歷程寫下來。

開啟 256 色的 Vim


terminal

我會用我的環境當例子,首先是 terminal,我是用 ubuntu 的 gnome terminal。
aknow@aknow-ubuntu:~$ echo $COLORTERM
gnome-terminal

他本身就有支援 256 色,這裡有個可以測試的程式 256-xterm-colors,可以跑看看確認 terminal 顏色沒問題。

From: https://github.com/guns/xterm-color-table.vim

tmux

接下來是 tmux,記得要在 .bashrc 裡加上:
export TERM="xterm-256color"

進 tmux,再跑跑看剛剛的程式,驗證 tmux 裡也有 256 色。

Vim

在 vimrc 裡設定:
set t_Co=256

開啟 Vim,執行:
:runtime syntax/colortest.vim

你會看到一些測試的顏色,當然還有更威的 256 色測試 xterm-color-table.vim,裝完後執行:
:XtermColorTable

From: https://github.com/guns/xterm-color-table.vim

如果這些都沒問題,恭喜你有 256 色的 Vim 了。

Colorschme 的選擇


Vim 有一些預設的 colorscheme,你可以選擇你想要的,執行以下指令就可以設定:
:colorscheme <scheme>

:colorscheme 可以簡寫為 :colo (懶人的哲學)

不知道有什麼 <scheme> 嗎?可以透過這兩個方法列出已安裝的 scheme。

  • :colo <space> <tab>
  • :colo <space> <c-d> (ctrl+d)


覺得不夠的話,還可以到 vimcolorschemetest,這裡有 400 多種 scheme 可以預覽和下載。

細部顏色的微調


如果你很龜毛還是想要調顏色的話,可以去修改 scheme 裡的設定,vim help 裡有說怎麼設。
:help highlight

基本上像這樣:
hi ErrorMsg       term=standout  cterm=bold  ctermfg=7  ctermbg=1

數字就是色碼,可以從剛剛的 xterm-color-table.vim 得到,然後前面的那個是 highlight group,想知道有哪些 highlight group 可以設,跑這個指令:
:so $VIMRUNTIME/syntax/hitest.vim

他會把各 highlight group 與目前的顏色顯示出來。


fixmyjs - 自動修改 js 的 lint errors

JSHint 是由 community 維護的 static code analysis tool,會掃過你的 code,然後列出錯誤或潛在的問題,不過這不是本文的重點,所以剩下的就不介紹了。

在列出錯誤後,你可以選擇手動去修改,或是有些錯誤實在是太愚蠢了,根本可以透過程式來幫你改,於是就有了 fixmyjs
FixMyJS is a tool that automatically fixes mistakes—such as missing semicolon, multiple definitions, etc.—reported by JSHint.

他有提供幾種執行方式:

我是用 Nodejs 的方式,可以從 command line 去跑,比較方便,基本上執行時有三個模式可以選擇:
  • 直接修改
  • dry-run,列出 diff
  • 生成 patch 檔

我習慣讓他直接改,然後用 version control tool 來看他到底改了什麼,而這時有些改錯的就可以順便修正一下。所以這不是完美的,用的時候要自己注意。例如,這樣的 javascript code
"use strict";
 
var foo = {
  fun1: function() {},
  fun2: function() {}
  fun3: function() {}
}
由於 JSHint 會報出這樣的錯誤
test.js: line 6, col 3, Expected '}' to match '{' from line 3 and instead saw 'fun3'.
test.js: line 6, col 7, Missing semicolon.                                        
test.js: line 6, col 7, Expected '(end)' and instead saw ':'.                        
他覺得第 6 行少一個分號,但我想要的應該是第 5 行少一個逗點,於是根據 JSHint 的結果 fixmyjs 就把他改成了這樣,在錯誤的地方補了 "Missing semicolon" ...

我怎麼用 github 與 Vundle 管理 Vim 的設定

這應該算是篇心得文吧!說說我走過的路。

先看一下為什麼會需要這樣的管理,以及他解決了什麼問題,我個人認為最重要的兩點是:
  1. 跨電腦、平台地同步設定
  2. 套件的管理與更新

Stage 1. 用 github 同步 


首先 Vim 用久之後,上面一定會有很多你自己的設定,也奘了亂七八糟的套件,你會希望當換到另一台電腦的時候,這些東西也可以一起同步過去。

如果只是要單純的同步,使用 dropbox 之類的工具就可以解決,可以把東西都放在某個 folder,然後把 Vim 的 runtime path 指過去,或是在 vimrc 裡 source dropbox 裡的檔案。

而這部份使用 github 的處理的好處是,你不需要先把 dropbox client 設好,只要有 git 就可以使用,這在 linux / mac 上更是顯得方便。另外透過這個方法,你的 Vim 設定還會有 version control 的功能,雖然我自己從來沒用上這點。

所以呢,你要做的事就是開一個 github account,然後把 Vim 設定統統丟進去,然後到別的環境使用 git clone 把你的設定抓下來,任何時後有修改再 commit / push 回去,以及用 pull 拿到最新的版本,就是這麼簡單。

Stage 2. pathogen 套件管理 / git submodule


以往裝 vim 的套件非常的麻煩,抓下來後,套件的各檔案,可能要放到不同的目錄裡,當裝了很多套件後,你的目錄就會超亂。這時候就有人開發了 pathogen 這個管理套件的套件,他藉由調整 runtime path 的方式,讓你可以把各套件裝在各自的目錄裡,整個就變得清爽整齊。

再來是套件的更新,許多套件都會持續的開發,可能是修 bug,也可能是加功能,這時候你可能會希望這些套件都有自動更新的功能,讓你維持在最新的版本。而這就是 git submodule 出馬的時候了,可以看一下這邊 Joseph 大大的 submodule 介紹,大致上就是說,你可以把別人的 git 當作 submodule 掛到你的 git repository 的某個位置。

整個用起來的原理是這樣,pathogen 可以把套件裝到某個位置,也就是你讓 Vim 知道要去哪裡 load 套件,而這時再用 git submodule,把這個套件的 git 掛到那個目錄,這樣你只要透過 git 更新,就可以隨時拿到最新版的套件。以 vgod 大大的 Vim 設定為例,這裡面的每一個項目都是一個 submodule,指到各套件的 git repository。

這部份的設定就不說了,因為這樣的方法我覺得已經不是主流了。

Stage 3. Vundle 套件管理


使用 Stage 2 的方法,必須要把套件一個個地裝成 submodule,十分的麻煩,而且當你不用的時候,要移除 submodule 也很痛苦,就我所知大概要下個 5 行指令才能作到。

受到 pathogen 的啟發,有人開發出了 Vundle,只要在 vimrc 裡寫明那些套件的 git repository 在哪,Vundle 會幫你作對應的 git 操作,而當 plugin 不用時,只要在 vimrc 裡把那行設定 comment 掉就好。

整個設起來會像這樣,現在你只需要一個 submodule 那就是 Vundle,其餘需要的套件就寫在 vimrc 裡,由 Vundle 來幫你管理。

Stage 4. 把 Vundle 的安裝直接寫在 vimrc 裡


Stage 3 的結果已經作到剩下 Vundle 一個 submodule,如果我們可以把這個也拿掉,那一切就會更簡潔漂亮,在網路上找到一個作法,他會在 vimrc 裡檢查你是否有裝 Vundle,沒有的話就幫你裝起來。

所以目前我的設定就是這樣,可以參考我的 vimrc 的前半段,當然,把 Vundle 的安裝也寫進去,只是爽度的問題,實質上沒什麼不同。

備註


有另一個 Vundle 的改版 NeoBundle,他提供更多的功能,這邊有篇文章有詳細的說明,主要是增加了:

  1. 套件可以定版,不是總是最新,可以鎖在某個 commit 以避免新版的 bug 或不相容
  2. 不只支援 git,還加了 svn、mercurial
  3. 可以設 build command,有些套件需要編譯,例如 YouCompleteMe,這時就可以設定安裝時要自動執行哪個 script

目前我沒有改用這個,主要是這些特點對我還說還不是必要,就懶得改了。

Programmer 都愛貼 code,gist 與 gist-vim 的搭配用法

身為一個寫 blog 的 programmer,不能少的就是在 blog 上面貼 code,最近的流行是用 gist,gist 可以讓你把一段 code 放在 github 上,而且還可以有 version control。

在 gist 畫面的左邊,會給你一個 embedded this gist 的連結,像這樣
<script src="https://gist.github.com/aknow/6232870.js"></script>

把他複製貼到 blogger 上就可以了,成果如下。

但是阿,如果你是手動把 code 弄到 gist 上面,那這樣就太遜了,基本上各大編輯器都有跟 gist 互動的 plugin,如果你用 Vim,可以使用 gist-vim,可以讓你直接在 Vim 裡生成、編輯、讀取 gist,完成後還可以幫你把連結開起來。

當然,這篇用的 gist 就是這樣產生的。

保持專注的工作方法

幾個月前曾經在 facebook 上看這到這張圖的分享,上面提到了幾種保持專注的方法。我們知道如果工作或學習時能夠進入專注的「心流」狀態,這時就會發現時間似乎過得超快,而生產力也爆增。

From: http://fundersandfounders.com/focus-hacks/
所以我們得努力讓自己進入這樣的狀態,但問題是,事實上常有些因素讓我們分心,大致上可分成兩種,外界的干擾,以及自己分心,今天要跟大家分享我利用圖中這兩項
  • put on headphones
  • time yourself
所嘗試過的努力與方法,基本上這應該算是要對抗自己分心。
首先是帶上耳機,帶耳機除了可以隔絕外界的聲音,不會受干擾,也可以減少自己想去聽辦公室八卦的欲望。但是太安靜其實反而不好,所以我還是想讓自己聽一些東西,這邊有個關鍵點,千萬不要聽有聽得懂的歌詞的歌,不然是會被帶走的,所以到底要聽什麼呢?
我有聽過白噪音(white noise),科學研究白噪音有許多好處,例如幫助睡眠,阻擋分心,提昇專注力,有一個網站 SimplyNoise 可以產生這樣的聲音,他還有 pink noise,brown noise 各式變形,這稱之為 colors of noise,有興趣可以去看看。另外 android 上也有很多 app 提供白噪音的產生。
好了,但是當我聽了一陣子之後實在是受不了,覺得自己像個笨蛋。這時候我發現了 coffitivity,他會產生像是身處在咖啡廳的聲音(不過是英文的),咖啡廳的好處我想很多人都知道,這也是為什麼許多人喜歡在那邊讀書或是工作,而我自己的親身體驗也是,在大學的時代的某陣子,我甚至都待在早餐店念書。
coffitivity 建議使用咖啡廳環繞再加上略為大聲的個人音樂,所以除了這個,我還搭配了一個音樂,真的有效,不過還是一樣,在連續聽了一個禮拜過後,就開始有點膩了。我開始在 youtube 上找還有什麼適合的,用關鍵字「music productivity」,發現許多人都建立了屬於他們的 productivity 播放清單,本來我也想仿照蒐集一個,但是工程師的美德就是懶,非不得已絕不自己動手,幸運的是我發現了這個,Study Music Project,以及他的 youtube channel
The Study Music Project is a collection of music productions composed, written, and produced by Dennis Kuo.The sole purpose of the music is to help you focus as you study for school. Instrumentation, melody, and other musical articulations have been well thought-out to enhance concentration.
所以我現在的搭配是 coffitivity + Study Music Project,試用了一陣子,感覺還不錯,包括我寫這篇 blog 時也是這樣聽的。
再來是 time yourself,我是用 pomodoro 的方式在工作,詳細內容就請大家自己去看,簡單講就是以 30 分鐘為一單位,認真做 25 分鐘然後休息 5 分鐘,接著下一個循環。有許多 pomodoro 的相關工具,desktop tool,chrome extension,mobile app,我習慣用的是 android 上面的 pomodroido,有一些功能,但是我只有當作計時器用而已,好處是有一個時間的 progress bar,當看到的時候就可以提醒自己,還有多少時間,要堅持下去,不要隨便分心。
在使用 pomodoro 時,我還會準備一個 interrupt list,萬一真的分心時,趕快把想到的事情記下來,這樣你的腦袋就會知道這個東西已經記在別處了,可以不用一直掛念,趕緊回到 focus 狀態,不過其實這也是標準 pomodoro 上面教的方法。這個 interrupt list 我是用 trello 管理的,並不是說 trello 特別適合,而是因為我是用 trello 在管理我的工作事項,這些 interrupt 很有可能變成之後的 todo item,建議直接用同一個工具管理。
其他的有機會再來分享,我也要朝著有生產力的偉大航道前進。

在 Vim 中使用 clang_complete 做程式碼補完

先看一下效果,在這個例子中,我使用 standard library 中的 vector 容器,當打到 v. 的時候,Vim 會自動跳出視窗列出可以使用的 function,圖片中顯示的是再打了 p 之後的篩選結果。

之前我是使用 ctags + OmniCppComplete來做程式碼補完,他的缺點是:

  1. 要先產生 tags。
  2. ctags 其實看不懂程式碼,有些 code 會跑不出來,例如 libstdc++,所以網路上常見的作法是拿一份修改過的 header 給 ctags 跑。

總體來說,這樣搭配的補完效果跟 visual studio 是完全不能比的。

clangcomplete 這個 plug-in 跟 OmniCppComplete 不同,他是使用 LLVM compiler 的 front-end clang 去 compile 你的程式,所以可以列出最精確的補完清單,甚至你還可以給他 include path 跟 compile option,又會更準。這樣用起來,補完的資訊跟就變得跟 visual studio 一樣,都是由 compiler 提供,相信整體的品質應該會好上許多。

回到先前的例子,可以把 clangcomplete 的執行想成是先 compile 你的程式,再根據結果給你補完的清單,所以如果我前面忘了打 #include ,這個清單是會跑不出來的,會找不到。

安裝方式

  1. 安裝 clang,ubuntu 可以透過 apt-get 或是軟體商城把套件 clang,libclang-dev 裝上即可。windows 的話可以抓 source code 自己 build,或是他有提供一個基於 mingw32win32 binary
  2. 裝完後可以參考網頁上的範例,試一下,確定你的 clang 是好的。記得要把 clang / libclang.a / libclang.so / clang.dll 的位置加到 PATH 中。
  3. 安裝 Vim plug-in clang_complete,參考作者的安裝說明,或是你有使用 pathogen.vim 在管理 plug-in 的話,那麼不用我說,你一定知道要怎麼裝!
  4. 根據我的經驗,在 windows 的話,要複製一份 clang.dll 改名為 libclang.dll,這樣 clang_complete 才找得到。

使用方式

  1. 當打到 . / -> / :: 等的時候,補完視窗就會自己跳出,或是可以按 。
  2. 其他相關的使用與設定
  3. clang_complete 會跟一些補完的套件衝突,例如 OmniCppComplete,記得要先把那些停掉。

延伸 Reference

成為一個努力的人 -- 我的 MOOCs 之旅

記得在去年底的時候,我對自己許了一個新年願望:希望在新的一年,每一天都可以覺得比昨天的自己又更進步了,就如同網路上流傳的一句話「每天進步0.01!一年後你就比現在強大36倍!」。是的,我想成為一個努力的人,我想透過一連串的習慣與改變,讓自己更努力。 不過說真的,要一直努力,其...