Skip to content

Commit

Permalink
feat: Detect ipython, use vertical movements.
Browse files Browse the repository at this point in the history
Before this change, MisTTY always used only horizontal movement, no
matter mistty-vertical-multiline-prompt-regexps.

With this change, mistty-vertical-multiline-prompt-regexps is taken into
account to enable or not vertical moves. The default value of this
option detects the default ipython prompts.
  • Loading branch information
szermatt committed Dec 29, 2024
1 parent 24735c2 commit 46b038c
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 75 deletions.
19 changes: 18 additions & 1 deletion mistty.el
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Set to 0 to disable truncation."
:type 'natnum)

(defcustom mistty-move-vertically-regexps
'("^In \\[0-9+\\]: " ; ipython
'("^In \\[[0-9]+\\]: " ; ipython
)
"Regexp that signals availability of vertical moves.
Expand Down Expand Up @@ -1570,6 +1570,11 @@ Also updates prompt and point."
(mistty--set-sync-mark-from-end prompt-beg)
(setq mistty--has-active-prompt (> cursor prompt-beg)))))

(let ((v (and on-prompt (mistty--can-move-vertically-p))))
(unless (eq v mistty--can-move-vertically)
(mistty-log "Can move vertically: %s" v)
(setq mistty--can-move-vertically v)))

;; Turn mistty-forbid-edit on or off
(let ((forbid-edit (mistty--match-forbid-edit-regexp-p)))
(cond
Expand Down Expand Up @@ -1684,6 +1689,18 @@ cursor to be considered."
(setq match t))))
match)))

(defun mistty--can-move-vertically-p ()
"Check whether vertical moves are allowed, return either nil or t.
Does not update `mistty--can-move-vertically'."
(save-excursion
(goto-char mistty-sync-marker)
(catch 'mistty-end-loop
(dolist (regexp mistty-move-vertically-regexps)
(when (search-forward-regexp regexp (pos-eol) 'noerror)
(throw 'mistty-end-loop t)))
nil)))

(defun mistty--sync-buffer (source-buffer &optional quick)
"Copy the sync region of SOURCE-BUFFER to the current buffer.
Expand Down
145 changes: 71 additions & 74 deletions test/mistty-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -4435,95 +4435,92 @@

(ert-deftest mistty-test-ipython-reconcile-in-another-line ()
(mistty-with-test-buffer (:shell ipython)
(let ((mistty--can-move-vertically t))
(mistty--send-string mistty-proc "for i in (1, 2, 3):\nif i > 2:\nprint(i)")
(mistty-wait-for-output :test (lambda () (save-excursion
(goto-char (point-min))
(and (search-forward "...:" nil 'noerror)
(search-forward "...:" nil 'noerror)))))
(let ((start (save-excursion
(goto-char (point-min))
(search-forward "In [")
(match-beginning 0))))
(mistty--send-string mistty-proc "for i in (1, 2, 3):\nif i > 2:\nprint(i)")
(mistty-wait-for-output :test (lambda () (save-excursion
(goto-char (point-min))
(and (search-forward "...:" nil 'noerror)
(search-forward "...:" nil 'noerror)))))
(let ((start (save-excursion
(goto-char (point-min))
(search-forward "In [")
(match-beginning 0))))


(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start)))
(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start)))

(mistty-run-command
(goto-char (point-min))
(search-forward "(1, 2, 3)")
(replace-match "(10, 11)" nil t)
(goto-char (point-min)))
(mistty-run-command
(goto-char (point-min))
(search-forward "(1, 2, 3)")
(replace-match "(10, 11)" nil t)
(goto-char (point-min)))

(should (equal (concat "In [1]: for i in (10, 11):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start)))))))
(should (equal (concat "In [1]: for i in (10, 11):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start))))))

(ert-deftest mistty-test-ipython-reconcile-multiline-delete ()
(mistty-with-test-buffer (:shell ipython)
(let ((mistty--can-move-vertically t))
(mistty--send-string mistty-proc "for i in (1, 2, 3):\nif i > 2:\nprint(i)")
(mistty-wait-for-output :test (lambda () (save-excursion
(goto-char (point-min))
(and (search-forward "...:" nil 'noerror)
(search-forward "...:" nil 'noerror)))))
(let ((start (save-excursion
(goto-char (point-min))
(search-forward "In [")
(match-beginning 0))))

(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start)))
(mistty--send-string mistty-proc "for i in (1, 2, 3):\nif i > 2:\nprint(i)")
(mistty-wait-for-output :test (lambda () (save-excursion
(goto-char (point-min))
(and (search-forward "...:" nil 'noerror)
(search-forward "...:" nil 'noerror)))))
(let ((start (save-excursion
(goto-char (point-min))
(search-forward "In [")
(match-beginning 0))))

(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start)))

(mistty-run-command
(goto-char (point-min))
(search-forward-regexp "if i > 2\\(.\\|\n\\)*print(i)")
(replace-match "total += i" nil t))
(goto-char (point-min))
(mistty-run-command
(goto-char (point-min))
(search-forward-regexp "if i > 2\\(.\\|\n\\)*print(i)")
(replace-match "total += i" nil t))
(goto-char (point-min))

(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: total += i")
(mistty-test-content :start start)))))))
(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: total += i")
(mistty-test-content :start start))))))

(ert-deftest mistty-test-ipython-move-cursor ()
(mistty-with-test-buffer (:shell ipython)
(let ((mistty--can-move-vertically t))
(mistty--send-string mistty-proc "for i in (1, 2, 3):\nif i > 2:\nprint(i)")
(mistty-wait-for-output :test (lambda () (save-excursion
(goto-char (point-min))
(and (search-forward "...:" nil 'noerror)
(search-forward "...:" nil 'noerror)))))
(let ((start (save-excursion
(goto-char (point-min))
(search-forward "In [")
(match-beginning 0))))
(mistty--send-string mistty-proc "for i in (1, 2, 3):\nif i > 2:\nprint(i)")
(mistty-wait-for-output :test (lambda () (save-excursion
(goto-char (point-min))
(and (search-forward "...:" nil 'noerror)
(search-forward "...:" nil 'noerror)))))
(let ((start (save-excursion
(goto-char (point-min))
(search-forward "In [")
(match-beginning 0))))


(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)<>")
(mistty-test-content :start start :show (point))))
(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)<>")
(mistty-test-content :start start :show (point))))

(mistty-run-command
(goto-char (point-min))
(mistty-test-goto "(1, 2, 3)"))
(mistty-run-command
(goto-char (point-min))
(mistty-test-goto "(1, 2, 3)"))

(should (equal (concat "In [1]: for i in <>(1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start :show (point))))
(should (equal (concat "In [1]: for i in <>(1, 2, 3):\n"
" ...: if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start :show (point))))

(mistty-run-command
(goto-char (point-min))
(mistty-test-goto "if"))
(mistty-run-command
(goto-char (point-min))
(mistty-test-goto "if"))

(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: <>if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start :show (point))))))))
(should (equal (concat "In [1]: for i in (1, 2, 3):\n"
" ...: <>if i > 2:\n"
" ...: print(i)")
(mistty-test-content :start start :show (point)))))))

0 comments on commit 46b038c

Please sign in to comment.