Screen の caption に Vim のタイトルを表示する(+タイトル文字列のカスタマイズとか)



Vim を起動するとタイトルバーに編集中のファイル名などが表示されます。

Screen で「タイトルバー」の代わりとなるものは caption ですが、そのままの設定では Vim からのメッセージが表示されません。
これは次のように設定すると解決します。^[ のところは Control + V ESC のように入力してください。

if &term =~ '^screen'
    set t_ts=^[k
    set t_fs=^[\
endif

はい。終わり。……では悲しいので、この文字列をもうちょっとカスタマイズしてみましょう。

タイトル文字列のカスタマイズ

次のように設定すると、この文字列を関数の返値に出来ます。

set titlestring=%{GetTitleString()}

あとは GetTitleString() を定義するだけです。上の SS にも挙げた設定はこんな感じ。

function! GetTitleString()
    " 各種フラグ
    let modified = getbufvar('', '&mod') ? '+' : ''
    let readonly = getbufvar('', '&ro') ? '=' : ''
    let modifiable = getbufvar('', '&ma') ? '' : '-'
    let flag = modified . readonly . modifiable
    let flag = len(flag) ? ' ' . flag : ''
    " ホスト名
    let host = hostname() . ':'
    " ファイル名
    let filename = expand('%:t')
    " ファイル名がない場合
    let filename = len(filename) ? filename : 'NEW FILE'
    " パス内を置換する
    let dir = expand('%:p:s!some-paths!PATH!:~:.:h')
    " dir を括弧で括る
    let dir = len(dir) && dir != '.' ? ' (' . dir . ')' : ''
    " 検索文字列
    let search_string = len(@/) ? ' [' . @/ . ']' : ''
    " 表示文字列を作成
    let str = host . filename . flag . dir . search_string
    " Screen などの時、タイトルバーに 2 バイト文字があったら化けるので対処する
    if !has('gui_running')
        let str2 = ''
        for char in split(str, '\zs')
            if char2nr(char) > 255
                let str2 = str2 . '_'
            else
                let str2 = str2 . char
            endif
        endfor
        let str = str2
    endif
    return str
endfunction

別に難しいところはないと思いますが、いくつか解説という名の備忘録を書いておきます。

パスを任意の文字列で置換する

expand() 関数を使うとファイルのパスを様々な形式で得ることが出来ます。引数に指定するべき文字列は、ここがいかにも vim 的ではあるのですが、非常にわかりにくいものになっています。

expand('%:p:s!some-paths!PATH!:~:.:h')

: 付きの文字列は修飾子と呼ばれるもので、これが左から順に適用されます。

%
ファイル名
:p
フルパスにする。
:s!some-paths!PATH!
some-paths という文字列を PATH に置換する。ex コマンド :s/// と同じ。
:~
ホームディレクトリ下にあるファイルならば、相対パス名に変換する。
:.
カレントディレクトリ化にあるファイルならば、相対パス名に変換する。
:h
ファイル名を取り除き、ディレクトリ名だけにする。

今回使ったのはこれらの修飾子だけですが、他にも色んなものが定義されています。:h expand() とか :h filename-modifiers とかしてヘルプを読んでみてください。

検索文字列を表示する

これは今回の件とはあんまり関係ないんですが、直前に検索した文字列は "/ レジスタに記録されています。これを変数として式中に使いたいときは @/ で参照できます。
詳しくは :h "/ してください。いつもこれ忘れるのでここにメモっときます。

文字列を 1 文字ごとに処理する

これも今回の件と直接関係ないですね。豆知識みたいなもんです。
次のループを使うと文字列 str 中の文字が 1 文字ずつ変数 c の中に入ります。詳しくは :h split() してください。

for c in split(str, '\zs')
    ...
endfor

コメントを残す