沒穿方服

索引

顯示╱隱藏內文

先推薦一下 EasyMotion

這幾天試用的 EasyMotion 某些場合下確實能增加編輯速度。 雖然使用頻率不高,但暫時也不會移除。

打從開始學 Vim 我就一向不相信「鍵盤比較快,請把滑鼠忘了」這種說法(現在也是)。
有時為了移動到某個位置,會進行很多無謂 motion,當按了大概 6 個鍵還到不了目標時,就會懊惱哦、我好慢!
目前感覺 EasyMotion 有打到這個問題,所以會繼續裝著、繼續驗證。

很難決定要設什麼 key

預設是用 <Leader>(\)開頭,配上 motion 指令就會發動,例如 \w\f\j
顯然 <Leader> 太容易跟別人相衝,plugin 也提供了方便把 leader 鍵換掉的選項,
但是要換哪個 key 還是很難決定。

ZeroMotion

最後想法是用 0 當 leader 鍵,語義上是把 motion 前的 {count} 變成 0
沒人知道 count 時,終極狀況就是沒有 count,不過 count 預設是 1,所以我只好下 0
多少也呼應原設計

It takes the <number> out of <number>w or <number>f{char} by highlighting all possible choices and allowing you to press one key to jump directly to the target.

0 不會太難按,平常也不會使用 0w0j(沒有這樣的 count),所以不易衝突。
缺點是把原本的 0(跳到第一個字)指令蓋掉了;
我是認為 0 幾乎用不到,通常 <Home>^ 就夠了,所以直接放棄。

map 指令的 {lhs} 可以不是用來 key 的。
這個用法至少在 2007 就被分享過(Vim: <Space>で始まるkey mappingの可視化 - while ("im automaton");)不過我是前陣子才知道的,sorry。

原本以為 map 就是 map 一個鍵,例如 map <C-S> :update<CR>
或 map 一串 key sequence 如 map jk zz

其實可以在 {lhs} 放抽象的 key sequence,例如以下 unite.vim 設定例片段:

nnoremap [unite] <Nop>
nmap f [unite]

nnoremap <silent> [unite]c :<C-u>UniteWithCurrentDir -buffer-name=files buffer file_mru bookmark file<CR>
nnoremap <silent> [unite]b :<C-u>UniteWithBufferDir -buffer-name=files -prompt=%\ buffer file_mru bookmark file<CR>
nnoremap <silent> [unite]r :<C-u>Unite -buffer-name=register register<CR>
nnoremap <silent> [unite]o :<C-u>Unite outline<CR>

定義了 [unite] 來取代 f,這樣就可以寫 [unite]c,使用時卻是按 fc。 有幾個好處:
1) 更好讀。
2) 不想用 f 要換掉時,只要改一個地方即可。
3) 按下 f 時,畫面下方會顯示 [fuf](如果沒把 'showcmd' 關掉的話),相當有意義。


再舉這幾天試用的 EasyMotion 設定為例:

noremap [emotion] <Nop>
noremap [emotion]<Space> f
map f [emotion]
let g:EasyMotion_leader_key = '[emotion]'

[emotion] 拿來當 EasyMotion 的啟動鍵,實際上是 f
想用原本的 f 時,就按 f<Space>


此外在 plugin 中常看到這樣的寫法(取自 rails.vim):

nnoremap <buffer> <silent> <Plug>RailsAlternate  :<C-U>A<CR>
nnoremap <buffer> <silent> <Plug>RailsRelated    :<C-U>R<CR>
nnoremap <buffer> <silent> <Plug>RailsFind       :<C-U>REfind<CR>

其中 nnoremap <Plug>RailsFind 看起來跟這篇道理很像,可以方便用 map <Plug>RailsFind 來定義 plugin 的 map。 不過 <Plug> 其實是 map 的一個保留字 <Plug>,把 <Plug>foo 放 {rhs} 時 'showcmd' 顯示也怪怪的;所以雖然可以用,還是先在 plugin 裡用就好了。

UNITE ALL SOURCES

為了寫這篇,還特地試了一下 Command-T 這個搜尋工具,它找的 source 是「檔案」。

Command-T 快速找到檔案,輸入框在圖片下方

Command-T

而我慣用的 FuzzyFinder 則是能找更多東西,例如之前寫過找 register分頁;執行的動作也不一定是「開啟」,可以是貼上、跳過去或其他。
加這些 script 時難免會想「不管什麼東西,只要 能找 的都交給 FuzzyFinder 吧」。

