improve multiple cursor support

This commit is contained in:
Jean-Philippe Bernardy 2015-10-15 22:00:16 +02:00
parent 20a1a90d11
commit aa99d82969
2 changed files with 55 additions and 40 deletions

View file

@ -99,6 +99,9 @@
"Normalize the region REG by making sure beginning < end."
(cons (min (cdr reg) (car reg)) (max (cdr reg) (car reg))))
(defun boon-reg-to-markers (reg)
(cons (copy-marker (car reg)) (copy-marker (cdr reg))))
(defun boon-borders (reg how-much)
"Given a normalized region REG, return its borders, whose size is HOW-MUCH."
(list (cons (cdr reg) (- (cdr reg) how-much))
@ -120,38 +123,50 @@ This function is meant to be called interactively."
(interactive (list (boon-spec-region "select borders")))
(cons 'region (mapcar 'boon-content (mapcar 'boon-normalize-reg regs))))
(defun boon-multiple-cursor-regs ()
"all regions defined by multiple-cursors-mode, and outside."
(cons (cons (mark) (point))
(if (and (bound-and-true-p multiple-cursors-mode)
(memq this-command mc/cmds-to-run-once))
(mapcar (lambda (o) (cons (marker-position (overlay-get o 'mark)) (marker-position (overlay-get o 'point))))
(mc/all-fake-cursors))
nil)))
(defun boon-spec-region (msg)
"Specify a region concisely using the keyboard.
The prompt (as MSG) is displayed. This function actually returns
a list of regions, in the form ((beginning . end) ...)"
(if (use-region-p) (list (cons (region-beginning) (region-end)))
;; TODO: detect multiple cursors and take all regions; for those commands that do set the multiple cursors.
(let (current-prefix-arg
;; this code fiddles with the prefix arg; but if we do
;; not hide our fiddling, the next command will use
;; the prefix arg that we have set.
(orig (point))
(km boon-select-map))
(setq current-prefix-arg 0)
(while (and km (keymapp km))
(let ((last-char (read-char (format "%s %s" msg current-prefix-arg))))
(if (and (>= last-char ?0) (<= last-char ?9))
(setq current-prefix-arg (+ (- last-char ?0) (* 10 current-prefix-arg )))
(setq km (lookup-key km (vector last-char))))))
(when (eq current-prefix-arg 0)
(setq current-prefix-arg nil))
(if km
(let (regs final)
(save-excursion
(setq regs (call-interactively km))
(setq final (point)))
;; (message (format "Reg = %s" regs))
(if (and regs
(listp regs)
(eq (car regs) 'region))
(cdr regs)
(list (cons orig final))))
(error "Unknown region specifier")))))
(if (use-region-p)
(boon-multiple-cursor-regs)
(let (current-prefix-arg
;; this code fiddles with the prefix arg; but if we do not
;; hide our fiddling, the next command will use the prefix
;; arg that we have set. So we dynamically bind another
;; current-prefix-arg here.
(km boon-select-map))
(setq current-prefix-arg 0)
(while (and km (keymapp km))
(let ((last-char (read-char (format "%s %s" msg current-prefix-arg))))
(if (and (>= last-char ?0) (<= last-char ?9))
(setq current-prefix-arg (+ (- last-char ?0) (* 10 current-prefix-arg )))
(setq km (lookup-key km (vector last-char))))))
(when (eq current-prefix-arg 0)
(setq current-prefix-arg nil))
(if km (apply 'append (mapcar (lambda (in-reg)
(let (regs final (orig (cdr in-reg)))
(save-excursion
;; (set-marker (mark-marker) (car in-reg))
(goto-char orig)
(setq regs (call-interactively km))
(setq final (point)))
(message "in-reg=%s regs=%s orig=%s final=%s" in-reg regs orig final)
(if (and regs
(listp regs)
(eq (car regs) 'region))
(cdr regs)
(list (cons orig final)))))
(boon-multiple-cursor-regs)))
(error "Unknown region specifier")))))
(provide 'boon-arguments)
;;; boon-arguments.el ends here

View file

@ -377,18 +377,12 @@ line."
(defun boon-lay-multiple-cursors (place-cursor regs)
"Create multiple cursor regions, using REGS.
If there is more than one, use mc/create-fake-cursor-at-point."
;; (mc/remove-fake-cursors)
;; (message "RUNNING LAY")
(mc/remove-fake-cursors)
(dolist (reg (cdr regs))
(funcall place-cursor reg)
(message "FK")
(mc/create-fake-cursor-at-point))
(funcall place-cursor (car regs))
;; (message "MC? %d" (mc/num))
(mc/maybe-multiple-cursors-mode)
;; (message "LAY: %s %d %d" (mc/all-fake-cursors) (point) (mark))
)
(mc/maybe-multiple-cursors-mode))
(defun boon-mark-region (regs)
"Mark the regions REGS."
@ -413,7 +407,9 @@ If there is more than one, use mc/create-fake-cursor-at-point."
(defun boon-take-region (regs)
"Kill the region given as REGS."
(interactive (list (boon-spec-region "take")))
(dolist (reg regs)
(message "boon-take-region: REGS=%s" regs)
(dolist (reg (mapcar 'boon-reg-to-markers regs))
(message "boon-take-region: killing: %s" reg)
(kill-region (car reg) (cdr reg))))
@ -437,10 +433,14 @@ If there is more than one, use mc/create-fake-cursor-at-point."
(defun boon-substitute-region (regs)
"Kill the regions REGS, and switch to insertion mode."
(interactive (list (boon-spec-region "replace")))
;; (dolist (reg (cdr regs)) (goto-char (cdr reg)))
(boon-lay-multiple-cursors (lambda (reg) (goto-char (cdr reg))) regs)
(boon-take-region regs)
(boon-set-insert-state))
(let ((markers (mapcar 'boon-reg-to-markers regs)))
;; use markers so that deleting things does not mess the positions
(boon-take-region regs)
(deactivate-mark t)
(boon-lay-multiple-cursors (lambda (reg)
(goto-char (cdr reg)))
markers)
(boon-set-insert-state)))
(defun boon-replace-by-character (replacement)
"Replace the character at point, or region if it is active, by the REPLACEMENT character."