LoginSignup
0
0

More than 5 years have passed since last update.

Vim script でオブジェクト指向とイベント駆動っぽいコードを書き捨てたので供養

Last updated at Posted at 2019-03-21

はじめに

この記事には Vim ユーザにとって便利なことはあまり書かれていない気がします。
Vim script を記述する際に面白い感じのコードを書いてみて、放置することに決めたので供養するための記事です。

やったこと

オブジェクト指向 + イベント駆動でバッファを更新するスクリプトを書いてみた。

オブジェクト指向っぽさ

下記のコードを書いてインスタンスを生成して利用します。
これは割と有名な書き方な気がします。

function! your#namespace#new()
  return s:Prototype.new()
endfunction

let s:Prototype = {}

function! s:Prototype.new()
  return extend(deepcopy(s:Prototype), {
    \    'flag': v:false
    \ })
endfunction

function! s:Prototype.toggle()
  let self.flag = !self.flag
endfunction

イベント駆動っぽさ

Vim にはビルトインでイベントを発火する仕組みがあります。(autocmd と呼ぶ)

しかし、基本的にグローバルな領域で発火されるので「特定インスタンスのメソッドをコールバックで呼ぶ」というののやり方がやりにくいです。(と思っているが、簡単な方法があるのかも)

自分はいいやり方がわからなかったので、下記のようなコードを書いてインスタンスとコールバック関数を紐づけてみました。(今回はバッファに紐づくインスタンスという形を取ってみました。)

function! your#namespace#new()
  return s:Prototype.new()
endfunction

let s:Prototype = {}

function! s:Prototype.new()
  let instance = extend(deepcopy(s:Prototype), {
    \    'bufnr': -1
    \ })

  " buffer を作成して、bufnr をインスタンスに紐付ける
  badd prototype
  let instance.bufnr = bufnr('$')

  " 管理バッファで発生したイベントにインスタンスのコールバックを登録する
  augroup printf('prototype_%s', self.bufnr)
    autocmd!
    call self.bind_autocmd('BufWinEnter', function(self.on_buf_win_enter))
    call self.bind_autocmd('BufWinLeave', function(self.on_buf_win_leave))
  augroup END

  return instance
endfunction

function! s:Prototype.on_buf_win_enter()
  echomsg 'on_buf_win_enter'
endfunction

function! s:Prototype.on_buf_win_leave()
  echomsg 'on_buf_win_leave'
endfunction

function! s:Prototype.bind_autocmd(event, func)
  call setbufvar(self.bufnr, printf('prototype_%s', a:event),  a:func)
  execute printf('autocmd! %s <buffer=%s> call getbufvar(%s, "prototype_%s")()',
        \ a:event,
        \ self.bufnr,
        \ self.bufnr,
        \ a:event)
endfunction

終わりに

なにか denite.nvim のようなピッカーを書いてみようかなとお勉強がてらコードを書いてみていて、面白い書き方になってきたので記事にしてみました。
コードはここにあります。

どう考えてもフィルタ速度が問題になりそうだし、denite.nvim 規模まで育てるのは無理だ。と悟ったので放置することに決め込んで記事を書いて供養とすることにしました。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0