@@ -184,13 +184,66 @@ selected=0
184184# Build a human-readable preview from tool_input. Each tool type gets a
185185# tailored display. MCP tools show pretty JSON. Edits show a diff preview.
186186_extract () { jq -r --arg f " $1 " ' .[$f] // empty' <<< " $TOOL_INPUT_JSON" 2> /dev/null; }
187- _truncate () {
188- local s=" $1 " max=" ${2:- 120} "
189- if [ " ${# s} " -gt " $max " ]; then
190- printf ' %s...' " ${s: 0: $((max - 3))} "
191- else
192- printf ' %s' " $s "
187+
188+ # _wrap_line: split a string into multiple lines at whitespace boundaries,
189+ # each line fitting within the given width. Falls back to hard-splitting
190+ # for any single run of non-whitespace longer than the width. Emits lines
191+ # via printf '%s\n' so callers can read them with `while IFS= read`.
192+ _wrap_line () {
193+ local s=" $1 " width=" ${2:- 100} "
194+ # Hard guard against tiny widths or empty input.
195+ [ " $width " -lt 20 ] && width=20
196+ if [ -z " $s " ] || [ " ${# s} " -le " $width " ]; then
197+ printf ' %s\n' " $s "
198+ return 0
193199 fi
200+ awk -v w=" $width " '
201+ {
202+ line = ""
203+ n = split($0, words, /[ \t]+/)
204+ for (i = 1; i <= n; i++) {
205+ word = words[i]
206+ if (word == "") continue
207+ if (length(line) == 0) {
208+ # First word on a line. If it itself exceeds width, hard-split it.
209+ while (length(word) > w) {
210+ print substr(word, 1, w)
211+ word = substr(word, w + 1)
212+ }
213+ line = word
214+ } else if (length(line) + 1 + length(word) <= w) {
215+ line = line " " word
216+ } else {
217+ print line
218+ while (length(word) > w) {
219+ print substr(word, 1, w)
220+ word = substr(word, w + 1)
221+ }
222+ line = word
223+ }
224+ }
225+ if (length(line) > 0) print line
226+ }
227+ ' <<< " $s"
228+ }
229+
230+ # _append_wrapped: push wrapped lines of $1 into preview_lines, updating
231+ # extra_height accordingly. Width defaults to terminal columns - 10 (for
232+ # "Input: " prefix and popup padding) or 100 if tput fails.
233+ _append_wrapped () {
234+ local s=" $1 "
235+ local cols
236+ cols=" $( tput cols 2> /dev/null || echo 0) "
237+ [ " $cols " -lt 40 ] && cols=110
238+ local width=$(( cols - 10 ))
239+ local first=1
240+ while IFS= read -r _wl; do
241+ preview_lines+=(" $_wl " )
242+ if [ " $first " -eq 0 ]; then
243+ extra_height=$(( extra_height + 1 ))
244+ fi
245+ first=0
246+ done < <( _wrap_line " $s " " $width " )
194247}
195248
196249# preview_lines: array of lines to display. Populated per tool type.
@@ -200,51 +253,68 @@ extra_height=0 # additional lines beyond standard 1-line preview
200253if [ -n " $TOOL_INPUT_JSON " ]; then
201254 case " $TOOL_NAME " in
202255 Bash)
203- preview_lines+=( " $( _truncate " $( _extract command) " 120 ) " )
256+ _append_wrapped " $( _extract command) "
204257 ;;
205258 WebFetch)
206- preview_lines+=( " $( _extract url) " )
259+ _append_wrapped " $( _extract url) "
207260 ;;
208261 WebSearch)
209262 _q=" $( _extract query) "
210- [ -n " $_q " ] && preview_lines+=(" search: $_q " ) || preview_lines+=(" $( _extract url) " )
263+ if [ -n " $_q " ]; then
264+ _append_wrapped " search: $_q "
265+ else
266+ _append_wrapped " $( _extract url) "
267+ fi
211268 ;;
212269 Edit|Write)
213- preview_lines+=( " $( _extract file_path) " )
270+ _append_wrapped " $( _extract file_path) "
214271 ;;
215272 Read|NotebookRead)
216- preview_lines+=( " $( _extract file_path) " )
273+ _append_wrapped " $( _extract file_path) "
217274 ;;
218275 NotebookEdit)
219276 _fp=" $( _extract file_path) "
220277 _cell=" $( _extract cell_id) "
221- preview_lines+=(" $_fp " )
222- [ -n " $_cell " ] && preview_lines+=(" cell: $_cell " ) && extra_height=1
278+ _append_wrapped " $_fp "
279+ if [ -n " $_cell " ]; then
280+ preview_lines+=(" cell: $_cell " )
281+ extra_height=$(( extra_height + 1 ))
282+ fi
223283 ;;
224284 Grep)
225285 _pat=" $( _extract pattern) "
226286 _path=" $( _extract path) "
227- preview_lines+=(" /$_pat /" )
228- [ -n " $_path " ] && preview_lines+=(" in: $_path " ) && extra_height=1
287+ _append_wrapped " /$_pat /"
288+ if [ -n " $_path " ]; then
289+ preview_lines+=(" in: $_path " )
290+ extra_height=$(( extra_height + 1 ))
291+ fi
229292 ;;
230293 Glob)
231294 _pat=" $( _extract pattern) "
232295 _path=" $( _extract path) "
233- preview_lines+=(" $_pat " )
234- [ -n " $_path " ] && preview_lines+=(" in: $_path " ) && extra_height=1
296+ _append_wrapped " $_pat "
297+ if [ -n " $_path " ]; then
298+ preview_lines+=(" in: $_path " )
299+ extra_height=$(( extra_height + 1 ))
300+ fi
235301 ;;
236302 Skill)
237303 _skill=" $( _extract skill) "
238304 _args=" $( _extract args) "
239305 if [ -n " $_args " ]; then
240- preview_lines+=( " $_skill $_args " )
306+ _append_wrapped " $_skill $_args "
241307 else
242- preview_lines+=( " $_skill " )
308+ _append_wrapped " $_skill "
243309 fi
244310 ;;
245311 Agent)
246312 _desc=" $( _extract description) "
247- [ -n " $_desc " ] && preview_lines+=(" $_desc " ) || preview_lines+=(" $( _truncate " $( _extract prompt) " 120) " )
313+ if [ -n " $_desc " ]; then
314+ _append_wrapped " $_desc "
315+ else
316+ _append_wrapped " $( _extract prompt) "
317+ fi
248318 ;;
249319 mcp__* )
250320 # MCP tools: pretty-print the JSON args with indentation.
@@ -266,13 +336,13 @@ if [ -n "$TOOL_INPUT_JSON" ]; then
266336 extra_height=$(( _line_count - 1 ))
267337 ;;
268338 * )
269- preview_lines+=( " $( _truncate " $TOOL_INPUT_JSON " 120 ) " )
339+ _append_wrapped " $TOOL_INPUT_JSON "
270340 ;;
271341 esac
272342fi
273343# Fallback if nothing was extracted.
274344if [ " ${# preview_lines[@]} " -eq 0 ]; then
275- preview_lines+=( " $( _truncate " $TOOL_INPUT_JSON " 120 ) " )
345+ _append_wrapped " $TOOL_INPUT_JSON "
276346fi
277347
278348# Session context for the header (helps distinguish multiple CC sessions).
0 commit comments