Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

clurin.vim = cycle.vim + switch.vim + α?

$
0
0

はじめに

これまで、switch.vimを使っていると、順方向にしかいけないことと, ctrl-A+に割り振りたいことなどに不満がでてきたので、clurin.vimを作ってみた。

提供する機能により、SunMonTue→ ... のような切り替えができます。本プラグインの特徴は以下の通りです

  • 正規表現での指定が可能 (switch.vim相当の機能はだいたいできる.)
  • 順方向だけでなく逆方向にもたどれる (cycle.vim相当のことができる)
  • n 個先にも飛べる
  • カーソル直下の文字にマッチするものがなかった場合の処理を設定可能
  • ファイルタイプ毎の設定が容易. (好みの問題かも)

switch.vimからの現時点での機能落ちは以下だと思います. 他にもあったらごめんなさい。

  • separate mappings (あまり必要性が...)
  • nested dict definitions (実現できないわけではない)

使い方

.vimrcに以下のように書いてください。

nmap +<Plug>(clurin-next)
nmap -<Plug>(clurin-prev)
vmap +<Plug>(clurin-next)
vmap -<Plug>(clurin-prev)

あとは、
1. Sunという文字列の上にカーソルを置いて,
2. +を押すと, Monになり,
3. 2+を押すと, Wedになり,
4. -を押すと, Tueになります.

カスタマイズ

設定はグローバル変数 g:clurinの定義により行います。g:clurinfiletypeをキーとする辞書です。 switch.vimでは「次にいくにはどう変換するか」を定義しますが、clurin.vimでは「自分になるにはどう変換するか」を定義します。以下に例を示します。

function!g:CountUp(str, cnt,def) abort
  " a:str: マッチした文字列  " a:cnt: clurin-next なら正の値, clurin-prev なら負の値  " a:def: マッチした定義return str2nr(a:str)+a:cnt
endfunctionfunction!g:CtrlAX(cnt) abort 
    ifa:cnt >=0
        execute 'normal!'a:cnt . "\<C-A>"else
        execute 'normal!'(-a:cnt) . "\<C-X>"endifendfunctionletg:clurin = {
\    '-': {
\        'def': [
\            ['on','off'],
\            [
\                {'pattern': '\<true\>','replace': 'true'},
\                {'pattern': '\<false\>','replace': 'false'}
\            ], 
\        ]  
\    }, 
\    'c': {
\        'def': [
\            ['&&','||'],
\            [
\                {'pattern': '\(\k\+\)\.','replace': '\1.'},
\                {'pattern': '\(\k\+\)->','replace': '\1->'}
\            ]  
\        ], 
\        'nomatch': function('g:CtrlAX')
\    }, 
\    'vim': {
\        'def': [
\            [
\                {'pattern': '''\(\k\+\)''','replace': '''\1'''},
\                {'pattern': '"\(\k\+\)"','replace': '"\1"'}
\            ],
\            [
\                {'pattern': '\(-\?\d\+\)','replace': function('g:CountUp')}
\            ]
\        ]  
\    }  
\}  

詳細をみていくと、

let g:clurin = {
\    '-': {

-はデフォルトの設定を表します。通常すべてのファイルタイプで使用されます。
cft=cの場合専用の設定になります。

\        'def': [
\            ['on', 'off'],

defの値はリストで、そこに切り替えるグループを定義します。この場合、onoffを切り替える定義になっています。

\            [
\                {'pattern': '\<true\>', 'replace': 'true'},
\                {'pattern': '\<false\>', 'replace': 'false'}
\            ], 
....
\            [
\                {'pattern': '\(\k\+\)\.', 'replace': '\1.'},
\                {'pattern': '\(\k\+\)->', 'replace': '\1->'}
\            ]  

正規表現を使いたい場合には、文字列ではなく辞書を使用します。patternにマッチしたもの, replaceに自分に変換するときのルールを書きます. 上のグループは truefalseのグループを表しています.

\        'nomatch': function('g:CtrlAX')

マッチするものがなかった場合の処理を Funcref で渡すことができます. この設定の場合, g:CtrlAXを呼び出して、Ctrl-A, Ctrl-X相当を実現しています。

\            [
\                {'pattern': '\(-\?\d\+\)', 'replace': function('g:CountUp')}
\            ]

(だいぶルール違反な気もしていますが)変換ルールに Funcref を渡すことも可能です。
うまく定義してやれば, vim-speeddatingと共存みたいなこともできると思いますし, switch.vimNested dict definitionsも実現できるはずです。

その他、サイクリックにしないとか、デフォルトの設定を利用しないとかも指定できます。詳細は近いうち更新されるであろうヘルプを参照してください。

マッチ判定ルール

カーソル下の文字列が複数のパターンにマッチする場合には以下の優先順位によりどのパターンを利用するかを判定します.
1. 開始位置がカーソル位置に近いほう
2. 対象文字列が短いほう
3. 定義された位置がはやいほう

どちらの場合もマッチしなかったほうがカーソル位置を移動すればマッチ対象にできるので、このルールを使用するようにしました。

定義は以下の順序で探索します.
1. g:clurin[&filetype]
2. g:clurin['-']
3. clurin.vimデフォルトの &filetype用定義
4. clurin.vimデフォルト定義 (-)

おわりに

何か問題・リクエスト等あれば issuesによろしくお願いします.


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>