Skip to content

Commit e8bf878

Browse files
pabl0karthink
authored andcommitted
gptel-transient: Polish gptel--read-with-prefix user experience
* gptel-transient.el (gptel--read-with-prefix-help): Turn into a function to show one function. (gptel--read-with-prefix): Enable resizing minibuffer (to make cycling the ov meaningful). Drop `make-separator-line' which is buggy. Move the prompt to the last line, which looks better and avoids cursor jumping. Use `window-max-chars-per-line' instead of `window-width' (which is incorrect in terminal). Replace newlines with return symbol. Calculate the multi-line layoyt correctly to use all available space on the last line. Cycle between just two modes: one line and multiple lines (hiding one line does not add much value). Don't show the TAB help if the whole prefix fits into one line. (gptel--infix-add-directive): Use simple prompt. * gptel-rewrite.el (gptel--infix-rewrite-extra): Use simple prompt. Replace RETURN LEFT (U+2C90) with smaller RETURN SYMBOL (U+23CE), which looks more readable (with many typefaces) between two pieces of text.
1 parent fc06fe9 commit e8bf878

File tree

3 files changed

+50
-53
lines changed

3 files changed

+50
-53
lines changed

gptel-rewrite.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ By default, gptel uses the directive associated with the `rewrite'
557557
:display-nil "(None)"
558558
:key "d"
559559
:format " %k %d %v"
560-
:prompt (concat "Instructions " gptel--read-with-prefix-help)
560+
:prompt "Instructions: "
561561
:reader (lambda (prompt _ history)
562562
(let* ((rewrite-directive
563563
(car-safe (gptel--parse-directive gptel--rewrite-directive

gptel-transient.el

Lines changed: 47 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -145,38 +145,34 @@ Meant to be called when `gptel-menu' is active."
145145
"\n"))
146146
ov))
147147

148-
(defconst gptel--read-with-prefix-help
148+
(defun gptel--read-with-prefix-help (s)
149+
"Show help for TAB key in `read-with-prefix-help'."
149150
(concat
150151
(propertize "(" 'face 'default)
151152
(propertize "TAB" 'face 'help-key-binding)
152-
(propertize ": expand, " 'face 'default)
153-
(propertize "M-n" 'face 'help-key-binding)
154-
(propertize "/" 'face 'default)
155-
(propertize "M-p" 'face 'help-key-binding)
156-
(propertize ": next/previous) " 'face 'default))
157-
"Help string ;TODO: ")
153+
(propertize (concat ": " s ") ") 'face 'default)))
158154

