"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))"

Tags:

Emacs

Debian