From 854b0a61bfe0e70e5220b246298ee070486cb979 Mon Sep 17 00:00:00 2001 From: David Florness Date: Thu, 16 Jul 2026 22:59:36 -0400 Subject: [PATCH] llm: pop company for agent-shell @/ completion agent-shell installs a post-self-insert-hook trigger that calls the built-in completion-at-point, which opens the *Completions* buffer. With global-company-mode on, that pre-empts company: the trigger runs on post-self-insert-hook *before* company's post-command-hook trigger, and a bare '/' has an empty prefix (below company-minimum-prefix-length), so company never fires for slash commands. (corfu works out of the box here because it hooks completion-in-region-function; company doesn't.) Fix: on agent-shell-completion-mode-hook -- which runs after the mode installs its trigger -- swap agent-shell's trigger for one that calls company-manual-begin on @ or / at a word boundary. company-manual-begin ignores company-minimum-prefix-length, so the command list pops even with nothing typed after the '/'. The swap is guarded on the private agent-shell--trigger-completion-at-point still being on the hook, so if agent-shell renames or drops it, this no-ops and falls back to upstream completion instead of double-triggering. Co-Authored-By: Claude Opus 4.8 --- lisp/llm.el | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lisp/llm.el b/lisp/llm.el index 61bfaa7..852d443 100644 --- a/lisp/llm.el +++ b/lisp/llm.el @@ -1,7 +1,37 @@ +(defun my-agent-shell-company-trigger () + "Pop up company for agent-shell @ and / completions at a word boundary. +`company-manual-begin' ignores `company-minimum-prefix-length', so the +command list appears even with no characters typed after the `/'." + (when (and (memq (char-before) '(?@ ?/)) + (or (= (point) (1+ (line-beginning-position))) + (memq (char-before (1- (point))) '(?\s ?\t ?\n)))) + (company-manual-begin))) + +(defun my-agent-shell-use-company-completion () + "Route agent-shell @/ completion through company. +agent-shell's own trigger calls `completion-at-point', which opens the +default *Completions* buffer from `post-self-insert-hook' before company's +`post-command-hook' trigger runs, so company never fires on a bare `/'. +Swap it for a trigger that invokes company directly. Runs from +`agent-shell-completion-mode-hook', after that mode installs its trigger. + +Guarded on the (private) `agent-shell--trigger-completion-at-point' still +being installed on the hook: if agent-shell renames or drops it, this +no-ops and leaves upstream's completion untouched rather than +double-triggering." + (when (and agent-shell-completion-mode + (memq #'agent-shell--trigger-completion-at-point + post-self-insert-hook)) + (remove-hook 'post-self-insert-hook + #'agent-shell--trigger-completion-at-point t) + (add-hook 'post-self-insert-hook + #'my-agent-shell-company-trigger nil t))) + (use-package agent-shell :custom (agent-shell-prefer-viewport-interaction t) (agent-shell-session-restore-verbosity 'full) + :hook (agent-shell-completion-mode . my-agent-shell-use-company-completion) :config (setq acp-logging-enabled t)) -- 2.38.4