Sự miêu tả
Hành vi mặc định khi gọi emacsclient là một chút bảo thủ. Kiểm tra nhận xét này từ
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. */
Từ mô tả và nhận xét của bạn, có vẻ như bạn đang cố gắng khởi động máy chủ Emacs theo yêu cầu đồng thời sử dụng -n
cờ. Nhận xét "ví dụ" ở đây là lý do tại sao emacsclient -n -a '' FILE
không thỏa mãn những gì bạn đang tìm kiếm khi không có máy chủ nào đang chạy.
- Các
-a ''
lý khởi động một daemon.
- Sau đó
emacsclient
bảo nó tạo khung đầu cuối mới, vì đó là mặc định trừ khi bạn đánh giá elisp.
- Các
-n
luận ngay lập tức giết chết mà khung nhà ga mới.
Nếu bạn có thể thay đổi Bước 2 để tạo khung đồ họa mới theo mặc định, thì
emacsclient -n -a '' FILE
sẽ làm những gì bạn muốn.
Giải pháp Elisp
Bạn có thể khiến Emacs tạo khung đồ họa mới theo mặc định nếu bạn tư vấn cho chức năng server-process-filter
như vậy:
(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"))))
Đặt nó trong tập tin init của bạn, sau đó, như đã nói, emacsclient -n -a '' FILE
và Bob là chú của bạn.
So sánh với giải pháp Shell
Một mặt, tôi có thể chỉ ra một vài lợi thế khi sử dụng phương pháp tiếp cận khiếm khuyết này so với việc sử dụng
tập lệnh được đề xuất bởi Archenoth
#!/bin/bash
emacs --eval '(server-start)' $* &
làm biên tập viên thay thế. Với sự thất bại:
save-buffers-kill-terminal
( C-x C-c
theo mặc định) hoạt động nhất quán trên tất cả các khung. Nó không bao giờ giết chết quá trình Emacs, bởi vì mọi khung hình luôn là một khung máy khách.
- Khung thiết bị đầu cuối của daemon treo xung quanh. Các lệnh như
find-grep
vậy bao ra các quy trình bên ngoài hoạt động tốt hơn khi thiết bị đầu cuối câm ở đó. Ít nhất, tôi trải nghiệm ít đau đầu liên quan đến thoát vỏ.
Mặt khác ... vâng.
- Kịch bản shell đó là đơn giản đẹp.
- Tư vấn giao thức truyền thông của Emacs thì không.
Phần kết luận
Có lẽ có một sự thỏa hiệp? Đây là điều tốt nhất tôi có thể nghĩ ra. Bạn đặt nó là $ EDITOR của bạn.
#!/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 ''
tùy chọn "khởi động trình nền Emacs và thử lại emacsclient" không?