Last active
November 23, 2017 12:58
-
-
Save thinca/ac438e1139c054b70a740b8f29e5ba0d to your computer and use it in GitHub Desktop.
Support :command in zsh in Vim (experimental)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# put this code in your .zshrc | |
if [[ "${VIM_TERMINAL_SHELL}" != "" ]]; then | |
command_not_found_handler() { | |
if [[ "${1}" != :* ]]; then | |
echo "command not found: ${1}" > /dev/stderr | |
return 127 | |
fi | |
echo -ne "\e_$*\e\\" > /dev/tty | |
while [[ ! -f "${VIM_TERMINAL_SHELL}" ]]; do | |
sleep 0.1 | |
done | |
cat "${VIM_TERMINAL_SHELL}" | |
rm "${VIM_TERMINAL_SHELL}" | |
} | |
fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function! s:out(ch, msg) abort | |
let cmd = matchstr(a:msg, "\e_:\\zs.\\{-}\\ze\e\\\\") | |
if empty(cmd) | |
return | |
endif | |
let result = '' | |
try | |
let result = execute(cmd) | |
let result = substitute(result, '^\n\(.*\)', '\1\n', '') | |
catch | |
let result .= v:exception . "\n" | |
finally | |
call writefile(split(result, "\n", 1), s:term_file, 'b') | |
endtry | |
endfunction | |
function! s:terminal() abort | |
let s:term_file = tempname() | |
call term_start(['/bin/zsh'], { | |
\ 'out_cb': function('s:out'), | |
\ 'env': {'VIM_TERMINAL_SHELL': s:term_file}, | |
\ }) | |
endfunction | |
command! Terminal call s:terminal() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Vim 内のターミナル内の zsh 内で
:cmd
と : 始まりのコマンドを実行するとホスト側の Vim でコマンドを実行して zsh 側に出力の結果を出すスクリプトのテスト。まだまだいくつか問題がある。
\e_...\e\\
を無視してくれないので出力に出てしまう:echo 'foo'
の'foo'
のクォートが zsh に食われて:echo foo
になってしまうcommand_not_found_handler
関数が定義されていた場合、競合するexecute()
を使っているので:redir
を使っているコマンドを実行すると失敗する