diff --git a/boon-arguments.el b/boon-arguments.el index 286f3ea..d8ee6b4 100644 --- a/boon-arguments.el +++ b/boon-arguments.el @@ -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 diff --git a/boon-main.el b/boon-main.el index 2adf229..a90f295 100644 --- a/boon-main.el +++ b/boon-main.el @@ -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."