■ MinGW版 Emacs 特有の設定


【お知らせ】


<2022/06/23 追記>
次のページに興味深い情報があります。
さらに msvcrt.dll を調べると、次のページが見つかりました。
Windows版 Emacs の utf-8 化、あと一歩というところでしょうか。

<2017/09/10 追記>
後半で紹介している 4096バイトを超えるデータを送出したときの問題の対策は、Emacs-25系では不要であることを確認しました。

<2015/10/30 追記>
fakecygpty を利用するための設定には、次のページのものもあります。私は使ってはいないのですが、ここの前半の設定の代わりに使えるのではないかと思います。
https://github.com/d5884/fakecygpty

<2015/07/26 追記>
NTEmacs スレッド5 の 131、132 の投稿の内容を踏まえ、設定を見直しました。
この見直しで、「shell-mode を使うための設定」や「multi-term を使うための設定」で行っていた shell の割り込みの設定が不要となりました。

<2015/07/26 追記>
fakecygpty.c のリンクを次のとおりに変更しました。新しいリンク先の fakecygpty.c を使うことで、twittering-mode が正常に動作するようです。
なお、gnupack-11.00 で twittering-mode を動かすためには、Cygwin に curl と gnupg のインストールが必要でした。

<2015/07/12 追記>
ここのページでの fakecygpty の利用は Cygwin の利用を前提に記載したものですが、次の 2ch の情報では MSYS2 でも利用可能なものとのことです。

<2015/04/09 追記>
Emacs-24.4 のための設定(【本題】の後者の設定)において、NTEmacsスレッド4 734、737 の対策も兼ねるため、4096バイトを超えない入力の場合でも一律同じ処理を実行するようにしました。

<2014/12/11 追記>
Emacs-24.4 では、fakecygpty を経由して起動したプロセスに対し、4096バイトを超える入力を一回に送り込むとレスポンスが帰ってこない状況となります。
これを改善する対策を追加しました。(NTEmacsスレッド4 714 の投稿を一部修正したものとなります。)

【本題】


NTEmacs で Cygwin のコマンドを fakecygpty 経由で起動するために必要となる設定です。

1) 次のページから fakecygpty.c をダウンロードし、Cygwin のコンパイラでコンパイルしてください。そして、~/bin 等のパスの通った場所に fakecygpty.exe という名称で置いてください。
コンパイル済みのものは、次のリンクからダウンロードできます。

2) 以下の設定を有効としてください。

start-process のアドバイスは、start-process 実行直前に処理が行われるよう、advice-add の depth の設定を 100 としています。
(require 'cl-lib)

;; process-connection-type が nil で start-process がコールされるけれども、fakecygpty を経由して
;; 起動したいプログラムの名称を列挙する
(defvar fakecygpty-program-list '("mozc_emacs_helper.sh"))

;; fakecygpty を経由するかを判断してプログラムを起動する
(advice-add 'start-process
            :around (lambda (orig-fun &rest args)
                      (when (and (nth 2 args)
                                 (or process-connection-type
                                     (member (replace-regexp-in-string "\\.exe$" ""
                                                                       (file-name-nondirectory (nth 2 args)))
                                             fakecygpty-program-list)))
                        (push "fakecygpty" (nthcdr 2 args)))
                      (apply orig-fun args))
            '((depth . 100)))

;; fakecygpty を経由して起動したプロセスに対し、コントロールキーを直接送信する
(cl-loop for (func ctrl-key) in '((interrupt-process "C-c")
                                  (quit-process      "C-\\")
                                  (stop-process      "C-z")
                                  (process-send-eof  "C-d"))
         do (eval `(advice-add ',func
                               :around (lambda (orig-fun &rest args)
                                         (let ((process (or (nth 0 args)
                                                            (get-buffer-process (current-buffer)))))
                                           (if (string= (car (process-command process)) "fakecygpty")
                                               (process-send-string (nth 0 args) (kbd ,ctrl-key))
                                             (apply orig-fun args)))))))

3) Emacs-24.4、Emacs-24.5 を利用している場合は、以下の設定も行ってください。Emacs-25系では不要な設定です。
;; Emacs-24.4、Emacs-24.5 では、4096バイトを超えるデータを一度にパイプ経由でプロセスに送り込むと、
;; レスポンスが帰ってこない状況となる。これを改善する。
;; (NTEmacsスレッド4 714 の投稿を一部修正したもの。NTEmacsスレッド4 734、737 の対策も兼ねるため、
;;   4096バイトを超えない入力の場合でも一律同じ処理を実行している。)

(defconst w32-pipe-limit 4096)

(defun ad-process-send-string (orig-fun &rest args)
  (if (not (eq (process-type (nth 0 args)) 'real))
      (apply orig-fun args)
    (let* ((process (or (nth 0 args)
                        (get-buffer-process (current-buffer))))
           (send-string (encode-coding-string (nth 1 args)
                                              (cdr (process-coding-system (get-process process)))))
           (send-string-length (length send-string)))
      (let ((inhibit-eol-conversion t)
            (from 0)
            to)
        (while (< from send-string-length)
          (setq to (min (+ from w32-pipe-limit) send-string-length))
          (setf (nth 1 args) (substring send-string from to))
          (apply orig-fun args)
          (setq from to))))))

(advice-add 'process-send-string :around #'ad-process-send-string))


<変更履歴>
  • 2012/12/30 start-process のアドバイスの定義を before から around に変更した。
  • 2012/12/31 start-process のアドバイスの定義に position の設定を追加した。
  • 2012/12/31 拡張子を取る方法に file-name-sans-extension を採用した。
  • 2013/09/09 fakecygpty の経由を回避するプロセスの指定方法を変更した。
  • 2013/09/12 プロセスの判定方法を再度見直しした。
  • 2013/10/10 fakecygpty を経由するかの判定時の suffix の扱いを見直しした。
  • 2014/12/11 Emacs-24.4 では、fakecygpty を経由して起動したプロセスに対し、4096バイトを超える入力を一回に送り込むとレスポンスが帰ってこない状況となる。これを改善する対策を追加した。
  • 2014/12/14 process-connection-type の設定の状況で fakecygpty 経由でプログラムを起動するかどうかを判断するように見直した。
  • 2014/12/18 NTEmacsスレッド4 726 の対策を反映した。(inhibit-eol-conversion を t に束縛して process-send-string を実行することで、改行変換が二回行われないようにしている。)
  • 2015/04/09 Emacs-24.4 のための設定(後者の設定)において、NTEmacsスレッド4 734、737 の対策も兼ねるため、4096バイトを超えない入力の場合でも一律同じ処理を実行するようにした。
  • 2015/07/26 fakecygpty.c のリンクを改善版のものに変更した。
  • 2015/07/26 NTEmacs スレッド5 の 131、132 の投稿の内容を踏まえ、設定を見直した。
  • 2015/09/09 advice を Emacs-24.4 以降の書式に見直した。


最終更新:2021年06月25日 14:15
添付ファイル