mirror of
https://github.com/magnars/multiple-cursors.el.git
synced 2025-10-13 13:03:03 +00:00
Fix issues with mc/cycle-(backward|forward) where the cycling was dependent on not having an active mark.
This patch also adds two utility functions mc/first-cursor-after and mc/last-cursor-before.
This commit is contained in:
parent
324d9354b5
commit
e4adefc04e
@ -54,31 +54,63 @@
|
|||||||
(setq prev cursor))))
|
(setq prev cursor))))
|
||||||
prev))
|
prev))
|
||||||
|
|
||||||
(defun mc/cycle-forward (&optional error-if-no-next-cursor)
|
(defcustom mc/cycle-looping-behaviour 'continue
|
||||||
(interactive "P")
|
"What to do if asked to cycle beyond the last cursor or before the first cursor."
|
||||||
(let ((next-cursor (mc/next-cursor-after-point)))
|
:type '(radio (const :tag "Loop around to beginning/end of document." continue)
|
||||||
(cond
|
(const :tag "Warn and then loop around." warn)
|
||||||
(next-cursor
|
(const :tag "Signal an error." error)))
|
||||||
(mc/create-fake-cursor-at-point)
|
|
||||||
(mc/pop-state-from-overlay next-cursor)
|
|
||||||
(recenter))
|
|
||||||
(error-if-no-next-cursor
|
|
||||||
(error "We're already at the last cursor"))
|
|
||||||
(t
|
|
||||||
(mc/cycle-backward t)))))
|
|
||||||
|
|
||||||
(defun mc/cycle-backward (&optional error-if-no-previous-cursor)
|
(defun mc/handle-loop-condition (error-message)
|
||||||
(interactive "P")
|
(ecase mc/cycle-looping-behaviour
|
||||||
(let ((prev-cursor (mc/prev-cursor-before-point)))
|
(error (error error-message))
|
||||||
(cond
|
(warn (message error-message))
|
||||||
(prev-cursor
|
(continue nil)))
|
||||||
(mc/create-fake-cursor-at-point)
|
|
||||||
(mc/pop-state-from-overlay prev-cursor)
|
(defun mc/cycle (next-cursor fallback-cursor loop-message)
|
||||||
(recenter))
|
(when (null next-cursor)
|
||||||
(error-if-no-previous-cursor
|
(mc/handle-loop-condition loop-message)
|
||||||
(error "We're already at the first cursor"))
|
(setf next-cursor fallback-cursor))
|
||||||
(t
|
(mc/create-fake-cursor-at-point)
|
||||||
(mc/cycle-forward t)))))
|
(mc/pop-state-from-overlay next-cursor)
|
||||||
|
(recenter))
|
||||||
|
|
||||||
|
(defun extreme (sequence predicate &optional key)
|
||||||
|
"Returns the most predicate-y element of sequence; equivalent
|
||||||
|
to (first (sort sequence text)). The extreme of the empty list is
|
||||||
|
always nil."
|
||||||
|
(let ((extreme (first sequence)))
|
||||||
|
(dolist (i (rest sequence))
|
||||||
|
(when (funcall predicate
|
||||||
|
(funcall (or key 'identity) i)
|
||||||
|
(funcall (or key 'identity) extreme))
|
||||||
|
(setf extreme i)))
|
||||||
|
extreme))
|
||||||
|
|
||||||
|
(defun mc/first-cursor-after (point)
|
||||||
|
"Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)."
|
||||||
|
(extreme (remove-if (lambda (cursor)
|
||||||
|
(< (mc/cursor-beg cursor) point))
|
||||||
|
(mc/all-fake-cursors))
|
||||||
|
'< 'mc/cursor-beg))
|
||||||
|
|
||||||
|
(defun mc/last-cursor-before (point)
|
||||||
|
"Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)."
|
||||||
|
(extreme (remove-if (lambda (cursor)
|
||||||
|
(> (mc/cursor-end cursor) point))
|
||||||
|
(mc/all-fake-cursors))
|
||||||
|
'> 'mc/cursor-end))
|
||||||
|
|
||||||
|
(defun mc/cycle-forward ()
|
||||||
|
(interactive)
|
||||||
|
(mc/cycle (mc/next-cursor-after-point)
|
||||||
|
(mc/first-cursor-after (point-min))
|
||||||
|
"We're already at the last cursor."))
|
||||||
|
|
||||||
|
(defun mc/cycle-backward ()
|
||||||
|
(interactive)
|
||||||
|
(mc/cycle (mc/prev-cursor-before-point)
|
||||||
|
(mc/last-cursor-before (point-max))
|
||||||
|
"We're already at the last cursor"))
|
||||||
|
|
||||||
(define-key mc/keymap (kbd "C-v") 'mc/cycle-forward)
|
(define-key mc/keymap (kbd "C-v") 'mc/cycle-forward)
|
||||||
(define-key mc/keymap (kbd "M-v") 'mc/cycle-backward)
|
(define-key mc/keymap (kbd "M-v") 'mc/cycle-backward)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user