Vim 外掛程式 FuzzyFinder 實在方便。(但這篇不含介紹)

除了找檔案、buffer、help 等 13 目標外,亦有 API 讓其他資料享用其搜尋介面。

以下使用 FuzzyFinder 的 Callback-Item 模式,列出所有 register,選取項目並開啟時,便直接貼上 register 內容,或噴到一個新視窗(可編輯後再手動 :%y x 存回 x register)。 尚有毛病但還堪用。

具體用例:

  • <LocalLeader>fp → 開啟 registers 選單。選好按 <CR> 貼上,或按 <LocalLeader><CR> 開到新視窗。
  • <LocalLeader>fP → 同上,但貼在游標之前。

選單展開(看得出顯示有問題)

單行太長時,顯示有問題

將 @7 內容開到新視窗

上面視窗即 @7 的內容


程式碼展開如下(放在 .vimrc)

let g:fuf_regListener = {}
let g:fuf_regListener.putBefore = 0   " 0: p, 1: P

function! g:fuf_regListener.onComplete(item, method)
  let l:regName = strpart(a:item, 1, 1)
  if a:method == 4
    silent exec 'normal "' . l:regName . (g:fuf_regListener.putBefore ? 'P' : 'p')
  else
    exec '7new [@' . escape( l:regName, '"' ) . ']'
    setlocal noswapfile buftype=nofile bufhidden=wipe
    exec '0put=@' . l:regName
    redraw
    setlocal nomodified
  endif
endf

function! g:fuf_regListener.onAbort()
endf

function! g:fuf_regFinder(putBefore)
  let g:fuf_regListener.putBefore = a:putBefore
  redir => l:regs
  silent exec ':registers'
  redir END
  let l:regList = split(l:regs, '\n')
  let l:regList = filter(l:regList, 'v:val =~ "' . escape('\m^".\s\{3,}\S\+', '\"') . '"')  " remove non-register lines
  "let l:regList = map(l:regList, 'substitute(v:val, "\\m.\\{' . &columns . '}\\zs.*", "...", "")')  " has problem with long line
  call fuf#callbackitem#launch('', 1, 'registers>', g:fuf_regListener, l:regList, 0)
endf

nnoremap <LocalLeader>fp :call g:fuf_regFinder(0)<CR>
nnoremap <LocalLeader>fP :call g:fuf_regFinder(1)<CR>

其中 onCompletemethod 參數,取決於選擇項目時按了哪個 FuzzyFinder 的 mapping(詳見 |fuf-options|):

  • 1 → 普通開啟
  • 2 → split 開啟
  • 3 → vsplit 開啟(我 map 到 <LocalLeader><CR>
  • 4 → tab 開啟(我 map 到 <CR>

程式在 register 單行內容很長時會有問題:選單顯示錯誤/無法取得 register 名稱。把後面截斷可解決(但截掉部份當然搜不到)。暫且加上 nowrap 減少狀況:autocmd BufEnter \[fuf\] setlocal nowrap


幾支 register 相關 plugin,也許這才是你要的:

  • YankRing.vimp 貼完以後,按 <CTRL-P> 可以立刻換成其他剪下的內容。也可開視窗檢視過去 yank 內容。
  • tregisters: 可列出 register 還能直接編輯,不過我沒裝成功。