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:
Marco Baringer 2012-10-10 13:39:28 +02:00
parent 324d9354b5
commit e4adefc04e

View File

@ -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)