159155
(defun gptel--read-with-prefix (prefix)
160156
"Show string PREFIX in the minibuffer after the minibuffer prompt.
161157
162158
PREFIX is shown in an overlay. Repeated calls to this function
163-
will toggle its visibility state."
159+
will toggle its visibility state (one line, maximum, none)."
164160
(unless (minibufferp)
165161
(user-error "This command is intended to be used in the minibuffer."))
162+
(set (make-local-variable 'resize-mini-windows) t)
166163
(let* ((update
167164
(lambda (ov s)
168-
(overlay-put
169-
ov 'after-string
170-
(and s (concat (propertize (concat "\n" s "\n") 'face 'shadow)
171-
(make-separator-line))))))
172-
(max-width (- (window-width) (minibuffer-prompt-end)))
165+
(overlay-put ov 'before-string
166+
(and s (propertize (concat s (propertize "\n"'face '(shadow default)))
167+
'rear-nonsticky t 'front-nonsticky t)))))
168+
(max (or max-mini-window-height 0.4))
169+
(max-width (window-max-chars-per-line))
173170
(max (or max-mini-window-height 0.4))
174171
(max-height (- (or (and (natnump max) max)
175172
(floor (* max (frame-height))))
176-
5)))
173+
5))
174+
(prefix (string-replace "\n" "" prefix)))
177175
(when (and prefix (not (string-empty-p prefix)) (> max-height 1))
178-
(unless visual-line-mode (visual-line-mode 1))
179-
(goto-char (minibuffer-prompt-end))
180176
(pcase-let ((`(,prop . ,ov)
181177
(get-char-property-and-overlay
182178
(point-min) 'gptel)))
@@ -185,33 +181,35 @@ will toggle its visibility state."
185181
(point-min) (minibuffer-prompt-end) nil t)))
186182
(pcase prop
187183
('partial
188-
(if (> (length prefix) max-width)
189-
(progn
190-
(overlay-put ov 'gptel 'prefix)
191-
(let ((disp-size
192-
(cl-loop for char across prefix
193-
for idx upfrom 0
194-
with n = 0 with max-length = (* max-height max-width)
195-
if (eq char ?\n) do (cl-incf n)
196-
if (> n max-height) return idx
197-
if (> idx max-length)
198-
return idx
199-
finally return nil)))
200-
(funcall update ov
201-
(if disp-size
202-
(truncate-string-to-width
203-
prefix disp-size nil nil 'ellipsis)
204-
prefix))))
205-
(overlay-put ov 'gptel 'hide)
206-
(funcall update ov nil)))
207-
('prefix (overlay-put ov 'gptel 'hide)
208-
(funcall update ov nil))
209-
(_ (overlay-put ov 'gptel 'partial)
210-
(funcall update ov (truncate-string-to-width
211-
prefix max-width nil nil
212-
'ellipsis))))))))
213-
214-
(defun gptel--transient-read-number (prompt _initial-input history)
184+
(overlay-put ov 'gptel 'one-line)
185+
(funcall update ov
186+
(with-temp-buffer
187+
(insert (gptel--read-with-prefix-help "shrink"))
188+
(let ((b (point)))
189+
(insert prefix)
190+
(set-text-properties b (point-max) '(face (shadow default))))
191+
(goto-char (point-min))
192+
(let ((fill-column max-width))
193+
(fill-region (point) (point-max)))
194+
(goto-line (min max-height (line-number-at-pos (point-max))))
195+
(concat (buffer-substring 1 (point))
196+
(propertize (truncate-string-to-width
197+
(buffer-substring (point) (point-max))
198+
(1- max-width) nil
199+
nil
200+
t) 'face '(shadow default))))))
201+
(_ (funcall update ov
202+
(if (>= (length prefix) max-width)
203+
(let ((he (gptel--read-with-prefix-help "expand")))
204+
(overlay-put ov 'gptel 'partial)
205+
(concat he (propertize (truncate-string-to-width
206+
prefix
207+
(- max-width (length he))
208+
nil nil t)
209+
'face '(shadow default))))
210+
(overlay-put ov 'gptel 'hide)
211+
(propertize prefix 'face '(shadow default))))))))))
212+
(defun gptel--transient-read-number (prompt initial-input history)
215213
"Read a numeric value from the minibuffer.
216214
217215
PROMPT, _INITIAL-INPUT and HISTORY are as in the transient reader
@@ -239,7 +237,7 @@ Handle formatting for system messages when the active
239237
(propertize "]" 'face 'transient-heading))
240238
(if message
241239
(gptel--describe-directive
242-
message (max (- (window-width) 12) 14) "")
240+
message (max (- (window-width) 12) 14) "")
243241
"[No system message set]")))
244242

245243
(defun gptel--tools-init-value (obj)
@@ -390,7 +388,7 @@ which see."
390388
(len (length val)))
391389
(ptv (concat
392390
"\"" (string-replace
393-
"\n" ""
391+
"\n" ""
394392
(truncate-string-to-width
395393
val 20 nil nil t))
396394
"\"" (when (> len 20)
@@ -768,7 +766,7 @@ If EXTERNAL is non-nil, include external sources of directives."
768766
(concat "(" (gptel--describe-directive prompt (- width 30)) ")")
769767
'face 'shadow))
770768
`(lambda () (interactive)
771-
(message "%s: %s" ,msg ,(gptel--describe-directive prompt 100 ""))
769+
(message "%s: %s" ,msg ,(gptel--describe-directive prompt 100 ""))
772770
(gptel--set-with-scope ',sym ',prompt gptel--set-buffer-locally))
773771
:transient 'transient--do-return)
774772
into prompt-suffixes
@@ -1212,19 +1210,18 @@ Or in an extended conversation:
12121210
:display-nil 'none
12131211
:overlay nil
12141212
:argument ":"
1215-
:prompt (concat "Add instructions for next request only "
1216-
gptel--read-with-prefix-help)
1213+
:prompt "Instruction for next request: "
12171214
:reader (lambda (prompt initial history)
12181215
(let* ((directive
12191216
(car-safe (gptel--parse-directive gptel--system-message 'raw)))
12201217
(cycle-prefix (lambda () (interactive)
1221-
(gptel--read-with-prefix directive)))
1218+
(gptel--read-with-prefix directive)))
12221219
(minibuffer-local-map
12231220
(make-composed-keymap
12241221
(define-keymap "TAB" cycle-prefix "<tab>" cycle-prefix)
12251222
minibuffer-local-map))
12261223
(extra (minibuffer-with-setup-hook cycle-prefix
1227-
(read-string prompt (or initial " ") history))))
1224+
(read-string prompt nil history (or initial)))))
12281225
(unless (string-empty-p extra) extra)))
12291226
:format " %k %d %v"
12301227
:key "d"

gptel.el

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,7 +1956,7 @@ buffer."
19561956
(format "#<lambda %#x>" (sxhash s)))
19571957
((byte-code-function-p s)
19581958
(format "#<compiled %#x>" (sxhash s)))
1959-
((stringp s) (string-replace "\n" "" s))
1959+
((stringp s) (string-replace "\n" "" s))
19601960
(t (prin1-to-string s)))))
19611961
(inhibit-read-only t)
19621962
(info (gptel-fsm-info fsm))
@@ -3241,7 +3241,7 @@ NAME and ARG-VALUES are the name and arguments for the call."
32413241
(cond ((stringp arg)
32423242
(prin1-to-string
32433243
(replace-regexp-in-string
3244-
"\n" "" (truncate-string-to-width
3244+
"\n" "" (truncate-string-to-width
32453245
arg (floor (window-width) 2)
32463246
nil nil t))))
32473247
(t (prin1-to-string arg))))

0 commit comments

Comments
 (0)