MATLABのデフォルト文字コードはShift_JISなので、vimをutf-8ベースで動かしている場合、そのままではシームレスに編集することが出来ません。
この記事では、そんな問題を解決する方法をご紹介します。windows環境で動作を確認しています。
MATLAB側をutf-8に変更すると色々面倒くさい
MATLABのデフォルト文字コードをutf-8に変更する方法はあるのですが、次の通りいくつかデメリットがあります。
- 逆に今まで作ったShift_JISのファイルが全て文字化けする
- 他の人とコード共有がしにくくなる
- 文字コードの変更はMATLAB標準の設定機能にないので、多少裏ワザ的な方法を用いる必要がある(動作が完全に保証されているわけではない)
自分にとっては大してデメリットじゃないな
と思った方はMATLABをutf-8化するのも選択肢に入りますが、基本的にはvim側をShift_JISに対応させる方が面倒が少ないです。 以下、その方法をまとめていきます。
mファイルだけShift_JISで開く
vimrcに次の1行を書くと、mファイルだけShift_JISで開かれるようになります。
" matlabファイルはShift_JISで開く autocmd FileType matlab setlocal fenc=sjis
これだけで、基本のコーディングならほぼ問題なくできるはずです。
ALE(シンタックスチェッカープラグイン)の設定
vimのシンタックスチェッカープラグインであるALEをMATLABに対応させておくと、コーディングがより快適になります。
設定次第で多少見た目は変わりますが、次のように構文エラーや警告メッセージをvimから直接確認できるようになります。
ALEによるMATLABコードチェックを有効にする
ALEは、MATLABのmlintという機能(コマンド)を用いてシンタックスチェックを行います。次の文をvimrcに記述すると、ALEによるMATLABコードのチェックが有効になります。
" ALEでmlintを使用するよう設定 let g:ale_linters = { \ 'matlab': ['mlint'] \}
mlintコマンドの実態であるmlint.exeにパスが通っていないと、ALEに「そんな命令しらないよ」と言われて終わってしまうので、忘れずにパスを通しておきましょう。
Windowsの場合、スタートボタンから「環境変数」と入力すると環境変数の設定画面に飛べます。環境変数PATHに、mlint.exeのある下記パスを追加してください。
# パスを通す場所の例 # XXの部分は自身の環境に合わせて変更してください。 C:\Program Files\MATLAB\R20XX\bin\winXX
mファイルだけShift_JISでチェックする
次に文字化け対策です。ALEもutf-8ベースで動くので、そのままでは警告メッセージが文字化けしてしまいます。これを直していきましょう。
ALEのスクリプトをMATLAB用にちょびっと変更します。
変更スクリプト1:ale/autoload/ale/util.vim
ale#util#Writefile関数を次のように書き換えます。
function! ale#util#Writefile(buffer, lines, filename) abort if &filetype == 'matlab' let l:corrected_lines = getbufvar(a:buffer, '&fileformat') is# 'dos' \ ? map(copy(a:lines), 'iconv( v:val . "\r", &encoding, "sjis")') \ : map(copy(a:lines), 'iconv( v:val, &encoding, "sjis")') else let l:corrected_lines = getbufvar(a:buffer, '&fileformat') is# 'dos' \ ? map(copy(a:lines), 'v:val . "\r"') \ : a:lines endif call writefile(l:corrected_lines, a:filename) " no-custom-checks endfunction
変更スクリプト2:ale/ale_linters/matlab/mlint.vim
ale_linters#matlab#mlint#Handle関数を次のように書き換えます。
function! ale_linters#matlab#mlint#Handle(buffer, lines) abort " Matches patterns like the following: " " L 27 (C 1): FNDEF: Terminate statement with semicolon to suppress output. " L 30 (C 13-15): FNDEF: A quoted string is unterminated. let l:pattern = '^L \(\d\+\) (C \([0-9-]\+\)): \([A-Z]\+\): \(.\+\)$' let l:output = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) let l:lnum = l:match[1] + 0 let l:col = l:match[2] + 0 let l:code = l:match[3] let l:text = l:match[4] " Suppress erroneous waring about filename " TODO: Enable this error when copying filename is supported if l:code is# 'FNDEF' continue endif " ==== 書き換えここから ==== call add(l:output, { \ 'bufnr': a:buffer, \ 'lnum': l:lnum, \ 'col': l:col, \ 'text': iconv(l:text, "sjis", &encoding), \ 'type': 'W', \}) " ==== 書き換えここまで ==== endfor return l:output endfunction
もしこれでも文字化けが直らない場合は、プラグインマネージャーがどこかでコードをキャッシュしている可能性があるので、プラグインマネージャーのキャッシュを初期化するか、ALEを再ダウンロードしてみてください。
それでは、快適なvim&MATLABライフを!
コメント