From 89b03f9bef67a6fe751088e12b3097466833bd3f Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Thu, 10 Apr 2014 01:08:05 -0700 Subject: [PATCH] Add ctags, multiple cursors, bump multi-line it. --- .mc-lists.el | 19 + elpa/ctags-20110911.304/ctags-autoloads.el | 18 + elpa/ctags-20110911.304/ctags-pkg.el | 1 + elpa/ctags-20110911.304/ctags.el | 137 ++++ elpa/ctags-readme.txt | 26 + .../ctags-update-autoloads.el | 42 + .../ctags-update-pkg.el | 1 + .../ctags-update-20131125.743/ctags-update.el | 295 +++++++ elpa/ctags-update-readme.txt | 35 + .../mc-cycle-cursors.el | 122 +++ .../mc-edit-lines.el | 110 +++ .../mc-mark-more.el | 561 ++++++++++++++ .../mc-mark-pop.el | 22 + .../mc-separate-operations.el | 90 +++ .../multiple-cursors-autoloads.el | 262 +++++++ .../multiple-cursors-core.el | 729 ++++++++++++++++++ .../multiple-cursors-pkg.el | 1 + .../multiple-cursors.el | 191 +++++ .../rectangular-region-mode.el | 124 +++ elpa/multiple-cursors-readme.txt | 155 ++++ init.el | 11 + lisp/multi-line-it | 2 +- 22 files changed, 2953 insertions(+), 1 deletion(-) create mode 100644 .mc-lists.el create mode 100644 elpa/ctags-20110911.304/ctags-autoloads.el create mode 100644 elpa/ctags-20110911.304/ctags-pkg.el create mode 100644 elpa/ctags-20110911.304/ctags.el create mode 100644 elpa/ctags-readme.txt create mode 100644 elpa/ctags-update-20131125.743/ctags-update-autoloads.el create mode 100644 elpa/ctags-update-20131125.743/ctags-update-pkg.el create mode 100644 elpa/ctags-update-20131125.743/ctags-update.el create mode 100644 elpa/ctags-update-readme.txt create mode 100644 elpa/multiple-cursors-20140105.259/mc-cycle-cursors.el create mode 100644 elpa/multiple-cursors-20140105.259/mc-edit-lines.el create mode 100644 elpa/multiple-cursors-20140105.259/mc-mark-more.el create mode 100644 elpa/multiple-cursors-20140105.259/mc-mark-pop.el create mode 100644 elpa/multiple-cursors-20140105.259/mc-separate-operations.el create mode 100644 elpa/multiple-cursors-20140105.259/multiple-cursors-autoloads.el create mode 100644 elpa/multiple-cursors-20140105.259/multiple-cursors-core.el create mode 100644 elpa/multiple-cursors-20140105.259/multiple-cursors-pkg.el create mode 100644 elpa/multiple-cursors-20140105.259/multiple-cursors.el create mode 100644 elpa/multiple-cursors-20140105.259/rectangular-region-mode.el create mode 100644 elpa/multiple-cursors-readme.txt diff --git a/.mc-lists.el b/.mc-lists.el new file mode 100644 index 00000000..61cd085d --- /dev/null +++ b/.mc-lists.el @@ -0,0 +1,19 @@ +;; This file is automatically generated by the multiple-cursors +;; extension. +;; It keeps track of your preferences for running commands with +;; multiple cursors. + +(setq mc/cmds-to-run-for-all + '( + isearch-backward-regexp + isearch-printing-char + kill-region + yas/expand + )) + +(setq mc/cmds-to-run-once + '( + isearch-delete-char + python-indent-electric-colon + smex + )) diff --git a/elpa/ctags-20110911.304/ctags-autoloads.el b/elpa/ctags-20110911.304/ctags-autoloads.el new file mode 100644 index 00000000..5339aa79 --- /dev/null +++ b/elpa/ctags-20110911.304/ctags-autoloads.el @@ -0,0 +1,18 @@ +;;; ctags-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + + +;;;### (autoloads nil nil ("ctags-pkg.el" "ctags.el") (21317 48750 +;;;;;; 589620)) + +;;;*** + +(provide 'ctags-autoloads) +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; ctags-autoloads.el ends here diff --git a/elpa/ctags-20110911.304/ctags-pkg.el b/elpa/ctags-20110911.304/ctags-pkg.el new file mode 100644 index 00000000..9c68891d --- /dev/null +++ b/elpa/ctags-20110911.304/ctags-pkg.el @@ -0,0 +1 @@ +(define-package "ctags" "20110911.304" "Exuberant Ctags utilities for Emacs" (quote nil)) diff --git a/elpa/ctags-20110911.304/ctags.el b/elpa/ctags-20110911.304/ctags.el new file mode 100644 index 00000000..9d4b3225 --- /dev/null +++ b/elpa/ctags-20110911.304/ctags.el @@ -0,0 +1,137 @@ +;;; ctags.el --- Exuberant Ctags utilities for Emacs + +;; Copyright (C) 2011 Free Software Foundation, Inc. + +;; Version: 20110911.304 +;; X-Original-Version: 1.1.1 +;; Keywords: tags ctags etags +;; Author: Guilherme M. Gondim +;; Maintainer: Guilherme M. Gondim +;; URL: https://bitbucket.org/semente/ctags.el + +;; This file is NOT part of GNU Emacs. + +;; ctags.el is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; ctags.el is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with ctags.el. If not, see . + +;;; Commentary: + +;; Configuration example: + +;; (setq tags-revert-without-query t) +;; (global-set-key (kbd "") 'ctags-create-or-update-tags-table) + +;; Then just press to update or create your TAGS file. That function look +;; for a file TAGS in the current and its parent directories, if a TAG file is +;; not found it ask you where create a new one. + +;; Optionally you can use the function `ctags-search', a little wrapper for +;; `tags-search' that provides a default input like in `find-tag', to search +;; through all files listed in tags table. + +;; Also, if you prefer, you can override the key binding M-. for `find-tag' to +;; use `ctags-search': + +;; (global-set-key (kbd "M-.") 'ctags-search) + +;;; Installation: + +;; Add this to your Emacs configuration: + +;; (add-to-list 'load-path "/folder/containing/file") +;; (require 'ctags) + +;; Alternatively, you can install it using the Marmalade ELPA repository. + +;;; Code: + +(defvar ctags-command "/usr/bin/ctags -e -R ") + +(defun ctags () + (call-process-shell-command ctags-command nil "*Ctags*")) + + +(defun ctags-find-tags-file () + "Recursively searches each parent directory for a file named +TAGS and returns the path to that file or nil if a tags file is +not found or if the buffer is not visiting a file." + (progn + (defun find-tags-file-r (path) + "Find the tags file from current to the parent directories." + (let* ((parent-directory (file-name-directory (directory-file-name path))) + (tags-file-name (concat (file-name-as-directory path) "TAGS"))) + (cond + ((file-exists-p tags-file-name) (throw 'found tags-file-name)) + ((string= "/TAGS" tags-file-name) nil) + (t (find-tags-file-r parent-directory))))) + + (if (buffer-file-name) + (catch 'found + (find-tags-file-r (file-name-directory buffer-file-name))) + nil))) + +(defun ctags-set-tags-file () + "Uses `ctags-find-tags-file' to find a TAGS file. If found, +set 'tags-file-name' with its path or set as nil." + (setq-default tags-file-name (ctags-find-tags-file))) + +(defun ctags-create-tags-table () + (interactive) + (let* ((current-directory default-directory) + (top-directory (read-directory-name + "Top of source tree: " default-directory)) + (file-name (concat (file-name-as-directory top-directory) "TAGS"))) + (cd top-directory) + (if (not (= 0 (ctags))) + (message "Error creating %s!" file-name) + (setq-default tags-file-name file-name) + (message "Table %s created and configured." tags-file-name)) + (cd current-directory))) + +(defun ctags-update-tags-table () + (interactive) + (let ((current-directory default-directory)) + (if (not tags-file-name) + (message "Tags table not configured.") + (cd (file-name-directory tags-file-name)) + (if (not (= 0 (ctags))) + (message "Error updating %s!" tags-file-name) + (message "Table %s updated." tags-file-name)) + (cd current-directory)))) + +(defun ctags-create-or-update-tags-table () + "Create or update a tags table with `ctags-command'." + (interactive) + (if (not (ctags-set-tags-file)) + (ctags-create-tags-table) + (ctags-update-tags-table))) + + +(defun ctags-search () + "A wrapper for `tags-search' that provide a default input." + (interactive) + (let* ((symbol-at-point (symbol-at-point)) + (default (symbol-name symbol-at-point)) + (input (read-from-minibuffer + (if (symbol-at-point) + (concat "Tags search (default " default "): ") + "Tags search (regexp): ")))) + (if (and (symbol-at-point) (string= input "")) + (tags-search default) + (if (string= input "") + (message "You must provide a regexp.") + (tags-search input))))) + + +(provide 'ctags) +;;; ctags.el ends here diff --git a/elpa/ctags-readme.txt b/elpa/ctags-readme.txt new file mode 100644 index 00000000..8ecc8b01 --- /dev/null +++ b/elpa/ctags-readme.txt @@ -0,0 +1,26 @@ +Configuration example: + +(setq tags-revert-without-query t) +(global-set-key (kbd "") 'ctags-create-or-update-tags-table) + +Then just press to update or create your TAGS file. That function look +for a file TAGS in the current and its parent directories, if a TAG file is +not found it ask you where create a new one. + +Optionally you can use the function `ctags-search', a little wrapper for +`tags-search' that provides a default input like in `find-tag', to search +through all files listed in tags table. + +Also, if you prefer, you can override the key binding M-. for `find-tag' to +use `ctags-search': + +(global-set-key (kbd "M-.") 'ctags-search) + +Installation: + +Add this to your Emacs configuration: + +(add-to-list 'load-path "/folder/containing/file") +(require 'ctags) + +Alternatively, you can install it using the Marmalade ELPA repository. diff --git a/elpa/ctags-update-20131125.743/ctags-update-autoloads.el b/elpa/ctags-update-20131125.743/ctags-update-autoloads.el new file mode 100644 index 00000000..97e35a6b --- /dev/null +++ b/elpa/ctags-update-20131125.743/ctags-update-autoloads.el @@ -0,0 +1,42 @@ +;;; ctags-update-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + + +;;;### (autoloads (turn-on-ctags-auto-update-mode ctags-auto-update-mode +;;;;;; ctags-update) "ctags-update" "ctags-update.el" (21317 48806)) +;;; Generated autoloads from ctags-update.el + +(autoload 'ctags-update "ctags-update" "\ +update TAGS in parent directory using `exuberant-ctags'. +1. you can call this function directly, +2. enable `ctags-auto-update-mode', +3. with prefix `C-u' then you can generate a new TAGS file in directory, +4. with prefix `C-uC-u' save the command to kill-ring instead of execute it. + +\(fn &optional ARGS)" t nil) + +(autoload 'ctags-auto-update-mode "ctags-update" "\ +auto update TAGS using `exuberant-ctags' in parent directory. + +\(fn &optional ARG)" t nil) + +(autoload 'turn-on-ctags-auto-update-mode "ctags-update" "\ +turn on `ctags-auto-update-mode'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("ctags-update-pkg.el") (21317 48806 455939)) + +;;;*** + +(provide 'ctags-update-autoloads) +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; ctags-update-autoloads.el ends here diff --git a/elpa/ctags-update-20131125.743/ctags-update-pkg.el b/elpa/ctags-update-20131125.743/ctags-update-pkg.el new file mode 100644 index 00000000..c790e8f1 --- /dev/null +++ b/elpa/ctags-update-20131125.743/ctags-update-pkg.el @@ -0,0 +1 @@ +(define-package "ctags-update" "20131125.743" "(auto) update TAGS in parent directory using exuberant-ctags" (quote nil)) diff --git a/elpa/ctags-update-20131125.743/ctags-update.el b/elpa/ctags-update-20131125.743/ctags-update.el new file mode 100644 index 00000000..dd9c71f7 --- /dev/null +++ b/elpa/ctags-update-20131125.743/ctags-update.el @@ -0,0 +1,295 @@ +;;; ctags-update.el --- (auto) update TAGS in parent directory using exuberant-ctags + +;; Created: 2011-10-16 13:17 +;; Last Updated: 纪秀峰 2013-11-07 17:45:50 4 +;; Version: 20131125.743 +;; X-Original-Version: 0.2.2 +;; Author: Joseph(纪秀峰) jixiuf@gmail.com +;; Keywords: exuberant-ctags etags +;; URL: https://github.com/jixiuf/helm-etags-plus +;; https://github.com/emacsmirror/ctags-update + +;; Copyright (C) 2011,2012 Joseph(纪秀峰) all rights reserved. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Just put ctags-update.el to your load-path. +;; The load-path is usually ~/elisp/. +;; It's set in your ~/.emacs like this: +;; (add-to-list 'load-path (expand-file-name "~/elisp")) +;; +;; And the following to your ~/.emacs startup file. +;; +;;(autoload 'turn-on-ctags-auto-update-mode "ctags-update" "turn on `ctags-auto-update-mode'." t) +;;(add-hook 'c-mode-common-hook 'turn-on-ctags-auto-update-mode) +;; ... +;;(add-hook 'emacs-lisp-mode-hook 'turn-on-ctags-auto-update-mode) +;; +;; then when you save a file ,`ctags-auto-update-mode' will recursively searches each +;; parent directory for a file named 'TAGS'. if found ,it will use +;; `exuberant-ctags' update TAGS, +;; it would not be updated if last time calling `ctags-update' is not 5 minute age(default). +;; if no 'TAGS' found ,it will check `tags-table-list' and `tags-file-name' +;; if current buffer shares the same parent directory with `tags-file-name' or one element of +;; `tags-table-list' , it will auto create 'TAGS' file +;; eq: +;; (setq tags-file-name "/tmp/TAGS") +;; or +;; (setq tags-table-list '("/tmp/TAGS")) +;; +;; if you want to update (create) TAGS manually +;; you can +;; (autoload 'ctags-update "ctags-update" "update TAGS using ctags" t) +;; (global-set-key "\C-cE" 'ctags-update) +;; with prefix `C-u' ,then you can generate a new TAGS file in your selected directory, +;; with prefix `C-uC-u' same to prefix `C-u',but save it to kill-ring instead of execute it." + +;; +;; on windows ,you can custom `ctags-update-command' like this: +;; (when (equal system-type 'windows-nt) +;; (setq ctags-update-command (expand-file-name "~/.emacs.d/bin/ctags.exe"))) + +;;; Commands: +;; +;; Below are complete command list: +;; +;; `ctags-update' +;; update TAGS in parent directory using `exuberant-ctags'. +;; `ctags-auto-update-mode' +;; auto update TAGS using `exuberant-ctags' in parent directory. +;; `turn-on-ctags-auto-update-mode' +;; turn on `ctags-auto-update-mode'. +;; +;;; Customizable Options: +;; +;; Below are customizable option list: +;; +;; `ctags-update-command' +;; it only support `exuberant-ctags' +;; default = "ctags" +;; `ctags-update-delay-seconds' +;; in `after-save-hook' current-time - last-time must bigger than this value, +;; default = (* 5 60) +;; `ctags-update-other-options' +;; other options for ctags +;; default = (list "--exclude='*.elc'" "--exclude='*.class'" "--exclude='.git'" "--exclude='.svn'" ...) +;; `ctags-update-lighter' +;; Lighter displayed in mode line when `ctags-auto-update-mode' +;; default = " ctagsU" + +;;; Code: + +(require 'etags) + +(defgroup ctags-update nil + "auto update TAGS in parent directory using `exuberant-ctags'" + :prefix "ctags-update" + :group 'etags) + +(defcustom ctags-update-command "ctags" + "it only support `exuberant-ctags' +take care it is not the ctags in `emacs-VERSION/bin/' +you should download `exuberant-ctags' and make sure +the ctags is under $PATH before `emacs-VERSION/bin/'" + :type 'string + :group 'ctags-update) + +(defcustom ctags-update-delay-seconds (* 5 60) ; 5 mins +"in `after-save-hook' current-time - last-time must bigger than this value, +then `ctags-update' will be called" + :type 'integer + :group 'ctags-update) + +(defcustom ctags-update-other-options + (list + "--fields=+iaSt" + "--extra=+q" + "−−c++−kinds=+p" + "--exclude='*.elc'" + "--exclude='*.class'" + "--exclude='.git'" + "--exclude='.svn'" + "--exclude='SCCS'" + "--exclude='RCS'" + "--exclude='CVS'" + "--exclude='EIFGEN'") + "other options for ctags" + :group 'ctags-update + :type '(repeat string)) + +(defcustom ctags-update-lighter " ctagsU" + "Lighter displayed in mode line when `ctags-auto-update-mode' +is enabled." + :group 'ctags-update + :type 'string) + +(defvar ctags-update-last-update-time + (- (float-time (current-time)) ctags-update-delay-seconds 1) + "make sure when user first call `ctags-update' it can run immediately") + +(defvar ctags-auto-update-mode-map + (let ((map (make-sparse-keymap))) + map)) + +(defvar ctags-auto-update-mode-hook nil) + +(defvar ctags-update-use-xemacs-etags-p + (fboundp 'get-tag-table-buffer) + "Use XEmacs etags?") + +(defun ctags-update-file-truename (filename) "empty function") + +(if ctags-update-use-xemacs-etags-p + (unless (fboundp 'symlink-expand-file-name) + (fset 'symlink-expand-file-name 'file-truename))) +(if (fboundp 'symlink-expand-file-name) + (fset 'ctags-update-file-truename 'symlink-expand-file-name) + (fset 'ctags-update-file-truename 'file-truename)) + +(defun ctags-update-command-args (tagfile-full-path &optional save-tagfile-to-as) + "`tagfile-full-path' is the full path of TAGS file . when files in or under the same directory +with `tagfile-full-path' changed ,then TAGS file need to be updated. this function will generate +the command to update TAGS" + ;; on windows "ctags -R d:/.emacs.d" works , but "ctags -R d:/.emacs.d/" doesn't + (let*( (tagdir-with-slash-appended (expand-file-name (file-name-directory tagfile-full-path))) + (length-of-tagfile-directory (length tagdir-with-slash-appended)) + (tagdir-without-slash-appended (substring tagdir-with-slash-appended 0 (1- length-of-tagfile-directory))) + (args + (append + (list "-R" "-e" ) + (when (equal system-type 'windows-nt) + (list "-f" (get-system-file-path (or save-tagfile-to-as tagfile-full-path)))) + ctags-update-other-options + (if (equal system-type 'windows-nt) + (list tagdir-without-slash-appended) + (list ".")) + ))) + args)) +(defun ctags-update-get-command(command command-args) + "get the full command as string." + (concat command " "(mapconcat 'identity command-args " "))) + + +(defun get-system-file-path(file-path) + "when on windows `expand-file-name' will translate from \\ to / +some times it is not needed . then this function is used to translate / +to \\ when on windows" + (if (equal system-type 'windows-nt) + (convert-standard-filename file-path) + file-path)) + +(defun ctags-update-find-tags-file () + "recursively searches each parent directory for a file named 'TAGS' and returns the +path to that file or nil if a tags file is not found. Returns nil if the buffer is +not visiting a file" + (let ((tag-root-dir (locate-dominating-file default-directory "TAGS"))) + (if tag-root-dir + (expand-file-name "TAGS" tag-root-dir) + (if (and tags-file-name + (string-match (regexp-quote (ctags-update-file-truename default-directory)) + (ctags-update-file-truename tags-file-name))) + tags-file-name + (if tags-table-list + (let (matched-tag-names match-tag-element) + (dolist (tagname tags-table-list) + (when (string-match (regexp-quote (ctags-update-file-truename default-directory)) + (ctags-update-file-truename tagname)) + (add-to-list 'matched-tag-names tagname))) + (when matched-tag-names + (setq match-tag-element (car matched-tag-names)) + (if (file-directory-p match-tag-element) + (expand-file-name "TAGS" match-tag-element) + match-tag-element)))))))) + +;;;###autoload +(defun ctags-update(&optional args) + "update TAGS in parent directory using `exuberant-ctags'. +1. you can call this function directly, +2. enable `ctags-auto-update-mode', +3. with prefix `C-u' then you can generate a new TAGS file in directory, +4. with prefix `C-uC-u' save the command to kill-ring instead of execute it." + (interactive "P") + (let (tags-filename process) + (when (or (and args (setq tags-filename + (expand-file-name + "TAGS" (read-directory-name "Generate new TAGS to directory:" )))) + (and (not (get-process "update TAGS"));;if "update TAGS" process is not already running + (or (called-interactively-p 'interactive) + (> (- (float-time (current-time)) + ctags-update-last-update-time) + ctags-update-delay-seconds)) + (setq tags-filename (ctags-update-find-tags-file)) + (not (and (buffer-file-name) + (string-equal (ctags-update-file-truename tags-filename) + (ctags-update-file-truename (buffer-file-name))) + )))) + (setq ctags-update-last-update-time (float-time (current-time)));;update time + (let ((orig-default-directory default-directory) + (default-directory (file-name-directory tags-filename))) + (when (equal system-type 'windows-nt) + (setq default-directory orig-default-directory)) + (cond + ;;with prefix `C-uC-u' save the command to kill-ring + ;; sometime the directory you select need root privilege + ;; so save the command to kill-ring, + ((and (called-interactively-p 'interactive) args (equal args '(16))) + (kill-new (format "cd %s && %s" default-directory + (ctags-update-get-command + ctags-update-command (ctags-update-command-args tags-filename)))) + (message "save ctags-upate command to king-ring. (C-y) yank it back.")) + (t + (setq process + (apply 'start-process ;; + "update TAGS" " *update TAGS*" + ctags-update-command + (ctags-update-command-args tags-filename))) + (set-process-sentinel process + (lambda (proc change) + (when (string-match "\\(finished\\|exited\\)" change) + (kill-buffer " *update TAGS*") + (message "TAGS in parent directory is updated. " ) + ))) + )))))) + +;;;###autoload +(define-minor-mode ctags-auto-update-mode + "auto update TAGS using `exuberant-ctags' in parent directory." + :lighter ctags-update-lighter + :keymap ctags-auto-update-mode-map + ;; :global t + :init-value nil + :group 'ctags-update + (if ctags-auto-update-mode + (progn + (add-hook 'after-save-hook 'ctags-update nil t) + (run-hooks 'ctags-auto-update-mode-hook)) + (remove-hook 'after-save-hook 'ctags-update t))) + +;;;###autoload +(defun turn-on-ctags-auto-update-mode() + "turn on `ctags-auto-update-mode'." + (interactive) + (ctags-auto-update-mode 1)) + +(provide 'ctags-update) + +;; Local Variables: +;; coding: utf-8 +;; indent-tabs-mode: nil +;; tab-width: 4 +;; End: + +;;; ctags-update.el ends here diff --git a/elpa/ctags-update-readme.txt b/elpa/ctags-update-readme.txt new file mode 100644 index 00000000..824ea0ac --- /dev/null +++ b/elpa/ctags-update-readme.txt @@ -0,0 +1,35 @@ +Just put ctags-update.el to your load-path. +The load-path is usually ~/elisp/. +It's set in your ~/.emacs like this: +(add-to-list 'load-path (expand-file-name "~/elisp")) + +And the following to your ~/.emacs startup file. + +(autoload 'turn-on-ctags-auto-update-mode "ctags-update" "turn on `ctags-auto-update-mode'." t) +(add-hook 'c-mode-common-hook 'turn-on-ctags-auto-update-mode) +... +(add-hook 'emacs-lisp-mode-hook 'turn-on-ctags-auto-update-mode) + +then when you save a file ,`ctags-auto-update-mode' will recursively searches each +parent directory for a file named 'TAGS'. if found ,it will use +`exuberant-ctags' update TAGS, +it would not be updated if last time calling `ctags-update' is not 5 minute age(default). +if no 'TAGS' found ,it will check `tags-table-list' and `tags-file-name' +if current buffer shares the same parent directory with `tags-file-name' or one element of +`tags-table-list' , it will auto create 'TAGS' file +eq: + (setq tags-file-name "/tmp/TAGS") + or + (setq tags-table-list '("/tmp/TAGS")) + +if you want to update (create) TAGS manually +you can + (autoload 'ctags-update "ctags-update" "update TAGS using ctags" t) + (global-set-key "\C-cE" 'ctags-update) +with prefix `C-u' ,then you can generate a new TAGS file in your selected directory, +with prefix `C-uC-u' same to prefix `C-u',but save it to kill-ring instead of execute it." + + +on windows ,you can custom `ctags-update-command' like this: +(when (equal system-type 'windows-nt) + (setq ctags-update-command (expand-file-name "~/.emacs.d/bin/ctags.exe"))) diff --git a/elpa/multiple-cursors-20140105.259/mc-cycle-cursors.el b/elpa/multiple-cursors-20140105.259/mc-cycle-cursors.el new file mode 100644 index 00000000..bb86aaa7 --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/mc-cycle-cursors.el @@ -0,0 +1,122 @@ +;;; mc-cycle-cursors.el + +;; Copyright (C) 2012 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This scrolls the buffer to center each cursor in turn. +;; Scroll down with C-v, scroll up with M-v +;; This is nice when you have cursors that's outside of your view. + +;;; Code: + +(require 'multiple-cursors-core) + +(eval-when-compile (require 'cl)) + +(defun mc/next-fake-cursor-after-point () + (let ((pos (point)) + (next-pos (1+ (point-max))) + next) + (mc/for-each-fake-cursor + (let ((cursor-pos (overlay-get cursor 'point))) + (when (and (< pos cursor-pos) + (< cursor-pos next-pos)) + (setq next-pos cursor-pos) + (setq next cursor)))) + next)) + +(defun mc/prev-fake-cursor-before-point () + (let ((pos (point)) + (prev-pos (1- (point-min))) + prev) + (mc/for-each-fake-cursor + (let ((cursor-pos (overlay-get cursor 'point))) + (when (and (> pos cursor-pos) + (> cursor-pos prev-pos)) + (setq prev-pos cursor-pos) + (setq prev cursor)))) + prev)) + +(defcustom mc/cycle-looping-behaviour 'continue + "What to do if asked to cycle beyond the last cursor or before the first cursor." + :type '(radio (const :tag "Loop around to beginning/end of document." continue) + (const :tag "Warn and then loop around." warn) + (const :tag "Signal an error." error) + (const :tag "Don't loop." stop)) + :group 'multiple-cursors) + +(defun mc/handle-loop-condition (error-message) + (ecase mc/cycle-looping-behaviour + (error (error error-message)) + (warn (message error-message)) + (continue 'continue) + (stop 'stop))) + +(defun mc/first-fake-cursor-after (point) + "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." + (let* ((cursors (mc/all-fake-cursors)) + (cursors-after-point (remove-if (lambda (cursor) + (< (mc/cursor-beg cursor) point)) + cursors)) + (cursors-in-order (sort* cursors-after-point '< :key 'mc/cursor-beg))) + (first cursors-in-order))) + +(defun mc/last-fake-cursor-before (point) + "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." + (let* ((cursors (mc/all-fake-cursors)) + (cursors-before-point (remove-if (lambda (cursor) + (> (mc/cursor-end cursor) point)) + cursors)) + (cursors-in-order (sort* cursors-before-point '> :key 'mc/cursor-end))) + (first cursors-in-order))) + +(defun* mc/cycle (next-cursor fallback-cursor loop-message) + (when (null next-cursor) + (when (eql 'stop (mc/handle-loop-condition loop-message)) + (return-from mc/cycle nil)) + (setf next-cursor fallback-cursor)) + (mc/create-fake-cursor-at-point) + (mc/pop-state-from-overlay next-cursor) + (recenter)) + +(defun mc/cycle-forward () + (interactive) + (mc/cycle (mc/next-fake-cursor-after-point) + (mc/first-fake-cursor-after (point-min)) + "We're already at the last cursor.")) + +(defun mc/cycle-backward () + (interactive) + (mc/cycle (mc/prev-fake-cursor-before-point) + (mc/last-fake-cursor-before (point-max)) + "We're already at the last cursor")) + +(define-key mc/keymap (kbd "C-v") 'mc/cycle-forward) +(define-key mc/keymap (kbd "M-v") 'mc/cycle-backward) + +(provide 'mc-cycle-cursors) + + +;; Local Variables: +;; coding: utf-8 +;; byte-compile-warnings: (not cl-functions) +;; End: + +;;; mc-cycle-cursors.el ends here diff --git a/elpa/multiple-cursors-20140105.259/mc-edit-lines.el b/elpa/multiple-cursors-20140105.259/mc-edit-lines.el new file mode 100644 index 00000000..20668cfa --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/mc-edit-lines.el @@ -0,0 +1,110 @@ +;;; mc-edit-lines.el + +;; Copyright (C) 2012 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This file contains functions to add multiple cursors to consecutive lines +;; given an active region. + +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'multiple-cursors-core) + +(defcustom mc/edit-lines-empty-lines nil + "What should be done by `mc/edit-lines' when a line is not long enough." + :type '(radio (const :tag "Pad the line with spaces." pad) + (const :tag "Ignore the line." ignore) + (const :tag "Signal an error." error) + (const :tag "Nothing. Cursor is at end of line." nil)) + :group 'multiple-cursors) + +;;;###autoload +(defun mc/edit-lines (&optional arg) + "Add one cursor to each line of the active region. +Starts from mark and moves in straight down or up towards the +line point is on. + +What is done with lines which are not long enough is governed by +`mc/edit-lines-empty-lines'. The prefix argument ARG can be used +to override this. If ARG is a symbol (when called from Lisp), +that symbol is used instead of `mc/edit-lines-empty-lines'. +Otherwise, if ARG negative, short lines will be ignored. Any +other non-nil value will cause short lines to be padded." + (interactive "P") + (when (not (and mark-active (/= (point) (mark)))) + (error "Mark a set of lines first")) + (mc/remove-fake-cursors) + (let* ((col (current-column)) + (point-line (line-number-at-pos)) + (mark-line (progn (exchange-point-and-mark) (line-number-at-pos))) + (direction (if (< point-line mark-line) :up :down)) + (style (cond + ;; called from lisp + ((and arg (symbolp arg)) + arg) + ;; negative argument + ((< (prefix-numeric-value arg) 0) + 'ignore) + (arg 'pad) + (t mc/edit-lines-empty-lines)))) + (deactivate-mark) + (when (and (eq direction :up) (bolp)) + (previous-logical-line 1 nil) + (move-to-column col)) + ;; Add the cursors + (while (not (eq (line-number-at-pos) point-line)) + ;; Pad the line + (when (eq style 'pad) + (while (< (current-column) col) + (insert " "))) + ;; Error + (when (and (eq style 'error) + (not (equal col (current-column)))) + (error "Short line encountered in `mc/edit-lines'")) + ;; create the cursor + (unless (and (eq style 'ignore) + (not (equal col (current-column)))) + (mc/create-fake-cursor-at-point)) + ;; proceed to next + (if (eq direction :up) + (previous-logical-line 1 nil) + (next-logical-line 1 nil)) + (move-to-column col)) + (multiple-cursors-mode))) + +;;;###autoload +(defun mc/edit-ends-of-lines () + "Add one cursor to the end of each line in the active region." + (interactive) + (mc/edit-lines) + (mc/execute-command-for-all-cursors 'end-of-line)) + +;;;###autoload +(defun mc/edit-beginnings-of-lines () + "Add one cursor to the beginning of each line in the active region." + (interactive) + (mc/edit-lines) + (mc/execute-command-for-all-cursors 'beginning-of-line)) + +(provide 'mc-edit-lines) + +;;; mc-edit-lines.el ends here diff --git a/elpa/multiple-cursors-20140105.259/mc-mark-more.el b/elpa/multiple-cursors-20140105.259/mc-mark-more.el new file mode 100644 index 00000000..ef4b8771 --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/mc-mark-more.el @@ -0,0 +1,561 @@ +;;; mc-mark-more.el + +;; Copyright (C) 2012 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This file contains functions to mark more parts of the buffer. +;; See ./features/mark-more.feature for examples. + +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'multiple-cursors-core) +(require 'thingatpt) + +(defun mc/cursor-end (cursor) + (if (overlay-get cursor 'mark-active) + (max (overlay-get cursor 'point) + (overlay-get cursor 'mark)) + (overlay-get cursor 'point))) + +(defun mc/cursor-beg (cursor) + (if (overlay-get cursor 'mark-active) + (min (overlay-get cursor 'point) + (overlay-get cursor 'mark)) + (overlay-get cursor 'point))) + +(defun mc/furthest-region-end () + (let ((end (max (mark) (point)))) + (mc/for-each-fake-cursor + (setq end (max end (mc/cursor-end cursor)))) + end)) + +(defun mc/first-region-start () + (let ((beg (min (mark) (point)))) + (mc/for-each-fake-cursor + (setq beg (min beg (mc/cursor-beg cursor)))) + beg)) + +(defun mc/furthest-cursor-before-point () + (let ((beg (min (mark) (point))) + furthest) + (mc/for-each-fake-cursor + (when (< (mc/cursor-beg cursor) beg) + (setq beg (mc/cursor-beg cursor)) + (setq furthest cursor))) + furthest)) + +(defun mc/furthest-cursor-after-point () + (let ((end (max (mark) (point))) + furthest) + (mc/for-each-fake-cursor + (when (> (mc/cursor-end cursor) end) + (setq end (mc/cursor-end cursor)) + (setq furthest cursor))) + furthest)) + +(defun mc/region-strings () + (let ((strings (list (buffer-substring-no-properties (point) (mark))))) + (mc/for-each-fake-cursor + (add-to-list 'strings (buffer-substring-no-properties + (mc/cursor-beg cursor) + (mc/cursor-end cursor)))) + strings)) + +(defvar mc/enclose-search-term nil + "How should mc/mark-more-* search for more matches? + +Match everything: nil +Match only whole words: 'words +Match only whole symbols: 'symbols + +Use like case-fold-search, don't recommend setting it globally.") + +(defun mc/mark-more-like-this (skip-last direction) + (let ((case-fold-search nil) + (re (regexp-opt (mc/region-strings) mc/enclose-search-term)) + (point-out-of-order (ecase direction + (forwards (< (point) (mark))) + (backwards (not (< (point) (mark)))))) + (furthest-cursor (ecase direction + (forwards (mc/furthest-cursor-after-point)) + (backwards (mc/furthest-cursor-before-point)))) + (start-char (ecase direction + (forwards (mc/furthest-region-end)) + (backwards (mc/first-region-start)))) + (search-function (ecase direction + (forwards 'search-forward-regexp) + (backwards 'search-backward-regexp))) + (match-point-getter (ecase direction + (forwards 'match-beginning) + (backwards 'match-end)))) + (if (and skip-last (not furthest-cursor)) + (error "No cursors to be skipped") + (mc/save-excursion + (goto-char start-char) + (when skip-last + (mc/remove-fake-cursor furthest-cursor)) + (if (funcall search-function re nil t) + (progn + (push-mark (funcall match-point-getter 0)) + (when point-out-of-order + (exchange-point-and-mark)) + (mc/create-fake-cursor-at-point)) + (error "no more matches found.")))))) + +;;;###autoload +(defun mc/mark-next-like-this (arg) + "Find and mark the next part of the buffer matching the currently active region +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (if (region-active-p) + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-after-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (mc/mark-more-like-this (= arg 0) 'forwards)) + (mc/mark-lines arg 'forwards)) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/mark-next-word-like-this (arg) + (interactive "p") + (let ((mc/enclose-search-term 'words)) + (mc/mark-next-like-this arg))) + +;;;###autoload +(defun mc/mark-next-symbol-like-this (arg) + (interactive "p") + (let ((mc/enclose-search-term 'symbols)) + (mc/mark-next-like-this arg))) + +;;;###autoload +(defun mc/mark-previous-like-this (arg) + "Find and mark the previous part of the buffer matching the currently active region +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (if (region-active-p) + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-before-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (mc/mark-more-like-this (= arg 0) 'backwards)) + (mc/mark-lines arg 'backwards)) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/mark-previous-word-like-this (arg) + (interactive "p") + (let ((mc/enclose-search-term 'words)) + (mc/mark-previous-like-this arg))) + +;;;###autoload +(defun mc/mark-previous-symbol-like-this (arg) + (interactive "p") + (let ((mc/enclose-search-term 'symbols)) + (mc/mark-previous-like-this arg))) + +(defun mc/mark-lines (num-lines direction) + (dotimes (i num-lines) + (mc/create-fake-cursor-at-point) + (ecase direction + (forwards (loop do (next-logical-line 1 nil) + while (mc/all-fake-cursors (point) (1+ (point))))) + (backwards (loop do (previous-logical-line 1 nil) + while (mc/all-fake-cursors (point) (1+ (point)))))))) + +;;;###autoload +(defun mc/mark-next-lines (arg) + (interactive "p") + (mc/mark-lines arg 'forwards) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/mark-previous-lines (arg) + (interactive "p") + (mc/mark-lines arg 'backwards) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/unmark-next-like-this () + "Deselect next part of the buffer matching the currently active region." + (interactive) + (mc/mark-next-like-this -1)) + +;;;###autoload +(defun mc/unmark-previous-like-this () + "Deselect prev part of the buffer matching the currently active region." + (interactive) + (mc/mark-previous-like-this -1)) + +;;;###autoload +(defun mc/skip-to-next-like-this () + "Skip the current one and select the next part of the buffer matching the currently active region." + (interactive) + (mc/mark-next-like-this 0)) + +;;;###autoload +(defun mc/skip-to-previous-like-this () + "Skip the current one and select the prev part of the buffer matching the currently active region." + (interactive) + (mc/mark-previous-like-this 0)) + +;;;###autoload +(defun mc/mark-all-like-this () + "Find and mark all the parts of the buffer matching the currently active region" + (interactive) + (unless (region-active-p) + (error "Mark a region to match first.")) + (mc/remove-fake-cursors) + (let ((master (point)) + (case-fold-search nil) + (point-first (< (point) (mark))) + (re (regexp-opt (mc/region-strings) mc/enclose-search-term))) + (mc/save-excursion + (goto-char 0) + (while (search-forward-regexp re nil t) + (push-mark (match-beginning 0)) + (when point-first (exchange-point-and-mark)) + (unless (= master (point)) + (mc/create-fake-cursor-at-point)) + (when point-first (exchange-point-and-mark))))) + (if (> (mc/num-cursors) 1) + (multiple-cursors-mode 1) + (multiple-cursors-mode 0))) + +(defun mc--select-thing-at-point (thing) + (let ((bound (bounds-of-thing-at-point thing))) + (when bound + (set-mark (car bound)) + (goto-char (cdr bound)) + bound))) + +(defun mc--select-thing-at-point-or-bark (thing) + (unless (or (region-active-p) (mc--select-thing-at-point thing)) + (error "Mark a region or set cursor on a %s." thing))) + +;;;###autoload +(defun mc/mark-all-words-like-this () + (interactive) + (mc--select-thing-at-point-or-bark 'word) + (let ((mc/enclose-search-term 'words)) + (mc/mark-all-like-this))) + +;;;###autoload +(defun mc/mark-all-symbols-like-this () + (interactive) + (mc--select-thing-at-point-or-bark 'symbol) + (let ((mc/enclose-search-term 'symbols)) + (mc/mark-all-like-this))) + +;;;###autoload +(defun mc/mark-all-in-region (beg end) + "Find and mark all the parts in the region matching the given search" + (interactive "r") + (let ((search (read-from-minibuffer "Mark all in region: ")) + (case-fold-search nil)) + (if (string= search "") + (message "Mark aborted") + (progn + (mc/remove-fake-cursors) + (goto-char beg) + (while (search-forward search end t) + (push-mark (match-beginning 0)) + (mc/create-fake-cursor-at-point)) + (let ((first (mc/furthest-cursor-before-point))) + (if (not first) + (error "Search failed for %S" search) + (mc/pop-state-from-overlay first))) + (if (> (mc/num-cursors) 1) + (multiple-cursors-mode 1) + (multiple-cursors-mode 0)))))) + +(when (not (fboundp 'set-temporary-overlay-map)) + ;; Backport this function from newer emacs versions + (defun set-temporary-overlay-map (map &optional keep-pred) + "Set a new keymap that will only exist for a short period of time. +The new keymap to use must be given in the MAP variable. When to +remove the keymap depends on user input and KEEP-PRED: + +- if KEEP-PRED is nil (the default), the keymap disappears as + soon as any key is pressed, whether or not the key is in MAP; + +- if KEEP-PRED is t, the keymap disappears as soon as a key *not* + in MAP is pressed; + +- otherwise, KEEP-PRED must be a 0-arguments predicate that will + decide if the keymap should be removed (if predicate returns + nil) or kept (otherwise). The predicate will be called after + each key sequence." + + (let* ((clearfunsym (make-symbol "clear-temporary-overlay-map")) + (overlaysym (make-symbol "t")) + (alist (list (cons overlaysym map))) + (clearfun + `(lambda () + (unless ,(cond ((null keep-pred) nil) + ((eq t keep-pred) + `(eq this-command + (lookup-key ',map + (this-command-keys-vector)))) + (t `(funcall ',keep-pred))) + (remove-hook 'pre-command-hook ',clearfunsym) + (setq emulation-mode-map-alists + (delq ',alist emulation-mode-map-alists)))))) + (set overlaysym overlaysym) + (fset clearfunsym clearfun) + (add-hook 'pre-command-hook clearfunsym) + + (push alist emulation-mode-map-alists)))) + +;;;###autoload +(defun mc/mark-more-like-this-extended () + "Like mark-more-like-this, but then lets you adjust with arrows key. +The adjustments work like this: + + Mark previous like this and set direction to 'up + Mark next like this and set direction to 'down + +If direction is 'up: + + Skip past the cursor furthest up + Remove the cursor furthest up + +If direction is 'down: + + Remove the cursor furthest down + Skip past the cursor furthest down + +The bindings for these commands can be changed. See `mc/mark-more-like-this-extended-keymap'." + (interactive) + (mc/mmlte--down) + (set-temporary-overlay-map mc/mark-more-like-this-extended-keymap t)) + +(defvar mc/mark-more-like-this-extended-direction nil + "When using mc/mark-more-like-this-extended are we working on the next or previous cursors?") + +(make-variable-buffer-local 'mc/mark-more-like-this-extended) + +(defun mc/mmlte--message () + (if (eq mc/mark-more-like-this-extended-direction 'up) + (message " to mark previous, to skip, to remove, to mark next") + (message " to mark next, to skip, to remove, to mark previous"))) + +(defun mc/mmlte--up () + (interactive) + (mc/mark-previous-like-this 1) + (setq mc/mark-more-like-this-extended-direction 'up) + (mc/mmlte--message)) + +(defun mc/mmlte--down () + (interactive) + (mc/mark-next-like-this 1) + (setq mc/mark-more-like-this-extended-direction 'down) + (mc/mmlte--message)) + +(defun mc/mmlte--left () + (interactive) + (if (eq mc/mark-more-like-this-extended-direction 'down) + (mc/unmark-next-like-this) + (mc/skip-to-previous-like-this)) + (mc/mmlte--message)) + +(defun mc/mmlte--right () + (interactive) + (if (eq mc/mark-more-like-this-extended-direction 'up) + (mc/unmark-previous-like-this) + (mc/skip-to-next-like-this)) + (mc/mmlte--message)) + +(defvar mc/mark-more-like-this-extended-keymap (make-sparse-keymap)) + +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--up) +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--down) +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--left) +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--right) + +(defvar mc--restrict-mark-all-to-symbols nil) + +;;;###autoload +(defun mc/mark-all-like-this-dwim (arg) + "Tries to guess what you want to mark all of. +Can be pressed multiple times to increase selection. + +With prefix, it behaves the same as original `mc/mark-all-like-this'" + (interactive "P") + (if arg + (mc/mark-all-like-this) + (if (and (not (use-region-p)) + (derived-mode-p 'sgml-mode) + (mc--on-tag-name-p)) + (mc/mark-sgml-tag-pair) + (let ((before (mc/num-cursors))) + (unless (eq last-command 'mc/mark-all-like-this-dwim) + (setq mc--restrict-mark-all-to-symbols nil)) + (unless (use-region-p) + (mc--mark-symbol-at-point) + (setq mc--restrict-mark-all-to-symbols t)) + (if mc--restrict-mark-all-to-symbols + (mc/mark-all-symbols-like-this-in-defun) + (mc/mark-all-like-this-in-defun)) + (when (<= (mc/num-cursors) before) + (if mc--restrict-mark-all-to-symbols + (mc/mark-all-symbols-like-this) + (mc/mark-all-like-this))) + (when (<= (mc/num-cursors) before) + (mc/mark-all-like-this)))))) + +;;;###autoload +(defun mc/mark-all-dwim (arg) + "Tries even harder to guess what you want to mark all of. + +If the region is active and spans multiple lines, it will behave +as if `mc/mark-all-in-region'. With the prefix ARG, it will call +`mc/edit-lines' instead. + +If the region is inactive or on a single line, it will behave like +`mc/mark-all-like-this-dwim'." + (interactive "P") + (if (and (use-region-p) + (not (> (mc/num-cursors) 1)) + (not (= (line-number-at-pos (region-beginning)) + (line-number-at-pos (region-end))))) + (if arg + (call-interactively 'mc/edit-lines) + (call-interactively 'mc/mark-all-in-region)) + (progn + (setq this-command 'mc/mark-all-like-this-dwim) + (mc/mark-all-like-this-dwim arg)))) + +(defun mc--in-defun () + (bounds-of-thing-at-point 'defun)) + +;;;###autoload +(defun mc/mark-all-like-this-in-defun () + "Mark all like this in defun." + (interactive) + (if (mc--in-defun) + (save-restriction + (widen) + (narrow-to-defun) + (mc/mark-all-like-this)) + (mc/mark-all-like-this))) + +;;;###autoload +(defun mc/mark-all-words-like-this-in-defun () + "Mark all words like this in defun." + (interactive) + (mc--select-thing-at-point-or-bark 'word) + (if (mc--in-defun) + (save-restriction + (widen) + (narrow-to-defun) + (mc/mark-all-words-like-this)) + (mc/mark-all-words-like-this))) + +;;;###autoload +(defun mc/mark-all-symbols-like-this-in-defun () + "Mark all symbols like this in defun." + (interactive) + (mc--select-thing-at-point-or-bark 'symbol) + (if (mc--in-defun) + (save-restriction + (widen) + (narrow-to-defun) + (mc/mark-all-symbols-like-this)) + (mc/mark-all-symbols-like-this))) + +(defun mc--mark-symbol-at-point () + "Select the symbol under cursor" + (interactive) + (when (not (use-region-p)) + (let ((b (bounds-of-thing-at-point 'symbol))) + (goto-char (car b)) + (set-mark (cdr b))))) + +(defun mc--get-nice-sgml-context () + (car + (last + (progn + (when (looking-at "<") (forward-char 1)) + (when (looking-back ">") (forward-char -1)) + (sgml-get-context))))) + +(defun mc--on-tag-name-p () + (let* ((context (save-excursion (mc--get-nice-sgml-context))) + (tag-name-len (length (aref context 4))) + (beg (aref context 2)) + (end (+ beg tag-name-len (if (eq 'open (aref context 1)) 1 3)))) + (and context + (>= (point) beg) + (<= (point) end)))) + +;;;###autoload +(defun mc/add-cursor-on-click (event) + "Add a cursor where you click." + (interactive "e") + (mouse-minibuffer-check event) + ;; Use event-end in case called from mouse-drag-region. + ;; If EVENT is a click, event-end and event-start give same value. + (let ((position (event-end event))) + (if (not (windowp (posn-window position))) + (error "Position not in text area of window")) + (select-window (posn-window position)) + (if (numberp (posn-point position)) + (save-excursion + (goto-char (posn-point position)) + (mc/create-fake-cursor-at-point))) + (mc/maybe-multiple-cursors-mode))) + +;;;###autoload +(defun mc/mark-sgml-tag-pair () + "Mark the tag we're in and its pair for renaming." + (interactive) + (when (not (mc--inside-tag-p)) + (error "Place point inside tag to rename.")) + (let ((context (mc--get-nice-sgml-context))) + (if (looking-at " +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This file contains functions that work differently on each cursor, +;; instead of treating all of them the same. + +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'multiple-cursors-core) + +;;;###autoload +(defun mc/insert-numbers (arg) + "Insert increasing numbers for each cursor, starting at 0 or ARG." + (interactive "P") + (setq mc--insert-numbers-number (or arg 0)) + (mc/for-each-cursor-ordered + (mc/execute-command-for-fake-cursor 'mc--insert-number-and-increase cursor))) + +(defvar mc--insert-numbers-number 0) + +(defun mc--insert-number-and-increase () + (interactive) + (insert (number-to-string mc--insert-numbers-number)) + (setq mc--insert-numbers-number (1+ mc--insert-numbers-number))) + +(defun mc--ordered-region-strings () + (let (strings) + (save-excursion + (mc/for-each-cursor-ordered + (setq strings (cons (buffer-substring-no-properties + (mc/cursor-beg cursor) + (mc/cursor-end cursor)) strings)))) + (nreverse strings))) + +(defvar mc--strings-to-replace nil) + +(defun mc--replace-region-strings-1 () + (interactive) + (delete-region (region-beginning) (region-end)) + (save-excursion (insert (car mc--strings-to-replace))) + (setq mc--strings-to-replace (cdr mc--strings-to-replace))) + +(defun mc--replace-region-strings () + (mc/for-each-cursor-ordered + (mc/execute-command-for-fake-cursor 'mc--replace-region-strings-1 cursor))) + +;;;###autoload +(defun mc/reverse-regions () + (interactive) + (if (not multiple-cursors-mode) + (progn + (mc/mark-next-lines 1) + (mc/reverse-regions) + (multiple-cursors-mode 0)) + (unless (use-region-p) + (mc/execute-command-for-all-cursors 'mark-sexp)) + (setq mc--strings-to-replace (nreverse (mc--ordered-region-strings))) + (mc--replace-region-strings))) + +;;;###autoload +(defun mc/sort-regions () + (interactive) + (unless (use-region-p) + (mc/execute-command-for-all-cursors 'mark-sexp)) + (setq mc--strings-to-replace (sort (mc--ordered-region-strings) 'string<)) + (mc--replace-region-strings)) + +(provide 'mc-separate-operations) +;;; mc-separate-operations.el ends here diff --git a/elpa/multiple-cursors-20140105.259/multiple-cursors-autoloads.el b/elpa/multiple-cursors-20140105.259/multiple-cursors-autoloads.el new file mode 100644 index 00000000..76bed1ca --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/multiple-cursors-autoloads.el @@ -0,0 +1,262 @@ +;;; multiple-cursors-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + + +;;;### (autoloads (mc/edit-beginnings-of-lines mc/edit-ends-of-lines +;;;;;; mc/edit-lines) "mc-edit-lines" "mc-edit-lines.el" (21317 +;;;;;; 60626)) +;;; Generated autoloads from mc-edit-lines.el + +(autoload 'mc/edit-lines "mc-edit-lines" "\ +Add one cursor to each line of the active region. +Starts from mark and moves in straight down or up towards the +line point is on. + +What is done with lines which are not long enough is governed by +`mc/edit-lines-empty-lines'. The prefix argument ARG can be used +to override this. If ARG is a symbol (when called from Lisp), +that symbol is used instead of `mc/edit-lines-empty-lines'. +Otherwise, if ARG negative, short lines will be ignored. Any +other non-nil value will cause short lines to be padded. + +\(fn &optional ARG)" t nil) + +(autoload 'mc/edit-ends-of-lines "mc-edit-lines" "\ +Add one cursor to the end of each line in the active region. + +\(fn)" t nil) + +(autoload 'mc/edit-beginnings-of-lines "mc-edit-lines" "\ +Add one cursor to the beginning of each line in the active region. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (mc/mark-sgml-tag-pair mc/add-cursor-on-click mc/mark-all-symbols-like-this-in-defun +;;;;;; mc/mark-all-words-like-this-in-defun mc/mark-all-like-this-in-defun +;;;;;; mc/mark-all-dwim mc/mark-all-like-this-dwim mc/mark-more-like-this-extended +;;;;;; mc/mark-all-in-region mc/mark-all-symbols-like-this mc/mark-all-words-like-this +;;;;;; mc/mark-all-like-this mc/skip-to-previous-like-this mc/skip-to-next-like-this +;;;;;; mc/unmark-previous-like-this mc/unmark-next-like-this mc/mark-previous-lines +;;;;;; mc/mark-next-lines mc/mark-previous-symbol-like-this mc/mark-previous-word-like-this +;;;;;; mc/mark-previous-like-this mc/mark-next-symbol-like-this +;;;;;; mc/mark-next-word-like-this mc/mark-next-like-this) "mc-mark-more" +;;;;;; "mc-mark-more.el" (21317 60626)) +;;; Generated autoloads from mc-mark-more.el + +(autoload 'mc/mark-next-like-this "mc-mark-more" "\ +Find and mark the next part of the buffer matching the currently active region +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-next-word-like-this "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/mark-next-symbol-like-this "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-like-this "mc-mark-more" "\ +Find and mark the previous part of the buffer matching the currently active region +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-word-like-this "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-symbol-like-this "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/mark-next-lines "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-lines "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/unmark-next-like-this "mc-mark-more" "\ +Deselect next part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/unmark-previous-like-this "mc-mark-more" "\ +Deselect prev part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/skip-to-next-like-this "mc-mark-more" "\ +Skip the current one and select the next part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/skip-to-previous-like-this "mc-mark-more" "\ +Skip the current one and select the prev part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/mark-all-like-this "mc-mark-more" "\ +Find and mark all the parts of the buffer matching the currently active region + +\(fn)" t nil) + +(autoload 'mc/mark-all-words-like-this "mc-mark-more" "\ + + +\(fn)" t nil) + +(autoload 'mc/mark-all-symbols-like-this "mc-mark-more" "\ + + +\(fn)" t nil) + +(autoload 'mc/mark-all-in-region "mc-mark-more" "\ +Find and mark all the parts in the region matching the given search + +\(fn BEG END)" t nil) + +(autoload 'mc/mark-more-like-this-extended "mc-mark-more" "\ +Like mark-more-like-this, but then lets you adjust with arrows key. +The adjustments work like this: + + Mark previous like this and set direction to 'up + Mark next like this and set direction to 'down + +If direction is 'up: + + Skip past the cursor furthest up + Remove the cursor furthest up + +If direction is 'down: + + Remove the cursor furthest down + Skip past the cursor furthest down + +The bindings for these commands can be changed. See `mc/mark-more-like-this-extended-keymap'. + +\(fn)" t nil) + +(autoload 'mc/mark-all-like-this-dwim "mc-mark-more" "\ +Tries to guess what you want to mark all of. +Can be pressed multiple times to increase selection. + +With prefix, it behaves the same as original `mc/mark-all-like-this' + +\(fn ARG)" t nil) + +(autoload 'mc/mark-all-dwim "mc-mark-more" "\ +Tries even harder to guess what you want to mark all of. + +If the region is active and spans multiple lines, it will behave +as if `mc/mark-all-in-region'. With the prefix ARG, it will call +`mc/edit-lines' instead. + +If the region is inactive or on a single line, it will behave like +`mc/mark-all-like-this-dwim'. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-all-like-this-in-defun "mc-mark-more" "\ +Mark all like this in defun. + +\(fn)" t nil) + +(autoload 'mc/mark-all-words-like-this-in-defun "mc-mark-more" "\ +Mark all words like this in defun. + +\(fn)" t nil) + +(autoload 'mc/mark-all-symbols-like-this-in-defun "mc-mark-more" "\ +Mark all symbols like this in defun. + +\(fn)" t nil) + +(autoload 'mc/add-cursor-on-click "mc-mark-more" "\ +Add a cursor where you click. + +\(fn EVENT)" t nil) + +(autoload 'mc/mark-sgml-tag-pair "mc-mark-more" "\ +Mark the tag we're in and its pair for renaming. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (mc/mark-pop) "mc-mark-pop" "mc-mark-pop.el" (21317 +;;;;;; 60626)) +;;; Generated autoloads from mc-mark-pop.el + +(autoload 'mc/mark-pop "mc-mark-pop" "\ +Add a cursor at the current point, pop off mark ring and jump +to the popped mark. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (mc/sort-regions mc/reverse-regions mc/insert-numbers) +;;;;;; "mc-separate-operations" "mc-separate-operations.el" (21317 +;;;;;; 60626)) +;;; Generated autoloads from mc-separate-operations.el + +(autoload 'mc/insert-numbers "mc-separate-operations" "\ +Insert increasing numbers for each cursor, starting at 0 or ARG. + +\(fn ARG)" t nil) + +(autoload 'mc/reverse-regions "mc-separate-operations" "\ + + +\(fn)" t nil) + +(autoload 'mc/sort-regions "mc-separate-operations" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (set-rectangular-region-anchor) "rectangular-region-mode" +;;;;;; "rectangular-region-mode.el" (21317 60626)) +;;; Generated autoloads from rectangular-region-mode.el + +(autoload 'set-rectangular-region-anchor "rectangular-region-mode" "\ +Anchors the rectangular region at point. + +Think of this one as `set-mark' except you're marking a rectangular region. It is +an exceedingly quick way of adding multiple cursors to multiple lines. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("mc-cycle-cursors.el" "multiple-cursors-core.el" +;;;;;; "multiple-cursors-pkg.el" "multiple-cursors.el") (21317 60626 +;;;;;; 359650)) + +;;;*** + +(provide 'multiple-cursors-autoloads) +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; multiple-cursors-autoloads.el ends here diff --git a/elpa/multiple-cursors-20140105.259/multiple-cursors-core.el b/elpa/multiple-cursors-20140105.259/multiple-cursors-core.el new file mode 100644 index 00000000..f65ea4f6 --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/multiple-cursors-core.el @@ -0,0 +1,729 @@ +;;; multiple-cursors-core.el --- An experiment in multiple cursors for emacs. + +;; Copyright (C) 2012 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This file contains the core functionality of multiple-cursors. +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'cl) + +(require 'rect) + +(defvar mc--read-char) + +(defface mc/cursor-face + '((t (:inverse-video t))) + "The face used for fake cursors" + :group 'multiple-cursors) + +(defface mc/region-face + '((t :inherit region)) + "The face used for fake regions" + :group 'multiple-cursors) + +(defmacro mc/add-fake-cursor-to-undo-list (&rest forms) + "Make sure point is in the right place when undoing" + (let ((uc (make-symbol "undo-cleaner"))) + `(let ((,uc (cons 'apply (cons 'deactivate-cursor-after-undo (list id))))) + (setq buffer-undo-list (cons ,uc buffer-undo-list)) + ,@forms + (if (eq ,uc (car buffer-undo-list)) ;; if nothing has been added to the undo-list + (setq buffer-undo-list (cdr buffer-undo-list)) ;; then pop the cleaner right off again + (setq buffer-undo-list ;; otherwise add a function to activate this cursor + (cons (cons 'apply (cons 'activate-cursor-for-undo (list id))) buffer-undo-list)))))) + +(defun mc/all-fake-cursors (&optional start end) + (remove-if-not 'mc/fake-cursor-p + (overlays-in (or start (point-min)) + (or end (point-max))))) + +(defmacro mc/for-each-fake-cursor (&rest forms) + "Runs the body for each fake cursor, bound to the name cursor" + `(mapc #'(lambda (cursor) ,@forms) + (mc/all-fake-cursors))) + +(defmacro mc/save-excursion (&rest forms) + "Saves and restores all the state that multiple-cursors cares about." + (let ((cs (make-symbol "current-state"))) + `(let ((,cs (mc/store-current-state-in-overlay + (make-overlay (point) (point) nil nil t)))) + (overlay-put ,cs 'type 'original-cursor) + (save-excursion ,@forms) + (mc/pop-state-from-overlay ,cs)))) + +(defun mc--compare-by-overlay-start (o1 o2) + (< (overlay-start o1) (overlay-start o2))) + +(defmacro mc/for-each-cursor-ordered (&rest forms) + "Runs the body for each cursor, fake and real, bound to the name cursor" + (let ((rci (make-symbol "real-cursor-id"))) + `(let ((,rci (overlay-get (mc/create-fake-cursor-at-point) 'mc-id))) + (mapc #'(lambda (cursor) + (when (mc/fake-cursor-p cursor) + ,@forms)) + (sort (overlays-in (point-min) (point-max)) 'mc--compare-by-overlay-start)) + (mc/pop-state-from-overlay (mc/cursor-with-id ,rci))))) + +(defmacro mc/save-window-scroll (&rest forms) + "Saves and restores the window scroll position" + (let ((p (make-symbol "p")) + (s (make-symbol "start")) + (h (make-symbol "hscroll"))) + `(let ((,p (set-marker (make-marker) (point))) + (,s (set-marker (make-marker) (window-start))) + (,h (window-hscroll))) + ,@forms + (goto-char ,p) + (set-window-start nil ,s t) + (set-window-hscroll nil ,h) + (set-marker ,p nil) + (set-marker ,s nil)))) + +(defun mc/make-cursor-overlay-at-eol (pos) + "Create overlay to look like cursor at end of line." + (let ((overlay (make-overlay pos pos nil nil nil))) + (overlay-put overlay 'after-string (propertize " " 'face 'mc/cursor-face)) + overlay)) + +(defun mc/make-cursor-overlay-inline (pos) + "Create overlay to look like cursor inside text." + (let ((overlay (make-overlay pos (1+ pos) nil nil nil))) + (overlay-put overlay 'face 'mc/cursor-face) + overlay)) + +(defun mc/make-cursor-overlay-at-point () + "Create overlay to look like cursor. +Special case for end of line, because overlay over a newline +highlights the entire width of the window." + (if (eolp) + (mc/make-cursor-overlay-at-eol (point)) + (mc/make-cursor-overlay-inline (point)))) + +(defun mc/make-region-overlay-between-point-and-mark () + "Create overlay to look like active region." + (let ((overlay (make-overlay (mark) (point) nil nil t))) + (overlay-put overlay 'face 'mc/region-face) + (overlay-put overlay 'type 'additional-region) + overlay)) + +(defvar mc/cursor-specific-vars '(transient-mark-mode + kill-ring + kill-ring-yank-pointer + mark-ring + mark-active + yank-undo-function + autopair-action + autopair-wrap-action + er/history) + "A list of vars that need to be tracked on a per-cursor basis.") + +(defun mc/store-current-state-in-overlay (o) + "Store relevant info about point and mark in the given overlay." + (overlay-put o 'point (set-marker (make-marker) (point))) + (overlay-put o 'mark (set-marker (make-marker) (mark))) + (dolist (var mc/cursor-specific-vars) + (when (boundp var) (overlay-put o var (symbol-value var)))) + o) + +(defun mc/restore-state-from-overlay (o) + "Restore point and mark from stored info in the given overlay." + (goto-char (overlay-get o 'point)) + (set-marker (mark-marker) (overlay-get o 'mark)) + (dolist (var mc/cursor-specific-vars) + (when (boundp var) (set var (overlay-get o var))))) + +(defun mc/remove-fake-cursor (o) + "Delete overlay with state, including dependent overlays and markers." + (set-marker (overlay-get o 'point) nil) + (set-marker (overlay-get o 'mark) nil) + (mc/delete-region-overlay o) + (delete-overlay o)) + +(defun mc/pop-state-from-overlay (o) + "Restore the state stored in given overlay and then remove the overlay." + (mc/restore-state-from-overlay o) + (mc/remove-fake-cursor o)) + +(defun mc/delete-region-overlay (o) + "Remove the dependent region overlay for a given cursor overlay." + (ignore-errors + (delete-overlay (overlay-get o 'region-overlay)))) + +(defvar mc--current-cursor-id 0 + "Var to store increasing id of fake cursors, used to keep track of them for undo.") + +(defun mc/create-cursor-id () + "Returns a unique cursor id" + (incf mc--current-cursor-id)) + +(defun mc/create-fake-cursor-at-point (&optional id) + "Add a fake cursor and possibly a fake active region overlay based on point and mark. +Saves the current state in the overlay to be restored later." + (let ((overlay (mc/make-cursor-overlay-at-point))) + (overlay-put overlay 'mc-id (or id (mc/create-cursor-id))) + (overlay-put overlay 'type 'fake-cursor) + (overlay-put overlay 'priority 100) + (mc/store-current-state-in-overlay overlay) + (when (use-region-p) + (overlay-put overlay 'region-overlay + (mc/make-region-overlay-between-point-and-mark))) + overlay)) + +(defun mc/execute-command (cmd) + "Run command, simulating the parts of the command loop that makes sense for fake cursors." + (setq this-command cmd) + (run-hooks 'pre-command-hook) + (unless (eq this-command 'ignore) + (call-interactively cmd)) + (run-hooks 'post-command-hook) + (when deactivate-mark (deactivate-mark))) + +(defvar mc--executing-command-for-fake-cursor nil) + +(defun mc/execute-command-for-fake-cursor (cmd cursor) + (let ((mc--executing-command-for-fake-cursor t) + (id (overlay-get cursor 'mc-id)) + (annoying-arrows-mode nil) + (smooth-scroll-margin 0)) + (mc/add-fake-cursor-to-undo-list + (mc/pop-state-from-overlay cursor) + (ignore-errors + (mc/execute-command cmd) + (mc/create-fake-cursor-at-point id))))) + +(defun mc/execute-command-for-all-fake-cursors (cmd) + "Calls CMD interactively for each cursor. +It works by moving point to the fake cursor, setting +up the proper environment, and then removing the cursor. +After executing the command, it sets up a new fake +cursor with updated info." + (mc/save-excursion + (mc/save-window-scroll + (mc/for-each-fake-cursor + (save-excursion + (mc/execute-command-for-fake-cursor cmd cursor))))) + (mc--reset-read-prompts)) + +(defun mc/execute-command-for-all-cursors (cmd) + "Calls CMD interactively for the real cursor and all fakes." + (call-interactively cmd) + (mc/execute-command-for-all-fake-cursors cmd)) + +;; Intercept some reading commands so you won't have to +;; answer them for every single cursor + +(defvar mc--read-char nil) +(defvar multiple-cursors-mode nil) +(defadvice read-char (around mc-support activate) + (if (not multiple-cursors-mode) + ad-do-it + (unless mc--read-char + (setq mc--read-char ad-do-it)) + (setq ad-return-value mc--read-char))) + +(defvar mc--read-quoted-char nil) +(defadvice read-quoted-char (around mc-support activate) + (if (not multiple-cursors-mode) + ad-do-it + (unless mc--read-quoted-char + (setq mc--read-quoted-char ad-do-it)) + (setq ad-return-value mc--read-quoted-char))) + +(defun mc--reset-read-prompts () + (setq mc--read-char nil) + (setq mc--read-quoted-char nil)) + +(mc--reset-read-prompts) + +(defun mc/fake-cursor-p (o) + "Predicate to check if an overlay is a fake cursor" + (eq (overlay-get o 'type) 'fake-cursor)) + +(defun mc/cursor-with-id (id) + "Find the first cursor with the given id, or nil" + (find-if #'(lambda (o) (and (mc/fake-cursor-p o) + (= id (overlay-get o 'mc-id)))) + (overlays-in (point-min) (point-max)))) + +(defvar mc--stored-state-for-undo nil + "Variable to keep the state of the real cursor while undoing a fake one") + +(defun activate-cursor-for-undo (id) + "Called when undoing to temporarily activate the fake cursor which action is being undone." + (let ((cursor (mc/cursor-with-id id))) + (when cursor + (setq mc--stored-state-for-undo (mc/store-current-state-in-overlay + (make-overlay (point) (point) nil nil t))) + (mc/pop-state-from-overlay cursor)))) + +(defun deactivate-cursor-after-undo (id) + "Called when undoing to reinstate the real cursor after undoing a fake one." + (when mc--stored-state-for-undo + (mc/create-fake-cursor-at-point id) + (mc/pop-state-from-overlay mc--stored-state-for-undo) + (setq mc--stored-state-for-undo nil))) + +(defun mc/prompt-for-inclusion-in-whitelist (original-command) + "Asks the user, then adds the command either to the once-list or the all-list." + (let ((all-p (y-or-n-p (format "Do %S for all cursors?" original-command)))) + (if all-p + (add-to-list 'mc/cmds-to-run-for-all original-command) + (add-to-list 'mc/cmds-to-run-once original-command)) + (mc/save-lists) + all-p)) + +(defun mc/num-cursors () + "The number of cursors (real and fake) in the buffer." + (1+ (count-if 'mc/fake-cursor-p + (overlays-in (point-min) (point-max))))) + +(defvar mc--this-command nil + "Used to store the original command being run.") +(make-variable-buffer-local 'mc--this-command) + +(defun mc/make-a-note-of-the-command-being-run () + "Used with pre-command-hook to store the original command being run. +Since that cannot be reliably determined in the post-command-hook. + +Specifically, this-original-command isn't always right, because it could have +been remapped. And certain modes (cua comes to mind) will change their +remapping based on state. So a command that changes the state will afterwards +not be recognized through the command-remapping lookup." + (unless mc--executing-command-for-fake-cursor + (let ((cmd (or (command-remapping this-original-command) + this-original-command))) + (setq mc--this-command (and (not (eq cmd 'god-mode-self-insert)) + cmd))))) + +(defun mc/execute-this-command-for-all-cursors () + "Wrap around `mc/execute-this-command-for-all-cursors-1' to protect hook." + (condition-case error + (mc/execute-this-command-for-all-cursors-1) + (error + (message "[mc] problem in `mc/execute-this-command-for-all-cursors': %s" + (error-message-string error))))) + +;; execute-kbd-macro should never be run for fake cursors. The real cursor will +;; execute the keyboard macro, resulting in new commands in the command loop, +;; and the fake cursors can pick up on those instead. +(defadvice execute-kbd-macro (around skip-fake-cursors activate) + (unless mc--executing-command-for-fake-cursor + ad-do-it)) + +(defun mc/execute-this-command-for-all-cursors-1 () + "Used with post-command-hook to execute supported commands for all cursors. + +It uses two lists of commands to know what to do: the run-once +list and the run-for-all list. If a command is in neither of these lists, +it will prompt for the proper action and then save that preference. + +Some commands are so unsupported that they are even prevented for +the original cursor, to inform about the lack of support." + (unless mc--executing-command-for-fake-cursor + + (if (eq 1 (mc/num-cursors)) ;; no fake cursors? disable mc-mode + (multiple-cursors-mode 0) + (when this-original-command + (let ((original-command (or mc--this-command + (command-remapping this-original-command) + this-original-command))) + + ;; skip keyboard macros, since they will generate actual commands that are + ;; also run in the command loop - we'll handle those later instead. + (when (functionp original-command) + + ;; if it's a lambda, we can't know if it's supported or not + ;; - so go ahead and assume it's ok, because we're just optimistic like that + (if (or (not (symbolp original-command)) + ;; lambda registered by smartrep + (string-prefix-p "(" (symbol-name original-command))) + (mc/execute-command-for-all-fake-cursors original-command) + + ;; smartrep `intern's commands into own obarray to help + ;; `describe-bindings'. So, let's re-`intern' here to + ;; make the command comparable by `eq'. + (setq original-command (intern (symbol-name original-command))) + + ;; otherwise it's a symbol, and we can be more thorough + (if (get original-command 'mc--unsupported) + (message "%S is not supported with multiple cursors%s" + original-command + (get original-command 'mc--unsupported)) + (when (and original-command + (not (memq original-command mc--default-cmds-to-run-once)) + (not (memq original-command mc/cmds-to-run-once)) + (or (memq original-command mc--default-cmds-to-run-for-all) + (memq original-command mc/cmds-to-run-for-all) + (mc/prompt-for-inclusion-in-whitelist original-command))) + (mc/execute-command-for-all-fake-cursors original-command)))))))))) + +(defun mc/remove-fake-cursors () + "Remove all fake cursors. +Do not use to conclude editing with multiple cursors. For that +you should disable multiple-cursors-mode." + (mc/for-each-fake-cursor + (mc/remove-fake-cursor cursor))) + +(defun mc/keyboard-quit () + "Deactivate mark if there are any active, otherwise exit multiple-cursors-mode." + (interactive) + (if (not (use-region-p)) + (multiple-cursors-mode 0) + (deactivate-mark))) + +(defvar mc/keymap nil + "Keymap while multiple cursors are active. +Main goal of the keymap is to rebind C-g and to conclude +multiple cursors editing.") +(unless mc/keymap + (setq mc/keymap (make-sparse-keymap)) + (define-key mc/keymap (kbd "C-g") 'mc/keyboard-quit) + (define-key mc/keymap (kbd "") 'multiple-cursors-mode) + (when (fboundp 'phi-search) + (define-key mc/keymap (kbd "C-s") 'phi-search)) + (when (fboundp 'phi-search-backward) + (define-key mc/keymap (kbd "C-r") 'phi-search-backward))) + +(defun mc--all-equal (list) + "Are all the items in LIST equal?" + (let ((first (car list)) + (all-equal t)) + (while (and all-equal list) + (setq all-equal (equal first (car list))) + (setq list (cdr list))) + all-equal)) + +(defun mc--kill-ring-entries () + "Return the latest kill-ring entry for each cursor. +The entries are returned in the order they are found in the buffer." + (let (entries) + (mc/for-each-cursor-ordered + (setq entries (cons (car (overlay-get cursor 'kill-ring)) entries))) + (reverse entries))) + +(defun mc--maybe-set-killed-rectangle () + "Add the latest kill-ring entry for each cursor to killed-rectangle. +So you can paste it in later with `yank-rectangle'." + (let ((entries (mc--kill-ring-entries))) + (unless (mc--all-equal entries) + (setq killed-rectangle entries)))) + +(defvar mc/unsupported-minor-modes '(auto-complete-mode flyspell-mode) + "List of minor-modes that does not play well with multiple-cursors. +They are temporarily disabled when multiple-cursors are active.") + +(defvar mc/temporarily-disabled-minor-modes nil + "The list of temporarily disabled minor-modes.") +(make-variable-buffer-local 'mc/temporarily-disabled-minor-modes) + +(defun mc/temporarily-disable-minor-mode (mode) + "If MODE is available and turned on, remember that and turn it off." + (when (and (boundp mode) (eval mode)) + (add-to-list 'mc/temporarily-disabled-minor-modes mode) + (funcall mode -1))) + +(defun mc/temporarily-disable-unsupported-minor-modes () + (mapc 'mc/temporarily-disable-minor-mode mc/unsupported-minor-modes)) + +(defun mc/enable-minor-mode (mode) + (funcall mode 1)) + +(defun mc/enable-temporarily-disabled-minor-modes () + (mapc 'mc/enable-minor-mode mc/temporarily-disabled-minor-modes) + (setq mc/temporarily-disabled-minor-modes nil)) + +(defcustom mc/mode-line + `(" mc:" (:eval (format ,(propertize "%d" 'face 'font-lock-warning-face) + (mc/num-cursors)))) + "What to display in the mode line while multiple-cursors-mode is active." + :group 'multiple-cursors) +(put 'mc/mode-line 'risky-local-variable t) + +(define-minor-mode multiple-cursors-mode + "Mode while multiple cursors are active." + nil mc/mode-line mc/keymap + (if multiple-cursors-mode + (progn + (mc/temporarily-disable-unsupported-minor-modes) + (add-hook 'pre-command-hook 'mc/make-a-note-of-the-command-being-run nil t) + (add-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t t) + (run-hooks 'multiple-cursors-mode-enabled-hook)) + (remove-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t) + (remove-hook 'pre-command-hook 'mc/make-a-note-of-the-command-being-run t) + (setq mc--this-command nil) + (mc--maybe-set-killed-rectangle) + (mc/remove-fake-cursors) + (mc/enable-temporarily-disabled-minor-modes) + (run-hooks 'multiple-cursors-mode-disabled-hook))) + +(add-hook 'after-revert-hook #'(lambda () (multiple-cursors-mode 0))) + +(defun mc/maybe-multiple-cursors-mode () + "Enable multiple-cursors-mode if there is more than one currently active cursor." + (if (> (mc/num-cursors) 1) + (multiple-cursors-mode 1) + (multiple-cursors-mode 0))) + +(defmacro unsupported-cmd (cmd msg) + "Adds command to list of unsupported commands and prevents it +from being executed if in multiple-cursors-mode." + `(progn + (put (quote ,cmd) 'mc--unsupported ,msg) + (defadvice ,cmd (around unsupported-advice activate) + "command isn't supported with multiple cursors" + (unless (and multiple-cursors-mode (called-interactively-p 'any)) + ad-do-it)))) + +;; Commands that does not work with multiple-cursors +(unsupported-cmd isearch-forward ". Feel free to add a compatible version.") +(unsupported-cmd isearch-backward ". Feel free to add a compatible version.") + +;; Make sure pastes from other programs are added to all kill-rings when yanking +(defadvice current-kill (before interprogram-paste-for-all-cursors activate) + (let ((interprogram-paste (and (= n 0) + interprogram-paste-function + (funcall interprogram-paste-function)))) + (when interprogram-paste + ;; Add interprogram-paste to normal kill ring, just + ;; like current-kill usually does for itself. + ;; We have to do the work for it tho, since the funcall only returns + ;; something once. It is not a pure function. + (let ((interprogram-cut-function nil)) + (if (listp interprogram-paste) + (mapc 'kill-new (nreverse interprogram-paste)) + (kill-new interprogram-paste)) + ;; And then add interprogram-paste to the kill-rings + ;; of all the other cursors too. + (mc/for-each-fake-cursor + (let ((kill-ring (overlay-get cursor 'kill-ring)) + (kill-ring-yank-pointer (overlay-get cursor 'kill-ring-yank-pointer))) + (if (listp interprogram-paste) + (mapc 'kill-new (nreverse interprogram-paste)) + (kill-new interprogram-paste)) + (overlay-put cursor 'kill-ring kill-ring) + (overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer))))))) + +(defvar mc/list-file "~/.emacs.d/.mc-lists.el" + "The position of the file that keeps track of your preferences +for running commands with multiple cursors.") + +(defun mc/dump-list (list-symbol) + "Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer." + (symbol-macrolet ((value (symbol-value list-symbol))) + (insert "(setq " (symbol-name list-symbol) "\n" + " '(") + (newline-and-indent) + (set list-symbol + (sort value (lambda (x y) (string-lessp (symbol-name x) + (symbol-name y))))) + (mapc #'(lambda (cmd) (insert (format "%S" cmd)) (newline-and-indent)) + value) + (insert "))") + (newline))) + +(defun mc/save-lists () + "Saves preferences for running commands with multiple cursors to `mc/list-file'" + (with-temp-file mc/list-file + (emacs-lisp-mode) + (insert ";; This file is automatically generated by the multiple-cursors extension.") + (newline) + (insert ";; It keeps track of your preferences for running commands with multiple cursors.") + (newline) + (newline) + (mc/dump-list 'mc/cmds-to-run-for-all) + (newline) + (mc/dump-list 'mc/cmds-to-run-once))) + +(defvar mc/cmds-to-run-once nil + "Commands to run only once in multiple-cursors-mode.") + +(defvar mc--default-cmds-to-run-once nil + "Default set of commands to run only once in multiple-cursors-mode.") + +(setq mc--default-cmds-to-run-once '(mc/edit-lines + mc/edit-ends-of-lines + mc/edit-beginnings-of-lines + mc/mark-next-like-this + mc/mark-next-word-like-this + mc/mark-next-symbol-like-this + mc/mark-previous-like-this + mc/mark-previous-word-like-this + mc/mark-previous-symbol-like-this + mc/mark-all-like-this + mc/mark-all-words-like-this + mc/mark-all-symbols-like-this + mc/mark-more-like-this-extended + mc/mark-all-like-this-in-defun + mc/mark-all-words-like-this-in-defun + mc/mark-all-symbols-like-this-in-defun + mc/mark-all-like-this-dwim + mc/mark-all-dwim + mc/mark-sgml-tag-pair + mc/insert-numbers + mc/sort-regions + mc/reverse-regions + mc/cycle-forward + mc/cycle-backward + mc/add-cursor-on-click + mc/mark-pop + mc/add-cursors-to-all-matches + mc/mmlte--left + mc/mmlte--right + mc/mmlte--up + mc/mmlte--down + mc/unmark-next-like-this + mc/unmark-previous-like-this + mc/skip-to-next-like-this + mc/skip-to-previous-like-this + rrm/switch-to-multiple-cursors + save-buffer + ido-exit-minibuffer + exit-minibuffer + minibuffer-complete-and-exit + execute-extended-command + undo + redo + undo-tree-undo + undo-tree-redo + universal-argument + universal-argument-more + universal-argument-other-key + negative-argument + digit-argument + top-level + recenter-top-bottom + describe-mode + describe-key-1 + describe-function + describe-bindings + describe-prefix-bindings + view-echo-area-messages + other-window + kill-buffer-and-window + split-window-right + split-window-below + delete-other-windows + toggle-window-split + mwheel-scroll + scroll-up-command + scroll-down-command + mouse-set-point + mouse-drag-region + quit-window + toggle-read-only + windmove-left + windmove-right + windmove-up + windmove-down)) + +(defvar mc--default-cmds-to-run-for-all nil + "Default set of commands that should be mirrored by all cursors") + +(setq mc--default-cmds-to-run-for-all '(mc/keyboard-quit + self-insert-command + quoted-insert + previous-line + next-line + newline + newline-and-indent + open-line + delete-blank-lines + transpose-chars + transpose-lines + transpose-paragraphs + transpose-regions + join-line + right-char + right-word + forward-char + forward-word + left-char + left-word + backward-char + backward-word + forward-paragraph + backward-paragraph + upcase-word + downcase-word + capitalize-word + forward-list + backward-list + hippie-expand + hippie-expand-lines + yank + yank-pop + append-next-kill + kill-word + kill-line + kill-whole-line + backward-kill-word + backward-delete-char-untabify + delete-char delete-forward-char + delete-backward-char + py-electric-backspace + c-electric-backspace + org-delete-backward-char + python-indent-dedent-line-backspace + paredit-backward-delete + autopair-backspace + just-one-space + zap-to-char + end-of-line + set-mark-command + exchange-point-and-mark + cua-set-mark + cua-replace-region + move-end-of-line + beginning-of-line + move-beginning-of-line + kill-ring-save + back-to-indentation + subword-forward + subword-backward + subword-mark + subword-kill + subword-backward-kill + subword-transpose + subword-capitalize + subword-upcase + subword-downcase + er/expand-region + er/contract-region + smart-forward + smart-backward + smart-up + smart-down)) + +(defvar mc/cmds-to-run-for-all nil + "Commands to run for all cursors in multiple-cursors-mode") + +(load mc/list-file t) ;; load, but no errors if it does not exist yet please + +(provide 'multiple-cursors-core) + +;; Local Variables: +;; coding: utf-8 +;; byte-compile-warnings: (not cl-functions) +;; End: + +;;; multiple-cursors-core.el ends here diff --git a/elpa/multiple-cursors-20140105.259/multiple-cursors-pkg.el b/elpa/multiple-cursors-20140105.259/multiple-cursors-pkg.el new file mode 100644 index 00000000..5d24fdaf --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/multiple-cursors-pkg.el @@ -0,0 +1 @@ +(define-package "multiple-cursors" "20140105.259" "Multiple cursors for Emacs." 'nil) diff --git a/elpa/multiple-cursors-20140105.259/multiple-cursors.el b/elpa/multiple-cursors-20140105.259/multiple-cursors.el new file mode 100644 index 00000000..9c847ee6 --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/multiple-cursors.el @@ -0,0 +1,191 @@ +;;; multiple-cursors.el --- Multiple cursors for emacs. + +;; Copyright (C) 2012-2013 Magnar Sveen + +;; Author: Magnar Sveen +;; Version: 1.2.2 +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Multiple cursors for Emacs. This is some pretty crazy functionality, so yes, +;; there are kinks. Don't be afraid tho, I've been using it since 2011 with +;; great success and much merriment. + +;; ## Basic usage + +;; Start out with: + +;; (require 'multiple-cursors) + +;; Then you have to set up your keybindings - multiple-cursors doesn't presume to +;; know how you'd like them laid out. Here are some examples: + +;; When you have an active region that spans multiple lines, the following will +;; add a cursor to each line: + +;; (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines) + +;; When you want to add multiple cursors not based on continuous lines, but based on +;; keywords in the buffer, use: + +;; (global-set-key (kbd "C->") 'mc/mark-next-like-this) +;; (global-set-key (kbd "C-<") 'mc/mark-previous-like-this) +;; (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this) + +;; First mark the word, then add more cursors. + +;; To get out of multiple-cursors-mode, press `` or `C-g`. The latter will +;; first disable multiple regions before disabling multiple cursors. If you want to +;; insert a newline in multiple-cursors-mode, use `C-j`. + +;; ## Video + +;; You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.com/e13.html). + +;; ## Command overview + +;; ### Mark one more occurrence + +;; - `mc/mark-next-like-this`: Adds a cursor and region at the next part of the buffer forwards that matches the current region. +;; - `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words. +;; - `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols. +;; - `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region. +;; - `mc/mark-previous-word-like-this`: Like `mc/mark-previous-like-this` but only for whole words. +;; - `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols. +;; - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurances. +;; - `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section. + +;; ### Mark many occurrences + +;; - `mc/mark-all-like-this`: Marks all parts of the buffer that matches the current region. +;; - `mc/mark-all-words-like-this`: Like `mc/mark-all-like-this` but only for whole words. +;; - `mc/mark-all-symbols-like-this`: Like `mc/mark-all-like-this` but only for whole symbols. +;; - `mc/mark-all-in-region`: Prompts for a string to match in the region, adding cursors to all of them. +;; - `mc/mark-all-like-this-in-defun`: Marks all parts of the current defun that matches the current region. +;; - `mc/mark-all-words-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole words. +;; - `mc/mark-all-symbols-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole symbols. +;; - `mc/mark-all-like-this-dwim`: Tries to be smart about marking everything you want. Can be pressed multiple times. + +;; ### Special + +;; - `set-rectangular-region-anchor`: Think of this one as `set-mark` except you're marking a rectangular region. +;; - `mc/mark-sgml-tag-pair`: Mark the current opening and closing tag. +;; - `mc/insert-numbers`: Insert increasing numbers for each cursor, top to bottom. +;; - `mc/sort-regions`: Sort the marked regions alphabetically. +;; - `mc/reverse-regions`: Reverse the order of the marked regions. + +;; ## Tips and tricks + +;; - To get out of multiple-cursors-mode, press `` or `C-g`. The latter will +;; first disable multiple regions before disabling multiple cursors. If you want to +;; insert a newline in multiple-cursors-mode, use `C-j`. +;; +;; - Sometimes you end up with cursors outside of your view. You can +;; scroll the screen to center on each cursor with `C-v` and `M-v`. +;; +;; - Try pressing `mc/mark-next-like-this` with no region selected. It will just add a cursor +;; on the next line. +;; +;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode. +;; +;; - Notice that the number of cursors active can be seen in the modeline. +;; +;; - If you get out of multiple-cursors-mode and yank - it will yank only +;; from the kill-ring of main cursor. To yank from the kill-rings of +;; every cursor use yank-rectangle, normally found at C-x r y. +;; +;; - You can use `mc/reverse-regions` with nothing selected and just one cursor. +;; It will then flip the sexp at point and the one below it. +;; +;; - If you would like to keep the global bindings clean, and get custom keybindings +;; when the region is active, you can try [region-bindings-mode](https://github.com/fgallina/region-bindings-mode). +;; +;; BTW, I highly recommend adding `mc/mark-next-like-this` to a key binding that's +;; right next to the key for `er/expand-region`. + +;; ### Binding mouse events + +;; To override a mouse event, you will likely have to also unbind the +;; `down-mouse` part of the event. Like this: +;; +;; (global-unset-key (kbd "M-")) +;; (global-set-key (kbd "M-") 'mc/add-cursor-on-click) +;; +;; Or you can do like me and find an unused, but less convenient, binding: +;; +;; (global-set-key (kbd "C-S-") 'mc/add-cursor-on-click) + +;; ## Unknown commands + +;; Multiple-cursors uses two lists of commands to know what to do: the run-once list +;; and the run-for-all list. It comes with a set of defaults, but it would be beyond silly +;; to try and include all the known Emacs commands. + +;; So that's why multiple-cursors occasionally asks what to do about a command. It will +;; then remember your choice by saving it in `~/.emacs.d/.mc-lists.el`. You can change +;; the location with: + +;; (setq mc/list-file "/my/preferred/file") + +;; ## Known limitations + +;; * isearch-forward and isearch-backward aren't supported with multiple cursors. +;; You should feel free to add a simplified version that can work with it. +;; * Commands run with `M-x` won't be repeated for all cursors. +;; * All key bindings that refer to lambdas are always run for all cursors. If you +;; need to limit it, you will have to give it a name. +;; * Redo might screw with your cursors. Undo works very well. + +;; ## Contribute + +;; Yes, please do. There's a suite of tests, so remember to add tests for your +;; specific feature, or I might break it later. + +;; You'll find the repo at: + +;; https://github.com/magnars/multiple-cursors.el + +;; To fetch the test dependencies: + +;; $ cd /path/to/multiple-cursors +;; $ git submodule update --init + +;; Run the tests with: + +;; $ ./util/ecukes/ecukes --graphical + +;; ## Contributors + +;; * [Takafumi Arakaki](https://github.com/tkf) made .mc-lists.el diff friendly +;; * [Marco Baringer](https://github.com/segv) contributed looping to mc/cycle and adding cursors without region for mark-more. +;; * [Ivan Andrus](https://github.com/gvol) added showing number of cursors in mode-line +;; * [Fuco](https://github.com/Fuco1) added the first version of `mc/mark-all-like-this-dwim` + +;; Thanks! + +;;; Code: + +(require 'mc-edit-lines) +(require 'mc-cycle-cursors) +(require 'mc-mark-more) +(require 'mc-mark-pop) +(require 'rectangular-region-mode) +(require 'mc-separate-operations) + +(provide 'multiple-cursors) + +;;; multiple-cursors.el ends here diff --git a/elpa/multiple-cursors-20140105.259/rectangular-region-mode.el b/elpa/multiple-cursors-20140105.259/rectangular-region-mode.el new file mode 100644 index 00000000..6bd54c75 --- /dev/null +++ b/elpa/multiple-cursors-20140105.259/rectangular-region-mode.el @@ -0,0 +1,124 @@ +;;; rectangular-region-mode.el + +;; Copyright (C) 2012 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; (global-set-key (kbd "H-SPC") 'set-rectangular-region-anchor) + +;; Think of this one as `set-mark` except you're marking a rectangular region. It is +;; an exceedingly quick way of adding multiple cursors to multiple lines. + +;;; Code: + +(require 'multiple-cursors-core) + +(defvar rrm/anchor (make-marker) + "The position in the buffer that anchors the rectangular region.") + +(defvar rectangular-region-mode-map (make-sparse-keymap) + "Keymap for rectangular region is mainly for rebinding C-g") + +(define-key rectangular-region-mode-map (kbd "C-g") 'rrm/keyboard-quit) +(define-key rectangular-region-mode-map (kbd "") 'rrm/switch-to-multiple-cursors) + +(defvar rectangular-region-mode nil) + +(defun rrm/keyboard-quit () + "Exit rectangular-region-mode." + (interactive) + (rectangular-region-mode 0) + (rrm/remove-rectangular-region-overlays) + (deactivate-mark)) + +;; Bind this to a key (for instance H-SPC) to start rectangular-region-mode +;;;###autoload +(defun set-rectangular-region-anchor () + "Anchors the rectangular region at point. + +Think of this one as `set-mark' except you're marking a rectangular region. It is +an exceedingly quick way of adding multiple cursors to multiple lines." + (interactive) + (set-marker rrm/anchor (point)) + (push-mark (point)) + (rectangular-region-mode 1)) + +(defun rrm/remove-rectangular-region-overlays () + "Remove all rectangular-region overlays." + (mc/remove-fake-cursors) + (mapc #'(lambda (o) + (when (eq (overlay-get o 'type) 'additional-region) + (delete-overlay o))) + (overlays-in (point-min) (point-max)))) + +(defun rrm/repaint () + "Start from the anchor and draw a rectangle between it and point." + (if (not rectangular-region-mode) + (remove-hook 'post-command-hook 'rrm/repaint t) + ;; else + (rrm/remove-rectangular-region-overlays) + (let* ((annoying-arrows-mode nil) + (point-column (current-column)) + (point-line (line-number-at-pos)) + (anchor-column (save-excursion (goto-char rrm/anchor) (current-column))) + (anchor-line (save-excursion (goto-char rrm/anchor) (line-number-at-pos))) + (left-column (if (< point-column anchor-column) point-column anchor-column)) + (right-column (if (> point-column anchor-column) point-column anchor-column)) + (navigation-step (if (< point-line anchor-line) 1 -1))) + (move-to-column anchor-column) + (set-mark (point)) + (move-to-column point-column) + (mc/save-excursion + (while (not (= anchor-line (line-number-at-pos))) + (forward-line navigation-step) + (move-to-column anchor-column) + (when (= anchor-column (current-column)) + (set-mark (point)) + (move-to-column point-column) + (when (= point-column (current-column)) + (mc/create-fake-cursor-at-point)))))))) + +(defun rrm/switch-to-multiple-cursors (&rest forms) + "Switch from rectangular-region-mode to multiple-cursors-mode." + (interactive) + (rectangular-region-mode 0) + (multiple-cursors-mode 1)) + +(defadvice er/expand-region (before switch-from-rrm-to-mc activate) + (when rectangular-region-mode + (rrm/switch-to-multiple-cursors))) + +(defadvice kill-ring-save (before switch-from-rrm-to-mc activate) + (when rectangular-region-mode + (rrm/switch-to-multiple-cursors))) + +(define-minor-mode rectangular-region-mode + "A mode for creating a rectangular region to edit" + nil " rr" rectangular-region-mode-map + (if rectangular-region-mode + (progn + (add-hook 'after-change-functions 'rrm/switch-to-multiple-cursors t t) + (add-hook 'post-command-hook 'rrm/repaint t t)) + (remove-hook 'after-change-functions 'rrm/switch-to-multiple-cursors t) + (remove-hook 'post-command-hook 'rrm/repaint t) + (set-marker rrm/anchor nil))) + +(provide 'rectangular-region-mode) + +;;; rectangular-region-mode.el ends here diff --git a/elpa/multiple-cursors-readme.txt b/elpa/multiple-cursors-readme.txt new file mode 100644 index 00000000..798b679a --- /dev/null +++ b/elpa/multiple-cursors-readme.txt @@ -0,0 +1,155 @@ +Multiple cursors for Emacs. This is some pretty crazy functionality, so yes, +there are kinks. Don't be afraid tho, I've been using it since 2011 with +great success and much merriment. + +## Basic usage + +Start out with: + + (require 'multiple-cursors) + +Then you have to set up your keybindings - multiple-cursors doesn't presume to +know how you'd like them laid out. Here are some examples: + +When you have an active region that spans multiple lines, the following will +add a cursor to each line: + + (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines) + +When you want to add multiple cursors not based on continuous lines, but based on +keywords in the buffer, use: + + (global-set-key (kbd "C->") 'mc/mark-next-like-this) + (global-set-key (kbd "C-<") 'mc/mark-previous-like-this) + (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this) + +First mark the word, then add more cursors. + +To get out of multiple-cursors-mode, press `` or `C-g`. The latter will +first disable multiple regions before disabling multiple cursors. If you want to +insert a newline in multiple-cursors-mode, use `C-j`. + +## Video + +You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.com/e13.html). + +## Command overview + +### Mark one more occurrence + + - `mc/mark-next-like-this`: Adds a cursor and region at the next part of the buffer forwards that matches the current region. + - `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words. + - `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols. + - `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region. + - `mc/mark-previous-word-like-this`: Like `mc/mark-previous-like-this` but only for whole words. + - `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols. + - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurances. + - `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section. + +### Mark many occurrences + + - `mc/mark-all-like-this`: Marks all parts of the buffer that matches the current region. + - `mc/mark-all-words-like-this`: Like `mc/mark-all-like-this` but only for whole words. + - `mc/mark-all-symbols-like-this`: Like `mc/mark-all-like-this` but only for whole symbols. + - `mc/mark-all-in-region`: Prompts for a string to match in the region, adding cursors to all of them. + - `mc/mark-all-like-this-in-defun`: Marks all parts of the current defun that matches the current region. + - `mc/mark-all-words-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole words. + - `mc/mark-all-symbols-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole symbols. + - `mc/mark-all-like-this-dwim`: Tries to be smart about marking everything you want. Can be pressed multiple times. + +### Special + + - `set-rectangular-region-anchor`: Think of this one as `set-mark` except you're marking a rectangular region. + - `mc/mark-sgml-tag-pair`: Mark the current opening and closing tag. + - `mc/insert-numbers`: Insert increasing numbers for each cursor, top to bottom. + - `mc/sort-regions`: Sort the marked regions alphabetically. + - `mc/reverse-regions`: Reverse the order of the marked regions. + +## Tips and tricks + +- To get out of multiple-cursors-mode, press `` or `C-g`. The latter will + first disable multiple regions before disabling multiple cursors. If you want to + insert a newline in multiple-cursors-mode, use `C-j`. + +- Sometimes you end up with cursors outside of your view. You can + scroll the screen to center on each cursor with `C-v` and `M-v`. + +- Try pressing `mc/mark-next-like-this` with no region selected. It will just add a cursor + on the next line. + +- Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode. + +- Notice that the number of cursors active can be seen in the modeline. + +- If you get out of multiple-cursors-mode and yank - it will yank only + from the kill-ring of main cursor. To yank from the kill-rings of + every cursor use yank-rectangle, normally found at C-x r y. + +- You can use `mc/reverse-regions` with nothing selected and just one cursor. + It will then flip the sexp at point and the one below it. + +- If you would like to keep the global bindings clean, and get custom keybindings + when the region is active, you can try [region-bindings-mode](https://github.com/fgallina/region-bindings-mode). + +BTW, I highly recommend adding `mc/mark-next-like-this` to a key binding that's +right next to the key for `er/expand-region`. + +### Binding mouse events + +To override a mouse event, you will likely have to also unbind the +`down-mouse` part of the event. Like this: + + (global-unset-key (kbd "M-")) + (global-set-key (kbd "M-") 'mc/add-cursor-on-click) + +Or you can do like me and find an unused, but less convenient, binding: + + (global-set-key (kbd "C-S-") 'mc/add-cursor-on-click) + +## Unknown commands + +Multiple-cursors uses two lists of commands to know what to do: the run-once list +and the run-for-all list. It comes with a set of defaults, but it would be beyond silly +to try and include all the known Emacs commands. + +So that's why multiple-cursors occasionally asks what to do about a command. It will +then remember your choice by saving it in `~/.emacs.d/.mc-lists.el`. You can change +the location with: + + (setq mc/list-file "/my/preferred/file") + +## Known limitations + +* isearch-forward and isearch-backward aren't supported with multiple cursors. + You should feel free to add a simplified version that can work with it. +* Commands run with `M-x` won't be repeated for all cursors. +* All key bindings that refer to lambdas are always run for all cursors. If you + need to limit it, you will have to give it a name. +* Redo might screw with your cursors. Undo works very well. + +## Contribute + +Yes, please do. There's a suite of tests, so remember to add tests for your +specific feature, or I might break it later. + +You'll find the repo at: + + https://github.com/magnars/multiple-cursors.el + +To fetch the test dependencies: + + $ cd /path/to/multiple-cursors + $ git submodule update --init + +Run the tests with: + + $ ./util/ecukes/ecukes --graphical + +## Contributors + +* [Takafumi Arakaki](https://github.com/tkf) made .mc-lists.el diff friendly +* [Marco Baringer](https://github.com/segv) contributed looping to mc/cycle and adding cursors without region for mark-more. +* [Ivan Andrus](https://github.com/gvol) added showing number of cursors in mode-line +* [Fuco](https://github.com/Fuco1) added the first version of `mc/mark-all-like-this-dwim` + +Thanks! diff --git a/init.el b/init.el index 62c84ee4..7c6fac89 100644 --- a/init.el +++ b/init.el @@ -78,6 +78,9 @@ (setq flyspell-issue-welcome-flag nil) +(add-hook 'after-init-hook + '(lambda () (setq debug-on-error t))) + ;; ============================================================================= ;; Misc ;; ============================================================================= @@ -189,6 +192,14 @@ ;; Macros (fset 'ipdb "import ipdb; ipdb.set_trace()") +;; Multiple Cursors + +(global-set-key (kbd "C-x r t") 'mc/edit-lines) + +(global-set-key (kbd "C->") 'mc/mark-next-like-this) +(global-set-key (kbd "C-<") 'mc/mark-previous-like-this) +(global-set-key (kbd "C-c <") 'mc/mark-all-like-this) + ;; ============================================================================= ;; ELPA ;; ============================================================================= diff --git a/lisp/multi-line-it b/lisp/multi-line-it index da2e474e..c62ca553 160000 --- a/lisp/multi-line-it +++ b/lisp/multi-line-it @@ -1 +1 @@ -Subproject commit da2e474ec816c0f22037becc355d339899ddc1dd +Subproject commit c62ca553af2e23b7e06113b1b90f5c3165fe68a2