Vimで, setlocal wrap nowrapとsetlocal nowrapは違います.
setlocal wrap nowrapは上手く使えばいい副作用をもたらしてくれます.
Vimで日の丸
command! Flag call s:flag() function! s:flag() tabnew setlocal nowrap nonumber filetype=flag buftype=nofile nocursorline cursorcolumn call s:redraw() syntax match FlagBG '.*' contains=FlagFG,FlagBD syntax match FlagFG 'X' contained syntax match FlagBD 'Y' contained highlight FlagBG ctermfg=15 ctermbg=15 guifg=#ffffff guibg=#ffffff highlight FlagFG ctermfg=196 ctermbg=196 guifg=#ff0000 guibg=#ff0000 highlight FlagBD ctermfg=210 ctermbg=210 guifg=#ff8787 guibg=#ff8787 endfunction function! s:redraw() let [h, w] = [winheight(0), winwidth(0)] let r = min([2 * h, w]) * 0.3 let s = [] for i in range(h) let a = max([float2nr(sqrt(r * r - (h * 1.0 - i * 2.0) * (h * 1.0 - i * 2.0))), 0]) let b = max([float2nr(sqrt((r + 1) * (r + 1) - (h * 1.0 - i * 2.0) * (h * 1.0 - i * 2.0))) - a, 0]) let as = repeat('X', 2 * a) let bs = repeat('Y', b) call extend(s, [(repeat(' ', w / 2 - a - b).bs.as.bs.repeat(' ', w - a - b - w / 2))]) endfor silent % delete _ call setline(1, s) endfunction
cursorcolumnを設定しているのは, 見やすさのためです.
このスクリプトをplugin/flag.vimに保存し, :Flagで実行します.
画像を見て分かるように, vnewとかnewした時に, 半分が隠れてしまいます.
これを改善したスクリプトは以下のようになります.
command! Flag call s:flag() function! s:flag() tabnew setlocal nowrap nonumber filetype=flag buftype=nofile nocursorline cursorcolumn call s:redraw() augroup FlagAutoUpdate autocmd! autocmd BufEnter,VimResized * call s:update(expand('<abuf>')) augroup END augroup Flag autocmd WinEnter,BufEnter,VimResized <buffer> call s:redraw() augroup END syntax match FlagBG '.*' contains=FlagFG,FlagBD syntax match FlagFG 'X' contained syntax match FlagBD 'Y' contained highlight FlagBG ctermfg=15 ctermbg=15 guifg=#ffffff guibg=#ffffff highlight FlagFG ctermfg=196 ctermbg=196 guifg=#ff0000 guibg=#ff0000 highlight FlagBD ctermfg=210 ctermbg=210 guifg=#ff8787 guibg=#ff8787 endfunction function! s:redraw() let [h, w] = [winheight(0), winwidth(0)] let r = min([2 * h, w]) * 0.3 let s = [] for i in range(h) let a = max([float2nr(sqrt(r * r - (h * 1.0 - i * 2.0) * (h * 1.0 - i * 2.0))), 0]) let b = max([float2nr(sqrt((r + 1) * (r + 1) - (h * 1.0 - i * 2.0) * (h * 1.0 - i * 2.0))) - a, 0]) let as = repeat('X', 2 * a) let bs = repeat('Y', b) call extend(s, [(repeat(' ', w / 2 - a - b).bs.as.bs.repeat(' ', w - a - b - w / 2))]) endfor silent % delete _ call setline(1, s) endfunction function! s:update(bufnr) let nr = -1 let newnr = str2nr(a:bufnr) for buf in tabpagebuflist() if getbufvar(buf, '&filetype') == 'flag' && buf != newnr let nr = buf break endif endfor if nr == -1 | return | endif let winnr = bufwinnr(nr) let newbuf = bufwinnr(str2nr(a:bufnr)) let currentbuf = bufwinnr(bufnr('%')) execute winnr 'wincmd w' call s:redraw() if winnr != newbuf && newbuf != -1 execute newbuf 'wincmd w' elseif winnr != currentbuf && currentbuf != -1 execute currentbuf 'wincmd w' endif endfunction
実は, こうなってしまうのは, nowrapのせいです.
解決法は, 2つあります.
- setlocal wrap にする
- setlocal wrap nowrap を使う
一つ目の解決法は, 結構危険です.
なんかの拍子に行が折り返してしまうかもしれません.
つまり, 完璧に列数をコントロールしなければなりません.
非常に神経が磨り減ります.
そこで, 便利なのが二つ目の解決法です.
書き換える関数s:redrawを, 以下のように変更します.
function! s:redraw() ... silent % delete _ call setline(1, s) setlocal wrap nowrap endfunction
つまり, バッファーを書き換えた直後に setlocal wrap nowrap を入れるのです!
すると...
うまくいきました!!!
setlocal wrap nowrap凄い!!!
まとめ
ビジュアルが重要なプラグインで, 見た目が「常に」良くなるように見せるためには, 他のバッファーに入ったり削除したりした時にもプラグインのバッファーに戻って書き直しなければなりません.
しかも, そういうプラグインでは, おそらくsetlocal nowrapを使っていると思います.
$:vnewしてみて下さい.
ここに書いたような問題が発生するはずです.
そういう時は, setlocal wrap nowrapを使ってみて下さい.
あと, setlocal wrap nowrap と setlocal nowrap は違います.
意図的ですので, ダブってるよ!って突っ込まないで下さい.