kmacro-x-mc-extra.el (3654B)
1 ;;; kmacro-x-mc-extra.el --- Additional functionality for the multiple cursors -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2022-2025 Wojciech Siewierski 4 5 ;; Author: Wojciech Siewierski 6 ;; URL: https://github.com/vifon/kmacro-x.el 7 ;; Keywords: convenience 8 ;; Version: 0.9 9 10 ;; This program is free software; you can redistribute it and/or modify 11 ;; it under the terms of the GNU General Public License as published by 12 ;; the Free Software Foundation, either version 3 of the License, or 13 ;; (at your option) any later version. 14 15 ;; This program is distributed in the hope that it will be useful, 16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 ;; GNU General Public License for more details. 19 20 ;; You should have received a copy of the GNU General Public License 21 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 22 23 ;;; Commentary: 24 25 ;; Non-critical and/or experimental features for the multiple cursors 26 ;; based on keyboard macros. 27 28 ;;; Code: 29 30 (require 'kmacro-x-mc) 31 32 (require 'rect) 33 34 (defgroup kmacro-x-mc-extra nil 35 "Additional functionality for the multiple cursors." 36 :group 'kmacro-x-mc) 37 38 ;;;###autoload 39 (defun kmacro-x-mc-mark-at-click (event) 40 "Toggle the fake cursor at the mouse position. 41 42 EVENT is the mouse click event. 43 44 Some code borrowed from `mc/toggle-cursor-on-click'." 45 (interactive "e") 46 (mouse-minibuffer-check event) 47 (cancel-kbd-macro-events) 48 (let ((position (event-end event))) 49 (unless (windowp (posn-window position)) 50 (user-error "Position not in text area of window")) 51 (select-window (posn-window position)) 52 (let ((point (posn-point position))) 53 (unless (catch 'cursor 54 (dolist (ov (overlays-at point)) 55 (unless (kmacro-x-mc--main-cursor-p ov) 56 (delete-overlay ov) 57 (setq kmacro-x-mc-cursors 58 (delete ov kmacro-x-mc-cursors)) 59 (throw 'cursor ov)))) 60 (let ((ov (make-overlay point (1+ point) nil t))) 61 (unless kmacro-x-mc-mode 62 (let ((kmacro-x-mc-mark-whole-symbol nil) 63 (kmacro-x-mc--bounds-override (cons (point) (1+ (point))))) 64 (kmacro-x-mc-mode 1))) 65 (overlay-put ov 'face 'kmacro-x-mc-cursor-face) 66 (overlay-put ov 'offsets '(0 . 0)) 67 (push ov kmacro-x-mc-cursors)))))) 68 69 ;;;###autoload 70 (defun kmacro-x-mc-mark-next-or-rect () 71 "A smart version of `kmacro-x-mc-mark-next' with a fallback. 72 73 Acts just like `kmacro-x-mc-mark-next' but falls back to 74 `rectangle-mark-mode' when there is no selection." 75 (interactive) 76 (require 'rect) 77 (if (and (not rectangle-mark-mode) 78 (use-region-p)) 79 (progn 80 (setq this-command 'kmacro-x-mc-mark-next) 81 (kmacro-x-mc-mark-next)) 82 (unless rectangle-mark-mode 83 (rectangle-mark-mode 1)) 84 (rectangle-next-line))) 85 86 ;;;###autoload 87 (defun kmacro-x-mc-pause () 88 "Pause the macro recording to allow free movement. 89 90 Intended to be bound to `C-v' in `kmacro-x-mc-mode-map', calls 91 `scroll-up-command' when the macro is already paused." 92 (interactive) 93 (if defining-kbd-macro 94 (progn 95 (cancel-kbd-macro-events) 96 (save-mark-and-excursion 97 (end-kbd-macro) 98 (message "%s" (substitute-command-keys 99 "Macro recording paused, press \ 100 `\\[exit-recursive-edit]' to exit recursive edit")) 101 (recursive-edit) 102 (start-kbd-macro 'append 'no-exec))) 103 (call-interactively #'scroll-up-command))) 104 105 (provide 'kmacro-x-mc-extra) 106 ;;; kmacro-x-mc-extra.el ends here