物置き

smartchr周りの設定を変更

先日のエントリで設定したものを使っているうちに、置換モードで入力している時は、smartchrの機能を無効にしたいと思った。
そこで、直接smartchr#one_ofを呼ぶのではなく、
間にラッパー関数を置いて、そこで現在のモードをチェックして
置換モードだったら、smartchr#one_ofを呼ばないようにした。
また、ついでに先日のエントリでの、直前のパターンを指定する処理もこのラッパー関数で行うようにした。
こんな感じ。

function! Customchr(org_char, ...)
  let md = mode()
  " 置換モードの場合は何もしない
  if md == 'R' | return a:org_char | endif

  for i in range(0, len(a:000)-1)
    " 可変長引数部に文字列が入っていた時、以前の型がリストの場合
    " エラーになるための対処
    if exists('x')| unlet x | endif
    let x = a:000[i]
    " 文字列が渡されたら、それをそのまま返す
    if type(x) == type('') | return x | endif
    if type(x) != type([]) | continue | endif

    let t = type(x[0])
    if t == type(function('tr'))
      return call(x[0], x[1:])
    endif

    let array = []
    if (t == type([]))
      let array = x[0]
    elseif (t == type('') && search(x[0].'\%#', 'bcn')) || (t == type(0) && x[0] != 0)
      let array = x[1:]
    endif

    if len(array) > 0
      if type(array[0]) == type(function('tr'))
        return call(array[0], array[1:])
      elseif type(array[0]) == type('')
        return call('smartchr#one_of', array)
      elseif type(array[0]) == type([])
        return call('smartchr#one_of', array[0])
      endif
      return a:org_char
    endif
  endfor
  return a:org_char
endfunction

# ついでのわりには、そっちまわりの処理のほうが長くなってしまったが・・


最初のパラメータで、元の文字を指定する。これは置換モードだった場合に元のテキストを入力するために使うため。
二つ目以降のパラメータはリストを指定する。
リストの最初の要素が文字列だった場合は、カーソル直前のパターンであるものとして評価する。
パターンは、必ず「カーソル直前」のパターンとして評価される(内部で'\%#'を付加しているため)
最初の要素が数値だった場合は真偽値として評価を行う。
評価結果が真だった場合に、そのリストの2番目以降の内容で返す文字列を決定する。
最初の要素が関数参照だった場合は、それをそのままよびだす。
引数は以降の要素をそのままわたす。
最初の要素がリストだった場合、それをそのままsmartchr#one_ofに渡す。


最初の要素が文字列または数値で、
2番目の要素が文字列だった場合は、以降の要素をそのままsmartchr#one_ofに渡す。
2番目の要素が関数への参照だった場合はそれを呼び出す。
関数呼び出しの際の引数は、関数参照以降のリスト要素をそのまま渡す。

(しかし、こうして書くと結構ややこしいな・・)

使う際はこんな感じで。

inoremap <buffer><expr> < Customchr('<',
			\['^#include', ' <'], ['\<template','<'], [[' < ', ' << ', '<']])

・・・んー、前よりもましにはなったけど、まだ微妙な感じがしなくもない・・

ちなみに上記の例のこの場合、'<'を入力する際、
カーソル直前のテキストが「^#include」だったら)(つまり、行頭が#includeだったら)
' <'を挿入し(#includeと'<'の間に空白を入れる)
そうでなかったら、直前のテキストが「template」だったら、空白を入れずに<を挿入し、それも一致しない場合にはsmartchr#one_of(' < ', ' << ', '<')を呼ぶ、というもの。


というのをラッパー関数を書いたけど、今朝smartchr.vimの作者の方のBlogのエントリでこんな記述を発見。

smartchr - separate search patterns and texts to be inserted


おお。それが実現すれば、このラッパー関数でやっていることはやらずに済む。
これはwktkでござる。
あと、

tab pages in MRU-order


というのも気になる。これもwktk