Clean up multiple-cursors-core

This commit is contained in:
Magnar Sveen 2012-06-21 15:46:16 +02:00
parent 8d491719f6
commit 87169c884c
2 changed files with 37 additions and 25 deletions

View File

@ -8,7 +8,7 @@ mark-multiple if point and mark is on different columns."
(interactive) (interactive)
(when (not (use-region-p)) (when (not (use-region-p))
(error "Mark a set of lines first.")) (error "Mark a set of lines first."))
(mc/remove-additional-cursors) (mc/remove-fake-cursors)
(let* ((point-line (line-number-at-pos)) (let* ((point-line (line-number-at-pos))
(mark-line (progn (exchange-point-and-mark) (line-number-at-pos))) (mark-line (progn (exchange-point-and-mark) (line-number-at-pos)))
(navigation-func (if (< point-line mark-line) 'previous-line 'next-line))) (navigation-func (if (< point-line mark-line) 'previous-line 'next-line)))

View File

@ -54,7 +54,7 @@ highlights the entire width of the window."
(setq mark-active (overlay-get o 'mark-active)) (setq mark-active (overlay-get o 'mark-active))
(when (boundp 'er/history) (setq er/history (overlay-get o 'er/history)))) (when (boundp 'er/history) (setq er/history (overlay-get o 'er/history))))
(defun mc/clean-up-state-overlay (o) (defun mc/remove-fake-cursor (o)
"Delete overlay with state, including dependent overlays and markers." "Delete overlay with state, including dependent overlays and markers."
(set-marker (overlay-get o 'point) nil) (set-marker (overlay-get o 'point) nil)
(set-marker (overlay-get o 'mark) nil) (set-marker (overlay-get o 'mark) nil)
@ -64,7 +64,7 @@ highlights the entire width of the window."
(defun mc/pop-state-from-overlay (o) (defun mc/pop-state-from-overlay (o)
"Restore the state stored in given overlay and then remove the overlay." "Restore the state stored in given overlay and then remove the overlay."
(mc/restore-state-from-overlay o) (mc/restore-state-from-overlay o)
(mc/clean-up-state-overlay o)) (mc/remove-fake-cursor o))
(defun mc/delete-region-overlay (o) (defun mc/delete-region-overlay (o)
"Remove the dependent region overlay for a given cursor overlay." "Remove the dependent region overlay for a given cursor overlay."
@ -88,18 +88,28 @@ It works by moving point to the fake cursor, setting
up the proper kill-ring, and then removing the cursor. up the proper kill-ring, and then removing the cursor.
After executing the command, it sets up a new fake After executing the command, it sets up a new fake
cursor with updated info." cursor with updated info."
(let ((current-state (mc/store-current-state-in-overlay (let ((annoying-arrows-mode nil))
(make-overlay (point) (point) nil nil t))) (mc/save-excursion
(annoying-arrows-mode nil)) (mc/for-each-fake-cursor
(save-excursion (mc/pop-state-from-overlay cursor)
(mapc #'(lambda (o)
(when (eq (overlay-get o 'type) 'additional-cursor)
(mc/pop-state-from-overlay o)
(ignore-errors (ignore-errors
(call-interactively cmd) (call-interactively cmd)
(when deactivate-mark (deactivate-mark)) (when deactivate-mark (deactivate-mark))
(mc/create-fake-cursor-at-point)))) (mc/create-fake-cursor-at-point))))))
(defmacro mc/for-each-fake-cursor (&rest forms)
"Runs the body for each fake cursor, bound to the name cursor"
`(mapc #'(lambda (cursor)
(when (eq (overlay-get cursor 'type) 'additional-cursor)
,@forms))
(overlays-in (point-min) (point-max)))) (overlays-in (point-min) (point-max))))
(defmacro mc/save-excursion (&rest forms)
"Saves and restores all the state that multiple-cursors cares about."
`(let ((current-state (mc/store-current-state-in-overlay
(make-overlay (point) (point) nil nil t))))
(overlay-put current-state 'type 'original-cursor)
(save-excursion ,@forms)
(mc/pop-state-from-overlay current-state))) (mc/pop-state-from-overlay current-state)))
(defun mc/execute-this-command-for-all-cursors () (defun mc/execute-this-command-for-all-cursors ()
@ -117,14 +127,12 @@ cursors."
(message "Skipping %S" this-original-command) (message "Skipping %S" this-original-command)
(mc/execute-command-for-all-fake-cursors this-original-command)))) (mc/execute-command-for-all-fake-cursors this-original-command))))
(defun mc/remove-additional-cursors () (defun mc/remove-fake-cursors ()
"Remove all fake cursors. "Remove all fake cursors.
Do not use to conclude editing with multiple cursors. For that Do not use to conclude editing with multiple cursors. For that
you should disable multiple-cursors-mode." you should disable multiple-cursors-mode."
(mapc #'(lambda (o) (mc/for-each-fake-cursor
(when (eq (overlay-get o 'type) 'additional-cursor) (mc/remove-fake-cursor cursor)))
(mc/clean-up-state-overlay o)))
(overlays-in (point-min) (point-max))))
(defun mc/keyboard-quit () (defun mc/keyboard-quit ()
"Deactivate mark if there are any active, otherwise exit multiple-cursors-mode." "Deactivate mark if there are any active, otherwise exit multiple-cursors-mode."
@ -146,10 +154,10 @@ multiple cursors editing.")
(define-minor-mode multiple-cursors-mode (define-minor-mode multiple-cursors-mode
"Mode while multiple cursors are active." "Mode while multiple cursors are active."
nil " mc" mc/keymap nil " mc" mc/keymap
(cond ((not multiple-cursors-mode) (if multiple-cursors-mode
(add-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t t)
(remove-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t) (remove-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t)
(mc/remove-additional-cursors)) (mc/remove-fake-cursors)))
(t (add-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t t))))
(defvar mc--unsupported-cmds '() (defvar mc--unsupported-cmds '()
"List of commands that does not work well with multiple cursors. "List of commands that does not work well with multiple cursors.
@ -168,6 +176,10 @@ from being executed if in multiple-cursors-mode."
;; Commands that make a giant mess of multiple cursors ;; Commands that make a giant mess of multiple cursors
(unsupported-cmd yank-pop) (unsupported-cmd yank-pop)
;; Commands to run only once (not yet in use)
(setq mc--cmds-run-once '(mark-next-like-this
save-buffer))
;; Commands that should be mirrored by all cursors ;; Commands that should be mirrored by all cursors
(setq mc--cmds '(mc/keyboard-quit (setq mc--cmds '(mc/keyboard-quit
self-insert-command self-insert-command