Files
roam/azosemacs.org
T
2026-10-05 09:48:25 +03:00

2.5 KiB

azos/emacs

Gotchas

  • async-shell-command spawns subprocesses with TERM=dumb and no real controlling tty (confirmed: no INSIDE_EMACS, pty exists but curses can't use it). Any gpg/pinentry prompt triggered from such a process (e.g. signed git commits) fails with "Inappropriate ioctl for device" once the pinentry PIN cache expires — pinentry-emacs mode silently isn't engaged either, since gpg only requests it when INSIDE_EMACS is set, which async-shell-command doesn't set (unlike M-x shell=/comint, which does). Fix: run the command in a real pty via =vterm instead (confirmed working — vterm-term-environment-variable is set to xterm-256color). Fixed in azos/roam/backup (features/lauretta/emacs/config.org) 2026-10-04.
  • org-babel emacs-lisp source blocks evaluate with dynamic binding by default (ob-emacs-lisp.el defaults :lexical to "no"), and config.org sets no :lexical header anywhere (file-wide or per-block). This silently breaks closures in async code: a pattern like (let ((output "")) (make-process :filter (lambda (_p chunk) (setq output ...)) :sentinel (lambda (_p _e) ... output ...))) fails because the let-bound output unwinds before the async filter/sentinel callbacks run — they don't lexically close over it. The failure is silent: errors like "Symbol's value as variable is void: output" only appear in *Messages*, not as visible UI errors, and whatever the sentinel was supposed to set (e.g. elfeed-feeds) just stays nil. This hit the elfeed-protocol Nextcloud News auth block (fetches a pass(1) password asynchronously via make-process to avoid blocking Emacs's command loop and deadlocking with pinentry-emacs, then sets elfeed-feeds from the sentinel) — elfeed-update appeared to "do nothing" because of this exact bug. Fix/convention: for any async Emacs Lisp in this repo's org-babel blocks (process filters/sentinels, timers, callbacks) that needs to carry state across the async boundary, don't rely on closures over let-bound locals unless the block explicitly sets :lexical yes. Instead store state on the process object itself via process-put=/=process-get (works regardless of lexical/dynamic binding) — this is the pattern now used in the elfeed-protocol block. Fixed in features/lauretta/emacs/config.org (Elfeed Nextcloud News Sync section) 2026-10-05.

azos