3.1 KiB
3.1 KiB
azos/emacs
Gotchas
async-shell-commandspawns subprocesses withTERM=dumband no real controlling tty (confirmed: noINSIDE_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 whenINSIDE_EMACSis set, whichasync-shell-commanddoesn't set (unlikeM-x shell=/comint, which does). Fix: run the command in a real pty via =vterminstead (confirmed working —vterm-term-environment-variableis set toxterm-256color). Fixed inazos/roam/backup(features/lauretta/emacs/config.org) 2026-10-04.- A nix rebuild (
azos-lauretta-update) only regenerates files on disk (e.g.config.org) — it never reloads anything into an already-running Emacs session.setq=/=defvarforms evaluated at startup (e.g.mu4e-contexts) stay stale until that exact top-level form is re-evaluated, e.g. viaemacsclient -e '(load-file "/tmp/x.el")'on a file containing just that extracted sexp (match parens exactly — an off-by-one line range truncates the form and errors "End of file during parsing" instead of warning about staleness). Discovered via mu4e context drift, see azos/mail Gotchas for the full incident. org-babelemacs-lispsource blocks evaluate with dynamic binding by default (ob-emacs-lisp.eldefaults:lexicalto"no"), andconfig.orgsets no:lexicalheader 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-boundoutputunwinds 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 staysnil. This hit the elfeed-protocol Nextcloud News auth block (fetches apass(1)password asynchronously viamake-processto avoid blocking Emacs's command loop and deadlocking with pinentry-emacs, then setselfeed-feedsfrom the sentinel) —elfeed-updateappeared 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 overlet-bound locals unless the block explicitly sets:lexical yes. Instead store state on the process object itself viaprocess-put=/=process-get(works regardless of lexical/dynamic binding) — this is the pattern now used in the elfeed-protocol block. Fixed infeatures/lauretta/emacs/config.org(Elfeed Nextcloud News Sync section) 2026-10-05.