2

ターミナル バッファで REPL と対話する Neovim プラグインに取り組んでいます。コマンドを REPL に送信し、応答をコピーして、何らかの方法でユーザーに表示できるようにしたいと考えています。現在、現在の vimscript 関数が終了するまでターミナル バッファは出力を更新しないようです。

function! plugin#eval(str)
    call s:send_to_repl(str)
    echomsg s:get_response()
endfunction

get_response関数は、更新される前に端末バッファーで動作しているためです。

現在、neovim のジョブ コントロールを使用していますが、これがバニラ vim で実現できればなおさらです。

端末を初期化するために使用しているコードは次のとおりです。

function! s:start_buffer(height)
    set bufhidden=hide
    set noswapfile
    set buftype=nofile
    set hidden
    terminal! stack ghci --with-ghc intero
    let l:buffer_id = bufnr('%')
    let g:intero_job_id = b:terminal_job_id
endfunction

コマンドをREPLに送信する方法は次のとおりです。

function! s:send(str)
    call jobsend(g:intero_job_id, add([a:str], ''))
endfunction

更新するコマンドを追加しようとしましたeditが、REPL では機能しないようです。

REPL と通信するためのコードはhereです。プロセスを管理するためのコードはhereです。

4

1 に答える 1

3

バッファでは、ハンドラ:termを設定できます。TextChangedたとえば、次のコードは:termバッファの内容全体を に送信しs:on_responseます。

autocmd TextChanged <buffer> call <SID>on_response(getline(1,'$'))

前のイベント以降の「新しい」テキストを特定するにTextChangedは、いくつかのカスタム ロジックが必要になります。およびマークがバッファに正しく設定されていません (これが自動的に実行'[できるかどうかはわかりませんが、バグ レポートを作成しました)。']:termnvim

ユーザーが通常モードの場合にのみ起動することに注意してTextChangedください (挿入モードを終了した直後にも)。

TextChangedI(I最後の に注意してください) は挿入モードで起動するはずですが、 では機能しません。:termこれはバグです。


もう 1 つの方法は、ユーザー タイマーを使用することです ( を参照:help timer_start)。s:on_reponse(timer_id)毎秒呼び出すタイマーは次のとおりです。

call timer_start(1000, '<SID>on_response', {'repeat':-1})

しかし、これは理想的ではありません。なぜなら、端末とタイマー ID のマップを保持する必要がある (または、すべての:terminalバッファーを反復してその内容を確認する) 必要があるからです。


ハンドラーを既存のジョブにアタッチできるようにする機能の機能要求を行いました(一方、ハンドラーは新しいジョブにのみ追加します)。これは、任意のバッファにアタッチするために使用できます。jobattach()on_stdoutjobstart()b:terminal_job_id:term

于 2016-07-07T14:00:14.450 に答える