expand-region.el (8506B)
1 ;;; expand-region.el --- Increase selected region by semantic units. -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2011-2023 Free Software Foundation, Inc 4 5 ;; Author: Magnar Sveen <magnars@gmail.com> 6 ;; Keywords: marking region 7 ;; URL: https://github.com/magnars/expand-region.el 8 ;; Version: 1.0.0 9 ;; Package-Requires: ((emacs "24.4")) 10 11 ;; This program is free software; you can redistribute it and/or modify 12 ;; it under the terms of the GNU General Public License as published by 13 ;; the Free Software Foundation, either version 3 of the License, or 14 ;; (at your option) any later version. 15 16 ;; This program is distributed in the hope that it will be useful, 17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 ;; GNU General Public License for more details. 20 21 ;; You should have received a copy of the GNU General Public License 22 ;; along with this program. If not, see <http://www.gnu.org/licenses/>. 23 24 ;;; Commentary: 25 26 ;; Expand region increases the selected region by semantic units. Just keep 27 ;; pressing the key until it selects what you want. 28 29 ;; An example: 30 31 ;; (setq alphabet-start "abc def") 32 33 ;; With the cursor at the `c`, it starts by marking the entire word `abc`, then 34 ;; expand to the contents of the quotes `abc def`, then to the entire quote 35 ;; `"abc def"`, then to the contents of the sexp `setq alphabet-start "abc def"` 36 ;; and finally to the entire sexp. 37 38 ;; You can set it up like this: 39 40 ;; (require 'expand-region) 41 ;; (global-set-key (kbd "C-=") 'er/expand-region) 42 43 ;; There's also `er/contract-region` if you expand too far. 44 45 ;; ## Video 46 47 ;; You can [watch an intro to expand-region at Emacs Rocks](http://emacsrocks.com/e09.html). 48 49 ;; ## Language support 50 51 ;; Expand region works fairly well with most languages, due to the general 52 ;; nature of the basic expansions: 53 54 ;; er/mark-word 55 ;; er/mark-symbol 56 ;; er/mark-method-call 57 ;; er/mark-inside-quotes 58 ;; er/mark-outside-quotes 59 ;; er/mark-inside-pairs 60 ;; er/mark-outside-pairs 61 62 ;; However, most languages also will benefit from some specially crafted 63 ;; expansions. For instance, expand-region comes with these extra expansions for 64 ;; html-mode: 65 66 ;; er/mark-html-attribute 67 ;; er/mark-inner-tag 68 ;; er/mark-outer-tag 69 70 ;; You can add your own expansions to the languages of your choice simply by 71 ;; creating a function that looks around point to see if it's inside or looking 72 ;; at the construct you want to mark, and if so - mark it. 73 74 ;; There's plenty of examples to look at in these files. 75 76 ;; After you make your function, add it to a buffer-local version of 77 ;; the `er/try-expand-list`. 78 79 ;; **Example:** 80 81 ;; Let's say you want expand-region to also mark paragraphs and pages in 82 ;; text-mode. Incidentally Emacs already comes with `mark-paragraph` and 83 ;; `mark-page`. To add it to the try-list, do this: 84 85 ;; (defun er/add-text-mode-expansions () 86 ;; (setq-local er/try-expand-list (append 87 ;; er/try-expand-list 88 ;; '(mark-paragraph 89 ;; mark-page)))) 90 91 ;; (er/enable-mode-expansions 'text-mode #'er/add-text-mode-expansions) 92 93 ;; Add that to its own file, and require it at the bottom of this one, 94 ;; where it says "Mode-specific expansions" 95 96 ;; **Warning:** Badly written expansions might slow down expand-region 97 ;; dramatically. Remember to exit quickly before you start traversing 98 ;; the entire document looking for constructs to mark. 99 100 ;; ## Contribute 101 102 ;; If you make some nice expansions for your favorite mode, it would be 103 ;; great if you opened a pull-request. The repo is at: 104 105 ;; https://github.com/magnars/expand-region.el 106 107 ;; Changes to `expand-region-core` itself must be accompanied by feature tests. 108 ;; They are written in [Ecukes](http://ecukes.info), a Cucumber for Emacs. 109 110 ;; To fetch the test dependencies: 111 112 ;; $ cd /path/to/expand-region 113 ;; $ git submodule init 114 ;; $ git submodule update 115 116 ;; Run the tests with: 117 118 ;; $ ./util/ecukes/ecukes features 119 120 ;; If you want to add feature-tests for your mode-specific expansions as well, 121 ;; that is utterly excellent. 122 123 ;; ## Contributors 124 125 ;; * [Josh Johnston](https://github.com/joshwnj) contributed `er/contract-region` 126 ;; * [Le Wang](https://github.com/lewang) contributed consistent handling of the mark ring, expanding into pairs/quotes just left of the cursor, and general code clean-up. 127 ;; * [Matt Briggs](https://github.com/mbriggs) contributed expansions for ruby-mode. 128 ;; * [Ivan Andrus](https://github.com/gvol) contributed expansions for python-mode, text-mode, LaTeX-mode and nxml-mode. 129 ;; * [Raimon Grau](https://github.com/kidd) added support for when transient-mark-mode is off. 130 ;; * [Gleb Peregud](https://github.com/gleber) contributed expansions for erlang-mode. 131 ;; * [fgeller](https://github.com/fgeller) and [edmccard](https://github.com/edmccard) contributed better support for python and its multiple modes. 132 ;; * [François Févotte](https://github.com/ffevotte) contributed expansions for C and C++. 133 ;; * [Roland Walker](https://github.com/rolandwalker) added option to copy the contents of the most recent action to a register, and some fixes. 134 ;; * [Damien Cassou](https://github.com/DamienCassou) added option to continue expanding/contracting with fast keys after initial expand. 135 136 ;; Thanks! 137 138 ;;; Code: 139 140 (require 'expand-region-core) 141 (require 'expand-region-custom) 142 (require 'er-basic-expansions) 143 144 ;;;###autoload 145 (defun er/expand-region (arg) 146 "Increase selected region by semantic units. 147 148 With prefix argument expands the region that many times. 149 If prefix argument is negative calls `er/contract-region'. 150 If prefix argument is 0 it resets point and mark to their state 151 before calling `er/expand-region' for the first time." 152 (interactive "p") 153 (if (< arg 1) 154 (er/contract-region (- arg)) 155 (er--prepare-expanding) 156 (while (>= arg 1) 157 (setq arg (- arg 1)) 158 (when (eq 'early-exit (er--expand-region-1)) 159 (setq arg 0))) 160 (when (and expand-region-fast-keys-enabled 161 (not (memq last-command '(er/expand-region er/contract-region)))) 162 (er/prepare-for-more-expansions)))) 163 164 (eval-after-load 'clojure-mode '(require 'clojure-mode-expansions)) 165 (eval-after-load 'css-mode '(require 'css-mode-expansions)) 166 (eval-after-load 'erlang-mode '(require 'erlang-mode-expansions)) 167 (eval-after-load 'feature-mode '(require 'feature-mode-expansions)) 168 (eval-after-load 'sgml-mode '(require 'html-mode-expansions)) ;; html-mode is defined in sgml-mode.el 169 (eval-after-load 'rhtml-mode '(require 'html-mode-expansions)) 170 (eval-after-load 'nxhtml-mode '(require 'html-mode-expansions)) 171 (eval-after-load 'web-mode '(require 'web-mode-expansions)) 172 (eval-after-load 'js '(require 'js-mode-expansions)) 173 (eval-after-load 'js2-mode '(require 'js-mode-expansions)) 174 (eval-after-load 'js2-mode '(require 'js2-mode-expansions)) 175 (eval-after-load 'js3-mode '(require 'js-mode-expansions)) 176 (eval-after-load 'latex '(require 'latex-mode-expansions)) 177 (eval-after-load 'nxml-mode '(require 'nxml-mode-expansions)) 178 (eval-after-load 'octave-mod '(require 'octave-expansions)) 179 (eval-after-load 'octave '(require 'octave-expansions)) 180 (eval-after-load 'python '(progn 181 (when expand-region-guess-python-mode 182 (expand-region-guess-python-mode)) 183 (if (eq 'python expand-region-preferred-python-mode) 184 (require 'python-el-expansions) 185 (require 'python-el-fgallina-expansions)))) 186 (eval-after-load 'python-mode '(require 'python-mode-expansions)) 187 (eval-after-load 'ruby-mode '(require 'ruby-mode-expansions)) 188 (eval-after-load 'org '(require 'the-org-mode-expansions)) 189 (eval-after-load 'cc-mode '(require 'cc-mode-expansions)) 190 (eval-after-load 'text-mode '(require 'text-mode-expansions)) 191 (eval-after-load 'cperl-mode '(require 'cperl-mode-expansions)) 192 (eval-after-load 'sml-mode '(require 'sml-mode-expansions)) 193 (eval-after-load 'enh-ruby-mode '(require 'enh-ruby-mode-expansions)) 194 (eval-after-load 'subword '(require 'subword-mode-expansions)) 195 (eval-after-load 'yaml-mode '(require 'yaml-mode-expansions)) 196 197 (provide 'expand-region) 198 199 ;;; expand-region.el ends here