在另一個 plugin: ku 裡這些「能找的東西」被進一步定義為 source
ku 在自訂 source 和相應的動作上有更完整的設計,而不是有「本來是用來找 file」的味道。

ku 找檔案的樣子

ku 找 file

按了 <Tab> 可以選 action,預設 mapping 跟 unite.vim 大致一樣

ku 選 action

最近才發現一個新的,Shougo 寫的 unite.vim,因為看到高手的設定檔換上了,就來試試。

不依靠 completion 介面

Unite.vim 第一個明顯特色是打開尋找 window 後,彈出選項的介面不是 Vim 的 completion 功能(按 <C-X><C-P> 彈出來的那種),而是自己在 buffer 裡畫出來的。
這表示可以進入 normal mode 改你的關鍵字,plugin 也更有機會對選項動手腳,畢竟 completion 原本用在 insert mode,確實限制較多。

左邊 split 的視窗就是 unite,大得嚇人(預設是水平 split 在上方,但還是很高)
這裡可以「多選」,以前是做不到的。

unite 多選

當然也有模糊搜尋,例如輸入 **/*re 7 !2 縮小搜尋結果

filter search

Buffer 裡面可以亂搞,例如可以進 visual mode 多選

visual mode

依照 source 的 kind 選擇能用的動作,概念跟 ku 差不多

選 action

好多好用的 source

Register、分頁都是預設就有了,doc 裡還有一堆,讀完還可以看 github wiki 上的 unite plugins,經常有新的 source 真是強大到令人生氣。
而且沒有限制一次只能找一種 source,例如 :Unite file buffer file_mru 會把檔案、buffer 和最近開的檔案放一起給你選。

找 register

找 register

/ 搜尋的結果當成 source,也是預設功能

find

把任意命令的輸出當成 source,例加下面是 :Unite output:version,這也是預設功能

unite output

結論

兩個問題 1) 開出來的 window 太大,好醜 2) 目前還是太常遇到 error
主要是問題 1 好像無解,所以我要繼續用 FuzzyFinder…… 不然其實解這些 error 也很有啟發性。
至於 ku 試了一下好像速度比較慢(可能 cache 沒設好?)文件也不是很全,有點疑惑為什麼不沿續開發 FuzzyFinder 就好。

按方向鍵的左,變成這樣,應該是鍵盤送出 ^[OD 的關係吧

error

輸入關鍵字時也可以按 <C-J> 切換選項,可是這時還在 insert mode,不小心會按到插字

E21

一邊喝飲料一邊讀別人的 vimrc 真是很棒的休閒活動。
我也想分享 vimrc 提供社群讀物。

於是建了一個 vimrc_human, 內容就是我的 vimrc 加上詳細註解(現在第一個 commit,都還沒加……),但也因為如此,它很難是我的最新設定。

bootleq/vimrc_human - GitHub

另一特徵是用 Vundle 管理 plugin、colorscheme 等擴充功能(沒聽過,可參考 Vundle, Bundler for Vim : O3noBLOG 簡介),Vundle 加上一些對 runtimepath 的處理,可以把整個環境裝到 /tmp/ 目錄下,避免跟原本的 ~/.vim 相衝(利用 rtp-=~/.vim,但 plugin 仍可能用到 ~/.vim 就是),讓「裝來玩玩」這件事變簡單了。
具體請參考 github 上的 README

註:

  1. 目前不支援 Windows 上的 gVim。 我自己用 Cygwin + gVim 是還可以。
  2. 「裝來玩」這件事是有安全性疑慮的,畢竟 vim script 神通廣大,請自己小心。

收到使用者對 Noise 的問題

為了等待某個詞的出現,我讓一個討論區,請一個外掛,不停地、不停地重讀。
假如能夠 find 到那個詞時,發出聲音通知我,

我就可以同時做別的事了。

解決辦法,在 Noise 設定這個聲音

DOMContentLoaded&gBrowser.contentWindow.find('WORD_I_CARE')

(事件類型是 window event)

每次 DOM 讀完後,便自動進行尋找(Ctrl + F),若有找到就發出聲音。

實際上要加入網址限制,免得每個網站都自動尋找:

DOMContentLoaded&(event.target.location.host==='www.forum.com'&&gBrowser.contentWindow.find('WORD_I_CARE'))

除了 host,也有其他屬性可用來設限制,參考 window.location (#properties) - MDC Doc Center

設定畫面