Deskripsi
Perilaku default saat menjalankan emacsclient sedikit konservatif. Lihat komentar ini dari
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. */
Dari uraian dan komentar Anda, sepertinya Anda mencoba memulai server Emacs sesuai permintaan sementara juga menggunakan -n
flag. Komentar "misalnya" di sini adalah mengapa emacsclient -n -a '' FILE
tidak memenuhi apa yang Anda cari ketika tidak ada server yang berjalan.
- The
-a ''
logika dijalankan daemon.
- Kemudian
emacsclient
katakan itu untuk membuat bingkai terminal baru, karena itu default kecuali Anda mengevaluasi elisp.
- The
-n
logika segera membunuh kerangka terminal baru.
Jika Anda dapat mengubah Langkah 2 untuk membuat bingkai grafis baru secara default, maka
emacsclient -n -a '' FILE
lakukan apa yang Anda inginkan.
Solusi Elisp
Anda dapat menyebabkan Emacs untuk membuat bingkai grafis baru secara default jika Anda menyarankan fungsi server-process-filter
seperti:
(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"))))
Masukkan itu ke dalam file init Anda, lalu, seperti yang dikatakan, emacsclient -n -a '' FILE
dan Bob adalah paman Anda.
Bandingkan dengan Solusi Shell
Di satu sisi, saya bisa menunjukkan beberapa keuntungan menggunakan pendekatan defadvice ini dibandingkan dengan menggunakan
skrip yang disarankan oleh Archenoth
#!/bin/bash
emacs --eval '(server-start)' $* &
sebagai editor alternatif. Dengan defadvice:
save-buffers-kill-terminal
( C-x C-c
secara default) berperilaku konsisten di semua bingkai. Itu tidak pernah membunuh proses Emacs, karena setiap frame selalu merupakan bingkai klien.
- Bingkai terminal daemon menggantung. Perintah seperti
find-grep
itu keluar untuk proses eksternal berperilaku lebih baik ketika terminal bisu ada. Setidaknya, saya mengalami lebih sedikit sakit kepala terkait shell yang lepas.
Di sisi lain ... ya.
- Script shell itu sangat sederhana.
- Nasihat protokol komunikasi Emacs tidak.
Kesimpulan
Mungkin ada kompromi? Ini adalah yang terbaik yang bisa saya pikirkan. Anda menetapkannya sebagai $ EDITOR Anda.
#!/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 ''
, "mulai daemon Emacs dan coba lagi emacsclient"?