Function: eca-chat--doctor-format

eca-chat--doctor-format is a natively compiled function defined in eca-chat.el.

Signature

(eca-chat--doctor-format SRC-BUF)

Documentation

Return a markdown diagnostic string describing chat buffer SRC-BUF.

Captures major-mode derivation, RET binding, shadowing minor modes, ECA chat state, prompt overlays, and rule-based hints.

Source Code

;; Defined in /nix/store/jklqzw6pzz6j4jrbv8wy0iwgi7jlrbld-emacs-packages-deps/share/emacs/site-lisp/elpa/eca-20260928.1827/eca-chat.el
(defun eca-chat--doctor-format (src-buf)
  "Return a markdown diagnostic string describing chat buffer SRC-BUF.
Captures `major-mode' derivation, RET binding, shadowing minor modes,
ECA chat state, prompt overlays, and rule-based hints."
  (let* ((mm (buffer-local-value 'major-mode src-buf))
         (in-chat-p (with-current-buffer src-buf
                      (derived-mode-p 'eca-chat-mode)))
         (parent-mode (and (boundp 'eca-chat-parent-mode)
                           eca-chat-parent-mode))
         (def-dir (buffer-local-value 'default-directory src-buf))
         (ret-cmd (with-current-buffer src-buf
                    (key-binding (kbd "RET"))))
         (return-cmd (with-current-buffer src-buf
                       (key-binding (kbd "<return>"))))
         (cm-cmd (with-current-buffer src-buf
                   (key-binding (kbd "C-m"))))
         (input-method (buffer-local-value 'current-input-method src-buf))
         (e-indent (and (boundp 'electric-indent-mode)
                        (buffer-local-value 'electric-indent-mode src-buf)))
         (e-pair (and (boundp 'electric-pair-mode)
                      (buffer-local-value 'electric-pair-mode src-buf)))
         (e-quote (and (boundp 'electric-quote-mode)
                       (buffer-local-value 'electric-quote-mode src-buf)))
         (evil-on (and (boundp 'evil-mode) (symbol-value 'evil-mode)))
         (evil-state-val (and (boundp 'evil-state)
                              (buffer-local-value 'evil-state src-buf)))
         (viper-on (and (boundp 'viper-mode) (symbol-value 'viper-mode)))
         (god-on (and (boundp 'god-local-mode)
                      (buffer-local-value 'god-local-mode src-buf)))
         (sp-on (and (boundp 'smartparens-mode)
                     (buffer-local-value 'smartparens-mode src-buf)))
         (paredit-on (and (boundp 'paredit-mode)
                          (buffer-local-value 'paredit-mode src-buf)))
         (corfu-on (and (boundp 'corfu-mode)
                        (buffer-local-value 'corfu-mode src-buf)))
         (company-on (and (boundp 'company-mode)
                          (buffer-local-value 'company-mode src-buf)))
         (chat-id (buffer-local-value 'eca-chat--id src-buf))
         (closed (buffer-local-value 'eca-chat--closed src-buf))
         (loading (buffer-local-value 'eca-chat--chat-loading src-buf))
         (pending (buffer-local-value 'eca-chat--pending-questions src-buf))
         (session (with-current-buffer src-buf
                    (ignore-errors (eca-session))))
         (prompt-area (with-current-buffer src-buf
                        (ignore-errors (eca-chat--prompt-area-ov))))
         (prompt-field (with-current-buffer src-buf
                         (ignore-errors (eca-chat--prompt-field-ov))))
         (prompt-content (with-current-buffer src-buf
                           (ignore-errors (eca-chat--prompt-content))))
         (pt (with-current-buffer src-buf (point)))
         (self (eca-chat--doctor-self-check src-buf))
         (hints nil))
    ;; --- compute hints ---
    (unless in-chat-p
      (push (format "Inspected buffer's `major-mode' is `%s' and is not \
derived from `eca-chat-mode'.  `eca-chat-mode' likely failed to activate." mm)
            hints))
    (when (and in-chat-p
               (not (eq ret-cmd 'eca-chat--key-pressed-return)))
      (push (format "RET is bound to `%s', not \
`eca-chat--key-pressed-return'.  Another keymap is intercepting RET — see \
\"Likely shadowing\" below." ret-cmd)
            hints))
    (when (and in-chat-p (null session))
      (push "(eca-session) returned nil from inside the chat buffer — \
the buffer is not registered to any ECA workspace." hints))
    (when (and in-chat-p (null prompt-area))
      (push "The `eca-chat-prompt-area' overlay is missing — chat buffer is \
in an inconsistent state.  Try `M-x eca-chat-reset'." hints))
    (when (and in-chat-p evil-on (eq evil-state-val 'insert))
      (push "evil-mode is in insert state.  `evil-insert-state-map' (an \
emulation map) beats major-mode maps.  If RET above is `evil-ret' / \
`newline', that is the cause." hints))
    (when (and in-chat-p pending)
      (push "An unanswered question is pending \
(`eca-chat--pending-questions' non-nil).  RET without freeform input is \
intentionally a no-op until you answer the question." hints))
    (when (and in-chat-p closed)
      (push "This chat is marked closed (`eca-chat--closed' non-nil); \
sending will raise a user-error." hints))
    (when (and in-chat-p (not (plist-get self :mode-map-ret-ok)))
      (push (format "`eca-chat-mode-map' RET is `%s', expected \
`eca-chat--key-pressed-return'.  Some code has clobbered the mode-map \
after `eca-chat' was loaded; check your user config."
                    (plist-get self :mode-map-ret))
            hints))
    (when (and in-chat-p (eq (plist-get self :cond-ok) nil))
      (push "`eca-chat--key-pressed-return' references the markdown-link \
clause before the expandable clause.  Loaded code predates commit \
`dac33d8'; pull master, restart Emacs, and `M-x byte-recompile-directory' \
if the warning persists." hints))
    (when (and in-chat-p (plist-get self :has-label)
               (not (plist-get self :label-ret-ok)))
      (push "The first expandable block label has no RET binding in its \
`keymap' text-property.  Either the loaded `eca-chat-expandable.el' \
predates commit `dac33d8' or this block was rendered before the fix was \
reloaded; start a new chat or wait for a fresh tool call to be rendered."
            hints))
    (when (and in-chat-p (plist-get self :stale-elc-p))
      (push (format "`%s' is newer than the loaded `%s'.  Recompile \
(`M-x byte-recompile-directory') or delete the stale `.elc' and restart \
Emacs." (plist-get self :source-file) (plist-get self :loaded-file))
            hints))
    ;; --- render report into temp buffer and return as string ---
    (with-temp-buffer
      (insert "### Inspected chat buffer\n\n")
      (insert (format "- buffer:            %s\n" (buffer-name src-buf)))
      (insert (format "- major-mode:        %s\n" mm))
      (insert (format "- derived from `eca-chat-mode': %s\n"
                      (if in-chat-p "yes" "NO")))
      (insert (format "- `eca-chat-parent-mode': %s\n" parent-mode))
      (insert (format "- default-directory: %s\n\n" def-dir))
      (insert "### Key bindings in chat buffer\n\n")
      (insert (format "- RET        → %s\n" (or ret-cmd "<unbound>")))
      (insert (format "- <return>   → %s\n" (or return-cmd "<unbound>")))
      (insert (format "- C-m        → %s\n\n" (or cm-cmd "<unbound>")))
      (insert "### Likely shadowing / input translation\n\n")
      (insert (format "- current-input-method:  %s\n" (or input-method "nil")))
      (insert (format "- electric-indent-mode:  %s\n" e-indent))
      (insert (format "- electric-pair-mode:    %s\n" e-pair))
      (insert (format "- electric-quote-mode:   %s\n" e-quote))
      (insert (format "- evil-mode:             %s (state=%s)\n"
                      evil-on evil-state-val))
      (insert (format "- viper-mode:            %s\n" viper-on))
      (insert (format "- god-local-mode:        %s\n" god-on))
      (insert (format "- smartparens-mode:      %s\n" sp-on))
      (insert (format "- paredit-mode:          %s\n" paredit-on))
      (insert (format "- corfu-mode:            %s\n" corfu-on))
      (insert (format "- company-mode:          %s\n\n" company-on))
      (insert "### ECA chat state\n\n")
      (insert (format "- eca-chat--id:                %s\n" chat-id))
      (insert (format "- eca-chat--closed:            %s\n" closed))
      (insert (format "- eca-chat--chat-loading:      %s\n" loading))
      (insert (format "- eca-chat--pending-questions: %d\n"
                      (length pending)))
      (insert "- (eca-session): ")
      (if session
          (insert (format "found (id=%s, roots=%S)\n\n"
                          (eca--session-id session)
                          (eca--session-workspace-folders session)))
        (insert "NIL — buffer is not registered to a workspace\n\n"))
      (insert "### Self-check\n\n")
      (insert (format "- `eca-chat-mode-map' RET → %s  %s\n"
                      (or (plist-get self :mode-map-ret) "<unbound>")
                      (if (plist-get self :mode-map-ret-ok) "✓" "✗")))
      (insert (format
               "- `eca-chat--key-pressed-return': expandable before \
markdown-link  %s\n"
               (let ((status (plist-get self :cond-ok)))
                 (cond ((eq status t) "✓")
                       ((null status) "✗")
                       (t "? (could not introspect)")))))
      (if (plist-get self :has-label)
          (insert (format "- nearest expandable label RET → %s  %s\n"
                          (let ((b (plist-get self :label-ret)))
                            (cond ((null b) "<unbound>")
                                  ((functionp b) "<toggle lambda>")
                                  (t (format "%s" b))))
                          (if (plist-get self :label-ret-ok) "✓" "✗")))
        (insert "- nearest expandable label RET: n.a. \
(no blocks rendered yet)\n"))
      (insert (format "- loaded from: %s\n"
                      (or (plist-get self :loaded-file) "<unknown>")))
      (when (plist-get self :stale-elc-p)
        (insert (format "  ⚠ source `%s' is newer than the loaded `.elc'\n"
                        (plist-get self :source-file))))
      (insert "\n")
      (insert "### Prompt overlays\n\n")
      (insert (format "- prompt-area overlay:  %s\n"
                      (if prompt-area
                          (format "%d..%d"
                                  (overlay-start prompt-area)
                                  (overlay-end prompt-area))
                        "MISSING")))
      (insert (format "- prompt-field overlay: %s\n"
                      (if prompt-field
                          (format "%d..%d"
                                  (overlay-start prompt-field)
                                  (overlay-end prompt-field))
                        "MISSING")))
      (insert (format "- point:                %d\n" pt))
      (insert (format "- (eca-chat--prompt-content): %S\n\n" prompt-content))
      (insert "### Hints\n\n")
      (if hints
          (dolist (h (nreverse hints))
            (insert "- " h "\n"))
        (insert "- No obvious issue detected by the static checks.\n"))
      (buffer-string))))