utf-8のvimでShift_JISのMATLABコードを編集する設定

MATLAB

MATLABのデフォルト文字コードはShift_JISなので、vimをutf-8ベースで動かしている場合、そのままではシームレスに編集することが出来ません。

この記事では、そんな問題を解決する方法をご紹介します。windows環境で動作を確認しています。

※MATLAB2020aから、デフォルトの文字コードがutf-8になりました。このページの情報は、MATLAB2019b以前のバージョン用にご活用ください。

スポンサーリンク

MATLAB側をutf-8に変更すると色々面倒くさい

MATLABのデフォルト文字コードをutf-8に変更する方法はあるのですが、次の通りいくつかデメリットがあります。

  1. 逆に今まで作ったShift_JISのファイルが全て文字化けする
  2. 他の人とコード共有がしにくくなる
  3. 文字コードの変更は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ライフを!

コメント