Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

767 lines
33 KiB

  1. ;;; multiple-cursors-core.el --- An experiment in multiple cursors for emacs.
  2. ;; Copyright (C) 2012 Magnar Sveen
  3. ;; Author: Magnar Sveen <magnars@gmail.com>
  4. ;; Keywords: editing cursors
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; This file contains the core functionality of multiple-cursors.
  17. ;; Please see multiple-cursors.el for more commentary.
  18. ;;; Code:
  19. (require 'cl-lib)
  20. (require 'rect)
  21. (defvar mc--read-char)
  22. (defface mc/cursor-face
  23. '((t (:inverse-video t)))
  24. "The face used for fake cursors"
  25. :group 'multiple-cursors)
  26. (defface mc/region-face
  27. '((t :inherit region))
  28. "The face used for fake regions"
  29. :group 'multiple-cursors)
  30. (defmacro mc/add-fake-cursor-to-undo-list (&rest forms)
  31. "Make sure point is in the right place when undoing"
  32. (let ((uc (make-symbol "undo-cleaner")))
  33. `(let ((,uc (cons 'apply (cons 'deactivate-cursor-after-undo (list id)))))
  34. (setq buffer-undo-list (cons ,uc buffer-undo-list))
  35. ,@forms
  36. (if (eq ,uc (car buffer-undo-list)) ;; if nothing has been added to the undo-list
  37. (setq buffer-undo-list (cdr buffer-undo-list)) ;; then pop the cleaner right off again
  38. (setq buffer-undo-list ;; otherwise add a function to activate this cursor
  39. (cons (cons 'apply (cons 'activate-cursor-for-undo (list id))) buffer-undo-list))))))
  40. (defun mc/all-fake-cursors (&optional start end)
  41. (cl-remove-if-not 'mc/fake-cursor-p
  42. (overlays-in (or start (point-min))
  43. (or end (point-max)))))
  44. (defmacro mc/for-each-fake-cursor (&rest forms)
  45. "Runs the body for each fake cursor, bound to the name cursor"
  46. `(mapc #'(lambda (cursor) ,@forms)
  47. (mc/all-fake-cursors)))
  48. (defmacro mc/save-excursion (&rest forms)
  49. "Saves and restores all the state that multiple-cursors cares about."
  50. (let ((cs (make-symbol "current-state")))
  51. `(let ((,cs (mc/store-current-state-in-overlay
  52. (make-overlay (point) (point) nil nil t))))
  53. (overlay-put ,cs 'type 'original-cursor)
  54. (save-excursion ,@forms)
  55. (mc/pop-state-from-overlay ,cs))))
  56. (defun mc--compare-by-overlay-start (o1 o2)
  57. (< (overlay-start o1) (overlay-start o2)))
  58. (defmacro mc/for-each-cursor-ordered (&rest forms)
  59. "Runs the body for each cursor, fake and real, bound to the name cursor"
  60. (let ((rci (make-symbol "real-cursor-id")))
  61. `(let ((,rci (overlay-get (mc/create-fake-cursor-at-point) 'mc-id)))
  62. (mapc #'(lambda (cursor)
  63. (when (mc/fake-cursor-p cursor)
  64. ,@forms))
  65. (sort (overlays-in (point-min) (point-max)) 'mc--compare-by-overlay-start))
  66. (mc/pop-state-from-overlay (mc/cursor-with-id ,rci)))))
  67. (defmacro mc/save-window-scroll (&rest forms)
  68. "Saves and restores the window scroll position"
  69. (let ((p (make-symbol "p"))
  70. (s (make-symbol "start"))
  71. (h (make-symbol "hscroll")))
  72. `(let ((,p (set-marker (make-marker) (point)))
  73. (,s (set-marker (make-marker) (window-start)))
  74. (,h (window-hscroll)))
  75. ,@forms
  76. (goto-char ,p)
  77. (set-window-start nil ,s t)
  78. (set-window-hscroll nil ,h)
  79. (set-marker ,p nil)
  80. (set-marker ,s nil))))
  81. (defun mc/make-cursor-overlay-at-eol (pos)
  82. "Create overlay to look like cursor at end of line."
  83. (let ((overlay (make-overlay pos pos nil nil nil)))
  84. (overlay-put overlay 'after-string (propertize " " 'face 'mc/cursor-face))
  85. overlay))
  86. (defun mc/make-cursor-overlay-inline (pos)
  87. "Create overlay to look like cursor inside text."
  88. (let ((overlay (make-overlay pos (1+ pos) nil nil nil)))
  89. (overlay-put overlay 'face 'mc/cursor-face)
  90. overlay))
  91. (defun mc/make-cursor-overlay-at-point ()
  92. "Create overlay to look like cursor.
  93. Special case for end of line, because overlay over a newline
  94. highlights the entire width of the window."
  95. (if (eolp)
  96. (mc/make-cursor-overlay-at-eol (point))
  97. (mc/make-cursor-overlay-inline (point))))
  98. (defun mc/make-region-overlay-between-point-and-mark ()
  99. "Create overlay to look like active region."
  100. (let ((overlay (make-overlay (mark) (point) nil nil t)))
  101. (overlay-put overlay 'face 'mc/region-face)
  102. (overlay-put overlay 'type 'additional-region)
  103. overlay))
  104. (defvar mc/cursor-specific-vars '(transient-mark-mode
  105. kill-ring
  106. kill-ring-yank-pointer
  107. mark-ring
  108. mark-active
  109. yank-undo-function
  110. autopair-action
  111. autopair-wrap-action
  112. er/history)
  113. "A list of vars that need to be tracked on a per-cursor basis.")
  114. (defun mc/store-current-state-in-overlay (o)
  115. "Store relevant info about point and mark in the given overlay."
  116. (overlay-put o 'point (set-marker (make-marker) (point)))
  117. (overlay-put o 'mark (set-marker (make-marker) (mark)))
  118. (dolist (var mc/cursor-specific-vars)
  119. (when (boundp var) (overlay-put o var (symbol-value var))))
  120. o)
  121. (defun mc/restore-state-from-overlay (o)
  122. "Restore point and mark from stored info in the given overlay."
  123. (goto-char (overlay-get o 'point))
  124. (set-marker (mark-marker) (overlay-get o 'mark))
  125. (dolist (var mc/cursor-specific-vars)
  126. (when (boundp var) (set var (overlay-get o var)))))
  127. (defun mc/remove-fake-cursor (o)
  128. "Delete overlay with state, including dependent overlays and markers."
  129. (set-marker (overlay-get o 'point) nil)
  130. (set-marker (overlay-get o 'mark) nil)
  131. (mc/delete-region-overlay o)
  132. (delete-overlay o))
  133. (defun mc/pop-state-from-overlay (o)
  134. "Restore the state stored in given overlay and then remove the overlay."
  135. (mc/restore-state-from-overlay o)
  136. (mc/remove-fake-cursor o))
  137. (defun mc/delete-region-overlay (o)
  138. "Remove the dependent region overlay for a given cursor overlay."
  139. (ignore-errors
  140. (delete-overlay (overlay-get o 'region-overlay))))
  141. (defvar mc--current-cursor-id 0
  142. "Var to store increasing id of fake cursors, used to keep track of them for undo.")
  143. (defun mc/create-cursor-id ()
  144. "Returns a unique cursor id"
  145. (cl-incf mc--current-cursor-id))
  146. (defvar mc--max-cursors-original nil
  147. "This variable maintains the original maximum number of cursors.
  148. When `mc/create-fake-cursor-at-point' is called and
  149. `mc/max-cursors' is overridden, this value serves as a backup so
  150. that `mc/max-cursors' can take on a new value. When
  151. `mc/remove-fake-cursors' is called, the values are reset.")
  152. (defcustom mc/max-cursors nil
  153. "Safety ceiling for the number of active cursors.
  154. If your emacs slows down or freezes when using too many cursors,
  155. customize this value appropriately.
  156. Cursors will be added until this value is reached, at which point
  157. you can either temporarily override the value or abort the
  158. operation entirely.
  159. If this value is nil, there is no ceiling."
  160. :type '(integer)
  161. :group 'multiple-cursors)
  162. (defun mc/create-fake-cursor-at-point (&optional id)
  163. "Add a fake cursor and possibly a fake active region overlay based on point and mark.
  164. Saves the current state in the overlay to be restored later."
  165. (unless mc--max-cursors-original
  166. (setq mc--max-cursors-original mc/max-cursors))
  167. (when mc/max-cursors
  168. (unless (< (mc/num-cursors) mc/max-cursors)
  169. (if (yes-or-no-p (format "%d active cursors. Continue? " (mc/num-cursors)))
  170. (setq mc/max-cursors (read-number "Enter a new, temporary maximum: "))
  171. (mc/remove-fake-cursors)
  172. (error "Aborted: too many cursors"))))
  173. (let ((overlay (mc/make-cursor-overlay-at-point)))
  174. (overlay-put overlay 'mc-id (or id (mc/create-cursor-id)))
  175. (overlay-put overlay 'type 'fake-cursor)
  176. (overlay-put overlay 'priority 100)
  177. (mc/store-current-state-in-overlay overlay)
  178. (when (use-region-p)
  179. (overlay-put overlay 'region-overlay
  180. (mc/make-region-overlay-between-point-and-mark)))
  181. overlay))
  182. (defun mc/execute-command (cmd)
  183. "Run command, simulating the parts of the command loop that makes sense for fake cursors."
  184. (setq this-command cmd)
  185. (run-hooks 'pre-command-hook)
  186. (unless (eq this-command 'ignore)
  187. (call-interactively cmd))
  188. (run-hooks 'post-command-hook)
  189. (when deactivate-mark (deactivate-mark)))
  190. (defvar mc--executing-command-for-fake-cursor nil)
  191. (defun mc/execute-command-for-fake-cursor (cmd cursor)
  192. (let ((mc--executing-command-for-fake-cursor t)
  193. (id (overlay-get cursor 'mc-id))
  194. (annoying-arrows-mode nil)
  195. (smooth-scroll-margin 0))
  196. (mc/add-fake-cursor-to-undo-list
  197. (mc/pop-state-from-overlay cursor)
  198. (ignore-errors
  199. (mc/execute-command cmd)
  200. (mc/create-fake-cursor-at-point id)))))
  201. (defun mc/execute-command-for-all-fake-cursors (cmd)
  202. "Calls CMD interactively for each cursor.
  203. It works by moving point to the fake cursor, setting
  204. up the proper environment, and then removing the cursor.
  205. After executing the command, it sets up a new fake
  206. cursor with updated info."
  207. (mc/save-excursion
  208. (mc/save-window-scroll
  209. (mc/for-each-fake-cursor
  210. (save-excursion
  211. (mc/execute-command-for-fake-cursor cmd cursor)))))
  212. (mc--reset-read-prompts))
  213. (defun mc/execute-command-for-all-cursors (cmd)
  214. "Calls CMD interactively for the real cursor and all fakes."
  215. (call-interactively cmd)
  216. (mc/execute-command-for-all-fake-cursors cmd))
  217. ;; Intercept some reading commands so you won't have to
  218. ;; answer them for every single cursor
  219. (defvar mc--read-char nil)
  220. (defvar multiple-cursors-mode nil)
  221. (defadvice read-char (around mc-support activate)
  222. (if (not multiple-cursors-mode)
  223. ad-do-it
  224. (unless mc--read-char
  225. (setq mc--read-char ad-do-it))
  226. (setq ad-return-value mc--read-char)))
  227. (defvar mc--read-quoted-char nil)
  228. (defadvice read-quoted-char (around mc-support activate)
  229. (if (not multiple-cursors-mode)
  230. ad-do-it
  231. (unless mc--read-quoted-char
  232. (setq mc--read-quoted-char ad-do-it))
  233. (setq ad-return-value mc--read-quoted-char)))
  234. (defun mc--reset-read-prompts ()
  235. (setq mc--read-char nil)
  236. (setq mc--read-quoted-char nil))
  237. (mc--reset-read-prompts)
  238. (defun mc/fake-cursor-p (o)
  239. "Predicate to check if an overlay is a fake cursor"
  240. (eq (overlay-get o 'type) 'fake-cursor))
  241. (defun mc/cursor-with-id (id)
  242. "Find the first cursor with the given id, or nil"
  243. (cl-find-if #'(lambda (o) (and (mc/fake-cursor-p o)
  244. (= id (overlay-get o 'mc-id))))
  245. (overlays-in (point-min) (point-max))))
  246. (defvar mc--stored-state-for-undo nil
  247. "Variable to keep the state of the real cursor while undoing a fake one")
  248. (defun activate-cursor-for-undo (id)
  249. "Called when undoing to temporarily activate the fake cursor which action is being undone."
  250. (let ((cursor (mc/cursor-with-id id)))
  251. (when cursor
  252. (setq mc--stored-state-for-undo (mc/store-current-state-in-overlay
  253. (make-overlay (point) (point) nil nil t)))
  254. (mc/pop-state-from-overlay cursor))))
  255. (defun deactivate-cursor-after-undo (id)
  256. "Called when undoing to reinstate the real cursor after undoing a fake one."
  257. (when mc--stored-state-for-undo
  258. (mc/create-fake-cursor-at-point id)
  259. (mc/pop-state-from-overlay mc--stored-state-for-undo)
  260. (setq mc--stored-state-for-undo nil)))
  261. (defun mc/prompt-for-inclusion-in-whitelist (original-command)
  262. "Asks the user, then adds the command either to the once-list or the all-list."
  263. (let ((all-p (y-or-n-p (format "Do %S for all cursors?" original-command))))
  264. (if all-p
  265. (add-to-list 'mc/cmds-to-run-for-all original-command)
  266. (add-to-list 'mc/cmds-to-run-once original-command))
  267. (mc/save-lists)
  268. all-p))
  269. (defun mc/num-cursors ()
  270. "The number of cursors (real and fake) in the buffer."
  271. (1+ (cl-count-if 'mc/fake-cursor-p
  272. (overlays-in (point-min) (point-max)))))
  273. (defvar mc--this-command nil
  274. "Used to store the original command being run.")
  275. (make-variable-buffer-local 'mc--this-command)
  276. (defun mc/make-a-note-of-the-command-being-run ()
  277. "Used with pre-command-hook to store the original command being run.
  278. Since that cannot be reliably determined in the post-command-hook.
  279. Specifically, this-original-command isn't always right, because it could have
  280. been remapped. And certain modes (cua comes to mind) will change their
  281. remapping based on state. So a command that changes the state will afterwards
  282. not be recognized through the command-remapping lookup."
  283. (unless mc--executing-command-for-fake-cursor
  284. (let ((cmd (or (command-remapping this-original-command)
  285. this-original-command)))
  286. (setq mc--this-command (and (not (eq cmd 'god-mode-self-insert))
  287. cmd)))))
  288. (defun mc/execute-this-command-for-all-cursors ()
  289. "Wrap around `mc/execute-this-command-for-all-cursors-1' to protect hook."
  290. (condition-case error
  291. (mc/execute-this-command-for-all-cursors-1)
  292. (error
  293. (message "[mc] problem in `mc/execute-this-command-for-all-cursors': %s"
  294. (error-message-string error)))))
  295. ;; execute-kbd-macro should never be run for fake cursors. The real cursor will
  296. ;; execute the keyboard macro, resulting in new commands in the command loop,
  297. ;; and the fake cursors can pick up on those instead.
  298. (defadvice execute-kbd-macro (around skip-fake-cursors activate)
  299. (unless mc--executing-command-for-fake-cursor
  300. ad-do-it))
  301. (defun mc/execute-this-command-for-all-cursors-1 ()
  302. "Used with post-command-hook to execute supported commands for all cursors.
  303. It uses two lists of commands to know what to do: the run-once
  304. list and the run-for-all list. If a command is in neither of these lists,
  305. it will prompt for the proper action and then save that preference.
  306. Some commands are so unsupported that they are even prevented for
  307. the original cursor, to inform about the lack of support."
  308. (unless mc--executing-command-for-fake-cursor
  309. (if (eq 1 (mc/num-cursors)) ;; no fake cursors? disable mc-mode
  310. (multiple-cursors-mode 0)
  311. (when this-original-command
  312. (let ((original-command (or mc--this-command
  313. (command-remapping this-original-command)
  314. this-original-command)))
  315. ;; skip keyboard macros, since they will generate actual commands that are
  316. ;; also run in the command loop - we'll handle those later instead.
  317. (when (functionp original-command)
  318. ;; if it's a lambda, we can't know if it's supported or not
  319. ;; - so go ahead and assume it's ok, because we're just optimistic like that
  320. (if (or (not (symbolp original-command))
  321. ;; lambda registered by smartrep
  322. (string-prefix-p "(" (symbol-name original-command)))
  323. (mc/execute-command-for-all-fake-cursors original-command)
  324. ;; smartrep `intern's commands into own obarray to help
  325. ;; `describe-bindings'. So, let's re-`intern' here to
  326. ;; make the command comparable by `eq'.
  327. (setq original-command (intern (symbol-name original-command)))
  328. ;; otherwise it's a symbol, and we can be more thorough
  329. (if (get original-command 'mc--unsupported)
  330. (message "%S is not supported with multiple cursors%s"
  331. original-command
  332. (get original-command 'mc--unsupported))
  333. (when (and original-command
  334. (not (memq original-command mc--default-cmds-to-run-once))
  335. (not (memq original-command mc/cmds-to-run-once))
  336. (or (memq original-command mc--default-cmds-to-run-for-all)
  337. (memq original-command mc/cmds-to-run-for-all)
  338. (mc/prompt-for-inclusion-in-whitelist original-command)))
  339. (mc/execute-command-for-all-fake-cursors original-command))))))))))
  340. (defun mc/remove-fake-cursors ()
  341. "Remove all fake cursors.
  342. Do not use to conclude editing with multiple cursors. For that
  343. you should disable multiple-cursors-mode."
  344. (mc/for-each-fake-cursor
  345. (mc/remove-fake-cursor cursor))
  346. (when mc--max-cursors-original
  347. (setq mc/max-cursors mc--max-cursors-original))
  348. (setq mc--max-cursors-original nil))
  349. (defun mc/keyboard-quit ()
  350. "Deactivate mark if there are any active, otherwise exit multiple-cursors-mode."
  351. (interactive)
  352. (if (not (use-region-p))
  353. (multiple-cursors-mode 0)
  354. (deactivate-mark)))
  355. (defvar mc/keymap nil
  356. "Keymap while multiple cursors are active.
  357. Main goal of the keymap is to rebind C-g and <return> to conclude
  358. multiple cursors editing.")
  359. (unless mc/keymap
  360. (setq mc/keymap (make-sparse-keymap))
  361. (define-key mc/keymap (kbd "C-g") 'mc/keyboard-quit)
  362. (define-key mc/keymap (kbd "<return>") 'multiple-cursors-mode)
  363. (when (fboundp 'phi-search)
  364. (define-key mc/keymap (kbd "C-s") 'phi-search))
  365. (when (fboundp 'phi-search-backward)
  366. (define-key mc/keymap (kbd "C-r") 'phi-search-backward)))
  367. (defun mc--all-equal (list)
  368. "Are all the items in LIST equal?"
  369. (let ((first (car list))
  370. (all-equal t))
  371. (while (and all-equal list)
  372. (setq all-equal (equal first (car list)))
  373. (setq list (cdr list)))
  374. all-equal))
  375. (defun mc--kill-ring-entries ()
  376. "Return the latest kill-ring entry for each cursor.
  377. The entries are returned in the order they are found in the buffer."
  378. (let (entries)
  379. (mc/for-each-cursor-ordered
  380. (setq entries (cons (car (overlay-get cursor 'kill-ring)) entries)))
  381. (reverse entries)))
  382. (defun mc--maybe-set-killed-rectangle ()
  383. "Add the latest kill-ring entry for each cursor to killed-rectangle.
  384. So you can paste it in later with `yank-rectangle'."
  385. (let ((entries (let (mc/max-cursors) (mc--kill-ring-entries))))
  386. (unless (mc--all-equal entries)
  387. (setq killed-rectangle entries))))
  388. (defvar mc/unsupported-minor-modes '(company-mode auto-complete-mode flyspell-mode jedi-mode)
  389. "List of minor-modes that does not play well with multiple-cursors.
  390. They are temporarily disabled when multiple-cursors are active.")
  391. (defvar mc/temporarily-disabled-minor-modes nil
  392. "The list of temporarily disabled minor-modes.")
  393. (make-variable-buffer-local 'mc/temporarily-disabled-minor-modes)
  394. (defun mc/temporarily-disable-minor-mode (mode)
  395. "If MODE is available and turned on, remember that and turn it off."
  396. (when (and (boundp mode) (eval mode))
  397. (add-to-list 'mc/temporarily-disabled-minor-modes mode)
  398. (funcall mode -1)))
  399. (defun mc/temporarily-disable-unsupported-minor-modes ()
  400. (mapc 'mc/temporarily-disable-minor-mode mc/unsupported-minor-modes))
  401. (defun mc/enable-minor-mode (mode)
  402. (funcall mode 1))
  403. (defun mc/enable-temporarily-disabled-minor-modes ()
  404. (mapc 'mc/enable-minor-mode mc/temporarily-disabled-minor-modes)
  405. (setq mc/temporarily-disabled-minor-modes nil))
  406. (defcustom mc/mode-line
  407. `(" mc:" (:eval (format ,(propertize "%d" 'face 'font-lock-warning-face)
  408. (mc/num-cursors))))
  409. "What to display in the mode line while multiple-cursors-mode is active."
  410. :group 'multiple-cursors)
  411. (put 'mc/mode-line 'risky-local-variable t)
  412. ;;;###autoload
  413. (define-minor-mode multiple-cursors-mode
  414. "Mode while multiple cursors are active."
  415. nil mc/mode-line mc/keymap
  416. (if multiple-cursors-mode
  417. (progn
  418. (mc/temporarily-disable-unsupported-minor-modes)
  419. (add-hook 'pre-command-hook 'mc/make-a-note-of-the-command-being-run nil t)
  420. (add-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t t)
  421. (run-hooks 'multiple-cursors-mode-enabled-hook))
  422. (remove-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t)
  423. (remove-hook 'pre-command-hook 'mc/make-a-note-of-the-command-being-run t)
  424. (setq mc--this-command nil)
  425. (mc--maybe-set-killed-rectangle)
  426. (mc/remove-fake-cursors)
  427. (mc/enable-temporarily-disabled-minor-modes)
  428. (run-hooks 'multiple-cursors-mode-disabled-hook)))
  429. (add-hook 'after-revert-hook #'(lambda () (multiple-cursors-mode 0)))
  430. (defun mc/maybe-multiple-cursors-mode ()
  431. "Enable multiple-cursors-mode if there is more than one currently active cursor."
  432. (if (> (mc/num-cursors) 1)
  433. (multiple-cursors-mode 1)
  434. (multiple-cursors-mode 0)))
  435. (defmacro unsupported-cmd (cmd msg)
  436. "Adds command to list of unsupported commands and prevents it
  437. from being executed if in multiple-cursors-mode."
  438. `(progn
  439. (put (quote ,cmd) 'mc--unsupported ,msg)
  440. (defadvice ,cmd (around unsupported-advice activate)
  441. "command isn't supported with multiple cursors"
  442. (unless (and multiple-cursors-mode (called-interactively-p 'any))
  443. ad-do-it))))
  444. ;; Commands that does not work with multiple-cursors
  445. (unsupported-cmd isearch-forward ". Feel free to add a compatible version.")
  446. (unsupported-cmd isearch-backward ". Feel free to add a compatible version.")
  447. ;; Make sure pastes from other programs are added to all kill-rings when yanking
  448. (defadvice current-kill (before interprogram-paste-for-all-cursors activate)
  449. (let ((interprogram-paste (and (= n 0)
  450. interprogram-paste-function
  451. (funcall interprogram-paste-function))))
  452. (when interprogram-paste
  453. ;; Add interprogram-paste to normal kill ring, just
  454. ;; like current-kill usually does for itself.
  455. ;; We have to do the work for it tho, since the funcall only returns
  456. ;; something once. It is not a pure function.
  457. (let ((interprogram-cut-function nil))
  458. (if (listp interprogram-paste)
  459. (mapc 'kill-new (nreverse interprogram-paste))
  460. (kill-new interprogram-paste))
  461. ;; And then add interprogram-paste to the kill-rings
  462. ;; of all the other cursors too.
  463. (mc/for-each-fake-cursor
  464. (let ((kill-ring (overlay-get cursor 'kill-ring))
  465. (kill-ring-yank-pointer (overlay-get cursor 'kill-ring-yank-pointer)))
  466. (if (listp interprogram-paste)
  467. (mapc 'kill-new (nreverse interprogram-paste))
  468. (kill-new interprogram-paste))
  469. (overlay-put cursor 'kill-ring kill-ring)
  470. (overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer)))))))
  471. (defvar mc/list-file (locate-user-emacs-file ".mc-lists.el")
  472. "The position of the file that keeps track of your preferences
  473. for running commands with multiple cursors.")
  474. (defun mc/dump-list (list-symbol)
  475. "Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer."
  476. (cl-symbol-macrolet ((value (symbol-value list-symbol)))
  477. (insert "(setq " (symbol-name list-symbol) "\n"
  478. " '(")
  479. (newline-and-indent)
  480. (set list-symbol
  481. (sort value (lambda (x y) (string-lessp (symbol-name x)
  482. (symbol-name y)))))
  483. (mapc #'(lambda (cmd) (insert (format "%S" cmd)) (newline-and-indent))
  484. value)
  485. (insert "))")
  486. (newline)))
  487. (defun mc/save-lists ()
  488. "Saves preferences for running commands with multiple cursors to `mc/list-file'"
  489. (with-temp-file mc/list-file
  490. (emacs-lisp-mode)
  491. (insert ";; This file is automatically generated by the multiple-cursors extension.")
  492. (newline)
  493. (insert ";; It keeps track of your preferences for running commands with multiple cursors.")
  494. (newline)
  495. (newline)
  496. (mc/dump-list 'mc/cmds-to-run-for-all)
  497. (newline)
  498. (mc/dump-list 'mc/cmds-to-run-once)))
  499. (defvar mc/cmds-to-run-once nil
  500. "Commands to run only once in multiple-cursors-mode.")
  501. (defvar mc--default-cmds-to-run-once nil
  502. "Default set of commands to run only once in multiple-cursors-mode.")
  503. (setq mc--default-cmds-to-run-once '(mc/edit-lines
  504. mc/edit-ends-of-lines
  505. mc/edit-beginnings-of-lines
  506. mc/mark-next-like-this
  507. mc/mark-next-like-this-word
  508. mc/mark-next-like-this-symbol
  509. mc/mark-next-word-like-this
  510. mc/mark-next-symbol-like-this
  511. mc/mark-previous-like-this
  512. mc/mark-previous-word-like-this
  513. mc/mark-previous-symbol-like-this
  514. mc/mark-all-like-this
  515. mc/mark-all-words-like-this
  516. mc/mark-all-symbols-like-this
  517. mc/mark-more-like-this-extended
  518. mc/mark-all-like-this-in-defun
  519. mc/mark-all-words-like-this-in-defun
  520. mc/mark-all-symbols-like-this-in-defun
  521. mc/mark-all-like-this-dwim
  522. mc/mark-all-dwim
  523. mc/mark-sgml-tag-pair
  524. mc/insert-numbers
  525. mc/insert-letters
  526. mc/sort-regions
  527. mc/reverse-regions
  528. mc/cycle-forward
  529. mc/cycle-backward
  530. mc/add-cursor-on-click
  531. mc/mark-pop
  532. mc/add-cursors-to-all-matches
  533. mc/mmlte--left
  534. mc/mmlte--right
  535. mc/mmlte--up
  536. mc/mmlte--down
  537. mc/unmark-next-like-this
  538. mc/unmark-previous-like-this
  539. mc/skip-to-next-like-this
  540. mc/skip-to-previous-like-this
  541. rrm/switch-to-multiple-cursors
  542. mc-hide-unmatched-lines-mode
  543. hum/keyboard-quit
  544. hum/unhide-invisible-overlays
  545. save-buffer
  546. ido-exit-minibuffer
  547. exit-minibuffer
  548. minibuffer-complete-and-exit
  549. execute-extended-command
  550. undo
  551. redo
  552. undo-tree-undo
  553. undo-tree-redo
  554. universal-argument
  555. universal-argument-more
  556. universal-argument-other-key
  557. negative-argument
  558. digit-argument
  559. top-level
  560. recenter-top-bottom
  561. describe-mode
  562. describe-key-1
  563. describe-function
  564. describe-bindings
  565. describe-prefix-bindings
  566. view-echo-area-messages
  567. other-window
  568. kill-buffer-and-window
  569. split-window-right
  570. split-window-below
  571. delete-other-windows
  572. toggle-window-split
  573. mwheel-scroll
  574. scroll-up-command
  575. scroll-down-command
  576. mouse-set-point
  577. mouse-drag-region
  578. quit-window
  579. toggle-read-only
  580. windmove-left
  581. windmove-right
  582. windmove-up
  583. windmove-down))
  584. (defvar mc--default-cmds-to-run-for-all nil
  585. "Default set of commands that should be mirrored by all cursors")
  586. (setq mc--default-cmds-to-run-for-all '(mc/keyboard-quit
  587. self-insert-command
  588. quoted-insert
  589. previous-line
  590. next-line
  591. newline
  592. newline-and-indent
  593. open-line
  594. delete-blank-lines
  595. transpose-chars
  596. transpose-lines
  597. transpose-paragraphs
  598. transpose-regions
  599. join-line
  600. right-char
  601. right-word
  602. forward-char
  603. forward-word
  604. left-char
  605. left-word
  606. backward-char
  607. backward-word
  608. forward-paragraph
  609. backward-paragraph
  610. upcase-word
  611. downcase-word
  612. capitalize-word
  613. forward-list
  614. backward-list
  615. hippie-expand
  616. hippie-expand-lines
  617. yank
  618. yank-pop
  619. append-next-kill
  620. kill-word
  621. kill-line
  622. kill-whole-line
  623. backward-kill-word
  624. backward-delete-char-untabify
  625. delete-char delete-forward-char
  626. delete-backward-char
  627. py-electric-backspace
  628. c-electric-backspace
  629. org-delete-backward-char
  630. cperl-electric-backspace
  631. python-indent-dedent-line-backspace
  632. paredit-backward-delete
  633. autopair-backspace
  634. just-one-space
  635. zap-to-char
  636. end-of-line
  637. set-mark-command
  638. exchange-point-and-mark
  639. cua-set-mark
  640. cua-replace-region
  641. cua-delete-region
  642. move-end-of-line
  643. beginning-of-line
  644. move-beginning-of-line
  645. kill-ring-save
  646. back-to-indentation
  647. subword-forward
  648. subword-backward
  649. subword-mark
  650. subword-kill
  651. subword-backward-kill
  652. subword-transpose
  653. subword-capitalize
  654. subword-upcase
  655. subword-downcase
  656. er/expand-region
  657. er/contract-region
  658. smart-forward
  659. smart-backward
  660. smart-up
  661. smart-down))
  662. (defvar mc/cmds-to-run-for-all nil
  663. "Commands to run for all cursors in multiple-cursors-mode")
  664. (load mc/list-file t) ;; load, but no errors if it does not exist yet please
  665. (provide 'multiple-cursors-core)
  666. ;; Local Variables:
  667. ;; coding: utf-8
  668. ;; End:
  669. ;;; multiple-cursors-core.el ends here