I have written a custom interactive command that takes a character as an argument. When I happen to use the key binding for that command while in a eshell buffer where a long-running command is currently running, I get this backtrace:
Debugger entered--Lisp error: (wrong-type-argument characterp (switch-frame #<frame perf_log.1 0x2b7af490>))
char-to-string((switch-frame #<frame perf_log.1 0x2b7af490>))
eshell-self-insert-command()
call-interactively(eshell-self-insert-command nil nil)
command-execute(eshell-self-insert-command)
So I looked at the code for that function:
(defun eshell-self-insert-command ()
(interactive)
(process-send-string
(eshell-interactive-process)
(char-to-string (if (symbolp last-command-event)
(get last-command-event 'ascii-character)
last-command-event))))
The only reference to which I can find is inside the ominous sounding function eshell-intercept-commands
.
I suspect that in that circumstance eshell mistakenly thinks that the last command event was intended for it. Is there a way to filter those instances?
The full implementation of my command is below (it assigns unique characters to emacs windows, displays the character in the modeline, then lets me switch to that window by pressing a hotkey and letter assigned to the window):
(defconst md-glyphs
'(?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z
?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
?^ ?\# ?\ ?> ?\; ?\" ?* ?\' ?% ?\\ ?\` ?$ ?[ ?_ ?\, ?{ ?:
?! ?- ?\( ?\| ?~ ?\. ?? ?= ?\) ?< ?} ?& ?/ ?@ ?+ ?]))
(defun md-get-window-glyph (w)
(let* ((fp (frame-parameters (window-frame w)))
(frame-top (cdr (assoc 'top fp)))
(frame-left (cdr (assoc 'left fp)))
(window-top (window-top-line w))
(window-left (window-left-column w))
(hash (md5 (format "%S %S %S %S" frame-top frame-left window-top window-left)))
(glyph (nth (% (string-to-number (substring hash 0 2) 16) (length md-glyphs)) md-glyphs)))
(char-to-string glyph)))
(setq-default mode-line-format
(append
(list '(:eval (propertize (format "[%s] " (md-get-window-glyph (get-buffer-window))) 'face 'font-lock-constant-face)))
mode-line-format))
(defun md-select-window-with-glyph (chosen-glyph)
(interactive "cWindow glyph: ")
(dolist (f (frame-list))
(dolist (w (window-list f 0))
(ignore-errors
(when (equal (downcase (md-get-window-glyph w)) (downcase (char-to-string chosen-glyph)))
(select-frame-set-input-focus f)
(select-window w))))))
(global-set-key (kbd "M-d") #'md-select-window-with-glyph)