"Unknown terminal type" error when trying to run emacsclient
Explanation of the bug
remember-other-frame
calls switch-to-buffer-other-frame
which calls display-buffer
with the variable pop-up-frames
set to t
. This results in a call to make-frame
with the argument pop-up-frame-alist
. The function make-frame
creates a frame on the same display device as the current selected frame. (What Emacs calls a frame is what GUIs call a window, except that a frame can also be in a text terminal.) At this point, Emacs is still running in daemon mode, so there is no selected frame. Thus make-frame
sees no GUI environment and thinks it should create a terminal frame, but there is no text terminal either, resulting in the confusing error message “Unknown terminal type”.
Simple but clumsy workaround
remember-other-frame
is the right function to call from within an existing Emacs window, but is technically wrong from emacsclient. There, we should be using the -c
option to make Emacs create a new frame, and the plain remember
function.
emacsclient -a "" -c -e "(remember)"
However this is not very nice because remember
creates a window which has to be dismissed with C-c C-c
(which is also what saves the note), then the frame has to be dismissed with C-x 5 0
. If you forget C-c C-c
(which is all the more likely because the message to type C-x 5 0
overwrites the message to type C-c C-c
in the echo area), the note isn't even saved.
A nicer workaround
Instruct make-frame
explicitly to create the frame on the current X display.
emacsclient -a "" -e "
(let ((pop-up-frame-alist \`((window-system . x)
(display . \"$DISPLAY\")
,@pop-up-frame-alist)))
(remember-other-frame))"
You can put this all in one line, just make sure not to change the punctuation.
emacsclient -a "" -e "(let ((pop-up-frame-alist \`((window-system . x) (display . \"$DISPLAY\") ,@pop-up-frame-alist))) (remember-other-frame))"