LoginSignup
3
5

More than 5 years have passed since last update.

Vim (CUI) にASCIIベースのスクロールバーを追加する

Posted at

概要

  • 長いファイルを編集していると迷子になりやすいので、現在どの辺を編集しているのか一目で分かるようにした。
    • 折畳みで多少は改善するのだが。
  • やったことは基本的に https://superuser.com/a/445233 の改変と解説。
  • 表示範囲を - で、カーソル位置を @ で表示する。
    Capture.PNG

解説不要。使えればいい!

これを vimrc に貼り付けます。以上。

func! STL()
  let barWidth = &columns / 6
  let barWidth = barWidth < 3 ? 3 : barWidth
  let n = line('$') > 1 ? line('$') - 1 : line('$')
  let buf_top    = (line('w0') - 1) * (barWidth - 1) / n
  let buf_bottom = (line('w$')    ) * (barWidth - 1) / n
  let cursor     = (line('.')  - 1) * (barWidth - 1) / n
  let n1 = buf_top
  let n2 = cursor - n1
  let n2 = n1 + n2 >= barWidth ? barWidth - n1 - 1 : n2
  let n3 = buf_bottom - cursor
  let n3 = n1 + n2 + n3 >= barWidth ? barWidth - n1 - n2 - 1 : n3
  let n4 = barWidth - n1 - n2 - n3 - 1
  let bar = '['.repeat(' ', n1).repeat('-', n2).'@'.repeat('-', n3).repeat(' ', n4).']'
  let stl_left = ' '
  let stl_right = ' %<%F %m%r%h%w%=[%{&fenc},%{&ff},%Y] (%03l/%03L,%03v) '
  return stl_left.bar.stl_right
endfunc
set laststatus=2
set statusline=%!STL()

解説

スクロールバーの長さを決める

  let barWidth = &columns / 6
  let barWidth = barWidth < 3 ? 3 : barWidth

私は1行の1/6にした。お好みで。2行目は例外処理。

バッファ(画面に表示されている範囲)とカーソル位置を取得

  let n = line('$') > 1 ? line('$') - 1 : line('$')
  let buf_top    = (line('w0') - 1) * (barWidth - 1) / n
  let buf_bottom = (line('w$')    ) * (barWidth - 1) / n
  let cursor     = (line('.')  - 1) * (barWidth - 1) / n

4行目を例に取ると、カーソル行を line('.') で取得してスクロールバーの長さ barWidth を掛けて、ファイル行数 line('$') のようなもので割っている。

スクロールバー各部分の長さを決める

  let n1 = buf_top
  let n2 = cursor - n1
  let n2 = n1 + n2 >= barWidth ? barWidth - n1 - 1 : n2
  let n3 = buf_bottom - cursor
  let n3 = n1 + n2 + n3 >= barWidth ? barWidth - n1 - n2 - 1 : n3
  let n4 = barWidth - n1 - n2 - n3 - 1

n1, n2, n3, n4 はそれぞれ以下の部分。三項演算子を使っているのは和が barWidth を超えないための例外処理。
Capture.PNG

スクロールバーを作る

  let bar = '['.repeat(' ', n1).repeat('-', n2).'@'.repeat('-', n3).repeat(' ', n4).']'

各部分を repeat 関数で作って . で文字列連結。

残り処理

  let stl_left = ' '
  let stl_right = ' %<%F %m%r%h%w%=[%{&fenc},%{&ff},%Y] (%03l/%03L,%03v) '
  return stl_left.bar.stl_right
(中略)
set laststatus=2
set statusline=%!STL()

statusline に代入したいもののうち、stl_leftstl_right はスクロールバーの左右に置きたい要素をお好みで。.で文字列連結。

set laststatus=2statusline を独立行に表示する。set statusline=%!STL() で上記関数の戻り値を statusline にリアルタイム表示すれば完了!

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5