Fix TUI terminal: command output, prompt colors, and missing TLS stubs
ober
139b5b2c12315d0bbf1aa12a25600dca4fbe4b51
--- a/build-binary.ss +++ b/build-binary.ss @@ -525,7 +525,32 @@ echo OK" (let* ((cmd "gcc -c -O2 -o jemacs-jsh-coreutils-stubs.o support/jsh_coreutils_stubs.c -Wall 2>&1")) (unless (= 0 (system cmd)) (display "Error: jsh_coreutils_stubs.c (dynamic) compilation failed\n") - (exit 1)))) + (exit 1))) + ;; TLS rustls stubs (jerboa_tls_* Rust FFI symbols — jemacs TUI doesn't use HTTPS) + (let ((stub-file "jemacs-tls-stubs.c")) + (call-with-output-file stub-file + (lambda (out) + (fprintf out "/* Stub — jemacs TUI doesn't use rustls TLS */~n") + (fprintf out "#include <stddef.h>~n#include <stdint.h>~n") + (fprintf out "uint64_t jerboa_tls_server_new(const char *c, const char *k) { return 0; }~n") + (fprintf out "uint64_t jerboa_tls_server_new_mtls(const char *c, const char *k, const char *ca) { return 0; }~n") + (fprintf out "void jerboa_tls_server_free(uint64_t s) {}~n") + (fprintf out "uint64_t jerboa_tls_accept(uint64_t s, int fd) { return 0; }~n") + (fprintf out "uint64_t jerboa_tls_connect(const char *h, int p) { return 0; }~n") + (fprintf out "uint64_t jerboa_tls_connect_pinned(const char *h, int p, const uint8_t *fp, size_t fplen) { return 0; }~n") + (fprintf out "uint64_t jerboa_tls_connect_mtls(const char *h, int p, const char *c, const char *k, const char *ca) { return 0; }~n") + (fprintf out "int jerboa_tls_read(uint64_t s, uint8_t *buf, uint64_t len) { return -1; }~n") + (fprintf out "int jerboa_tls_write(uint64_t s, const uint8_t *buf, uint64_t len) { return -1; }~n") + (fprintf out "int jerboa_tls_flush(uint64_t s) { return -1; }~n") + (fprintf out "void jerboa_tls_close(uint64_t s) {}~n") + (fprintf out "int jerboa_tls_set_nonblock(uint64_t s, int nb) { return -1; }~n") + (fprintf out "int jerboa_tls_get_fd(uint64_t s) { return -1; }~n") + (fprintf out "size_t jerboa_last_error(uint8_t *buf, size_t len) { return 0; }~n")) + 'replace) + (let ((cmd "gcc -c -O2 -o jemacs-tls-stubs.o jemacs-tls-stubs.c -Wall 2>&1")) + (unless (= 0 (system cmd)) + (display "Error: TLS stubs compilation failed\n") + (exit 1))))) ;; jemacs-main.c (let* ((static-flag (if jemacs-static? "-DJEMACS_STATIC_BUILD" "")) @@ -575,6 +600,7 @@ tui_static_symbols.o \ jemacs-main.o jemacs-pcre2-shim.o jemacs-repl-shim.o \ jemacs-jsh-ffi.o jemacs-libcoreutils.o jemacs-embed-crypto.o \ jemacs-ssh-agent-stub.o jemacs-jsh-coreutils-stubs.o \ +jemacs-tls-stubs.o \ -L~a -lkernel -llz4 -lz \ ~a ~a \ -lm -ldl -lpthread 2>&1" --- a/src/jerboa-emacs/app.ss +++ b/src/jerboa-emacs/app.ss @@ -429,14 +429,18 @@ ;; Feed data to VT100 screen buffer, then render (begin (vtscreen-feed! vt data) - (let* ((rendered (vtscreen-render vt)) - (full (if (vtscreen-alt-screen? vt) - rendered - (string-append (or (terminal-state-pre-pty-text ts) "") - rendered)))) - (editor-set-text ed full) - (editor-goto-pos ed (editor-get-text-length ed)) - (editor-scroll-caret ed))) + (if (vtscreen-alt-screen? vt) + ;; Alt-screen (vim, top): replace entire content + (let ((rendered (vtscreen-render vt))) + (editor-set-text ed rendered) + (editor-goto-pos ed (editor-get-text-length ed)) + (editor-scroll-caret ed)) + ;; Normal command output: vtscreen accumulates it, + ;; but we don't replace text (that nukes styles). + ;; Just scroll to end — 'done handler will append final output. + (begin + (editor-goto-pos ed (editor-get-text-length ed)) + (editor-scroll-caret ed)))) ;; Fallback: strip ANSI and append (no vtscreen) (let* ((segments (parse-ansi-segments data)) (start-pos (editor-get-text-length ed))) @@ -452,16 +456,17 @@ (when win (let ((ed (edit-window-editor win))) ;; For full-screen programs: restore pre-PTY text - ;; For simple commands: keep output - (when pre-text - (if alt-screen? - (editor-set-text ed pre-text) - (let* ((output (or final-render "")) - (sep (if (and (> (string-length output) 0) - (not (char=? (string-ref output (- (string-length output) 1)) #\newline))) - "\n" "")) - (full (string-append pre-text output sep))) - (editor-set-text ed full)))) + ;; For simple commands: append output (preserving existing styles) + (if (and pre-text alt-screen?) + ;; Alt-screen (vim, less): restore original text + (editor-set-text ed pre-text) + ;; Normal commands: append rendered output after existing text + ;; Don't use editor-set-text — it nukes all Scintilla styles + (let ((output (or final-render ""))) + (when (> (string-length output) 0) + (editor-append-text ed output) + (unless (char=? (string-ref output (- (string-length output) 1)) #\newline) + (editor-append-text ed "\n"))))) (let* ((raw-prompt (terminal-prompt-raw ts)) (segments (parse-ansi-segments raw-prompt)) (start-pos (editor-get-text-length ed))) --- a/src/jerboa-emacs/editor-core.ss +++ b/src/jerboa-emacs/editor-core.ss @@ -2154,7 +2154,10 @@ (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)) + (let* ((input-len (- text-byte-len prompt-byte-pos)) + (sub (make-bytevector input-len))) + (bytevector-copy! text-bytes prompt-byte-pos sub 0 input-len) + (utf8->string sub)) ""))) ;; Append newline after user input (editor-append-text ed "\n")