MATLABのデフォルト文字コードはShift_JISなので、vimをutf-8ベースで動かしている場合、そのままではシームレスに編集することが出来ません。
この記事では、そんな問題を解決する方法をご紹介します。windows環境で動作を確認しています。
※MATLAB2020aから、デフォルトの文字コードがutf-8になりました。このページの情報は、MATLAB2019b以前のバージョン用にご活用ください。
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ライフを!

