沒穿方服

封存

顯示╱隱藏內文

對齊文字用的 plugin,以前我是用 Dr. ChipAlign.vim,現在換成 Alignta 了;雖然預設功能比較不豐富,但實在好懂多了。

目前 ver. 0.2.1 只有日本語的 doc,如果 help 打不開(E426),可能要先 :set notagbsearch


SYNOPSIS of Alignta command (for v. 0.2.1, UNOFFICIAL)

                              (Shifting
                               Alignment)
                                 <- 
                                 -> 
                                 <--
                                 -->

:[range]Alignta[!] [filter]  [align method][margin]   [-p] pattern[{count}] [pattern2 ...]

                   g/pattern  (Padding                              number
                   v/pattern   Alignment)                            '+'
                                  <           n:n                
                                  |        [0-9][0-9]
                                  >          [0-9]
                                  =          
                              (repeat as     @margin
                                LM[R]...)
  • !

    有 ! 的話,pattern 會被解釋為 regexp。

  • filter

    指定忽略哪些特殊的行(通常是註解)不進行對齊。g/pattern 只處理符合的行;v/pattern 不處理符合的行。

  • align method

    Alignta 的對齊分為 Shifting Alignment 和 Padding Alignment 兩種。
    align method 參數也分為兩套,區別是哪一套的同時,也用來指定對齊細節。

    Shifting Alignment 比較簡單,只是將 pattern 的開頭垂直排在一起。
    <- 是將每一行符合的部分,對齊到其中最靠左的 column;-> 則是對齊到最靠右的 column。
    兩個 dash 的版本(例如 -->)表示使用 tab 字元排版。

    另一種 Padding Alignment 是依 patten 將文字拆成多個欄位。
    以 {L}{M}{R} 為一個單位,{M} 就是 pattern 符合的欄,{L}{R} 是它的左右側。 可以用 <|>= 指定各欄位靠左、靠中、靠右或保持原本方式對齊。
    註:{R} 可省略,表示跟 {L} 相同,例如 :Alignta <|> = 讓等號兩邊靠外對齊。
    註:若後面有指定多個 pattern,這裡可以重覆 {L}{M}{R} 來指定多個對齊方式。

  • margin

    指定各欄位的間隔。
    一般是配合 align metohd,有幾個欄位就寫幾個 margin,各個 margin 以冒號分開,例如 :Alignta <<3:1 =
    也可簡寫為 {L-margin}{R-margin} 或 {LR-margin},但 margin 必須是個位數( 0-9,10 就不行了), 例如 46 即 4:6,4 即 4:4。
    若沒有 align method,只想設 margin 時,在前面加 @ 即可,例如 :Alignta @00 =

  • -p

    如果後面的 pattern 是特殊字,加上 -p 可確保它被視為 pattern。 例如 :Alignta -p << 是以 << 作為 pattern。

  • pattern[{count}]

    pattern 指定要用什麼來對齊。
    如果有設定 alignta_default_arguments 變數,那這個也能省略。

    pattern 後面可以加 {count},指定要符合幾次,超過 count 就不會再對齊了。
    例如 :Alignta ={2} 只會處理前兩個等號,之後的就保持原狀。
    {+} 表示有 pattern 符合時才對齊,否則不理它。

    count 的預設值在 Shifting Alignment 是 {1},Padding Alignment 是 {+}

  • pattern2 ...

    支援複數的 pattern,直接寫在後面。例如 :Alignta = /* */

  • :Align

    如果沒裝 Align.vim,那 :Align 就是 :Alignta 的別名,直接用 :Align 也 OK。

Help 檔案中,超連結的寫法是用兩個星號圍起來,例如:

*starting.txt*  For Vim version 7.3.  Last change: 2010 Sep 18
                                        *bold* *underline* *undercurl*
                                        *inverse* *italic* *standout*
term={attr-list}                        *attr-list* *highlight-term* *E418*
                                                        *right-justify*
PREVENTING LOADING                                              *netrw-noload*

如果是寫在行尾的,我就每次看了都想把它靠右對齊……

目前應該是沒這規範,看過的 help 也沒特別處理;總之我寫了一個 function 來做這件事;
只支援單行、只處理最後一個 *entry*,超過 'textwidth' 的也不管:

Right justify *keyword* in Vim help files. — Gist


使用前('textwidth' 為 78,游標在 CONFIGURATION 那一行)

==============================================================================
CONFIGURATION                         *gsession-configuration*

使用後

==============================================================================
CONFIGURATION                                         *gsession-configuration*

可以在 filetype 為 help 時定義這個 key mapping

nnoremap <silent> <buffer> <LocalLeader>= :call HelpHyperTextEntryJustify()<Enter>

原版的 ShowMarks 在 2004 後就沒更新了,在 Vim7 使用會有一些問題。 我聯絡不上作者,又 script 授權是 public domain,於是直接開個版本來維護:

bootleq/ShowMarks - GitHub

其中幾個修改參考了 vi/vim使用进阶: 指随意动,移动如飞 (二) – 易水博客 的 patch。

主要問題與修改

  • key mapping

    ※如果你有舊版,可以下 :verbose map <Leader>m 檢視它定義的 5 個 mapping,另有 \smm 也是。
    commit:a7d7d62 首先要改的是 map => nmap,以免在 Visual mode 或 Select mode(例如 snipMate 停著等輸入時就是 Select mode)按 m 變成 ShowMarks 操作導致錯誤。
    再來增加了停用預設 mapping 的選項和 <Plug>ShowMarksOn 這樣的 mapping(讓使用者用 map mo <Plug>ShowMarksOn 自訂按鍵),應該是 plugin 預設 map 的最佳作法。 commit:72727b 另外原版用到 \sm 來轉接 m 指令(以便按下 m 時,除了原本 m 要做的事,還要 call 別的函數),這裡利用 :normal! 不會被 remap 的特性取代,也把它拿掉了。
  • 「刪除 mark」的實作

    commit:7ad76a
    單純是 Vim7 的新功能 :delmarks
    舊版 :ShowMarksClearMark 作法是把 mark 都移到第 0 行,幾乎是不堪用的。
  • 判斷 mark 所在行數

    commit:6e087f4
    Vim 6/7 處理 line("'g")(取 g mark 的行數)時,若 mark 在別的 buffer 就會有不一致結果。
    單純改用 getpos("'g") 來判斷。
  • 放棄 Vim 6 以下的支援

    掰掰。

先推薦一下 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 裡用就好了。