From 9905d48a36926891bc139863ab660f91ba2a130c Mon Sep 17 00:00:00 2001 From: Kinneyzhang Date: Tue, 1 Sep 2026 09:37:35 +0800 Subject: [PATCH] fix(preview): suppress narrow-width editor artifacts --- etaf-playground.el | 27 ++++++++++++-- scripts/playground-gui-scenarios.el | 14 +++++++- tests/etaf-playground-tests.el | 48 +++++++++++++++++++++++++ tests/playground-gui-scenarios-tests.el | 6 ++-- 4 files changed, 88 insertions(+), 7 deletions(-) diff --git a/etaf-playground.el b/etaf-playground.el index cfc5374..200c774 100644 --- a/etaf-playground.el +++ b/etaf-playground.el @@ -484,6 +484,23 @@ only file evaluated by the framework." (etaf-playground--root-factory spec) name static-form ecss-form))) +(defun etaf-playground--apply-preview-display-settings () + "Suppress text-editor redisplay artifacts in the current preview buffer. + +An ETAF preview owns its viewport and line layout. Editor continuation and +truncation indicators otherwise leak into narrow generated canvases as dark +blocks at the right edge." + (setq-local truncate-lines t + auto-hscroll-mode t + fringe-indicator-alist + (cl-remove-if + (lambda (entry) + (memq (car-safe entry) '(truncation continuation))) + (copy-tree fringe-indicator-alist)) + bidi-display-reordering nil + bidi-paragraph-direction 'left-to-right + bidi-inhibit-bpa t)) + (defun etaf-playground--preview-mode-setup (buffer session) "Prepare generated preview BUFFER for SESSION." (with-current-buffer buffer @@ -497,7 +514,7 @@ only file evaluated by the framework." (format " ETAF Preview %s | g refresh q close" (etaf-playground-session-name session))) (buffer-disable-undo) - (setq-local truncate-lines nil)) + (etaf-playground--apply-preview-display-settings)) buffer) (defun etaf-playground--mount-example-now @@ -517,7 +534,10 @@ SESSION supplies authoritative source buffers. MOUNT-OPTIONS is forwarded to (etaf-mount buffer (etaf-playground-read-pair name session) mount-options)) (with-current-buffer buffer - (setq-local etaf-playground-current-example name)) + (setq-local etaf-playground-current-example name) + ;; Publication may restore renderer-owned buffer settings. The generated + ;; preview display contract is final and must win after the mount. + (etaf-playground--apply-preview-display-settings)) buffer)) (defun etaf-playground-mount-example @@ -545,6 +565,7 @@ public framework render burst so GC cannot split an interactive mount." (etaf-playground-session-name session) (error-message-string error-data)))) (setq-local buffer-read-only t) + (etaf-playground--apply-preview-display-settings) (setq-local header-line-format (format " ETAF Preview %s | ERROR | g retry q close" (etaf-playground-session-name session))))))) @@ -653,7 +674,7 @@ the preview instead of destroying the source workspace." (define-derived-mode etaf-playground-preview-mode special-mode "ETAF-Preview" "Read-only major mode for a mounted ETAF Playground preview." - (setq-local truncate-lines nil) + (etaf-playground--apply-preview-display-settings) (setq-local buffer-read-only nil) (setq-local mode-line-process nil)) diff --git a/scripts/playground-gui-scenarios.el b/scripts/playground-gui-scenarios.el index 6b4b534..3b0483e 100644 --- a/scripts/playground-gui-scenarios.el +++ b/scripts/playground-gui-scenarios.el @@ -104,6 +104,10 @@ (let* ((buffer (etaf-gui-verifier-context-target-buffer context)) (mounted (and (buffer-live-p buffer) (ebox-surface-buffer-mounted-p buffer))) + (canvas-settings + (and mounted + (with-current-buffer buffer + (list truncate-lines fringe-indicator-alist)))) (text (and mounted (with-current-buffer buffer (buffer-substring-no-properties @@ -116,6 +120,12 @@ (etaf-gui-verifier-assert "visible-output-nonempty" (etaf-playground-gui-scenarios--visible-window-content-p context)) + (etaf-gui-verifier-assert + "generated-canvas-truncates-editor-lines" (car canvas-settings)) + (etaf-gui-verifier-assert + "generated-canvas-hides-editor-edge-indicators" + (and (not (assq 'truncation (cadr canvas-settings))) + (not (assq 'continuation (cadr canvas-settings))))) (etaf-gui-verifier-assert "no-render-error" (and text @@ -351,6 +361,8 @@ product-specific postcondition in the evidence stream." (etaf-playground-gui-scenarios--windowed-action) (etaf-playground-gui-scenarios--resize-action "resize-narrow" 900 500) + (etaf-playground-gui-scenarios--resize-action + "resize-compact" 700 500) (etaf-playground-gui-scenarios--scroll-action "scroll-down" #'ebox-scroll-page-down) (etaf-playground-gui-scenarios--reset-scroll-action) @@ -396,7 +408,7 @@ product-specific postcondition in the evidence stream." (etaf-playground-gui-scenarios--maximize-action)) :completion (lambda (context) - (= (etaf-gui-verifier-context-action-count context) 12)))) + (= (etaf-gui-verifier-context-action-count context) 13)))) (defun etaf-playground-gui-scenarios-ebox (scenario fixture) "Return one Ebox SCENARIO adapter for FIXTURE." diff --git a/tests/etaf-playground-tests.el b/tests/etaf-playground-tests.el index e1ffed8..8374c68 100644 --- a/tests/etaf-playground-tests.el +++ b/tests/etaf-playground-tests.el @@ -118,6 +118,54 @@ :type 'file-missing) injected))))) +(ert-deftest etaf-playground-preview-suppresses-editor-redisplay-artifacts () + "Generated previews hide wrapping indicators that appear as edge blocks." + (let ((buffer (generate-new-buffer " *etaf-preview-display-settings*")) + (session (etaf-playground--session-create :name "display-settings"))) + (unwind-protect + (progn + (with-current-buffer buffer + (etaf-playground-preview-mode) + ;; Reused preview buffers may have settings changed by a caller; + ;; session setup must restore the generated-canvas contract. + (setq-local truncate-lines nil + auto-hscroll-mode nil + fringe-indicator-alist + '((truncation left-arrow right-arrow) + (continuation left-curly-arrow right-curly-arrow)) + bidi-display-reordering t + bidi-paragraph-direction nil + bidi-inhibit-bpa nil)) + (etaf-playground--preview-mode-setup buffer session) + (cl-letf (((symbol-function 'etaf-runtime-for-buffer) + (lambda (_buffer) nil)) + ((symbol-function 'etaf-playground-read-pair) + (lambda (&rest _arguments) 'preview-view)) + ((symbol-function 'etaf-mount) + (lambda (&rest _arguments) + ;; Model renderer publication restoring ordinary editor + ;; defaults after the preview mode was initialized. + (setq-local truncate-lines nil + auto-hscroll-mode nil + fringe-indicator-alist + '((truncation left-arrow right-arrow) + (continuation + left-curly-arrow right-curly-arrow)) + bidi-display-reordering t + bidi-paragraph-direction nil + bidi-inhibit-bpa nil)))) + (etaf-playground--mount-example-now + buffer "display-settings" session nil)) + (with-current-buffer buffer + (should truncate-lines) + (should auto-hscroll-mode) + (should-not (assq 'truncation fringe-indicator-alist)) + (should-not (assq 'continuation fringe-indicator-alist)) + (should-not bidi-display-reordering) + (should (eq bidi-paragraph-direction 'left-to-right)) + (should bidi-inhibit-bpa))) + (when (buffer-live-p buffer) (kill-buffer buffer))))) + (defun etaf-playground-test--text (buffer) "Return BUFFER's plain rendered text." (with-current-buffer buffer diff --git a/tests/playground-gui-scenarios-tests.el b/tests/playground-gui-scenarios-tests.el index c6b1a59..ad17f42 100644 --- a/tests/playground-gui-scenarios-tests.el +++ b/tests/playground-gui-scenarios-tests.el @@ -29,9 +29,9 @@ (should (equal (mapcar #'etaf-gui-verifier-action-id actions) - '("mount" "leave-fullscreen" "resize-narrow" "scroll-down" - "reset-scroll" "resize-wide" "row-select" "data-mutation" - "filter-reading" "theme-toggle" "pagination" + '("mount" "leave-fullscreen" "resize-narrow" "resize-compact" + "scroll-down" "reset-scroll" "resize-wide" "row-select" + "data-mutation" "filter-reading" "theme-toggle" "pagination" "maximize-frame"))) (should (funcall