Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e8184d8
Initial markdown-text integration
xenodium May 17, 2026
8e53972
Getting rid of cache to avoid regeneration. Always append.
xenodium May 17, 2026
88eb93a
Fixes updating fragment labels
xenodium May 18, 2026
359507f
Fixing inline markup rendering regression
xenodium May 19, 2026
76213b7
Bundle experimental markdown renderer
xenodium May 19, 2026
8c705cc
Removing cl-position-if usage
xenodium May 19, 2026
fc0f619
Favor map.el
xenodium May 20, 2026
ea00ede
Add padding and background color to source blocks
xenodium May 20, 2026
1a45150
agent-shell-markdown.el perf improvements
xenodium May 21, 2026
0017376
Improving streaming performance
xenodium May 21, 2026
9307d20
Fixes headings partially rendered when partially streamed
xenodium May 21, 2026
1da98b9
Render blockquotes
xenodium May 21, 2026
9948e25
Fixing blockquote test
xenodium May 21, 2026
ef4d6f3
Strip rendered properties when pasting copied text
xenodium May 21, 2026
4b97625
Improve code block handling
xenodium May 22, 2026
34b98ca
Render code block language
xenodium May 22, 2026
e154851
Add copy buttons to snippets
xenodium May 22, 2026
067cbe8
Fixing code block test supporting labels + button
xenodium May 22, 2026
03fe433
Fixing incomplete table header recognition while streaming
xenodium May 23, 2026
1d10802
Getting rid of snippet background color and all the padding
xenodium May 23, 2026
47f2760
Fix body-invisible-p for whitespace-only bodies #597
xenodium May 25, 2026
8289506
Make code block label actual buffer text (not display only) #597
xenodium May 27, 2026
33b663c
Echo "Press RET to copy" on snippet label point entering
xenodium May 28, 2026
cc9fea4
Fix rendering diff #597
xenodium May 29, 2026
ed6c15a
Update markdown rendering test #597
xenodium May 29, 2026
3e6b816
Add markdown avoiding diff test #597
xenodium May 29, 2026
0ce2970
Fixing tests
xenodium May 29, 2026
51d65fe
Make code block padded background non-trimmeable
xenodium May 29, 2026
04860d5
Removing surgical from function names
xenodium May 29, 2026
047f34c
Fixing some CONTRIBUTING.org items
xenodium May 29, 2026
38b62b5
Fixing │ table alignment cases
xenodium May 30, 2026
8fd978c
ui: add fragment fold DWIM + global cycle commands
codeluggage May 27, 2026
831136d
ui: align fragment fold commands with project conventions
codeluggage May 27, 2026
86e6f5b
comments about dedup, fix some formatting, rip out
codeluggage May 27, 2026
270ad55
add new test coverage for UI, fix code style
codeluggage May 27, 2026
7bf5080
ui: re-align text-property plists to inline-markdown convention
codeluggage May 28, 2026
8425b6c
tests: cover DWIM toggle through `--surgical-replace-body'
codeluggage May 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,288 changes: 2,288 additions & 0 deletions agent-shell-markdown.el

Large diffs are not rendered by default.

586 changes: 441 additions & 145 deletions agent-shell-ui.el

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion agent-shell-viewport.el
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

(declare-function agent-shell--current-shell "agent-shell")
(declare-function agent-shell--display-buffer "agent-shell")
(declare-function agent-shell--next-command-and-response "agent-shell")
(declare-function agent-shell--get-region "agent-shell")
(declare-function agent-shell--insert-to-shell-buffer "agent-shell")
(declare-function agent-shell--make-header "agent-shell")
Expand Down Expand Up @@ -843,7 +844,7 @@ buffer from the snapshot and switch to edit mode."
(comint-next-prompt 1)
(= orig-line (point))))
(error "No next page")))
(shell-maker-next-command-and-response backwards))))
(agent-shell--next-command-and-response backwards))))
(agent-shell-viewport--initialize
:prompt (car next) :response (cdr next))
(goto-char (if start-at-top
Expand Down
140 changes: 114 additions & 26 deletions agent-shell.el
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
(require 'map)
(unless (require 'markdown-overlays nil 'noerror)
(error "Please update 'shell-maker' to v0.91.2 or newer"))
(require 'agent-shell-markdown)
(require 'agent-shell-anthropic)
(require 'agent-shell-auggie)
(require 'agent-shell-codebuddy)
Expand Down Expand Up @@ -100,6 +101,30 @@
;; lexical bindings (which would not affect `auto-insert' behavior).
(defvar auto-insert)

