]> git.eshelyaron.com Git - emacs.git/commitdiff
Preserve ERC prompt and its bounding markers
authorF. Jason Park <jp@neverwas.me>
Mon, 20 Feb 2023 05:33:36 +0000 (21:33 -0800)
committerF. Jason Park <jp@neverwas.me>
Sat, 8 Apr 2023 21:23:51 +0000 (14:23 -0700)
* lisp/erc/erc.el (erc--assert-input-bounds): Add possibly temporary
helper function to sync `process-mark' to `erc-insert-marker' in
server buffer.
(erc-display-line-1): Expect `erc-insert-marker' to always be
initialized.  Assert some essential invariants regarding insert
markers.
(erc-send-current-line): Delete typed input but not the prompt.
(erc-display-msg): Rework slightly to respect existing markers.
* test/lisp/erc/erc-dcc-tests.el
(erc-dcc-tests--dcc-handle-ctcp-send): Set insert marker.
* test/lisp/erc/erc-networks-tests.el
(erc-networks--rename-server-buffer--existing-live): Initialize
markers to appease `erc--assert-input-bounds'.
* test/lisp/erc/erc-tests.el (erc-ring-previous-command): Fix sloppy
mock.  (Bug#60936.)

lisp/erc/erc.el
test/lisp/erc/erc-dcc-tests.el
test/lisp/erc/erc-networks-tests.el
test/lisp/erc/erc-tests.el

index 85f0416f44b987dd5631870a0d5b92849c00efbe..6e14f4780e4410fac45d08727072025fc6c9f8ee 100644 (file)
@@ -2632,6 +2632,16 @@ this option to nil."
   :type 'boolean
   :group 'erc)
 
+(define-inline erc--assert-input-bounds ()
+  (inline-quote
+   (progn (when (and (processp erc-server-process)
+                     (eq (current-buffer) (process-buffer erc-server-process)))
+            ;; It's believed that these only need syncing immediately
+            ;; following the first two insertions in a server buffer.
+            (set-marker (process-mark erc-server-process) erc-insert-marker))
+          (cl-assert (< erc-insert-marker erc-input-marker))
+          (cl-assert (= (field-end erc-insert-marker) erc-input-marker)))))
+
 (defun erc-display-line-1 (string buffer)
   "Display STRING in `erc-mode' BUFFER.
 Auxiliary function used in `erc-display-line'.  The line gets filtered to
@@ -2641,8 +2651,7 @@ Afterwards, `erc-insert-modify' and `erc-insert-post-hook' get called.
 If STRING is nil, the function does nothing."
   (when string
     (with-current-buffer (or buffer (process-buffer erc-server-process))
-      (let ((insert-position (or (marker-position erc-insert-marker)
-                                 (point-max))))
+      (let ((insert-position (marker-position erc-insert-marker)))
         (let ((string string) ;; FIXME! Can this be removed?
               (buffer-undo-list t)
               (inhibit-read-only t))
@@ -2667,6 +2676,7 @@ If STRING is nil, the function does nothing."
                 (widen)
                 (goto-char insert-position)
                 (insert-before-markers string)
+                (erc--assert-input-bounds)
                 ;; run insertion hook, with point at restored location
                 (save-restriction
                   (narrow-to-region insert-position (point))
@@ -2674,7 +2684,8 @@ If STRING is nil, the function does nothing."
                   (run-hooks 'erc-insert-post-hook)
                   (when erc-remove-parsed-property
                     (remove-text-properties (point-min) (point-max)
-                                            '(erc-parsed nil))))))))
+                                            '(erc-parsed nil))))
+                (erc--assert-input-bounds)))))
         (run-hooks 'erc-insert-done-hook)
         (erc-update-undo-list (- (or (marker-position erc-insert-marker)
                                      (point-max))
@@ -6006,8 +6017,7 @@ When the returned value is a string, pass it to `erc-error'.")
               (progn ; unprogn this during next major surgery
                 (erc-set-active-buffer (current-buffer))
                 ;; Kill the input and the prompt
-                (delete-region (erc-beg-of-input-line)
-                               (erc-end-of-input-line))
+                (delete-region erc-input-marker (erc-end-of-input-line))
                 (unwind-protect
                     (erc-send-input str 'skip-ws-chk)
                   ;; Fix the buffer if the command didn't kill it
@@ -6015,12 +6025,7 @@ When the returned value is a string, pass it to `erc-error'.")
                     (with-current-buffer old-buf
                       (save-restriction
                         (widen)
-                        (goto-char (point-max))
-                        (when (processp erc-server-process)
-                          (set-marker (process-mark erc-server-process) (point)))
-                        (set-marker erc-insert-marker (point))
                         (let ((buffer-modified (buffer-modified-p)))
-                          (erc-display-prompt)
                           (set-buffer-modified-p buffer-modified))))))
 
                 ;; Only when last hook has been run...
@@ -6106,21 +6111,21 @@ Return non-nil only if we actually send anything."
 (defun erc-display-msg (line)
   "Display LINE as a message of the user to the current target at point."
   (when erc-insert-this
-    (let ((insert-position (point)))
-      (insert (erc-format-my-nick))
-      (let ((beg (point)))
-        (insert line)
-        (erc-put-text-property beg (point)
-                               'font-lock-face 'erc-input-face))
-      (insert "\n")
-      (when (processp erc-server-process)
-        (set-marker (process-mark erc-server-process) (point)))
-      (set-marker erc-insert-marker (point))
-      (save-excursion
+    (save-excursion
+      (erc--assert-input-bounds)
+      (let ((insert-position (marker-position erc-insert-marker))
+            beg)
+        (goto-char insert-position)
+        (insert-before-markers (erc-format-my-nick))
+        (setq beg (point))
+        (insert-before-markers line)
+        (erc-put-text-property beg (point) 'font-lock-face 'erc-input-face)
+        (insert-before-markers "\n")
         (save-restriction
           (narrow-to-region insert-position (point))
           (run-hooks 'erc-send-modify-hook)
-          (run-hooks 'erc-send-post-hook))))))
+          (run-hooks 'erc-send-post-hook))
+        (erc--assert-input-bounds)))))
 
 (defun erc-command-symbol (command)
   "Return the ERC command symbol for COMMAND if it exists and is bound."
index fed86eff2c5ae32927b584690a854a89ad159a07..7fb5f82e784ed152463051151c1de7e95e67c47b 100644 (file)
@@ -60,6 +60,8 @@
             erc-input-marker (make-marker)
             erc-insert-marker (make-marker)
             erc-server-current-nick "dummy")
+      (erc-display-prompt)
+      (set-marker erc-insert-marker (pos-bol))
       (set-process-query-on-exit-flag erc-server-process nil)
       (should-not erc-dcc-list)
       (erc-ctcp-query-DCC erc-server-process
index 96836c29aed150ce7f8ca24f9423f4c7c8836d7c..b9d216f217bd5134e59134b2169e9c14e442a486 100644 (file)
         (erc-mode)
         (setq erc-network 'FooNet
               erc-server-current-nick "tester"
-              erc-insert-marker (set-marker (make-marker) (point-max))
+              erc-insert-marker (make-marker)
+              erc-input-marker (make-marker)
               erc-server-process (erc-networks-tests--create-live-proc)
               erc-networks--id (erc-networks--id-create nil))
-        (should-not (erc-networks--rename-server-buffer erc-server-process))
+        (set-process-sentinel erc-server-process #'ignore)
+        (erc-display-prompt nil (point-max))
+        (set-marker erc-insert-marker (pos-bol))
+        (erc-display-message nil 'notice (current-buffer) "notice")
+        (with-silent-modifications
+          (should-not (erc-networks--rename-server-buffer erc-server-process)))
         (should (eq erc-active-buffer old-buf))
         (should-not (erc-server-process-alive))
         (should (string= (buffer-name) "irc.foonet.org"))
index 795864a2cc240f118af2fb9871b9a551c87b19ed..b2f24aa718e26612119171c80cea301f910f4f00 100644 (file)
     ;;
     (cl-letf (((symbol-function 'erc-process-input-line)
                (lambda (&rest _)
-                 (insert-before-markers
-                  (erc-display-message-highlight 'notice "echo: one\n"))))
+                 (erc-display-message
+                  nil 'notice (current-buffer) "echo: one\n")))
               ((symbol-function 'erc-command-no-process-p)
                (lambda (&rest _) t)))
       (ert-info ("Create ring, populate, recall")