DEV Community

KOGA Mitsuhiro
KOGA Mitsuhiro

Posted on • Originally published at qiita.com

WindowsのGVimの:terminalから色々なシェルを使う

はじめに

最近、vimに実装された:terminalが便利そうなのでWindowsから色々いじってみました。
Windows版はvim-jpからzipをダウンロードできます。
何か不具合がある場合はナイトリービルドのvim/vim-win32-installerも試せます。

gvim-terminal.png

上のキャプチャではVimを4つに分割してそれぞれ以下のシェルを動かしています。

Git Bash コマンドプロンプト
WSL Bash PowerShell

:terminalのヘルプと概要はここから

以下、私の好みでオプションに++close++curwinを指定しています。

コマンドプロンプトとPowerShellを動かすやつ

この2つは簡単です。

:terminal ++close ++curwin

Windowsのデフォルトシェルはコマンドプロンプトなのでシェルを指定しなくてもよいです。

:terminal ++close ++curwin powershell

PowerShellはデフォルトシェルではないので引数に指定します。

WSLのBashを動かすやつ

Windows10 Fall Creators Update以降

:terminal ++close ++curwin ubuntu

ubuntu.exeコマンドがbashの実行とホームディレクトリの移動を兼ねているので簡単です。

Windows10 Fall Creators Updateより前

:terminal ++close ++curwin C:/WINDOWS/System32/bash.exe -c "cd; bash -l"

Windows側からWSLのホームディレクトリに移動できないので-cオプションで移動後にbashを起動しています。
シェル起動時のディレクトリがどこでもよいならこのオプションは不要です。

Git for WindowsのBashを動かすやつ

vim 8.0.1240以降

環境変数を渡したいので:terminalではなくterm_start関数を使います。

function! GitBash()
    " 日本語Windowsの場合`ja`が設定されるので、入力ロケールに合わせたUTF-8に設定しなおす
    let l:env = {
                \ 'LANG': systemlist('"C:/Program Files/Git/usr/bin/locale.exe" -iU')[0],
                \ }

    " remote連携のための設定
    if has('clientserver')
        call extend(l:env, {
                    \ 'GVIM': $VIMRUNTIME,
                    \ 'VIM_SERVERNAME': v:servername,
                    \ })
    endif

    " term_startでgit for windowsのbashを実行する
    call term_start(['C:/Program Files/Git/bin/bash.exe', '-l'], {
                \ 'term_name': 'Git',
                \ 'term_finish': 'close',
                \ 'curwin': v:true,
                \ 'cwd': $USERPROFILE,
                \ 'env': l:env,
                \ })

endfunction

nnoremap <Leader>g :<C-u>call GitBash()<CR>

vim 8.0.1240より前

vim 8.0.1240より前のWindows版はterm_startにバグがありenvが渡されないので直接環境変数を設定します。

function! GitBash()
    " 日本語Windowsの場合`ja`が設定されるので、入力ロケールに設定しなおす
    let l:oldlang = $LANG
    let $LANG = systemlist('"C:/Program Files/Git/usr/bin/locale.exe" -iU')[0]

    " remote連携のための設定
    let l:oldgvim = $GVIM
    let l:oldvimserver = $VIM_SERVERNAME
    let $GVIM = $VIMRUNTIME
    let $VIM_SERVERNAME = v:servername

    " Git for Windowsに同梱されたvimで誤作動するのでvimが設定する環境変数を削除する
    let l:oldvim = $VIM
    let l:oldvimruntime = $VIMRUNTIME
    let l:oldmyvimrc = $MYVIMRC
    let l:oldmygvimrc = $MYGVIMRC
    let $VIM = ''
    let $VIMRUNTIME = ''
    let $MYVIMRC = ''
    let $MYGVIMRC = ''

    " :terminalを実行したvimのservernameを設定する
    if has('clientserver')
        let $VIM_SERVERNAME = v:servername
    endif

    " ホームディレクトリに移動する
    lcd $USERPROFILE
    " :terminalでgit for windowsのbashを実行する
    terminal ++close ++curwin C:/Program Files/Git/bin/bash.exe -l

    " 環境変数とカレントディレクトリを元に戻す
    let $LANG = l:oldlang
    let $GVIM = l:oldgvim
    let $VIM_SERVERNAME = l:oldvimserver
    let $VIM = l:oldvim
    let $VIMRUNTIME = l:oldvimruntime
    let $MYVIMRC = l:oldmyvimrc
    let $MYGVIMRC = l:oldmygvimrc
    lcd -
endfunction

nnoremap <Leader>g :<C-u>call GitBash()<CR>

:terminalで起動したGit Bashから同梱のvimを実行しようとすると以下の理由で色々設定が必要でした。

  • LANGja_JPja_JP.UTF-8のような値にしないとlsで日本語が出ない
  • GVimが設定した環境変数のままだとGit for Windowsに同梱されたvimのパスと合わなくてエラーになる

更に、以下のaliasを~/.bashrcに設定しておくとremote - Vim日本語ドキュメントの機能を使って、Git Bash同梱のvimを使わずにGvimでファイルを開くことができます。

if [ -x $(cygpath "$GVIM\\vim.exe") -a -n $VIM_SERVERNAME ]; then
    alias vim="$(cygpath "$GVIM\\vim.exe") --servername $VIM_SERVERNAME --remote-silent"
fi

さいごに

minttyと比べると描画がちょっと遅かったり256色カラーにならなかったりと見劣りする部分はありますが、ターミナルのコピペをvimの操作で行ったり、複数のシェルを1つのウインドウにまとめられるのが便利でした。

参考リンク

Top comments (0)