Implement Qt electric indent mode

ober

2f5e40798eb89d6bdfd456ef47d7e7f6d7aeb0cf

diff --git a/src/jerboa-emacs/qt/commands-parity5.ss b/src/jerboa-emacs/qt/commands-parity5.ss
index 96e2697..89e2573 100644
--- a/src/jerboa-emacs/qt/commands-parity5.ss
+++ b/src/jerboa-emacs/qt/commands-parity5.ss
@@ -1370,6 +1370,15 @@
     (if *recentf-mode*
       "Recentf mode ON"
       "Recentf mode OFF")))
+(def (cmd-electric-indent-mode app)
+  "Toggle Qt electric-indent-mode newline indentation."
+  (set! *electric-indent-mode* (not *electric-indent-mode*))
+  (hash-put! *qt-toggle-states* 'electric-indent-mode *electric-indent-mode*)
+  (hash-put! *qt-toggle-states* 'toggle-electric-indent-mode *electric-indent-mode*)
+  (echo-message! (app-state-echo app)
+    (if *electric-indent-mode*
+      "Electric indent mode ON"
+      "Electric indent mode OFF")))
 (def *qt-run-with-timer-counter* 0)
 
 (def (next-run-with-timer-name!)
@@ -1481,6 +1490,8 @@
       (cons 'toggle-winner-mode cmd-winner-mode)
       (cons 'recentf-mode cmd-recentf-mode)
       (cons 'toggle-recentf-mode cmd-recentf-mode)
+      (cons 'electric-indent-mode cmd-electric-indent-mode)
+      (cons 'toggle-electric-indent-mode cmd-electric-indent-mode)
       (cons 'run-with-timer cmd-run-with-timer)
       (cons 'ibuffer-mark cmd-ibuffer-mark)
       (cons 'ibuffer-delete cmd-ibuffer-delete)
diff --git a/src/jerboa-emacs/qt/commands.ss b/src/jerboa-emacs/qt/commands.ss
index f39c07a..67d7fb2 100644
--- a/src/jerboa-emacs/qt/commands.ss
+++ b/src/jerboa-emacs/qt/commands.ss
@@ -309,7 +309,7 @@
       ((chat-buffer? buf)   (cmd-chat-send app))
       (else
         (let ((ed (current-qt-editor app)))
-          (if *auto-indent*
+          (if (and *auto-indent* *electric-indent-mode*)
             ;; Auto-indent: copy previous line's leading whitespace
             (let ((indent (current-line-indent ed)))
               (qt-plain-text-edit-insert-text! ed (string-append "\n" indent)))
diff --git a/tests/test-qt-part2.ss b/tests/test-qt-part2.ss
index d085329..7d7c10c 100644
--- a/tests/test-qt-part2.ss
+++ b/tests/test-qt-part2.ss
@@ -27,6 +27,7 @@
         (only (jerboa-emacs qt commands-edit) *line-numbers-visible*)
         (only (jerboa-emacs qt commands-core)
               *so-long-threshold* *winner-mode* *winner-history* *winner-future*)
+        (only (jerboa-emacs qt commands-shell) *auto-indent*)
         (only (jerboa-emacs persist)
               *recentf-mode* *recent-files* recent-files-add!)
         (only (jerboa-emacs qt commands-parity5) schedule-user-timer!)
@@ -110,7 +111,7 @@
       (loop (+ i 1)
             (cons (string-append "line " (number->string i) "\n") acc)))))
 
-(display "\n=== Qt Part2 Groups 44-63 ===\n")
+(display "\n=== Qt Part2 Groups 44-64 ===\n")
 
 (test-case "group44 qt key/mouse fidelity"
   (check (qt-key-event->string QT_KEY_RETURN 0 "") => "C-m")
@@ -372,9 +373,35 @@
           (setenv "HOME" (or old-home "/tmp"))
           (with-catch (lambda (e) #f)
             (lambda () (delete-file path))))))))
+(test-case "group64 electric-indent-mode controls newline indentation"
+  (let-values (((ed w app) (make-qt-test-app "part2-64")))
+    (let ((old-electric *electric-indent-mode*)
+          (old-auto *auto-indent*))
+      (dynamic-wind
+        (lambda ()
+          (set! *electric-indent-mode* #t)
+          (set! *auto-indent* #t))
+        (lambda ()
+          (qt-plain-text-edit-set-text! ed "  alpha")
+          (qt-plain-text-edit-set-cursor-position! ed (string-length "  alpha"))
+          (execute-command! app 'electric-indent-mode)
+          (check *electric-indent-mode* => #f)
+          (check (echo-state-message (app-state-echo app)) => "Electric indent mode OFF")
+          (execute-command! app 'newline)
+          (check (qt-plain-text-edit-text ed) => "  alpha\n")
+          (execute-command! app 'toggle-electric-indent-mode)
+          (check *electric-indent-mode* => #t)
+          (check (echo-state-message (app-state-echo app)) => "Electric indent mode ON")
+          (qt-plain-text-edit-set-text! ed "  beta")
+          (qt-plain-text-edit-set-cursor-position! ed (string-length "  beta"))
+          (execute-command! app 'newline)
+          (check (qt-plain-text-edit-text ed) => "  beta\n  "))
+        (lambda ()
+          (set! *electric-indent-mode* old-electric)
+          (set! *auto-indent* old-auto))))))
 (newline)
 (let ([total (+ *pass* *fail*)])
-  (printf "Part2 results: ~a/~a tests passed (groups 44-63)~n" *pass* total)
+  (printf "Part2 results: ~a/~a tests passed (groups 44-64)~n" *pass* total)
   (when (> *fail* 0)
     (printf "FAILED: ~a test(s)~n" *fail*))
   (when (= *fail* 0)