説明文
emacsclientを呼び出すときのデフォルトの動作は少し保守的です。emacsclient.cからこのコメントをチェックしてください
:
/* Unless we are certain we don't want to occupy the tty, send our
tty information to Emacs. For example, in daemon mode Emacs may
need to occupy this tty if no other frame is available. */
説明とコメントから、-n
フラグを使用しながらオンデマンドでEmacsサーバーを起動しようとしているようです。ここの「例」のコメントは、emacsclient -n -a '' FILE
サーバーが実行されていないときに探しているものを満たさない理由です。
-a ''
ロジックは、デーモンを起動します。
- 次に
emacsclient
、新しいターミナルフレームを作成するように指示します。これは、elispを評価していない限り、これがデフォルトであるためです。
-n
ロジックは、すぐにその新しいターミナルフレームを殺します。
ステップ2を変更して、デフォルトで新しいグラフィックフレームを作成できる場合
emacsclient -n -a '' FILE
は、必要な処理を実行します。
Elispソリューション
Emacsにデフォルトで新しいグラフィックフレームを作成させるには、次のように関数に通知しますserver-process-filter
。
(defadvice server-process-filter (before prefer-graphical activate)
;; STRING is a sequence of commands sent from emacsclient to the server.
(when (and
;; Check that we're editing a file, as opposed to evaluating elisp.
(string-match "-file" string)
;; Check that there are no frames beyond the Emacs daemon's terminal.
(daemonp)
(null (cdr (frame-list)))
(eq (selected-frame) terminal-frame)
;; Check that we have a graphical display.
;; `display-graphic-p' doesn't work here.
(getenv "DISPLAY"))
(setq string (concat
;; STRING must be all one line, but comes to us
;; newline-terminated. Strip off the trailing newline.
(replace-regexp-in-string "\n$" "" string)
;; Add the commands to create a graphical frame.
"-window-system "
"-display " (getenv "DISPLAY")
;; Add back the newline.
"\n"))))
それをあなたのinitファイルに入れてください、そして、言われたように、emacsclient -n -a '' FILE
そしてボブはあなたの叔父です。
シェルソリューションと比較
一方で、私はArchenothによって提案されたスクリプトを使用する場合と比較して、このdefadviceアプローチを使用することのいくつかの利点を指摘でき
ます。
#!/bin/bash
emacs --eval '(server-start)' $* &
代替エディタとして。defadviceで:
save-buffers-kill-terminal
(C-x C-c
デフォルト)すべてのフレームにわたって一貫して動作します。すべてのフレームは常にクライアントフレームであるため、Emacsプロセスが強制終了されることはありません。
- デーモンのターミナルフレームがハングします。
find-grep
そのような外部プロセスへのシェルアウトのようなコマンドは、ダムターミナルが存在する場合により適切に動作します。少なくとも、シェルエスケープに関連する頭痛が少なくなります。
一方で...ええ。
- そのシェルスクリプトは美しくシンプルです。
- Emacsの通信プロトコルに助言することはできません。
結論
たぶん妥協があるのでしょうか?これは私が思いつくことができる最高のものです。$ EDITORとして設定します。
#!/bin/sh
emacsclient -e "(frames-on-display-list \"${DISPLAY}\")" 1>/dev/null 2>/dev/null
if [ "$?" = "1" ]; then
emacsclient -c -n -a "" "$@"
else
emacsclient -n "$@"
fi
-a ''
「Emacsデーモンを起動してemacsclientを再試行する」オプションを使用しないことを選択する理由はありますか?