tmux がなければ vim を使えばいいじゃない
tmux
がない環境で暮らすには
ターミナルでの快適な暮らしに tmux
は欠かせません。
しかしながら世の中には tmux
が使えない環境というものがあります。
そんな環境で暮らしていくには、どうすればよいでしょうか。
vim
を使いましょう。
vim
はターミナルを開けます。
画面の分割もできます。
タブだってあります。
目標はシェルをたくさん開くこと
目標は端末上でシェルをたくさん開くことです。
セッションのことは考えません。
作ったもの
いきなりですが、こちらが作ったものです。
細かな解説は省略します。
作ったもの (長いので折りたたんでいます)
"----------------------------------------
" 一般
"----------------------------------------
set encoding=utf-8
set visualbell t_vb=
set clipboard=unnamed,unnamedplus
"----------------------------------------
" 見た目の調整
"----------------------------------------
set showtabline=2
set laststatus=0
" ウィンドウ分割線をシンプルにする
set statusline=─
set fillchars+=stl:─,stlnc:─
set fillchars+=vert:│
highlight! link StatusLineTerm Comment
highlight! link StatusLineTermNC Comment
highlight! link VertSplit Comment
highlight! link TabLineFill ToolbarButton
" タブラインをシンプルにする
function! MyTabLine()
let s = ''
for i in range(tabpagenr('$'))
" タブ番号の設定
let tabnr = i + 1
" アクティブなタブの強調表示
let s ..= (tabnr == tabpagenr() ? '%#TabLineSel#' : '%#TabLine#')
let s ..= '%' .. tabnr .. 'T'
" タブ番号の表示
let s ..= ' ' .. tabnr .. ' '
endfor
" タブページ後の空白を埋める
let s ..= '%T%#TabLineFill#%='
return s
endfunction
set tabline=%!MyTabLine()
"----------------------------------------
" キーバインディング
"----------------------------------------
" INFO: alt を認識してくれない問題への対処
" https://vi.stackexchange.com/questions/2350/how-to-map-alt-key
" :help :set-termcap
for i in range(97,122)
let c = nr2char(i)
exec "set <M-" .. c .. ">=\e" .. c
exec "nno <M-" .. c .. "> " .. c
endfor
let g:mapleader="\<C-q>"
set termwinkey=<C-@>
" タブの作成
tno <silent> <Leader>c <C-\><C-n>:tab terminal<CR>
tno <silent> <M-m> <C-\><C-n>:tab terminal<CR>
" タブの移動
tno <expr><silent> <Leader>n tabpagenr('$') > 1 ? '<C-\><C-n>:tabnext<CR>' : ''
tno <expr><silent> <Leader>p tabpagenr('$') > 1 ? '<C-\><C-n>:tabprevious<CR>' : ''
" 画面分割
tno <silent> <Leader>" <C-\><C-n>:bel term<CR>
tno <silent> <Leader>% <C-\><C-n>:bel vert term<CR>
tno <silent> <M-n> <C-\><C-n>:call SplitWindow()<CR>
" ウィンドウが横長なら垂直分割、縦長なら水平分割
function! SplitWindow()
if winwidth(0) < winheight(0) * 2
bel term
else
bel vert term
endif
endfunction
" コピー/貼り付け
tno <silent> <Leader>[ <C-\><C-n>
tno <silent> <Leader>] <C-@>"+
" ウィンドウ間を移動
tno <silent> <M-h> <C-@>h
tno <silent> <M-j> <C-@>j
tno <silent> <M-k> <C-@>k
tno <silent> <M-l> <C-@>l
" ウィンドウのサイズ変更 (tmux の resize-pane 風)
function! ResizeVert(c)
if winnr('h') != winnr('l')
let l:c = winnr() == winnr('l') ? -a:c : a:c
exe 'vert resize ' .. printf('%+d', l:c)
endif
if mode() == 'n'
norm! i
endif
endfunction
function! ResizeHori(c)
if winnr('j') != winnr('k')
let l:c = winnr() == winnr('j') ? -a:c : a:c
exe 'resize ' .. printf('%+d', l:c)
endif
if mode() == 'n'
norm! i
endif
endfunction
tno <silent> <M-a> <C-\><C-n>:call ResizeVert(-1)<CR>
tno <silent> <M-s> <C-\><C-n>:call ResizeHori(+1)<CR>
tno <silent> <M-w> <C-\><C-n>:call ResizeHori(-1)<CR>
tno <silent> <M-d> <C-\><C-n>:call ResizeVert(+1)<CR>
" ウィンドウのキル
tno <silent> <Leader>x <C-@><C-c>
"----------------------------------------
" その他挙動の調整
"----------------------------------------
" Vim 起動時にターミナルを開く
autocmd VimEnter * term ++curwin
" タブ切り替え時に insert モードに入る
autocmd BufEnter * if &buftype ==# 'terminal' && mode() ==# 'n' | exe "norm! i" | endif
" Yank したら insert mode に移行
autocmd TextYankPost * if &buftype ==# 'terminal' && mode() ==# 'n' | exe "norm! i" | endif
この設定では次のことができます。
(<Leader>
は <C-q>
です。)
キー | 動作 |
---|---|
<Leader>c または <M-m>
|
タブを新規作成 |
<Leader>n |
次のタブへ |
<Leader>p |
前のタブへ |
<Leader>" |
画面を水平分割 |
<Leader>% |
画面を垂直分割 |
<M-n> |
アクティブなウィンドウが縦長なら水平分割、横長なら垂直分割 |
<Leader>[ |
ノーマルモードへ移行 |
<Leader>] |
貼り付け |
<M-h/j/k/l> |
指定方向のウィンドウに移動 |
<M-w/a/s/d> |
アクティブウィンドウのサイズを変更 |
このコードを .vimrc-tmux
として保存して、 vim -Nu .vimrc-tmux
で読み込んで起動します。 .bashrc
などにエイリアスを作っておくと便利です。
alias vmux='vim -Nu ~/.vimrc-tmux'
見た目
コマンドラインがあるので一番下の行は使えません。
課題
この設定にはまだまだ課題もあります。
プレフィックスの挙動が怪しい
プレフィックス (<Leader>
) を <C-q>
に設定していますが、一部の環境[1]ではこれが正しく動きません。
Meta キーの挙動が怪しい
<M-xx>
の形をしたキーバインドがいくつかあります。
こちらも環境によって動いたり動かなかったりするので注意が必要です。
本当は <M-H/J/K/L>
なども活用したかったのですが、手元の環境ではうまく動かせませんでした。
おわりに
ライトなユースケースには十分耐えうるかと思います。
ただ機能不足感は否めないので、改善案等ありましたらコメントいただけると嬉しいです。
-
Windows 上の
mintty
で動く Git Bash で問題が起きました。マルチプレクサ上でvim
を開いた状態 (vim
が入れ子になっている状態) で<C-q>
を押すと、入力がマルチプレクサではなく内側のvim
に吸われます。原因は分かっていませんが、mintty
の代わりにconhost.exe
を使うことで回避できます。 ↩︎
Discussion