Closed17

NeoVimのPluginを作ってみる①

JJJJ

とりあえずコマンドを呼んで、そこに入力したものを表示しながらeditができて、そのeditした情報をRust側で取得したい。
やりたいこととしては、vim-fugitiveでcommitをする時に指定してるeditorが立ち上がり、ファイルとしてどこかに保存するわけではないが保存した内容を取得はしたい。

JJJJ

大事なのはここら辺っぽい

function! testplugin#open_buffer() abort
  split hoge
  call append(0, 'hoge')
  call deletebufline('%', '$')
  setlocal buftype=nofile
  setlocal bufhidden=hide
  setlocal noswapfile nobuflisted
endfunction
JJJJ

何かを閲覧するだけとか、特定のキーを押したときにだけ反応させるとかであれば

nnoremap <silent> <buffer> call ...

<CR> にひっかけて getline('.') すればいい感じに出来るので buftype=nofile とかでひらけば良さそう。

JJJJ

上のやつ試したけど、書き込めないなと思って :Git を見直したけど、gitは .git/COMMIT_EDITMSG というファイルでやりとりしてるっぽいな...

JJJJ

plugin配下に適当にファイルを作って、それを操作してあとで消すみたいな方針が無難か...??
いったんそうの方針にしてみようか...

  1. fileを作る
  2. split filename でそのfileを開く
  3. 編集する
  4. 保存したらそのfileの中身を読み込む
  5. stdoutに吐く
  6. fileを削除する

でやってみるか👀

JJJJ

4が激ムズな気がする...
bufferを開くまではいいが開いたbufferを保存したかどうかってどうやったらわかるんだ...?

JJJJ

うーん、どうやらvirtual bufferというのがあるっぽい?👀

JJJJ

autocmdで BufWriteCmd をひっかけてコールするといけるっぽい。

JJJJ
function! s:read(args)
  augroup vimrpcsample-new-buffer
    autocmd!
    autocmd BufWriteCmd new-buffer call s:on_save()
  augroup END

  new
  call setline(1, a:args)

  file new-buffer
  set nomodified
  setlocal buftype=acwrite
  setlocal filetype=md
  setlocal noswapfile
endfunction

function! s:on_save()
  let lines = getline(0, line("$"))
  " bw new-buffer

  echo lines
  " call rpcnotify(s:vimrpcsampleJobId, "save", lines)
endfunction

こんな感じで、とりあえず :call s:read('hoge') 実行すると hoge って文字列が入った状態で画面上に新しいbufferが生まれる。んで、 :w:wq をするとその情報が取得できる。が、bufferを削除出来ていない。

bw new-buffer を実行すれば消せるんだけど、 :wq をしてた場合は元々開いてたbufferも抜けてしまう

JJJJ
function! s:read(args)
  augroup vimrpcsample-new-buffer
    autocmd!
    autocmd BufWriteCmd new-buffer call s:on_save()
  augroup END

  let s:parent_bufnr = bufnr('%')

  new
  call setline(1, a:args)

  file new-buffer
  set nomodified
  setlocal buftype=acwrite
  setlocal filetype=md
  setlocal noswapfile
endfunction

function! s:find_buf(bufnr) abort
  if !exists('*win_findbuf')
    " win_findbuf() is available since patch 7.4.1558
    return []
  endif

  return win_findbuf(a:bufnr)
endfunction

function! s:get_winid() abort
  if !exists('*win_getid')
    " win_getid() is available since patch 7.4.1557
    return 0
  endif

  return win_getid()
endfunction

function! s:gotoid(expr) abort
  if !exists('*win_gotoid')
    " win_gotoid() is available since patch 7.4.1557
    return 0
  endif

  return win_gotoid(a:expr)
endfunction

function! s:on_save()
  let lines = getline(1, line("$"))
  set nomodified

  echo lines

  let win_ids = s:find_buf(s:parent_bufnr)
  if empty(win_ids)
    return
  endif

  let win_id = s:get_winid()
  if s:gotoid(win_ids[0])
    call s:gotoid(win_id)
  endif

  " call rpcnotify(s:vimrpcsampleJobId, 'save', lines)
endfunction

こんな感じでいけた

このスクラップは2021/02/11にクローズされました