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)))
(defun mc/handle-loop-condition (error-message)
(ecase mc/cycle-looping-behaviour
(error (error error-message))
(warn (message error-message))
(continue nil)))
(defun mc/cycle (next-cursor fallback-cursor loop-message)
(when (null next-cursor)
(mc/handle-loop-condition loop-message)
(setf next-cursor fallback-cursor))
(mc/create-fake-cursor-at-point) (mc/create-fake-cursor-at-point)
(mc/pop-state-from-overlay next-cursor) (mc/pop-state-from-overlay next-cursor)
(recenter)) (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 extreme (sequence predicate &optional key)
(interactive "P") "Returns the most predicate-y element of sequence; equivalent
(let ((prev-cursor (mc/prev-cursor-before-point))) to (first (sort sequence text)). The extreme of the empty list is
(cond always nil."
(prev-cursor (let ((extreme (first sequence)))
(mc/create-fake-cursor-at-point) (dolist (i (rest sequence))
(mc/pop-state-from-overlay prev-cursor) (when (funcall predicate
(recenter)) (funcall (or key 'identity) i)
(error-if-no-previous-cursor (funcall (or key 'identity) extreme))
(error "We're already at the first cursor")) (setf extreme i)))
(t extreme))
(mc/cycle-forward t)))))
(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)