f

2016-07-24

How to set GVim default font

GVimでフォントを適切に設定する方法を記す。

導入

VimのGUIであるGVimでは,日本語フォントがきちんと設定されていないと日本語が横に間延びしたようになってしまいとても見にくくなってしまう。

これを防ぐには,GVimのフォント設定で日本語フォントをきちんと設定することが必要となる。しかし,存在しないフォントを指定するとWindows版のGVimでは以下のエラーが出てしまう。

E596: Invalid font(s)

なお,Linux版のGVimでは存在しないフォントを指定してもエラーは出ない。ただし,表示は横に間延びする。

一度きちんとフォント指定を済ませてしまえば,このような問題は起きないと思うかもしれないが,実はそうでもない。例えば,自分のPCではコーディング用にインストールしたフォントを表示するようにGVimで設定したとする。しかし,他人のPCでVimの設定だけ移動させて作業すると,フォントがインストールされていなくて,GVim起動時にエラーがでたり,表示が間延びしてしまう。

このようなフォント指定に対する問題を解決するには,設定したフォントが見つからなかった場合に,きちんと処理を入れれば済む。具体的には以下のどちらかとなる。

  • try-catch文で処理。
  • 処理の最後でOS標準フォントを指定。

try-catch文で対応する場合は以下のような設定を書けばよい。

try
  if has("gui_running")
    if has("gui_gtk2")
      set guifont=Migu\ 1M\ 9
    elseif has("gui_macvim")
      set guifont=Menlo\ Regular:h14
    elseif has("gui_win32")
      set guifont=Migu_1M:h9
    endif
  endif
catch /^Vim\%((\a\+)\)\=:E596/  " catch error E596: Invalid font(s):
endtry

ただ,try-catch文で処理する場合だと,最初のフォントが見つからなかった場合にしか対応できない。最初のフォントが見つからなければ,次のフォントを試すといったことができない。そのため,最後にOS標準フォントを指定することを勧めたい。

既にWindowsとLinuxのOS標準のコーディング用フォントは以下の記事で調査済みなのでこの成果を活用すればよい。これを使えば,いちいちtry-catch文で複雑なことをしなくても済む。

おすすめコーディング用OS標準フォント
言語WindowsLinux
英語ConsolasDejaVu Sans Mono
日本語HGGothicM,MS GothicTakaoGothic(Debian系),VL Gothic(RedHat系)

My Future Sight for Past: Best coding font in Windows and Linux default font

GVimのフォントのオプション

GVimでフォント設定に関するオプションは2種類ある。

それぞれ,英語(1バイト)と日本語(2バイト)フォントを指定する。guifontwideの値が空ならば,guifontの値が適用される。

WindowsとLinuxとでは,これらのオプションに指定する値の書式が少し異なっている。

Linuxであれば,フォント名の空白はバックスラッシュ\でエスケープする。フォントサイズは,フォント名の最後に空白に続けて指定する。

Windowsであれば,フォント名の空白にはバックスラッシュでエスケープする代わりにアンダーライン_も使える。フォントサイズ(高さ)はフォント名の直後にコロン:に続けて指定する。

また,これらのオプションには値をコンマ区切りで指定でき,先頭の値から順番に試し,最初に成功したものが値として適用される。例えば以下のようになる。

set guifont=Migu\ 1M\ 9, DejaVu\ Sans\ Mono\ 9  " Linux
set guifontwide=Migu_1M:h9,MS_Gothic:h9 " Windows

フォント設定例

コンマ区切りでフォントを指定できるので,上記で示したOS標準フォントを最後に指定すればそれで事足りる。しかし,そうはいかなかった。Windowsであれば,このコンマ区切りの指定は機能するのだが,Linuxでは機能しなかった。おそらくバグだと思う。この問題については,他にも以下で報告されていた。

VIM GTK-UI font - Stack Overflow

しかたないので,上記で書かれていたとおり,Linuxではフォントが存在するかどうかを判定して設定する。設定例は以下の通り。

" .gvimrc
let s:MYFONT = 'Migu 1M'
let s:MYFS   = '9'
if has('gui_win32')
  " ex: set guifont=Migu_1M:h9, Consolas:h9
let &guifont = s:MYFONT . ':h' . s:MYFS . ', Consolas:h' . s:MYFS let &guifontwide = s:MYFONT . ':h' . s:MYFS . ', HGGothicM:h' . s:MYFS let &guifontwide.= ', MS_Gothic:h' . s:MYFS elseif has('gui_gtk2') " set guifont=Migu\ 1M\ 9, DejaVu\ Sans\ Mono\ 9 " not working. Bug? " set guifontwide=Migu\ 1M\ 9, TakaoGothic\ 9 , VL\ Gothic\ 9 " not working. Bug? let &guifont = 'DejaVu Sans Mono ' . s:MYFS if system('fc-list | grep -c ' . shellescape(s:MYFONT)) > 0 let &guifont = s:MYFONT . ' ' . s:MYFS elseif system('fc-list | grep -c "TakaoGothic"' ) > 0 let &guifontwide = 'TakaoGothic ' . s:MYFS elseif system('fc-list | grep -c "VL Gothic"' ) > 0 let &guifontwide = 'VL Gothic ' . s:MYFS endif endif

フォント内に空白があるとバックスラッシュでエスケープしないといけないことと,フォントサイズを一括で指定したいのもあったので,変数を使った。

最初のif has('gui_win32')でWindowsのフォント設定をしている。GVimでは日本語と英語とで別々のフォントを指定できるので,Windowsのフォントには字形がなめらかできれいなHGGothicMを優先させている。

elseif has('gui_gtk2')からLinuxでのフォント設定をしている。最初にLinuxで共通で存在している英語フォントであるDejaVu Sans Monoを指定しておき,後から自分で指定したフォントと日本語用フォントを追加で指定している。フォントの存在の有無の判定で使っている以下の文がこのスクリプトでは重要と思われる。

  if     system('fc-list | grep -c ' . shellescape(s:MYFONT)) > 0

Vimのsystem関数はShellで実行した標準出力を返す。fc-listコマンドはインストールされているフォントリストを表示するので,そこから対象となるフォントが存在するかをgrepで検索し-cオプションでヒット件数を返している。これによりフォントの有無を判定している。s:MYFONT変数内に空白があるので,shellescape関数でエスケープしておく。

これでGVimのフォントでの問題はなくなっただろう。

0 件のコメント:

コメントを投稿