2016-07-06 68 views
1

我正在研究一個與終端緩衝區中的REPL交互的Neovim插件。我希望能夠向REPL發送命令,複製響應並以某種方式將其顯示給用戶。目前,終端緩衝似乎並不刷新輸出,直到當前的Vimscript函數結束,所以我不能有一個單一的功能呢,比如:Neovim異步緩衝區等待

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

get_response功能正在與終端緩衝器在它被更新之前。

目前,我使用neovim的作業控制,但如果這可以在vanilla 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

回答

3

:term緩衝區中,您可以設置一個TextChanged處理程序。例如。下面的代碼發送整個:term緩衝區內容s:on_response

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

搞清楚哪些文本是「新」,因爲以前的TextChanged事件將需要一些定製邏輯。 和']標記在:term緩衝區中沒有正確設置(我不確定這是否可以自動執行nvim,但是我製作了bug report)。

請注意,TextChanged只有在用戶處於正常模式時纔會觸發(離開插入模式後也會立即觸發)。

TextChangedI(注意I末)應在消防插入模式,但它不與:term工作,這是一個bug


另一種方法是用戶計時器(見:help timer_start)。下面是調用s:on_reponse(timer_id)每一秒的計時器:

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

但這並不是理想的,因爲你需要保持圖的終端和定時器的ID(或通過所有:terminal緩衝區迭代,並檢查他們的內容)。


我的jobattach()功能將允許連接on_stdout處理現有工作(而jobstart()只增加了處理程序作業)做了一個feature request。這可以用來附加任何:term緩衝區的b:terminal_job_id

+0

嗯,'TextChanged'' autocmd'不完全符合我的期望。它似乎只在用戶的光標當前位於終端緩衝區時觸發。現在檢出'jobattach' – ephrion

+1

'jobattach'尚不存在 - 這將是一個功能請求。 –

+1

@ephrion我使用計時器添加了另一個建議。但可能'jobattach()'是真正需要的。 –