2013年7月12日 星期五

讓 Vim 採用基於視覺行的游標移動

Vim 是一款文字編輯器,就是和微軟的記事本有著同樣用途的那種東西。

Vim 的其中一種介面--Gvim
這玩意兒外觀看起來破破的,但在同類軟體之中,其功能之強彈性之大卻是罕有敵手,我現在差不多寫任何純文字的東西都靠這個。

不過話說回來,Vim 彈性太大也導致了一些問題:因為各式各樣不同的人都在用它,如果沒有好好對它施以教育(設定),讓它適應自己的使用習慣,它可一點也不好用。但即使下定決心要對它進行設定,光基本設定參數就好長一大堆,初學者初設定時一定會昏倒個兩三回,這也實在……

不抱怨了,今天就來聊聊其中一項設定:「基於視覺行的游標移動。」



視覺行與實體行是啥?

在進入正文前,先簡單介紹一下視覺行與實體行的差異。

範例文字:以上這段文字中有 4 個實體行和 10 個視覺行。源自維基百科。

實體行

按 Enter 鍵時產生的行被稱為實體行。總地來說,實體行的行尾一定是 Enter 或文件尾巴。在網頁上,一個實體行也往往會被當成一個段落。實體行的英文正式稱呼為 "physical line",有時也被稱呼為 "logical line"。

視覺行

因為視窗橫向空間不足,而自動折行產生的新行就叫作視覺行。行數會受到視窗寬度影響而會自動變化。一般而言,網頁中一個段落(等於實體行)可能會佔據著很多個視覺行。視覺行似乎沒有正式的稱呼方式,這三個字是我自己發明的。



在用 Word 或其他文書或文字編輯軟體時,我們移動游標時都是依據視覺行來移動的:按「上」向上移動一個視覺行,按「下」游標下跑一個視覺行……理所當然!但 Vim 的游標偏偏是基於實體行來移動:按上下鍵時,游標是一次跳一個實體行。

……要我說啊,這實在是怪斃了!

寫程式時因為單獨的實體行都不長,如此操作倒也沒太大差別。不過當寫網誌或小說時,每個實體行都會因為過長而被折成好多個顯示行,基於實體行的移動此時就變得很不直覺,而且礙手礙腳,選字超麻煩,讓咱想在手與鍵盤之間選一個來砸。

其實這時該砸的是 Vim 才對。

Vim 的調整方法

我寫了些設定來把 Vim 教得更聰明一點。總之,請將以下設定貼入 Vim 的設定檔 vimrc 中。


    "===視覺光標操作 ===
    "一言以蔽之,按上下鍵將變更光標所處的可視行,而非實體行。
    noremap <silent> <Leader>w :call ToggleDisplayMove()<CR>

    let ToggleDisplayMove_Mode = 0

    function PhysicalLineMove()
        silent! nunmap <buffer> <Up>
        silent! nunmap <buffer> <Down>
        silent! nunmap <buffer> <Home>
        silent! nunmap <buffer> <End>
        silent! iunmap <buffer> <Up>
        silent! iunmap <buffer> <Down>
        silent! iunmap <buffer> <Home>
        silent! iunmap <buffer> <End>
        let g:ToggleDisplayMove_Mode = 0
    endfunction

    function DisplayedLineMove()
        noremap  <buffer> <silent> <Up>   gk
        noremap  <buffer> <silent> <Down> gj
        noremap  <buffer> <silent> <Home> g<Home>
        noremap  <buffer> <silent> <End>  g<End>
        inoremap <buffer> <silent> <Up>   <C-o>gk
        inoremap <buffer> <silent> <Down> <C-o>gj
        inoremap <buffer> <silent> <Home> <C-o>g<Home>
        inoremap <buffer> <silent> <End>  <C-o>g<End>
        let g:ToggleDisplayMove_Mode = 1    
    endfunction

    function ToggleDisplayMove()
        if g:ToggleDisplayMove_Mode
            call PhysicalLineMove()
            echo "Move cursor now base on PHYSICAL LINE"
        else
            call DisplayedLineMove()
            echo "Move cursor now base on DISPLAYED LINE"
        endif
    endfunction

    call DisplayedLineMove()


如此一來,Vim 預設就會採用「基於視覺行」的移動了。而當您想在兩種移動模式間切換時,只要輸入 <Leader>w 就可以無痛進行切換。

Vim 再教育完畢!Key 小說去吧。

參考資料

  • Vim 的設定說明(英),心臟不夠大顆者還請慎入,偏好中文的人則可以試著看簡中版。順便一提,我一直覺得 Vim 說明手冊的格式很不好讀,不知道為什麼設計成這樣。 
  • Leader 預設為 \,所以就是輸入 \w 切換。 
  • 我搜了一下,Vim 好像沒怎麼被娘化,這真是太奇怪了!不過話又說回來,我總覺得 Vim 其實應該是正太、弟弟、男的!而且氣質還類似於 Chobits 裡的那隻 ……

沒有留言:

張貼留言

☆每日吐嘈,有益身心☆
…不過還是請手下留情別太狠啊。