Windows 上の Emacs で M-x compile により、最近の Visual Studio 2022 のコマンドライン版 C++ コンパイラを使用すると文字化けするので対策

Windows 上で Emacs で M-x compile でコンパイルしてます。

Visual Studio 2022 の最近のバージョンではコマンドラインツール出力の文字コーディングが UTF-8 になりました。

CP932 (ShiftJIS) でバッチファイルを組んであり、そこから vsvarsall.bat と msbuild.exe を呼び出すようにしているので、メッセージのコーディングが混在し Emacs では文字化けするようになってしまいました。

その対策です。

以下を ~/.emacs 等に追加して再起動します。

;; Visual Studio 2022 でのビルドのためにコンパイルプロセスのコーディングシステムを切り替える
;;
;; 切り替えは以下の文字列パターンによる
;;
;;   /Visual Studio 20[2-9][0-9]/ (vcvarsall.bat が出力するメッセージ)
;;   /^INFO: The following lines are encoded in utf-8-dos./ (自作スクリプトに埋め込む用)
;;   /^INFO: The following lines are encoded in cp932-dos./ (自作スクリプトに埋め込む用)
;;
;; 切り替えは瞬時には行われないため、直後にメッセージを出力するときは "sleep 1" を実行するなどして
;; 少し待って欲しい。
;;
(defun vs2022-compilation-filter ()
  (let ((process (get-buffer-process "*compilation*")))
    (when (save-excursion
            (goto-char compilation-filter-start)
            (re-search-forward "Visual Studio 20[2-9][0-9]" nil t))
      (set-process-coding-system process 'utf-8-dos 'utf-8-dos))
    (save-excursion
      (goto-char compilation-filter-start)
      (when (re-search-forward "^INFO: The following lines are encoded in " nil t)
        (save-excursion
          (when (re-search-forward "utf-8-dos" nil t)
            (set-process-coding-system process 'utf-8-dos 'utf-8-dos)))
        (save-excursion
          (when (re-search-forward "cp932-dos" nil t)
            (set-process-coding-system process 'cp932-dos 'cp932-dos)))))))
(add-hook 'compilation-filter-hook 'vs2022-compilation-filter)

vcvarsall.bat が出力するメッセージ中の "Visual Studio 2022" に反応して、コンパイルプロセスのコーディングシステムを UTF-8 に切り替えるようにしました。前のバージョンの Visual Studio 2019 も使用しているのですが、こちらは従来通りですので、年号部分は 2020 から 2099 までに反応するように正規表現で指定しています。

また、msbuild の呼び出しから戻り、その後は CP932 でメッセージを出力することがあるため、以下の文字列をバッチファイルから出力することにし、これに反応してコンパイルプロセスのコーディングシステムを CP932 に戻すようにしました。

INFO: The following lines are encoded in cp932-dos.