Replace diff subprocesses with in-process (std text diff), use number->padded-string
ober
734ab0a748e551ca9ef0f5a4bb7e0aac62cb22a4
--- a/lib/jerboa-emacs/qt/commands-config.sls +++ b/lib/jerboa-emacs/qt/commands-config.sls @@ -29,7 +29,7 @@ getenv path-extension path-absolute? thread? make-mutex mutex? mutex-name sort sort!) (std sugar) (chez-scintilla constants) (std sort) - (std srfi srfi-13) (std text base64) + (std srfi srfi-13) (std text base64) (std text diff) (jerboa-emacs qt sci-shim) (jerboa-emacs core) (jerboa-emacs async) (jerboa-emacs snippets) (only (jerboa-emacs persist) record-face-customization! @@ -1221,27 +1221,33 @@ (echo-error! (app-state-echo app) "One or both files not found") - (let* ([proc (open-process - (list 'path: "/usr/bin/diff" 'arguments: - (list "-u" path-a path-b) - 'stdout-redirection: #t))] - [output (read-line proc #f)] + (let* ([text-a (read-file-as-string path-a)] + [text-b (read-file-as-string path-b)] + [lines-a (string-split text-a #\newline)] + [lines-b (string-split text-b #\newline)] + [output (diff-unified + path-a + path-b + lines-a + lines-b)] [ed (current-qt-editor app)] [fr (app-state-frame app)] [diff-buf (qt-buffer-create! "*Ediff*" ed #f)]) - (close-port proc) (qt-buffer-attach! ed diff-buf) (qt-edit-window-buffer-set! (qt-current-window fr) diff-buf) (qt-plain-text-edit-set-text! ed - (or output "No differences")) + (if (and output (> (string-length output) 0)) + output + "No differences")) (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) (qt-plain-text-edit-set-cursor-position! ed 0) - (when output (qt-highlight-diff! ed)) + (when (and output (> (string-length output) 0)) + (qt-highlight-diff! ed)) (echo-message! (app-state-echo app) "Diff complete"))))))))) --- a/lib/jerboa-emacs/qt/commands-search.sls +++ b/lib/jerboa-emacs/qt/commands-search.sls @@ -45,7 +45,7 @@ getenv path-extension path-absolute? thread? make-mutex mutex? mutex-name sort sort!) (std sugar) (chez-scintilla constants) (std sort) - (std srfi srfi-13) (std text base64) + (std srfi srfi-13) (std text base64) (std text diff) (jerboa-emacs qt sci-shim) (jerboa-emacs core) (jerboa-emacs async) (jerboa-emacs subprocess) (jerboa-emacs gsh-subprocess) (jerboa-emacs editor) @@ -1228,26 +1228,13 @@ (let* ([ed (current-qt-editor app)] [current-text (qt-plain-text-edit-text ed)] [file-text (read-file-as-string path)] - [tmp-path (string-append - "/tmp/jemacs-diff-" - (number->string (random-integer 100000)))] - [_ (write-string-to-file tmp-path current-text)] - [result (with-catch - (lambda (e) "Error running diff") - (lambda () - (let ([port (open-process - (list 'path: "/usr/bin/diff" - 'arguments: - (list "-u" path tmp-path) - 'stdout-redirection: #t - 'stderr-redirection: #t - 'pseudo-terminal: #f))]) - (let ([output (read-line port #f)]) - (close-port port) - (or output "No differences")))))]) - (with-catch - (lambda (_e) (void)) - (lambda () (delete-file tmp-path))) + [file-lines (string-split file-text #\newline)] + [buf-lines (string-split current-text #\newline)] + [result (diff-unified + path + "(buffer)" + file-lines + buf-lines)]) (let* ([fr (app-state-frame app)] [diff-buf (or (buffer-by-name "*Diff*") (qt-buffer-create! "*Diff*" ed #f))]) @@ -1257,7 +1244,9 @@ diff-buf) (qt-plain-text-edit-set-text! ed - (if (string=? result "") "No differences\n" result)) + (if (or (not result) (string=? result "")) + "No differences\n" + result)) (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) --- a/lib/jerboa-emacs/qt/commands-sexp.sls +++ b/lib/jerboa-emacs/qt/commands-sexp.sls @@ -37,7 +37,7 @@ getenv path-extension path-absolute? thread? make-mutex mutex? mutex-name sort sort!) (std sugar) (chez-scintilla constants) (std sort) - (std srfi srfi-13) (std text base64) + (std srfi srfi-13) (std text base64) (std text diff) (jerboa-emacs qt sci-shim) (jerboa-emacs core) (jerboa-emacs editor) (jerboa-emacs repl) (jerboa-emacs eshell) (jerboa-emacs shell) @@ -1046,67 +1046,50 @@ bufs)]) (if (or (not buf-a) (not buf-b)) (echo-error! (app-state-echo app) "Buffer not found") - (let* ([tmp-a (path-expand - "ediff-a" - (or (getenv "TMPDIR") "/tmp"))] - [tmp-b (path-expand - "ediff-b" - (or (getenv "TMPDIR") "/tmp"))]) - (let ([text-a ""] [text-b ""]) - (let ([fr (app-state-frame app)]) - (for-each - (lambda (win) - (when (eq? (qt-edit-window-buffer win) - buf-a) - (set! text-a - (qt-plain-text-edit-text - (qt-edit-window-editor win)))) - (when (eq? (qt-edit-window-buffer win) - buf-b) - (set! text-b - (qt-plain-text-edit-text - (qt-edit-window-editor win))))) - (qt-frame-windows fr))) - (call-with-output-file - tmp-a - (lambda (p) (display text-a p))) - (call-with-output-file - tmp-b - (lambda (p) (display text-b p))) - (let* ([proc (open-process - (list 'path: "/usr/bin/diff" - 'arguments: - (list "-u" tmp-a tmp-b) - 'stdout-redirection: #t))] - [output (read-line proc #f)] - [ed (current-qt-editor app)] - [fr (app-state-frame app)] - [diff-buf (qt-buffer-create! - "*Ediff*" - ed - #f)]) - (close-port proc) - (qt-buffer-attach! ed diff-buf) - (qt-edit-window-buffer-set! - (qt-current-window fr) - diff-buf) - (qt-plain-text-edit-set-text! - ed - (or output "No differences")) - (qt-text-document-set-modified! - (buffer-doc-pointer diff-buf) - #f) - (qt-plain-text-edit-set-cursor-position! ed 0) - (when output (qt-highlight-diff! ed)) - (with-catch - (lambda (_e) (void)) - (lambda () (delete-file tmp-a))) - (with-catch - (lambda (_e) (void)) - (lambda () (delete-file tmp-b))) - (echo-message! - (app-state-echo app) - "Diff complete"))))))))))) + (let ([text-a ""] [text-b ""]) + (let ([fr (app-state-frame app)]) + (for-each + (lambda (win) + (when (eq? (qt-edit-window-buffer win) buf-a) + (set! text-a + (qt-plain-text-edit-text + (qt-edit-window-editor win)))) + (when (eq? (qt-edit-window-buffer win) buf-b) + (set! text-b + (qt-plain-text-edit-text + (qt-edit-window-editor win))))) + (qt-frame-windows fr))) + (let* ([lines-a (string-split text-a #\newline)] + [lines-b (string-split text-b #\newline)] + [output (diff-unified + a-name + b-name + lines-a + lines-b)] + [ed (current-qt-editor app)] + [fr (app-state-frame app)] + [diff-buf (qt-buffer-create! + "*Ediff*" + ed + #f)]) + (qt-buffer-attach! ed diff-buf) + (qt-edit-window-buffer-set! + (qt-current-window fr) + diff-buf) + (qt-plain-text-edit-set-text! + ed + (if (and output (> (string-length output) 0)) + output + "No differences")) + (qt-text-document-set-modified! + (buffer-doc-pointer diff-buf) + #f) + (qt-plain-text-edit-set-cursor-position! ed 0) + (when (and output (> (string-length output) 0)) + (qt-highlight-diff! ed)) + (echo-message! + (app-state-echo app) + "Diff complete")))))))))) (def (word-at-point ed) "Extract the word at the cursor position. Returns (values word start end) or (values #f 0 0)." (let* ([text (qt-plain-text-edit-text ed)] --- a/lib/jerboa-emacs/qt/commands-shell2.sls +++ b/lib/jerboa-emacs/qt/commands-shell2.sls @@ -37,7 +37,7 @@ getenv path-extension path-absolute? thread? make-mutex mutex? mutex-name sort sort!) (std sugar) (chez-scintilla constants) (std sort) - (std srfi srfi-13) (std text base64) + (std srfi srfi-13) (std text base64) (std text diff) (jerboa-emacs qt sci-shim) (jerboa-emacs core) (only (jerboa-emacs persist) theme-settings-save! theme-settings-load! mx-history-save! mx-history-load!) @@ -379,55 +379,39 @@ (app-state-echo app) (string-append "Buffer not found: " other-name)) (let* ([ed (current-qt-editor app)] - [text1 (qt-plain-text-edit-text ed)] - [tmp1 "/tmp/jemacs-ediff-1.txt"] - [tmp2 "/tmp/jemacs-ediff-2.txt"]) - (call-with-output-file - tmp1 - (lambda (p) (display text1 p))) + [text1 (qt-plain-text-edit-text ed)]) (qt-buffer-attach! ed other-buf) (let ([text2 (qt-plain-text-edit-text ed)]) - (call-with-output-file - tmp2 - (lambda (p) (display text2 p))) (qt-buffer-attach! ed cur-buf) - (with-catch - (lambda (e) - (echo-error! (app-state-echo app) "diff failed")) - (lambda () - (let* ([proc (open-process - (list 'path: "diff" 'arguments: - (list "-u" - (string-append - "--label=" - cur-name) - (string-append - "--label=" - other-name) - tmp1 tmp2) - 'stdout-redirection: #t - 'stderr-redirection: #t))] - [output (read-line proc #f)] - [_ (close-port proc)] - [fr (app-state-frame app)] - [diff-buf (or (buffer-by-name - "*Ediff Regions*") - (qt-buffer-create! - "*Ediff Regions*" - ed - #f))]) - (qt-buffer-attach! ed diff-buf) - (qt-edit-window-buffer-set! - (qt-current-window fr) - diff-buf) - (qt-plain-text-edit-set-text! - ed - (or output "Buffers are identical")) - (qt-text-document-set-modified! - (buffer-doc-pointer diff-buf) - #f) - (qt-plain-text-edit-set-cursor-position! ed 0) - (qt-highlight-diff! ed))))))))))) + (let* ([lines1 (string-split text1 #\newline)] + [lines2 (string-split text2 #\newline)] + [output (diff-unified + cur-name + other-name + lines1 + lines2)] + [fr (app-state-frame app)] + [diff-buf (or (buffer-by-name + "*Ediff Regions*") + (qt-buffer-create! + "*Ediff Regions*" + ed + #f))]) + (qt-buffer-attach! ed diff-buf) + (qt-edit-window-buffer-set! + (qt-current-window fr) + diff-buf) + (qt-plain-text-edit-set-text! + ed + (if (and output (> (string-length output) 0)) + output + "Buffers are identical")) + (qt-text-document-set-modified! + (buffer-doc-pointer diff-buf) + #f) + (qt-plain-text-edit-set-cursor-position! ed 0) + (when (and output (> (string-length output) 0)) + (qt-highlight-diff! ed)))))))))) (def (cmd-show-paren-mode app) "Toggle show-paren-mode (bracket matching highlight). Enabled by default.\nWhen disabled, cursor-adjacent braces are no longer highlighted." (set! *qt-show-paren-enabled* (not *qt-show-paren-enabled*)) --- a/src/jerboa-emacs/editor-advanced.ss +++ b/src/jerboa-emacs/editor-advanced.ss @@ -10,6 +10,7 @@ :std/srfi/13 :std/text/base64 :std/text/hex + :std/text/diff :std/crypto/digest :chez-scintilla/constants :chez-scintilla/scintilla @@ -581,34 +582,19 @@ (echo-error! echo (string-append "File not found: " path)) (let* ((file-text (read-file-as-string path)) (buf-text (editor-get-text ed)) - ;; Write both to temp files and run diff - (pid (number->string (getpid))) - (tmp1 (string-append "/tmp/jemacs-diff-file-" pid)) - (tmp2 (string-append "/tmp/jemacs-diff-buf-" pid))) - (write-string-to-file file-text tmp1) - (write-string-to-file buf-text tmp2) - (let* ((proc (open-process - (list path: "/usr/bin/diff" - arguments: (list "-u" tmp1 tmp2) - stdin-redirection: #f - stdout-redirection: #t - stderr-redirection: #t))) - (output (read-line proc #f)) - (status (process-status proc))) - ;; Clean up temp files - (with-catch (lambda (_e) (void)) (lambda () (delete-file tmp1))) - (with-catch (lambda (_e) (void)) (lambda () (delete-file tmp2))) - (if (and output (> (string-length output) 0)) - ;; Show diff in *Diff* buffer - (let ((diff-buf (or (buffer-by-name "*Diff*") - (buffer-create! "*Diff*" ed #f)))) - (buffer-attach! ed diff-buf) - (set! (edit-window-buffer (current-window fr)) diff-buf) - (editor-set-text ed output) - (editor-set-save-point ed) - (editor-goto-pos ed 0) - (echo-message! echo "*Diff*")) - (echo-message! echo "No differences")))))))) + (file-lines (string-split file-text #\newline)) + (buf-lines (string-split buf-text #\newline)) + (output (diff-unified path "(buffer)" file-lines buf-lines))) + (if (and output (> (string-length output) 0)) + (let ((diff-buf (or (buffer-by-name "*Diff*") + (buffer-create! "*Diff*" ed #f)))) + (buffer-attach! ed diff-buf) + (set! (edit-window-buffer (current-window fr)) diff-buf) + (editor-set-text ed output) + (editor-set-save-point ed) + (editor-goto-pos ed 0) + (echo-message! echo "*Diff*")) + (echo-message! echo "No differences"))))))) ;;;============================================================================ ;;; Checksum: SHA256 @@ -950,55 +936,38 @@ (buf-b (and name-b (buffer-by-name name-b)))) (if (not buf-b) (echo-error! echo (string-append "No buffer: " (or name-b ""))) - ;; Get text from both buffers, write to temp files, diff - (let* ((pid (number->string (getpid))) - (tmp-a (string-append "/tmp/gerbil-ediff-a-" pid)) - (tmp-b (string-append "/tmp/gerbil-ediff-b-" pid))) - ;; We need the text from those buffers — find their windows - (let ((text-a #f) (text-b #f)) - (for-each - (lambda (win) - (let ((wb (edit-window-buffer win))) - (when (eq? wb buf-a) - (set! text-a (editor-get-text (edit-window-editor win)))) - (when (eq? wb buf-b) - (set! text-b (editor-get-text (edit-window-editor win)))))) - (frame-windows fr)) - ;; Fallback: if buffer not in a window, use current editor temporarily - (unless text-a - (buffer-attach! ed buf-a) - (set! text-a (editor-get-text ed))) - (unless text-b - (buffer-attach! ed buf-b) - (set! text-b (editor-get-text ed))) - ;; Write to temp files and diff - (write-string-to-file tmp-a text-a) - (write-string-to-file tmp-b text-b) - (let* ((proc (open-process - (list path: "/usr/bin/diff" - arguments: (list "-u" - (string-append "--label=" name-a) - (string-append "--label=" name-b) - tmp-a tmp-b) - stdout-redirection: #t - stderr-redirection: #t))) - (output (read-line proc #f)) - (status (process-status proc))) - ;; Cleanup temp files - (with-catch (lambda (_e) (void)) (lambda () (delete-file tmp-a))) - (with-catch (lambda (_e) (void)) (lambda () (delete-file tmp-b))) - ;; Show diff in buffer - (let ((diff-buf (buffer-create! "*Diff*" ed #f))) - (buffer-attach! ed diff-buf) - (set! (edit-window-buffer (current-window fr)) diff-buf) - (if (and (string? output) (> (string-length output) 0)) - (begin - (editor-set-text ed output) - (setup-diff-highlighting! ed)) - (editor-set-text ed "(no differences)\n")) - (editor-set-save-point ed) - (editor-goto-pos ed 0) - (editor-set-read-only ed #t)))))))))))) + ;; Get text from both buffers + (let ((text-a #f) (text-b #f)) + (for-each + (lambda (win) + (let ((wb (edit-window-buffer win))) + (when (eq? wb buf-a) + (set! text-a (editor-get-text (edit-window-editor win)))) + (when (eq? wb buf-b) + (set! text-b (editor-get-text (edit-window-editor win)))))) + (frame-windows fr)) + ;; Fallback: if buffer not in a window, use current editor temporarily + (unless text-a + (buffer-attach! ed buf-a) + (set! text-a (editor-get-text ed))) + (unless text-b + (buffer-attach! ed buf-b) + (set! text-b (editor-get-text ed))) + ;; In-process diff + (let* ((lines-a (string-split text-a #\newline)) + (lines-b (string-split text-b #\newline)) + (output (diff-unified name-a name-b lines-a lines-b)) + (diff-buf (buffer-create! "*Diff*" ed #f))) + (buffer-attach! ed diff-buf) + (set! (edit-window-buffer (current-window fr)) diff-buf) + (if (and (string? output) (> (string-length output) 0)) + (begin + (editor-set-text ed output) + (setup-diff-highlighting! ed)) + (editor-set-text ed "(no differences)\n")) + (editor-set-save-point ed) + (editor-goto-pos ed 0) + (editor-set-read-only ed #t)))))))))) ;;;============================================================================ ;;; Simple calculator --- a/src/jerboa-emacs/org-parse.ss +++ b/src/jerboa-emacs/org-parse.ss @@ -13,6 +13,7 @@ date-hour date-minute date-second date->time-utc time-difference time-second date-week-day make-time time-utc) + (only-in :std/misc/number number->padded-string) ./pregexp-compat :std/misc/string) @@ -113,9 +114,7 @@ Returns an org-timestamp struct or #f on parse failure." (def (pad-02 n) "Pad an integer to 2-digit zero-padded string." - (if (< n 10) - (string-append "0" (number->string n)) - (number->string n))) + (number->padded-string n 2)) (def (org-timestamp->date ts) "Convert an org-timestamp to a SRFI-19 date for arithmetic." --- a/src/jerboa-emacs/qt/commands-config.ss +++ b/src/jerboa-emacs/qt/commands-config.ss @@ -9,6 +9,7 @@ :std/sort :std/srfi/13 :std/text/base64 + :std/text/diff :jerboa-emacs/qt/sci-shim :jerboa-emacs/core :jerboa-emacs/async @@ -1043,22 +1044,22 @@ modified so the next save uses the new encoding." (path-b (path-expand file-b))) (if (not (and (file-exists? path-a) (file-exists? path-b))) (echo-error! (app-state-echo app) "One or both files not found") - (let* ((proc (open-process - (list path: "/usr/bin/diff" - arguments: (list "-u" path-a path-b) - stdout-redirection: #t))) - (output (read-line proc #f)) - ;; Omit process-status (Qt SIGCHLD race) + (let* ((text-a (read-file-as-string path-a)) + (text-b (read-file-as-string path-b)) + (lines-a (string-split text-a #\newline)) + (lines-b (string-split text-b #\newline)) + (output (diff-unified path-a path-b lines-a lines-b)) (ed (current-qt-editor app)) (fr (app-state-frame app)) (diff-buf (qt-buffer-create! "*Ediff*" ed #f))) - (close-port proc) (qt-buffer-attach! ed diff-buf) (set! (qt-edit-window-buffer (qt-current-window fr)) diff-buf) - (qt-plain-text-edit-set-text! ed (or output "No differences")) + (qt-plain-text-edit-set-text! ed + (if (and output (> (string-length output) 0)) output "No differences")) (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) (qt-plain-text-edit-set-cursor-position! ed 0) - (when output (qt-highlight-diff! ed)) + (when (and output (> (string-length output) 0)) + (qt-highlight-diff! ed)) (echo-message! (app-state-echo app) "Diff complete"))))))))) ;;;============================================================================ --- a/src/jerboa-emacs/qt/commands-search.ss +++ b/src/jerboa-emacs/qt/commands-search.ss @@ -9,6 +9,7 @@ :std/sort :std/srfi/13 :std/text/base64 + :std/text/diff :jerboa-emacs/qt/sci-shim :jerboa-emacs/core :jerboa-emacs/async @@ -1092,23 +1093,9 @@ Supports Gerbil (.ss), Python, JS/TS, Go, Shell, C/C++, Ruby." (let* ((ed (current-qt-editor app)) (current-text (qt-plain-text-edit-text ed)) (file-text (read-file-as-string path)) - ;; Write current buffer to temp file for diff - (tmp-path (string-append "/tmp/jemacs-diff-" (number->string (random-integer 100000)))) - (_ (write-string-to-file tmp-path current-text)) - (result (with-catch - (lambda (e) "Error running diff") - (lambda () - (let ((port (open-process - (list path: "/usr/bin/diff" - arguments: ["-u" path tmp-path] - stdout-redirection: #t - stderr-redirection: #t - pseudo-terminal: #f)))) - (let ((output (read-line port #f))) - (close-port port) - (or output "No differences"))))))) - ;; Clean up temp file - (with-catch (lambda (_e) (void)) (lambda () (delete-file tmp-path))) + (file-lines (string-split file-text #\newline)) + (buf-lines (string-split current-text #\newline)) + (result (diff-unified path "(buffer)" file-lines buf-lines))) ;; Show diff in buffer (let* ((fr (app-state-frame app)) (diff-buf (or (buffer-by-name "*Diff*") @@ -1116,7 +1103,7 @@ Supports Gerbil (.ss), Python, JS/TS, Go, Shell, C/C++, Ruby." (qt-buffer-attach! ed diff-buf) (set! (qt-edit-window-buffer (qt-current-window fr)) diff-buf) (qt-plain-text-edit-set-text! ed - (if (string=? result "") "No differences\n" result)) + (if (or (not result) (string=? result "")) "No differences\n" result)) (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) (qt-plain-text-edit-set-cursor-position! ed 0) (qt-highlight-diff! ed))) --- a/src/jerboa-emacs/qt/commands-sexp.ss +++ b/src/jerboa-emacs/qt/commands-sexp.ss @@ -9,6 +9,7 @@ :std/sort :std/srfi/13 :std/text/base64 + :std/text/diff :jerboa-emacs/qt/sci-shim :jerboa-emacs/core :jerboa-emacs/editor @@ -908,43 +909,33 @@ (buf-b (find (lambda (b) (string=? (buffer-name b) b-name)) bufs))) (if (or (not buf-a) (not buf-b)) (echo-error! (app-state-echo app) "Buffer not found") - ;; Write both to temp files and diff - (let* ((tmp-a (path-expand "ediff-a" (or (getenv "TMPDIR") "/tmp"))) - (tmp-b (path-expand "ediff-b" (or (getenv "TMPDIR") "/tmp")))) - ;; Get text from buffers - (let ((text-a "") - (text-b "")) - ;; Find editors showing these buffers - (let ((fr (app-state-frame app))) - (for-each - (lambda (win) - (when (eq? (qt-edit-window-buffer win) buf-a) - (set! text-a (qt-plain-text-edit-text (qt-edit-window-editor win)))) - (when (eq? (qt-edit-window-buffer win) buf-b) - (set! text-b (qt-plain-text-edit-text (qt-edit-window-editor win))))) - (qt-frame-windows fr))) - (call-with-output-file tmp-a (lambda (p) (display text-a p))) - (call-with-output-file tmp-b (lambda (p) (display text-b p))) - (let* ((proc (open-process - (list path: "/usr/bin/diff" - arguments: (list "-u" tmp-a tmp-b) - stdout-redirection: #t))) - (output (read-line proc #f)) - ;; Omit process-status (Qt SIGCHLD race) - (ed (current-qt-editor app)) - (fr (app-state-frame app)) - (diff-buf (qt-buffer-create! "*Ediff*" ed #f))) - (close-port proc) - (qt-buffer-attach! ed diff-buf) - (set! (qt-edit-window-buffer (qt-current-window fr)) diff-buf) - (qt-plain-text-edit-set-text! ed (or output "No differences")) - (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) - (qt-plain-text-edit-set-cursor-position! ed 0) - (when output (qt-highlight-diff! ed)) - ;; Clean up temp files - (with-catch (lambda (_e) (void)) (lambda () (delete-file tmp-a))) - (with-catch (lambda (_e) (void)) (lambda () (delete-file tmp-b))) - (echo-message! (app-state-echo app) "Diff complete"))))))))))) + ;; Get text from buffers + (let ((text-a "") + (text-b "")) + (let ((fr (app-state-frame app))) + (for-each + (lambda (win) + (when (eq? (qt-edit-window-buffer win) buf-a) + (set! text-a (qt-plain-text-edit-text (qt-edit-window-editor win)))) + (when (eq? (qt-edit-window-buffer win) buf-b) + (set! text-b (qt-plain-text-edit-text (qt-edit-window-editor win))))) + (qt-frame-windows fr))) + ;; In-process diff + (let* ((lines-a (string-split text-a #\newline)) + (lines-b (string-split text-b #\newline)) + (output (diff-unified a-name b-name lines-a lines-b)) + (ed (current-qt-editor app)) + (fr (app-state-frame app)) + (diff-buf (qt-buffer-create! "*Ediff*" ed #f))) + (qt-buffer-attach! ed diff-buf) + (set! (qt-edit-window-buffer (qt-current-window fr)) diff-buf) + (qt-plain-text-edit-set-text! ed + (if (and output (> (string-length output) 0)) output "No differences")) + (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) + (qt-plain-text-edit-set-cursor-position! ed 0) + (when (and output (> (string-length output) 0)) + (qt-highlight-diff! ed)) + (echo-message! (app-state-echo app) "Diff complete")))))))))) ;;;============================================================================ ;;; Highlight symbol / clear highlight --- a/src/jerboa-emacs/qt/commands-shell2.ss +++ b/src/jerboa-emacs/qt/commands-shell2.ss @@ -9,6 +9,7 @@ :std/sort :std/srfi/13 :std/text/base64 + :std/text/diff :jerboa-emacs/qt/sci-shim :jerboa-emacs/core (only-in :jerboa-emacs/persist theme-settings-save! theme-settings-load! @@ -255,39 +256,27 @@ (if (not other-buf) (echo-error! (app-state-echo app) (string-append "Buffer not found: " other-name)) (let* ((ed (current-qt-editor app)) - (text1 (qt-plain-text-edit-text ed)) - (tmp1 "/tmp/jemacs-ediff-1.txt") - (tmp2 "/tmp/jemacs-ediff-2.txt")) - (call-with-output-file tmp1 (lambda (p) (display text1 p))) + (text1 (qt-plain-text-edit-text ed))) ;; Get other buffer text by temporarily switching (qt-buffer-attach! ed other-buf) (let ((text2 (qt-plain-text-edit-text ed))) - (call-with-output-file tmp2 (lambda (p) (display text2 p))) ;; Switch back (qt-buffer-attach! ed cur-buf) - (with-catch - (lambda (e) (echo-error! (app-state-echo app) "diff failed")) - (lambda () - (let* ((proc (open-process - (list path: "diff" - arguments: (list "-u" - (string-append "--label=" cur-name) - (string-append "--label=" other-name) - tmp1 tmp2) - stdout-redirection: #t - stderr-redirection: #t))) - (output (read-line proc #f)) - (_ (close-port proc)) - (fr (app-state-frame app)) - (diff-buf (or (buffer-by-name "*Ediff Regions*") - (qt-buffer-create! "*Ediff Regions*" ed #f)))) - (qt-buffer-attach! ed diff-buf) - (set! (qt-edit-window-buffer (qt-current-window fr)) diff-buf) - (qt-plain-text-edit-set-text! ed - (or output "Buffers are identical")) - (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) - (qt-plain-text-edit-set-cursor-position! ed 0) - (qt-highlight-diff! ed))))))))))) + ;; In-process diff + (let* ((lines1 (string-split text1 #\newline)) + (lines2 (string-split text2 #\newline)) + (output (diff-unified cur-name other-name lines1 lines2)) + (fr (app-state-frame app)) + (diff-buf (or (buffer-by-name "*Ediff Regions*") + (qt-buffer-create! "*Ediff Regions*" ed #f)))) + (qt-buffer-attach! ed diff-buf) + (set! (qt-edit-window-buffer (qt-current-window fr)) diff-buf) + (qt-plain-text-edit-set-text! ed + (if (and output (> (string-length output) 0)) output "Buffers are identical")) + (qt-text-document-set-modified! (buffer-doc-pointer diff-buf) #f) + (qt-plain-text-edit-set-cursor-position! ed 0) + (when (and output (> (string-length output) 0)) + (qt-highlight-diff! ed)))))))))) ;;;============================================================================ ;;; Mode toggles (Emacs compatibility aliases)