(defvar agent-shell--experimental-renderer nil
"When non-nil, render markdown via `agent-shell-markdown'.

Internal/experimental. `agent-shell-markdown' replaces markup
characters with propertized text in place (no overlays), which
avoids the redisplay overhead of large overlay counts but
destroys the source markdown. Defaults to nil (keep current
`markdown-overlays' behaviour).")

(defun agent-shell--render-markdown ()
"Render markdown in current (narrowed) buffer.

Dispatches to `agent-shell-markdown-replace-markup' when
`agent-shell--experimental-renderer' is non-nil; otherwise falls
back to `markdown-overlays-put'.

`markdown-overlays-*' config bindings around the call still apply
in the overlay branch; they're intentionally ignored by
`agent-shell-markdown', which always highlights blocks and renders
resolvable images."
(if agent-shell--experimental-renderer
(agent-shell-markdown-replace-markup)
(markdown-overlays-put)))

(defcustom agent-shell-permission-icon "⚠"
"Icon displayed when shell commands require permission to execute.

Expand Down Expand Up @@ -2359,6 +2384,13 @@ DIFF should be in the form returned by `agent-shell--make-diff-info':
(add-text-properties line-start line-end
'(font-lock-face diff-hunk-header))))
(forward-line 1)))
;; Tag the whole diff as already-rendered output so the
;; markdown renderer's avoid-ranges include it — context
;; lines like ` # Foo' or ` > Bar' must display verbatim,
;; not as a header / blockquote. See PR #597.
(add-text-properties (point-min) (point-max)
'(agent-shell-markdown-frozen t
rear-nonsticky (agent-shell-markdown-frozen)))
(buffer-string)))
(delete-file old-file)
(delete-file new-file))))
Expand Down Expand Up @@ -3057,7 +3089,7 @@ by default, RENDER-BODY-IMAGES to enable inline image rendering in body."
(narrow-to-region body-start body-end)
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks)
(markdown-overlays-render-images render-body-images))
(markdown-overlays-put))))
(agent-shell--render-markdown))))
;; Note: For now, we're skipping applying markdown overlays
;; on left labels as they currently carry propertized text
;; for statuses (ie. boxed).
Expand All @@ -3069,7 +3101,7 @@ by default, RENDER-BODY-IMAGES to enable inline image rendering in body."
(narrow-to-region label-right-start label-right-end)
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks)
(markdown-overlays-render-images nil))
(markdown-overlays-put)))))
(agent-shell--render-markdown)))))
(when auto-scroll
(goto-char (point-max)))))))
(with-current-buffer (map-elt state :buffer)
Expand Down Expand Up @@ -3109,26 +3141,30 @@ by default, RENDER-BODY-IMAGES to enable inline image rendering in body."
;; Marking as field to avoid false positives in
;; `agent-shell-next-item' and `agent-shell-previous-item'.
(add-text-properties (or padding-start block-start)
(or padding-end block-end) '(field output)))
;; Apply markdown overlay to body.
(when-let ((body-start (map-nested-elt range '(:body :start)))
(body-end (map-nested-elt range '(:body :end))))
(narrow-to-region body-start body-end)
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks))
(markdown-overlays-put))
(widen))
;;
;; Note: For now, we're skipping applying markdown overlays
;; on left labels as they currently carry propertized text
;; for statuses (ie. boxed).
;;
;; Apply markdown overlay to right label.
(when-let ((label-right-start (map-nested-elt range '(:label-right :start)))
(label-right-end (map-nested-elt range '(:label-right :end))))
(narrow-to-region label-right-start label-right-end)
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks))
(markdown-overlays-put))
(widen)))
(or padding-end block-end) '(field output))
;; Apply markdown overlay to body. `inhibit-read-only'
;; must wrap the render call too — chars in the body
;; carry `read-only t' from `agent-shell-ui--insert-fragment',
;; and `agent-shell-markdown' modifies buffer chars (unlike the
;; overlay renderer which only adds overlays).
(when-let ((body-start (map-nested-elt range '(:body :start)))
(body-end (map-nested-elt range '(:body :end))))
(narrow-to-region body-start body-end)
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks))
(agent-shell--render-markdown))
(widen))
;;
;; Note: For now, we're skipping applying markdown overlays
;; on left labels as they currently carry propertized text
;; for statuses (ie. boxed).
;;
;; Apply markdown overlay to right label.
(when-let ((label-right-start (map-nested-elt range '(:label-right :start)))
(label-right-end (map-nested-elt range '(:label-right :end))))
(narrow-to-region label-right-start label-right-end)
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks))
(agent-shell--render-markdown))
(widen))))
(run-hook-with-args 'agent-shell-section-functions range)))
(unless auto-scroll
(goto-char saved-point)
Expand Down Expand Up @@ -5321,13 +5357,30 @@ Returns a buffer object or nil."
(with-current-buffer shell-buffer
(goto-char comint-last-input-start))))

(defun agent-shell--command-and-response-at-point ()
"Like `shell-maker--command-and-response-at-point' but preserves
visual padding emitted by the markdown renderer inside fragments
(e.g. source-block top/bottom vpad). Delegates the raw extraction
to shell-maker and runs the result through `agent-shell-trim'."
(when-let ((cell (shell-maker--command-and-response-at-point :trimmed nil)))
(cons (agent-shell-trim (car cell))
(agent-shell-trim (cdr cell)))))

(defun agent-shell--next-command-and-response (&optional backwards)
"Like `shell-maker-next-command-and-response' but preserves
visual padding inside fragments — see
`agent-shell--command-and-response-at-point'."
(when-let ((cell (shell-maker-next-command-and-response backwards :trimmed nil)))
(cons (agent-shell-trim (car cell))
(agent-shell-trim (cdr cell)))))

(defun agent-shell-interaction-at-point ()
"Return the interaction at point in the shell buffer.
Result is of the form ((:prompt . PROMPT) (:response . RESPONSE))."
(when-let ((shell-buffer (agent-shell--shell-buffer))
(result (with-current-buffer shell-buffer
(or (shell-maker--command-and-response-at-point)
(shell-maker-next-command-and-response t)))))
(or (agent-shell--command-and-response-at-point)
(agent-shell--next-command-and-response t)))))
`((:prompt . ,(car result))
(:response . ,(cdr result)))))

Expand Down Expand Up @@ -5439,7 +5492,7 @@ inserted into the shell buffer prompt."
```" (with-current-buffer output-buffer
(buffer-string))))))
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks))
(markdown-overlays-put))
(agent-shell--render-markdown))
(when (buffer-live-p output-buffer)
(kill-buffer output-buffer)))))))
(set-process-query-on-exit-flag proc nil)
Expand Down Expand Up @@ -6177,7 +6230,7 @@ Returns an alist with insertion details or nil otherwise:
(narrow-to-region insert-start insert-end)
(let ((markdown-overlays-highlight-blocks agent-shell-highlight-blocks)
(markdown-overlays-render-images nil))
(markdown-overlays-put))))
(agent-shell--render-markdown))))
(when submit
(shell-maker-submit)))
`((:buffer . ,shell-buffer)
Expand Down Expand Up @@ -7432,6 +7485,41 @@ or select a specific request to remove."
(map-put! agent-shell--state :pending-requests nil)
(message "Removed all pending requests"))))

(defun agent-shell-trim (text)
"Strip surrounding whitespace from TEXT, preserving renderer padding.

Like `string-trim', but whitespace chars carrying the
`agent-shell-non-trimmable' text property are treated as
intentional padding (e.g. the top/bottom vpad `\\n's the
source-block renderer inserts inside a fragment body) and left
alone. A blind `string-trim' would consume those chars on the
first / last block of a response and visibly clip the panel.

For example:

(agent-shell-trim \"\\n\\n hello \\n\\n\")
=> \"hello\"

(agent-shell-trim
(concat \"\\n\\nhello\\n\"
(propertize \"\\n\" \\='agent-shell-non-trimmable t)
\"\\n\\n\"))
=> \"hello\\n\\n\" ;; tagged trailing `\\n' preserved"
(and-let* ((text text)
(start 0)
(end (length text)))
(while (and (< start end)
(memq (seq-elt text start) '(?\s ?\t ?\n ?\r))
(not (get-text-property
start 'agent-shell-non-trimmable text)))
(setq start (1+ start)))
(while (and (< start end)
(memq (seq-elt text (1- end)) '(?\s ?\t ?\n ?\r))
(not (get-text-property
(1- end) 'agent-shell-non-trimmable text)))
(setq end (1- end)))
(substring text start end)))

(provide 'agent-shell)

;;; agent-shell.el ends here
Loading