Fix TUI terminal: use byte positions consistently for prompt-pos
ober
3b768c8cfd55b7353f1774b31335fe6d07a03d29
--- a/src/jerboa-emacs/editor-core.ss +++ b/src/jerboa-emacs/editor-core.ss @@ -2132,10 +2132,10 @@ (let* ((raw-prompt (terminal-prompt-raw ts)) (segments (parse-ansi-segments raw-prompt))) (editor-set-text ed "") - (let ((prompt-len (terminal-insert-styled! ed segments 0))) - (set! (terminal-state-prompt-pos ts) prompt-len) - (editor-goto-pos ed prompt-len) - (editor-scroll-caret ed)))) + (terminal-insert-styled! ed segments 0) + (set! (terminal-state-prompt-pos ts) (editor-get-text-length ed)) + (editor-goto-pos ed (editor-get-text-length ed)) + (editor-scroll-caret ed))) (echo-message! (app-state-echo app) (string-append name " started")))))) (def (cmd-terminal-send app) @@ -2150,10 +2150,11 @@ (terminal-send-input! ts "\n") (let* ((ed (current-editor app)) (text (editor-get-text ed)) - (text-len (string-length text)) - (prompt-pos (terminal-state-prompt-pos ts)) - (input (if (< prompt-pos text-len) - (substring text prompt-pos text-len) + (text-bytes (string->utf8 text)) + (text-byte-len (bytevector-length text-bytes)) + (prompt-byte-pos (terminal-state-prompt-pos ts)) ;; byte position + (input (if (< prompt-byte-pos text-byte-len) + (utf8->string (bytevector-copy text-bytes prompt-byte-pos text-byte-len)) ""))) ;; Append newline after user input (editor-append-text ed "\n") @@ -2187,10 +2188,10 @@ (let* ((raw-prompt (terminal-prompt-raw ts)) (segments (parse-ansi-segments raw-prompt))) (editor-set-text ed "") - (let ((prompt-len (terminal-insert-styled! ed segments 0))) - (set! (terminal-state-prompt-pos ts) prompt-len) - (editor-goto-pos ed prompt-len) - (editor-scroll-caret ed)))) + (terminal-insert-styled! ed segments 0) + (set! (terminal-state-prompt-pos ts) (editor-get-text-length ed)) + (editor-goto-pos ed (editor-get-text-length ed)) + (editor-scroll-caret ed))) ((eq? output 'exit) (terminal-stop! ts) (hash-remove! *terminal-state* buf) --- a/src/jerboa-emacs/terminal.ss +++ b/src/jerboa-emacs/terminal.ss @@ -422,23 +422,24 @@ (def (terminal-insert-styled! ed segments start-pos) "Insert text segments into editor at end, applying ANSI styles. - Returns the total number of bytes inserted." - (let loop ((segs segments) (pos start-pos) (total 0)) + start-pos is a BYTE position (Scintilla uses byte positions). + Returns the total number of BYTES inserted." + (let loop ((segs segments) (byte-pos start-pos) (total-bytes 0)) (if (null? segs) - total + total-bytes (let* ((seg (car segs)) (text (text-segment-text seg)) (fg (text-segment-fg-color seg)) (bold? (text-segment-bold? seg)) (style (color-to-style fg bold?)) - (text-len (string-length text))) + (byte-len (bytevector-length (string->utf8 text)))) ;; Insert the text (editor-append-text ed text) - ;; Apply style if not default + ;; Apply style if not default — Scintilla uses BYTE positions (when (> style 0) - (send-message ed SCI_STARTSTYLING pos 0) - (send-message ed SCI_SETSTYLING text-len style)) - (loop (cdr segs) (+ pos text-len) (+ total text-len)))))) + (send-message ed SCI_STARTSTYLING byte-pos 0) + (send-message ed SCI_SETSTYLING byte-len style)) + (loop (cdr segs) (+ byte-pos byte-len) (+ total-bytes byte-len)))))) ;;;============================================================================ ;;; Async PTY execution