Stabilize dired Qt attach path
ober
3f3f1ff5d6523192db8c7b859dbb3c738aec624d
--- a/lib/jerboa-emacs/qt/buffer.sls +++ b/lib/jerboa-emacs/qt/buffer.sls @@ -38,7 +38,7 @@ (hash-remove! *doc-editor-map* doc) (hash-remove! *doc-buffer-map* doc) (buffer-list-remove! buf))) - (def (qt-buffer-attach! editor buf) + (def (qt-buffer-attach! editor buf (run-post-hook? #t)) "Switch editor to display this buffer's document.\n Re-applies the document's read-only state after swap because QScintilla\n may have a widget-level readOnly flag that persists across document switches.\n Runs post-buffer-attach-hook to handle image/text display toggling.\n All visual changes are batched via setUpdatesEnabled to prevent flicker." (verbose-log! "qt-buffer-attach! buf=" (buffer-name buf)) (qt-widget-set-updates-enabled! editor #f) @@ -53,9 +53,10 @@ (qt-plain-text-edit-set-line-wrap! editor (not (or (eq? lang 'terminal) (eq? lang 'shell))))) - (verbose-log! - "qt-buffer-attach! post-buffer-attach-hook begin") - (run-hooks! 'post-buffer-attach-hook editor buf) + (when run-post-hook? + (verbose-log! + "qt-buffer-attach! post-buffer-attach-hook begin") + (run-hooks! 'post-buffer-attach-hook editor buf)) (verbose-log! "qt-buffer-attach! done buf=" (buffer-name buf))) --- a/lib/jerboa-emacs/qt/commands-edit.sls +++ b/lib/jerboa-emacs/qt/commands-edit.sls @@ -1065,28 +1065,38 @@ (chat-send! cs input))))))) (def (dired-open-directory! app dir-path) "Open a directory listing in a new dired buffer." - (let* ([dir (strip-trailing-slash dir-path)] - [name (string-append dir "/")] - [fr (app-state-frame app)] - [ed (current-qt-editor app)] - [buf (qt-buffer-create! name ed dir)]) - (buffer-lexer-lang-set! buf 'dired) - (qt-buffer-attach! ed buf) - (qt-edit-window-buffer-set! (qt-current-window fr) buf) + (let ([dir (strip-trailing-slash dir-path)]) + (verbose-log! "dired-open: begin dir=" dir) (let-values ([(text entries) (dired-format-listing dir)]) - (qt-plain-text-edit-set-text! ed text) - (qt-text-document-set-modified! (buffer-doc-pointer buf) #f) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_START) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) - (qt-plain-text-edit-move-cursor! - ed - QT_CURSOR_START_OF_BLOCK) - (hash-put! *dired-entries* buf entries)) - (echo-message! - (app-state-echo app) - (string-append "Directory: " dir)))) + (verbose-log! + "dired-open: listing ready len=" + (number->string (string-length text)) + " entries=" + (number->string (vector-length entries))) + (let* ([name (string-append dir "/")] + [fr (app-state-frame app)] + [ed (current-qt-editor app)] + [buf (qt-buffer-create! name ed dir)]) + (buffer-lexer-lang-set! buf 'dired) + (qt-buffer-attach! ed buf #f) + (verbose-log! "dired-open: attach without hook done") + (qt-edit-window-buffer-set! (qt-current-window fr) buf) + (qt-plain-text-edit-set-text! ed text) + (verbose-log! "dired-open: set text done") + (qt-text-document-set-modified! (buffer-doc-pointer buf) #f) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_START) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) + (qt-plain-text-edit-move-cursor! + ed + QT_CURSOR_START_OF_BLOCK) + (hash-put! *dired-entries* buf entries) + (run-hooks! 'post-buffer-attach-hook ed buf) + (verbose-log! "dired-open: post attach hook done") + (echo-message! + (app-state-echo app) + (string-append "Directory: " dir)))))) (def (cmd-dired-find-file app) "In a dired buffer, open the file or directory under cursor." (let* ([buf (current-qt-buffer app)] --- a/src/jerboa-emacs/qt/buffer.ss +++ b/src/jerboa-emacs/qt/buffer.ss @@ -48,7 +48,7 @@ (hash-remove! *doc-buffer-map* doc) (buffer-list-remove! buf))) -(def (qt-buffer-attach! editor buf) +(def (qt-buffer-attach! editor buf (run-post-hook? #t)) "Switch editor to display this buffer's document. Re-applies the document's read-only state after swap because QScintilla may have a widget-level readOnly flag that persists across document switches. @@ -74,8 +74,9 @@ (let ((lang (buffer-lexer-lang buf))) (qt-plain-text-edit-set-line-wrap! editor (not (or (eq? lang 'terminal) (eq? lang 'shell))))) - (verbose-log! "qt-buffer-attach! post-buffer-attach-hook begin") - ;; Toggle image/editor display via hook (set up in qt/app.ss) - (run-hooks! 'post-buffer-attach-hook editor buf) + (when run-post-hook? + (verbose-log! "qt-buffer-attach! post-buffer-attach-hook begin") + ;; Toggle image/editor display via hook (set up in qt/app.ss) + (run-hooks! 'post-buffer-attach-hook editor buf)) (verbose-log! "qt-buffer-attach! done buf=" (buffer-name buf))) (qt-widget-set-updates-enabled! editor #t)) --- a/src/jerboa-emacs/qt/commands-edit.ss +++ b/src/jerboa-emacs/qt/commands-edit.ss @@ -964,29 +964,39 @@ (def (dired-open-directory! app dir-path) "Open a directory listing in a new dired buffer." - (let* ((dir (strip-trailing-slash dir-path)) - (name (string-append dir "/")) - (fr (app-state-frame app)) - (ed (current-qt-editor app)) - (buf (qt-buffer-create! name ed dir))) - ;; Mark as dired buffer - (set! (buffer-lexer-lang buf) 'dired) - ;; Attach buffer to editor - (qt-buffer-attach! ed buf) - (set! (qt-edit-window-buffer (qt-current-window fr)) buf) - ;; Generate and set listing + (let ((dir (strip-trailing-slash dir-path))) + (verbose-log! "dired-open: begin dir=" dir) + ;; Generate the listing before swapping the new document into the editor. + ;; The post-attach hook expects the displayed document to be stable. (let-values (((text entries) (dired-format-listing dir))) - (qt-plain-text-edit-set-text! ed text) - (qt-text-document-set-modified! (buffer-doc-pointer buf) #f) - ;; Position cursor at first entry (line 3, after header + count + blank) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_START) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) - (qt-plain-text-edit-move-cursor! ed QT_CURSOR_START_OF_BLOCK) - ;; Store entries for navigation - (hash-put! *dired-entries* buf entries)) - (echo-message! (app-state-echo app) (string-append "Directory: " dir)))) + (verbose-log! "dired-open: listing ready len=" + (number->string (string-length text)) + " entries=" (number->string (vector-length entries))) + (let* ((name (string-append dir "/")) + (fr (app-state-frame app)) + (ed (current-qt-editor app)) + (buf (qt-buffer-create! name ed dir))) + ;; Mark as dired buffer + (set! (buffer-lexer-lang buf) 'dired) + ;; Attach without running post-buffer-attach-hook yet. We install the + ;; listing first, then run the hook once against the populated document. + (qt-buffer-attach! ed buf #f) + (verbose-log! "dired-open: attach without hook done") + (set! (qt-edit-window-buffer (qt-current-window fr)) buf) + (qt-plain-text-edit-set-text! ed text) + (verbose-log! "dired-open: set text done") + (qt-text-document-set-modified! (buffer-doc-pointer buf) #f) + ;; Position cursor at first entry (line 3, after header + count + blank) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_START) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_DOWN) + (qt-plain-text-edit-move-cursor! ed QT_CURSOR_START_OF_BLOCK) + ;; Store entries for navigation + (hash-put! *dired-entries* buf entries) + (run-hooks! 'post-buffer-attach-hook ed buf) + (verbose-log! "dired-open: post attach hook done") + (echo-message! (app-state-echo app) (string-append "Directory: " dir)))))) (def (cmd-dired-find-file app) "In a dired buffer, open the file or directory under cursor." @@ -1641,4 +1651,3 @@ Returns the clean text (without ANSI codes)." (qt-text-document-set-modified! (buffer-doc-pointer buf) #f))) (lambda (err) (echo-error! echo err)))))) -