#+BEGIN_SRC emacs-lisp
(if (>= emacs-major-version 24)
(progn
- (add-to-list 'load-path "~/.emacs.d/elpa/expand-region-20220729.659")
+ (add-to-list 'load-path "~/.emacs.d/elpa/expand-region-20221030.957")
(require 'expand-region)
(define-key global-map (kbd "C-c C-<f12>") 'er/contract-region )
(define-key global-map (kbd "C-c <f12>") 'er/expand-region )
+++ /dev/null
-;;; cc-mode-expansions.el --- C-specific expansions for expand-region
-
-;; Copyright (C) 2012 François Févotte
-
-;; Author: François Févotte
-;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Extra expansions for C-like modes that I've found useful so far:
-;;
-;; er/c-mark-statement
-;; Captures simple and more complex statements.
-;;
-;; er/c-mark-fully-qualified-name
-;; Captures identifiers composed of several '::'-separated parts.
-;;
-;; er/c-mark-function-call[-1|-2]
-;; Captures an identifier followed by a '()'-enclosed block.
-;;
-;; er/c-mark-statement-block[-1|-2]
-;; Captures a statement followed by a '{}'-enclosed block.
-;; This matches function definitions and if/for/... constructs.
-;;
-;; er/c-mark-vector-access[-1|-2]
-;; Captures an identifier followed by a '[]'-enclosed block.
-;;
-;; Feel free to contribute any other expansions for C at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(require 'er-basic-expansions)
-(require 'cc-cmds)
-
-(defun er/c-mark-statement ()
- "Mark the current C statement.
-
-This function tries to ensure that pair-delimited substring are
-either fully inside or fully outside the statement."
- (interactive)
- (unless (use-region-p)
- (set-mark (point)))
-
- (if (< (point) (mark))
- (exchange-point-and-mark))
-
- ;; Contract the region a bit to make the
- ;; er/c-mark-statement function idempotent
- (when (>= (- (point) (mark)) 2)
- (exchange-point-and-mark)
- (forward-char)
- (exchange-point-and-mark)
- (backward-char))
-
- (let (beg end)
- ;; Determine boundaries of the outside-pairs region
- (save-mark-and-excursion
- (c-end-of-statement)
- (er/mark-outside-pairs)
- (setq beg (point)
- end (mark)))
-
- ;; Determine boundaries of the statement as given
- ;; by c-beginning-of-statement/c-end-of-statement
- (c-end-of-statement)
- (exchange-point-and-mark)
- (c-end-of-statement)(c-beginning-of-statement 1)
-
- ;; If the two regions overlap, expand the region
- (cond ((and (<= (point) beg)
- (< (mark) end))
- (set-mark end))
- ((and (> (point) beg)
- (>= (mark) end))
- (goto-char beg)
- (c-end-of-statement)
- (c-beginning-of-statement 1)))))
-
-(defun er/c-mark-fully-qualified-name ()
- "Mark the current C++ fully qualified identifier.
-
-This function captures identifiers composed of multiple
-'::'-separated parts."
- (interactive)
- (er/mark-symbol)
- (when (use-region-p)
- (when (> (point) (mark))
- (exchange-point-and-mark))
- (while (er/looking-back-exact "::")
- (backward-char 2)
- (skip-syntax-backward "_w"))
- (exchange-point-and-mark)
- (while (looking-at "::")
- (forward-char 2)
- (skip-syntax-forward "_w"))
- (exchange-point-and-mark)))
-
-(defmacro er/c-define-construct (name mark-first-part open-brace doc)
- (let ((docstring (make-symbol "docstring-tmp")))
- (setq docstring
- (concat
- doc "\n\n"
- "This function tries to mark a region consisting of two parts:\n"
- (format " - the first part is marked using `%s'\n" (symbol-name mark-first-part))
- (format " - the second part is a block beginning with '%s'\n\n" open-brace)))
- `(progn
- (defun ,(intern (concat (symbol-name name) "-1")) ()
- ,(concat docstring
- "This function assumes that point is in the first part and the\n"
- "region is active.\n\n"
- (format "See also `%s'." (concat (symbol-name name) "-2")))
- (interactive)
- (when (use-region-p)
- (,mark-first-part)
- (exchange-point-and-mark)
- (let ((oldpos (point)))
- (skip-syntax-forward " ")
- (if (looking-at ,open-brace)
- (progn (forward-sexp)
- (exchange-point-and-mark))
- (goto-char oldpos)))))
- (defun ,(intern (concat (symbol-name name) "-2")) ()
- ,(concat docstring
- "This function assumes that the block constituting the second part\n"
- "is already marked and active.\n\n"
- (format "See also `%s'." (concat (symbol-name name) "-1")))
- (interactive)
- (when (use-region-p)
- (when (> (point) (mark))
- (exchange-point-and-mark))
- (when (looking-at ,open-brace)
- (let ((beg (point))
- (end (progn (forward-sexp 1)
- (point))))
- (goto-char beg)
- (skip-syntax-backward " ")
- (backward-char)
- (deactivate-mark)
- (,mark-first-part)
- (set-mark end))))))))
-
-(er/c-define-construct er/c-mark-function-call er/c-mark-fully-qualified-name "("
- "Mark the current function call.")
-(er/c-define-construct er/c-mark-statement-block er/c-mark-statement "{"
- "Mark the current block construct (like if, for, etc.)")
-(er/c-define-construct er/c-mark-vector-access er/c-mark-fully-qualified-name "\\["
- "Mark the current vector access.")
-
-(defun er/add-cc-mode-expansions ()
- "Adds expansions for buffers in c-mode."
- (set (make-local-variable 'er/try-expand-list)
- (append er/try-expand-list
- '(er/c-mark-statement
- er/c-mark-fully-qualified-name
- er/c-mark-function-call-1 er/c-mark-function-call-2
- er/c-mark-statement-block-1 er/c-mark-statement-block-2
- er/c-mark-vector-access-1 er/c-mark-vector-access-2))))
-
-(er/enable-mode-expansions 'c-mode 'er/add-cc-mode-expansions)
-(er/enable-mode-expansions 'c++-mode 'er/add-cc-mode-expansions)
-(er/enable-mode-expansions 'objc-mode 'er/add-cc-mode-expansions)
-(er/enable-mode-expansions 'java-mode 'er/add-cc-mode-expansions)
-(er/enable-mode-expansions 'idl-mode 'er/add-cc-mode-expansions)
-(er/enable-mode-expansions 'pike-mode 'er/add-cc-mode-expansions)
-(er/enable-mode-expansions 'awk-mode 'er/add-cc-mode-expansions)
-
-(provide 'cc-mode-expansions)
-
-;; cc-mode-expansions.el ends here
+++ /dev/null
-;;; clojure-mode-expansions.el --- Clojure-specific expansions for expand-region
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Extra expansions for clojure-mode:
-;;
-;; * `er/mark-clj-word` - includes dashes, but not slashes.
-;; * `er/mark-clj-regexp-literal`
-;; * `er/mark-clj-function-literal`
-;;
-;; Feel free to contribute any other expansions for Clojure at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(require 'er-basic-expansions)
-
-(defun er/mark-clj-word ()
- "Mark the entire word around or in front of point, including dashes."
- (interactive)
- (let ((word-regexp "\\(\\sw\\|-\\)"))
- (when (or (looking-at word-regexp)
- (er/looking-back-on-line word-regexp))
- (while (looking-at word-regexp)
- (forward-char))
- (set-mark (point))
- (while (er/looking-back-on-line word-regexp)
- (backward-char)))))
-
-(defun er/mark-clj-set-literal ()
- "Mark clj-set-literal presumes that point is outside the brackets.
-If point is inside the brackets, those will be marked first anyway."
- (interactive)
- (when (or (looking-at "#{")
- (er/looking-back-exact "#"))
- (forward-char 1)
- (search-backward "#")
- (set-mark (point))
- (search-forward "{")
- (forward-char -1)
- (forward-list 1)
- (exchange-point-and-mark)))
-
-(defun er/mark-clj-regexp-literal ()
- "Mark clj-regexp-literal presumes that point is outside the string.
-If point is inside the string, the quotes will be marked first anyway."
- (interactive)
- (when (or (looking-at "#\"")
- (er/looking-back-exact "#"))
- (forward-char 1)
- (search-backward "#")
- (set-mark (point))
- (search-forward "\"")
- (forward-char 1)
- (er--move-point-forward-out-of-string)
- (exchange-point-and-mark)))
-
-(defun er/mark-clj-function-literal ()
- "Mark clj-function-literal presumes that point is outside the parens.
-If point is inside the parens, they will be marked first anyway."
- (interactive)
- (when (or (looking-at "#(")
- (er/looking-back-exact "#"))
- (forward-char)
- (search-backward "#")
- (set-mark (point))
- (search-forward "(")
- (backward-char)
- (forward-list)
- (exchange-point-and-mark)))
-
-(defun er/add-clojure-mode-expansions ()
- "Adds clojure-specific expansions for buffers in clojure-mode"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(er/mark-clj-word
- er/mark-clj-regexp-literal
- er/mark-clj-set-literal
- er/mark-clj-function-literal))))
-
-(er/enable-mode-expansions 'clojure-mode 'er/add-clojure-mode-expansions)
-(er/enable-mode-expansions 'nrepl-mode 'er/add-clojure-mode-expansions)
-
-(provide 'clojure-mode-expansions)
-
-;; clojure-mode-expansions.el ends here
+++ /dev/null
-;;; cperl-mode-expansions.el --- perl-specific expansions for expand-region
-
-;; Copyright (C) 2012 Kang-min Liu
-
-;; Author: Kang-min Liu <gugodNOSPAMgugod.org>
-;; Keywords: marking region cperl
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/mark-cperl-variable-name ()
- "Marks one perl variable"
- (interactive)
- (forward-word)
- (backward-word)
- (search-backward-regexp "[@$%]" (line-beginning-position))
- (set-mark (point))
- (forward-char)
- (search-forward-regexp "[^a-z_]" (line-end-position))
- (backward-char)
- (exchange-point-and-mark))
-
-(defun er/mark-cperl-package-name ()
- "Marks one perl package name"
- (interactive)
- (forward-sexp)
- (backward-sexp)
- (set-mark (point))
- (forward-sexp)
- (search-backward "::" (line-beginning-position))
- (exchange-point-and-mark))
-
-(defun er/mark-cperl-subroutine ()
- "Marks current subroutine body."
- (interactive)
- (end-of-defun)
- (set-mark (point))
- (beginning-of-defun))
-
-(defun er/add-cperl-mode-expansions ()
- "Add cprel mode expansinos"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(er/mark-cperl-variable-name
- er/mark-cperl-package-name
- er/mark-cperl-subroutine
- ))))
-
-(er/enable-mode-expansions 'cperl-mode 'er/add-cperl-mode-expansions)
-
-(provide 'cperl-mode-expansions)
-
-;; cperl-mode-expansions.el ends here
+++ /dev/null
-;;; css-mode-expansions.el --- CSS-specific expansions for expand-region
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; For now I have only found the need for mark-css-declaration.
-;;
-;; Feel free to contribute any other expansions for CSS at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/mark-css-declaration ()
- "Marks one CSS declaration, eg. font-weight: bold;"
- (interactive)
- (search-backward-regexp "[;{] ?" (line-beginning-position))
- (forward-char)
- (set-mark (point))
- (search-forward ";" (line-end-position))
- (exchange-point-and-mark))
-
-(defun er/add-css-mode-expansions ()
- "Adds CSS-specific expansions for buffers in css-mode"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(er/mark-css-declaration))))
-
-(er/enable-mode-expansions 'css-mode 'er/add-css-mode-expansions)
-
-(provide 'css-mode-expansions)
-
-;; css-mode-expansions.el ends here
+++ /dev/null
-;;; enh-ruby-mode-expansions.el --- Expansions for enh-ruby-mode
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; enh-ruby-mode doesn't use ruby-mode's mark-defun - it has its own.
-;;
-;; Feel free to contribute any other expansions for enh-ruby-mode at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(defun er/add-enh-ruby-mode-expansions ()
- "Adds Ruby-specific expansions for buffers in enh-ruby-mode"
- (require 'ruby-mode-expansions)
-
- (set (make-local-variable 'er/try-expand-list) (append
- (remove 'er/mark-defun er/try-expand-list)
- '(er/mark-ruby-instance-variable
- er/mark-ruby-block-up))))
-
-(er/enable-mode-expansions 'enh-ruby-mode 'er/add-enh-ruby-mode-expansions)
-
-(provide 'enh-ruby-mode-expansions)
+++ /dev/null
-;;; er-basic-expansions.el --- Words, symbols, strings, et al
-
-;; Copyright (C) 2011-2013 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Expansions that are useful in any major mode.
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/mark-word ()
- "Mark the entire word around or in front of point."
- (interactive)
- (let ((word-regexp "\\sw"))
- (when (or (looking-at word-regexp)
- (er/looking-back-on-line word-regexp))
- (skip-syntax-forward "w")
- (set-mark (point))
- (skip-syntax-backward "w"))))
-
-(defun er/mark-symbol ()
- "Mark the entire symbol around or in front of point."
- (interactive)
- (let ((symbol-regexp "\\s_\\|\\sw"))
- (when (or (looking-at symbol-regexp)
- (er/looking-back-on-line symbol-regexp))
- (skip-syntax-forward "_w")
- (set-mark (point))
- (skip-syntax-backward "_w"))))
-
-(defun er/mark-symbol-with-prefix ()
- "Mark the entire symbol around or in front of point, including prefix."
- (interactive)
- (let ((symbol-regexp "\\s_\\|\\sw")
- (prefix-regexp "\\s'"))
- (when (or (looking-at prefix-regexp)
- (looking-at symbol-regexp)
- (er/looking-back-on-line symbol-regexp))
- (skip-syntax-forward "'")
- (skip-syntax-forward "_w")
- (set-mark (point))
- (skip-syntax-backward "_w")
- (skip-syntax-backward "'"))))
-
-;; Mark method call
-
-(defun er/mark-next-accessor ()
- "Presumes that current symbol is already marked, skips over one
-period and marks next symbol."
- (interactive)
- (when (use-region-p)
- (when (< (point) (mark))
- (exchange-point-and-mark))
- (let ((symbol-regexp "\\s_\\|\\sw"))
- (when (looking-at "\\.")
- (forward-char 1)
- (skip-syntax-forward "_w")
- (exchange-point-and-mark)))))
-
-(defun er/mark-method-call ()
- "Mark the current symbol (including dots) and then paren to closing paren."
- (interactive)
- (let ((symbol-regexp "\\(\\s_\\|\\sw\\|\\.\\)+"))
- (when (or (looking-at symbol-regexp)
- (er/looking-back-on-line symbol-regexp))
- (skip-syntax-backward "_w.")
- (set-mark (point))
- (when (looking-at symbol-regexp)
- (goto-char (match-end 0)))
- (if (looking-at "(")
- (forward-list))
- (exchange-point-and-mark))))
-
-;; Comments
-
-(defun er--point-is-in-comment-p ()
- "t if point is in comment, otherwise nil"
- (or (nth 4 (syntax-ppss))
- (memq (get-text-property (point) 'face) '(font-lock-comment-face font-lock-comment-delimiter-face))))
-
-(defun er/mark-comment ()
- "Mark the entire comment around point."
- (interactive)
- (when (er--point-is-in-comment-p)
- (let ((p (point)))
- (while (and (er--point-is-in-comment-p) (not (eobp)))
- (forward-char 1))
- (skip-chars-backward "\n\r")
- (set-mark (point))
- (goto-char p)
- (while (er--point-is-in-comment-p)
- (forward-char -1))
- (forward-char 1))))
-
-;; Quotes
-
-(defun er--current-quotes-char ()
- "The char that is the current quote delimiter"
- (nth 3 (syntax-ppss)))
-
-(defalias 'er--point-inside-string-p 'er--current-quotes-char)
-
-(defun er--move-point-forward-out-of-string ()
- "Move point forward until it exits the current quoted string."
- (er--move-point-backward-out-of-string)
- (forward-sexp))
-
-(defun er--move-point-backward-out-of-string ()
- "Move point backward until it exits the current quoted string."
- (goto-char (nth 8 (syntax-ppss))))
-
-(defun er/mark-inside-quotes ()
- "Mark the inside of the current string, not including the quotation marks."
- (interactive)
- (when (er--point-inside-string-p)
- (er--move-point-backward-out-of-string)
- (forward-char)
- (set-mark (point))
- (er--move-point-forward-out-of-string)
- (backward-char)
- (exchange-point-and-mark)))
-
-(defun er/mark-outside-quotes ()
- "Mark the current string, including the quotation marks."
- (interactive)
- (if (er--point-inside-string-p)
- (er--move-point-backward-out-of-string)
- (when (and (not (use-region-p))
- (er/looking-back-on-line "\\s\""))
- (backward-char)
- (er--move-point-backward-out-of-string)))
- (when (looking-at "\\s\"")
- (set-mark (point))
- (forward-char)
- (er--move-point-forward-out-of-string)
- (exchange-point-and-mark)))
-
-;; Pairs - ie [] () {} etc
-
-(defun er--point-inside-pairs-p ()
- "Is point inside any pairs?"
- (> (car (syntax-ppss)) 0))
-
-(defun er/mark-inside-pairs ()
- "Mark inside pairs (as defined by the mode), not including the pairs."
- (interactive)
- (when (er--point-inside-pairs-p)
- (goto-char (nth 1 (syntax-ppss)))
- (set-mark (save-excursion
- (forward-char 1)
- (skip-chars-forward er--space-str)
- (point)))
- (forward-list)
- (backward-char)
- (skip-chars-backward er--space-str)
- (exchange-point-and-mark)))
-
-(defun er--looking-at-pair ()
- "Is point looking at an opening pair char?"
- (looking-at "\\s("))
-
-(defun er--looking-at-marked-pair ()
- "Is point looking at a pair that is entirely marked?"
- (and (er--looking-at-pair)
- (use-region-p)
- (>= (mark)
- (save-excursion
- (forward-list)
- (point)))))
-
-(defun er/mark-outside-pairs ()
- "Mark pairs (as defined by the mode), including the pair chars."
- (interactive)
- (if (and (er/looking-back-on-line "\\s)+\\=")
- (not (er--looking-at-pair)))
- (ignore-errors (backward-list 1))
- (skip-chars-forward er--space-str))
- (when (and (er--point-inside-pairs-p)
- (or (not (er--looking-at-pair))
- (er--looking-at-marked-pair)))
- (goto-char (nth 1 (syntax-ppss))))
- (when (er--looking-at-pair)
- (set-mark (point))
- (forward-list)
- (exchange-point-and-mark)))
-
-(require 'thingatpt)
-
-(defun er/mark-url ()
- (interactive)
- (end-of-thing 'url)
- (set-mark (point))
- (beginning-of-thing 'url))
-
-(defun er/mark-email ()
- (interactive)
- (end-of-thing 'email)
- (set-mark (point))
- (beginning-of-thing 'email))
-
-(defun er/mark-defun ()
- "Mark defun around or in front of point."
- (interactive)
- (end-of-defun)
- (skip-chars-backward er--space-str)
- (set-mark (point))
- (beginning-of-defun)
- (skip-chars-forward er--space-str))
-
-;; Methods to try expanding to
-(setq er/try-expand-list
- (append '(er/mark-word
- er/mark-symbol
- er/mark-symbol-with-prefix
- er/mark-next-accessor
- er/mark-method-call
- er/mark-inside-quotes
- er/mark-outside-quotes
- er/mark-inside-pairs
- er/mark-outside-pairs
- er/mark-comment
- er/mark-url
- er/mark-email
- er/mark-defun)
- er/try-expand-list))
-
-(provide 'er-basic-expansions)
-;;; er-basic-expansions.el ends here
+++ /dev/null
-;;; erlang-mode-expansions.el --- Erlang-specific expansions for expand-region
-
-;; Copyright (C) 2012 Gleb Peregud
-
-;; Author: Gleb Peregud
-;; Based on python-mode-expansions by: Ivan Andrus <darthandrusNOSPAMgmail.com>
-;; Keywords: marking region erlang
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Feel free to contribute any other expansions for Erlang at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Bugs:
-
-;; Doesn't handle many Erlang syntax constructs, just the basics
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/add-erlang-mode-expansions ()
- "Adds Erlang-specific expansions for buffers in erlang-mode"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(erlang-mark-function
- erlang-mark-clause))))
-
-(er/enable-mode-expansions 'erlang-mode 'er/add-erlang-mode-expansions)
-
-(provide 'erlang-mode-expansions)
-
-;; erlang-mode-expansions.el ends here
+++ /dev/null
-;;; expand-region-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
- (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "cc-mode-expansions" "cc-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from cc-mode-expansions.el
-
-(register-definition-prefixes "cc-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "clojure-mode-expansions" "clojure-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from clojure-mode-expansions.el
-
-(register-definition-prefixes "clojure-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "cperl-mode-expansions" "cperl-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from cperl-mode-expansions.el
-
-(register-definition-prefixes "cperl-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "css-mode-expansions" "css-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from css-mode-expansions.el
-
-(register-definition-prefixes "css-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "enh-ruby-mode-expansions" "enh-ruby-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from enh-ruby-mode-expansions.el
-
-(register-definition-prefixes "enh-ruby-mode-expansions" '("er/add-enh-ruby-mode-expansions"))
-
-;;;***
-\f
-;;;### (autoloads nil "er-basic-expansions" "er-basic-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from er-basic-expansions.el
-
-(register-definition-prefixes "er-basic-expansions" '("er--" "er/mark-"))
-
-;;;***
-\f
-;;;### (autoloads nil "erlang-mode-expansions" "erlang-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from erlang-mode-expansions.el
-
-(register-definition-prefixes "erlang-mode-expansions" '("er/add-erlang-mode-expansions"))
-
-;;;***
-\f
-;;;### (autoloads nil "expand-region" "expand-region.el" (0 0 0 0))
-;;; Generated autoloads from expand-region.el
-
-(autoload 'er/expand-region "expand-region" "\
-Increase selected region by semantic units.
-
-With prefix argument expands the region that many times.
-If prefix argument is negative calls `er/contract-region'.
-If prefix argument is 0 it resets point and mark to their state
-before calling `er/expand-region' for the first time.
-
-\(fn ARG)" t nil)
-
-;;;***
-\f
-;;;### (autoloads nil "expand-region-core" "expand-region-core.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from expand-region-core.el
-
-(register-definition-prefixes "expand-region-core" '("er--" "er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "expand-region-custom" "expand-region-custom.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from expand-region-custom.el
-
-(let ((loads (get 'expand-region 'custom-loads))) (if (member '"expand-region-custom" loads) nil (put 'expand-region 'custom-loads (cons '"expand-region-custom" loads))))
-
-(defvar expand-region-preferred-python-mode 'python "\
-The name of your preferred python mode")
-
-(custom-autoload 'expand-region-preferred-python-mode "expand-region-custom" t)
-
-(defvar expand-region-guess-python-mode t "\
-If expand-region should attempt to guess your preferred python mode")
-
-(custom-autoload 'expand-region-guess-python-mode "expand-region-custom" t)
-
-(defvar expand-region-autocopy-register "" "\
-If set to a string of a single character (try \"e\"), then the
-contents of the most recent expand or contract command will
-always be copied to the register named after that character.")
-
-(custom-autoload 'expand-region-autocopy-register "expand-region-custom" t)
-
-(defvar expand-region-skip-whitespace t "\
-If expand-region should skip past whitespace on initial expansion")
-
-(custom-autoload 'expand-region-skip-whitespace "expand-region-custom" t)
-
-(defvar expand-region-fast-keys-enabled t "\
-If expand-region should bind fast keys after initial expand/contract")
-
-(custom-autoload 'expand-region-fast-keys-enabled "expand-region-custom" t)
-
-(defvar expand-region-contract-fast-key "-" "\
-Key to use after an initial expand/contract to contract once more.")
-
-(custom-autoload 'expand-region-contract-fast-key "expand-region-custom" t)
-
-(defvar expand-region-reset-fast-key "0" "\
-Key to use after an initial expand/contract to undo.")
-
-(custom-autoload 'expand-region-reset-fast-key "expand-region-custom" t)
-
-(defvar expand-region-exclude-text-mode-expansions '(html-mode nxml-mode) "\
-List of modes which derive from `text-mode' for which text mode expansions are not appropriate.")
-
-(custom-autoload 'expand-region-exclude-text-mode-expansions "expand-region-custom" t)
-
-(defvar expand-region-smart-cursor nil "\
-Defines whether the cursor should be placed intelligently after expansion.
-
-If set to t, and the cursor is already at the beginning of the new region,
-keep it there; otherwise, put it at the end of the region.
-
-If set to nil, always place the cursor at the beginning of the region.")
-
-(custom-autoload 'expand-region-smart-cursor "expand-region-custom" t)
-
-(define-obsolete-variable-alias 'er/enable-subword-mode\? 'expand-region-subword-enabled "2019-03-23")
-
-(defvar expand-region-subword-enabled nil "\
-Whether expand-region should use subword expansions.")
-
-(custom-autoload 'expand-region-subword-enabled "expand-region-custom" t)
-
-(register-definition-prefixes "expand-region-custom" '("expand-region-"))
-
-;;;***
-\f
-;;;### (autoloads nil "feature-mode-expansions" "feature-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from feature-mode-expansions.el
-
-(register-definition-prefixes "feature-mode-expansions" '("er--block-between-keywords" "er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "html-mode-expansions" "html-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from html-mode-expansions.el
-
-(register-definition-prefixes "html-mode-expansions" '("er--" "er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "js-mode-expansions" "js-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from js-mode-expansions.el
-
-(register-definition-prefixes "js-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "js2-mode-expansions" "js2-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from js2-mode-expansions.el
-
-(register-definition-prefixes "js2-mode-expansions" '("er/add-js2-mode-expansions" "js2-mark-parent-statement"))
-
-;;;***
-\f
-;;;### (autoloads nil "jsp-expansions" "jsp-expansions.el" (0 0 0
-;;;;;; 0))
-;;; Generated autoloads from jsp-expansions.el
-
-(register-definition-prefixes "jsp-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "latex-mode-expansions" "latex-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from latex-mode-expansions.el
-
-(register-definition-prefixes "latex-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "nxml-mode-expansions" "nxml-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from nxml-mode-expansions.el
-
-(register-definition-prefixes "nxml-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "octave-expansions" "octave-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from octave-expansions.el
-
-(register-definition-prefixes "octave-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "python-el-expansions" "python-el-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from python-el-expansions.el
-
-(register-definition-prefixes "python-el-expansions" '("er--python-string-delimiter" "er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "python-el-fgallina-expansions" "python-el-fgallina-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from python-el-fgallina-expansions.el
-
-(register-definition-prefixes "python-el-fgallina-expansions" '("er--python-" "er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "python-mode-expansions" "python-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from python-mode-expansions.el
-
-(register-definition-prefixes "python-mode-expansions" '("er--" "er/" "py-goto-beyond-clause"))
-
-;;;***
-\f
-;;;### (autoloads nil "ruby-mode-expansions" "ruby-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from ruby-mode-expansions.el
-
-(register-definition-prefixes "ruby-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "sml-mode-expansions" "sml-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from sml-mode-expansions.el
-
-(register-definition-prefixes "sml-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "subword-mode-expansions" "subword-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from subword-mode-expansions.el
-
-(register-definition-prefixes "subword-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "text-mode-expansions" "text-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from text-mode-expansions.el
-
-(register-definition-prefixes "text-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "the-org-mode-expansions" "the-org-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from the-org-mode-expansions.el
-
-(register-definition-prefixes "the-org-mode-expansions" '("er/"))
-
-;;;***
-\f
-;;;### (autoloads nil "web-mode-expansions" "web-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from web-mode-expansions.el
-
-(register-definition-prefixes "web-mode-expansions" '("er/add-web-mode-expansions"))
-
-;;;***
-\f
-;;;### (autoloads nil "yaml-mode-expansions" "yaml-mode-expansions.el"
-;;;;;; (0 0 0 0))
-;;; Generated autoloads from yaml-mode-expansions.el
-
-(register-definition-prefixes "yaml-mode-expansions" '("er--" "er/" "yaml-indent"))
-
-;;;***
-\f
-;;;### (autoloads nil nil ("expand-region-pkg.el") (0 0 0 0))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; expand-region-autoloads.el ends here
+++ /dev/null
-;;; expand-region-core.el --- Increase selected region by semantic units.
-
-;; Copyright (C) 2011-2013 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; The core functionality of expand-region.
-
-;; See README.md
-
-;;; Code:
-
-(eval-when-compile (require 'cl-lib))
-(require 'expand-region-custom)
-(declare-function er/expand-region "expand-region")
-
-(defvar er/history '()
- "A history of start and end points so we can contract after expanding.")
-
-;; history is always local to a single buffer
-(make-variable-buffer-local 'er/history)
-
-(defvar er--space-str " \t\n")
-(defvar er--blank-list (append er--space-str nil))
-
-(set-default 'er--show-expansion-message nil)
-
-(defvar er/try-expand-list nil
- "A list of functions that are tried when expanding.")
-
-(defvar er/save-mode-excursion nil
- "A function to save excursion state when expanding.")
-
-(defun er--prepare-expanding ()
- (when (and (er--first-invocation)
- (not (use-region-p)))
- (push-mark nil t) ;; one for keeping starting position
- (push-mark nil t)) ;; one for replace by set-mark in expansions
-
- (when (not transient-mark-mode)
- (setq-local transient-mark-mode (cons 'only transient-mark-mode))))
-
-(defun er--copy-region-to-register ()
- (when (and (stringp expand-region-autocopy-register)
- (> (length expand-region-autocopy-register) 0))
- (set-register (aref expand-region-autocopy-register 0)
- (filter-buffer-substring (region-beginning) (region-end)))))
-
-;; save-mark-and-excursion in Emacs 25 works like save-excursion did before
-(eval-when-compile
- (when (< emacs-major-version 25)
- (defmacro save-mark-and-excursion (&rest body)
- `(save-excursion ,@body))))
-
-(defmacro er--save-excursion (&rest body)
- `(let ((action (lambda ()
- (save-mark-and-excursion ,@body))))
- (if er/save-mode-excursion
- (funcall er/save-mode-excursion action)
- (funcall action))))
-
-(defun er--expand-region-1 ()
- "Increase selected region by semantic units.
-Basically it runs all the mark-functions in `er/try-expand-list'
-and chooses the one that increases the size of the region while
-moving point or mark as little as possible."
- (let* ((p1 (point))
- (p2 (if (use-region-p) (mark) (point)))
- (start (min p1 p2))
- (end (max p1 p2))
- (try-list er/try-expand-list)
- (best-start (point-min))
- (best-end (point-max))
- (set-mark-default-inactive nil))
-
- ;; add hook to clear history on buffer changes
- (unless er/history
- (add-hook 'after-change-functions 'er/clear-history t t))
-
- ;; remember the start and end points so we can contract later
- ;; unless we're already at maximum size
- (unless (and (= start best-start)
- (= end best-end))
- (push (cons p1 p2) er/history))
-
- (when (and expand-region-skip-whitespace
- (er--point-is-surrounded-by-white-space)
- (= start end))
- (skip-chars-forward er--space-str)
- (setq start (point)))
-
- (while try-list
- (er--save-excursion
- (ignore-errors
- (funcall (car try-list))
- (when (and (region-active-p)
- (er--this-expansion-is-better start end best-start best-end))
- (setq best-start (point))
- (setq best-end (mark))
- (when (and er--show-expansion-message (not (minibufferp)))
- (message "%S" (car try-list))))))
- (setq try-list (cdr try-list)))
-
- (setq deactivate-mark nil)
- ;; if smart cursor enabled, decide to put it at start or end of region:
- (if (and expand-region-smart-cursor
- (not (= start best-start)))
- (progn (goto-char best-end)
- (set-mark best-start))
- (goto-char best-start)
- (set-mark best-end))
-
- (er--copy-region-to-register)
-
- (when (and (= best-start (point-min))
- (= best-end (point-max))) ;; We didn't find anything new, so exit early
- 'early-exit)))
-
-(defun er--this-expansion-is-better (start end best-start best-end)
- "t if the current region is an improvement on previous expansions.
-
-This is provided as a separate function for those that would like
-to override the heuristic."
- (and
- (<= (point) start)
- (>= (mark) end)
- (> (- (mark) (point)) (- end start))
- (or (> (point) best-start)
- (and (= (point) best-start)
- (< (mark) best-end)))))
-
-(defun er/contract-region (arg)
- "Contract the selected region to its previous size.
-With prefix argument contracts that many times.
-If prefix argument is negative calls `er/expand-region'.
-If prefix argument is 0 it resets point and mark to their state
-before calling `er/expand-region' for the first time."
- (interactive "p")
- (if (< arg 0)
- (er/expand-region (- arg))
- (when er/history
- ;; Be sure to reset them all if called with 0
- (when (= arg 0)
- (setq arg (length er/history)))
-
- (when (not transient-mark-mode)
- (setq-local transient-mark-mode (cons 'only transient-mark-mode)))
-
- ;; Advance through the list the desired distance
- (while (and (cdr er/history)
- (> arg 1))
- (setq arg (- arg 1))
- (setq er/history (cdr er/history)))
- ;; Reset point and mark
- (let* ((last (pop er/history))
- (start (car last))
- (end (cdr last)))
- (goto-char start)
- (set-mark end)
-
- (er--copy-region-to-register)
-
- (when (eq start end)
- (deactivate-mark)
- (er/clear-history))))))
-
-(defun er/prepare-for-more-expansions-internal (repeat-key-str)
- "Return bindings and a message to inform user about them"
- (let ((msg (format "Type %s to expand again" repeat-key-str))
- (bindings (list (cons repeat-key-str '(er/expand-region 1)))))
- ;; If contract and expand are on the same binding, ignore contract
- (unless (string-equal repeat-key-str expand-region-contract-fast-key)
- (setq msg (concat msg (format ", %s to contract" expand-region-contract-fast-key)))
- (push (cons expand-region-contract-fast-key '(er/contract-region 1)) bindings))
- ;; If reset and either expand or contract are on the same binding, ignore reset
- (unless (or (string-equal repeat-key-str expand-region-reset-fast-key)
- (string-equal expand-region-contract-fast-key expand-region-reset-fast-key))
- (setq msg (concat msg (format ", %s to reset" expand-region-reset-fast-key)))
- (push (cons expand-region-reset-fast-key '(er/expand-region 0)) bindings))
- (cons msg bindings)))
-
-(defun er/prepare-for-more-expansions ()
- "Let one expand more by just pressing the last key."
- (let* ((repeat-key (event-basic-type last-input-event))
- (repeat-key-str (single-key-description repeat-key))
- (msg-and-bindings (er/prepare-for-more-expansions-internal repeat-key-str))
- (msg (car msg-and-bindings))
- (bindings (cdr msg-and-bindings)))
- (when repeat-key
- (er/set-temporary-overlay-map
- (let ((map (make-sparse-keymap)))
- (dolist (binding bindings map)
- (define-key map (read-kbd-macro (car binding))
- `(lambda ()
- (interactive)
- (setq this-command `,(cadr ',binding))
- (or (not expand-region-show-usage-message) (minibufferp) (message "%s" ,msg))
- (eval `,(cdr ',binding))))))
- t)
- (or (not expand-region-show-usage-message) (minibufferp) (message "%s" msg)))))
-
-(if (fboundp 'set-temporary-overlay-map)
- (fset 'er/set-temporary-overlay-map 'set-temporary-overlay-map)
- ;; Backport this function from newer emacs versions
- (defun er/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))))
-
-(defadvice keyboard-quit (before collapse-region activate)
- (when (memq last-command '(er/expand-region er/contract-region))
- (er/contract-region 0)))
-
-(defadvice minibuffer-keyboard-quit (around collapse-region activate)
- (if (memq last-command '(er/expand-region er/contract-region))
- (er/contract-region 0)
- ad-do-it))
-
-(defadvice cua-cancel (before collapse-region activate)
- (when (memq last-command '(er/expand-region er/contract-region))
- (er/contract-region 0)))
-
-(defun er/clear-history (&rest args)
- "Clear the history."
- (setq er/history '())
- (remove-hook 'after-change-functions 'er/clear-history t))
-
-(defsubst er--first-invocation ()
- "t if this is the first invocation of er/expand-region or er/contract-region"
- (not (memq last-command '(er/expand-region er/contract-region))))
-
-(defun er--point-is-surrounded-by-white-space ()
- (and (or (memq (char-before) er--blank-list)
- (eq (point) (point-min)))
- (memq (char-after) er--blank-list)))
-
-(defun er/enable-mode-expansions (mode add-fn)
- (add-hook (intern (format "%s-hook" mode)) add-fn)
- (save-window-excursion
- (dolist (buffer (buffer-list))
- (with-current-buffer buffer
- (when (derived-mode-p mode)
- (funcall add-fn))))))
-
-(defun er/enable-minor-mode-expansions (mode add-fn)
- (add-hook (intern (format "%s-hook" mode)) add-fn)
- (save-window-excursion
- (dolist (buffer (buffer-list))
- (with-current-buffer buffer
- (when (symbol-value mode)
- (funcall add-fn))))))
-
-;; Some more performant version of `looking-back'
-
-(defun er/looking-back-on-line (regexp)
- "Version of `looking-back' that only checks current line."
- (looking-back regexp (line-beginning-position)))
-
-(defun er/looking-back-exact (s)
- "Version of `looking-back' that only looks for exact matches, no regexp."
- (string= s (buffer-substring (- (point) (length s))
- (point))))
-
-(defun er/looking-back-max (regexp count)
- "Version of `looking-back' that only check COUNT chars back."
- (looking-back regexp (max 1 (- (point) count))))
-
-(provide 'expand-region-core)
-
-;;; expand-region-core.el ends here
+++ /dev/null
-;;; expand-region-custom.el --- Increase selected region by semantic units.
-
-;; Copyright (C) 2012 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file holds customization variables.
-
-;;; Code:
-
-;;;###autoload
-(defgroup expand-region nil
- "Increase selected region by semantic units."
- :group 'tools)
-
-;;;###autoload
-(defcustom expand-region-preferred-python-mode 'python
- "The name of your preferred python mode"
- :group 'expand-region
- :type '(choice (const :tag "Emacs' python.el" 'python)
- (const :tag "fgallina's python.el" 'fgallina-python)
- (const :tag "python-mode.el" 'python-mode)))
-
-;;;###autoload
-(defcustom expand-region-guess-python-mode t
- "If expand-region should attempt to guess your preferred python mode"
- :group 'expand-region
- :type '(choice (const :tag "Guess" t)
- (const :tag "Do not guess" nil)))
-
-(defun expand-region-guess-python-mode ()
- "Guess the user's preferred python mode."
- (setq expand-region-preferred-python-mode
- (if (fboundp 'python-setup-brm)
- 'python
- 'fgallina-python)))
-
-;;;###autoload
-(defcustom expand-region-autocopy-register ""
- "If set to a string of a single character (try \"e\"), then the
-contents of the most recent expand or contract command will
-always be copied to the register named after that character."
- :group 'expand-region
- :type 'string)
-
-;;;###autoload
-(defcustom expand-region-skip-whitespace t
- "If expand-region should skip past whitespace on initial expansion"
- :group 'expand-region
- :type '(choice (const :tag "Skip whitespace" t)
- (const :tag "Do not skip whitespace" nil)))
-
-;;;###autoload
-(defcustom expand-region-fast-keys-enabled t
- "If expand-region should bind fast keys after initial expand/contract"
- :group 'expand-region
- :type '(choice (const :tag "Enable fast keys" t)
- (const :tag "Disable fast keys" nil)))
-
-;;;###autoload
-(defcustom expand-region-contract-fast-key "-"
- "Key to use after an initial expand/contract to contract once more."
- :group 'expand-region
- :type 'string)
-
-;;;###autoload
-(defcustom expand-region-reset-fast-key "0"
- "Key to use after an initial expand/contract to undo."
- :group 'expand-region
- :type 'string)
-
-;;;###autoload
-(defcustom expand-region-exclude-text-mode-expansions
- '(html-mode nxml-mode)
- "List of modes which derive from `text-mode' for which text mode expansions are not appropriate."
- :group 'expand-region
- :type '(repeat (symbol :tag "Major Mode" unknown)))
-
-;;;###autoload
-(defcustom expand-region-smart-cursor nil
- "Defines whether the cursor should be placed intelligently after expansion.
-
-If set to t, and the cursor is already at the beginning of the new region,
-keep it there; otherwise, put it at the end of the region.
-
-If set to nil, always place the cursor at the beginning of the region."
- :group 'expand-region
- :type '(choice (const :tag "Smart behaviour" t)
- (const :tag "Standard behaviour" nil)))
-
-;;;###autoload
-(define-obsolete-variable-alias 'er/enable-subword-mode?
- 'expand-region-subword-enabled "2019-03-23")
-
-;;;###autoload
-(defcustom expand-region-subword-enabled nil
- "Whether expand-region should use subword expansions."
- :group 'expand-region
- :type '(choice (const :tag "Enable subword expansions" t)
- (const :tag "Disable subword expansions" nil)))
-
-(defcustom expand-region-show-usage-message t
- "Whether expand-region should show usage message."
- :group 'expand-region
- :type 'boolean)
-
-(provide 'expand-region-custom)
-
-;;; expand-region-custom.el ends here
+++ /dev/null
-(define-package "expand-region" "20220729.659" "Increase selected region by semantic units." 'nil :commit "c5c4362741deebb0985a8a29f9b8b0e25160764a" :authors
- '(("Magnar Sveen" . "magnarsNOSPAMgmail.com"))
- :maintainer
- '("Magnar Sveen" . "magnarsNOSPAMgmail.com")
- :keywords
- '("marking" "region"))
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
+++ /dev/null
-;;; expand-region.el --- Increase selected region by semantic units.
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Expand region increases the selected region by semantic units. Just keep
-;; pressing the key until it selects what you want.
-
-;; An example:
-
-;; (setq alphabet-start "abc def")
-
-;; With the cursor at the `c`, it starts by marking the entire word `abc`, then
-;; expand to the contents of the quotes `abc def`, then to the entire quote
-;; `"abc def"`, then to the contents of the sexp `setq alphabet-start "abc def"`
-;; and finally to the entire sexp.
-
-;; You can set it up like this:
-
-;; (require 'expand-region)
-;; (global-set-key (kbd "C-=") 'er/expand-region)
-
-;; There's also `er/contract-region` if you expand too far.
-
-;; ## Video
-
-;; You can [watch an intro to expand-region at Emacs Rocks](http://emacsrocks.com/e09.html).
-
-;; ## Language support
-
-;; Expand region works fairly well with most languages, due to the general
-;; nature of the basic expansions:
-
-;; er/mark-word
-;; er/mark-symbol
-;; er/mark-method-call
-;; er/mark-inside-quotes
-;; er/mark-outside-quotes
-;; er/mark-inside-pairs
-;; er/mark-outside-pairs
-
-;; However, most languages also will benefit from some specially crafted
-;; expansions. For instance, expand-region comes with these extra expansions for
-;; html-mode:
-
-;; er/mark-html-attribute
-;; er/mark-inner-tag
-;; er/mark-outer-tag
-
-;; You can add your own expansions to the languages of your choice simply by
-;; creating a function that looks around point to see if it's inside or looking
-;; at the construct you want to mark, and if so - mark it.
-
-;; There's plenty of examples to look at in these files.
-
-;; After you make your function, add it to a buffer-local version of
-;; the `er/try-expand-list`.
-
-;; **Example:**
-
-;; Let's say you want expand-region to also mark paragraphs and pages in
-;; text-mode. Incidentally Emacs already comes with `mark-paragraph` and
-;; `mark-page`. To add it to the try-list, do this:
-
-;; (defun er/add-text-mode-expansions ()
-;; (make-variable-buffer-local 'er/try-expand-list)
-;; (setq er/try-expand-list (append
-;; er/try-expand-list
-;; '(mark-paragraph
-;; mark-page))))
-
-;; (er/enable-mode-expansions 'text-mode 'er/add-text-mode-expansions)
-
-;; Add that to its own file, and require it at the bottom of this one,
-;; where it says "Mode-specific expansions"
-
-;; **Warning:** Badly written expansions might slow down expand-region
-;; dramatically. Remember to exit quickly before you start traversing
-;; the entire document looking for constructs to mark.
-
-;; ## Contribute
-
-;; If you make some nice expansions for your favorite mode, it would be
-;; great if you opened a pull-request. The repo is at:
-
-;; https://github.com/magnars/expand-region.el
-
-;; Changes to `expand-region-core` itself must be accompanied by feature tests.
-;; They are written in [Ecukes](http://ecukes.info), a Cucumber for Emacs.
-
-;; To fetch the test dependencies:
-
-;; $ cd /path/to/expand-region
-;; $ git submodule init
-;; $ git submodule update
-
-;; Run the tests with:
-
-;; $ ./util/ecukes/ecukes features
-
-;; If you want to add feature-tests for your mode-specific expansions as well,
-;; that is utterly excellent.
-
-;; ## Contributors
-
-;; * [Josh Johnston](https://github.com/joshwnj) contributed `er/contract-region`
-;; * [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.
-;; * [Matt Briggs](https://github.com/mbriggs) contributed expansions for ruby-mode.
-;; * [Ivan Andrus](https://github.com/gvol) contributed expansions for python-mode, text-mode, LaTeX-mode and nxml-mode.
-;; * [Raimon Grau](https://github.com/kidd) added support for when transient-mark-mode is off.
-;; * [Gleb Peregud](https://github.com/gleber) contributed expansions for erlang-mode.
-;; * [fgeller](https://github.com/fgeller) and [edmccard](https://github.com/edmccard) contributed better support for python and its multiple modes.
-;; * [François Févotte](https://github.com/ffevotte) contributed expansions for C and C++.
-;; * [Roland Walker](https://github.com/rolandwalker) added option to copy the contents of the most recent action to a register, and some fixes.
-;; * [Damien Cassou](https://github.com/DamienCassou) added option to continue expanding/contracting with fast keys after initial expand.
-
-;; Thanks!
-
-;;; Code:
-
-(require 'expand-region-core)
-(require 'expand-region-custom)
-(require 'er-basic-expansions)
-
-;;;###autoload
-(defun er/expand-region (arg)
- "Increase selected region by semantic units.
-
-With prefix argument expands the region that many times.
-If prefix argument is negative calls `er/contract-region'.
-If prefix argument is 0 it resets point and mark to their state
-before calling `er/expand-region' for the first time."
- (interactive "p")
- (if (< arg 1)
- (er/contract-region (- arg))
- (er--prepare-expanding)
- (while (>= arg 1)
- (setq arg (- arg 1))
- (when (eq 'early-exit (er--expand-region-1))
- (setq arg 0)))
- (when (and expand-region-fast-keys-enabled
- (not (memq last-command '(er/expand-region er/contract-region))))
- (er/prepare-for-more-expansions))))
-
-(eval-after-load 'clojure-mode '(require 'clojure-mode-expansions))
-(eval-after-load 'css-mode '(require 'css-mode-expansions))
-(eval-after-load 'erlang-mode '(require 'erlang-mode-expansions))
-(eval-after-load 'feature-mode '(require 'feature-mode-expansions))
-(eval-after-load 'sgml-mode '(require 'html-mode-expansions)) ;; html-mode is defined in sgml-mode.el
-(eval-after-load 'rhtml-mode '(require 'html-mode-expansions))
-(eval-after-load 'nxhtml-mode '(require 'html-mode-expansions))
-(eval-after-load 'web-mode '(require 'web-mode-expansions))
-(eval-after-load 'js '(require 'js-mode-expansions))
-(eval-after-load 'js2-mode '(require 'js-mode-expansions))
-(eval-after-load 'js2-mode '(require 'js2-mode-expansions))
-(eval-after-load 'js3-mode '(require 'js-mode-expansions))
-(eval-after-load 'latex '(require 'latex-mode-expansions))
-(eval-after-load 'nxml-mode '(require 'nxml-mode-expansions))
-(eval-after-load 'octave-mod '(require 'octave-expansions))
-(eval-after-load 'octave '(require 'octave-expansions))
-(eval-after-load 'python '(progn
- (when expand-region-guess-python-mode
- (expand-region-guess-python-mode))
- (if (eq 'python expand-region-preferred-python-mode)
- (require 'python-el-expansions)
- (require 'python-el-fgallina-expansions))))
-(eval-after-load 'python-mode '(require 'python-mode-expansions))
-(eval-after-load 'ruby-mode '(require 'ruby-mode-expansions))
-(eval-after-load 'org '(require 'the-org-mode-expansions))
-(eval-after-load 'cc-mode '(require 'cc-mode-expansions))
-(eval-after-load 'text-mode '(require 'text-mode-expansions))
-(eval-after-load 'cperl-mode '(require 'cperl-mode-expansions))
-(eval-after-load 'sml-mode '(require 'sml-mode-expansions))
-(eval-after-load 'enh-ruby-mode '(require 'enh-ruby-mode-expansions))
-(eval-after-load 'subword '(require 'subword-mode-expansions))
-(eval-after-load 'yaml-mode '(require 'yaml-mode-expansions))
-
-(provide 'expand-region)
-
-;;; expand-region.el ends here
+++ /dev/null
-;;; feature-mode-expansions.el --- cucumber-specific expansions for expand-region
-
-;; Copyright (C) 2012 Raimon Grau
-
-;; Author: Raimon Grau
-;; Based on js-mode-expansions by: Raimon Grau <raimonsterNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-
-;; expanders to mark feature semantic objects like step or scenario
-;;
-;; Expansions:
-;;
-;;
-;; er/mark-feature-scenario
-;; er/mark-feature-step
-
-(require 'expand-region-core)
-
-(defun er--block-between-keywords (start-keywords-regexp &optional end-keywords-regexp)
- (let* ((start-key-words (concat "^\\( \\)*" start-keywords-regexp))
- (end-key-words (concat "^\\( \\)*" (or end-keywords-regexp start-keywords-regexp))))
- (when (looking-at-p "[^\\s-]")
- (skip-syntax-forward "w."))
- (if (looking-at-p start-keywords-regexp)
- (progn (beginning-of-line)
- (exchange-point-and-mark))
- (re-search-backward start-key-words)
- (set-mark (point))
- (re-search-forward start-key-words))
- (unless (re-search-forward end-key-words (point-max) t)
- (goto-char (point-max)))
- (forward-line 0)
- (exchange-point-and-mark)))
-
-(defun er/mark-feature-scenario ()
- (interactive)
- (er--block-between-keywords "\\(Background:\\|Scenario:\\|Feature:\\)"))
-
-(defun er/mark-feature-step ()
- (interactive)
- (er--block-between-keywords "\\(And\\|Given\\|When\\|Then\\)" "\\(And\\|Given\\|When\\|Then\\|Scenario:\\)"))
-
-(defun er/add-feature-mode-expansions ()
- "Adds cucumber-specific expansions for buffers in feature-mode"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(er/mark-feature-scenario
- er/mark-feature-step))))
-
-(er/enable-mode-expansions 'feature-mode 'er/add-feature-mode-expansions)
-
-(provide 'feature-mode-expansions)
+++ /dev/null
-;;; html-mode-expansions.el --- HTML-specific expansions for expand-region
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Extra expansions for HTML that I've found useful so far:
-;;
-;; er/mark-html-attribute
-;; er/mark-inner-tag
-;; er/mark-outer-tag
-;;
-;; Feel free to contribute any other expansions for HTML at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(require 'sgml-mode)
-
-(defun er/mark-html-attribute ()
- "Mark html-attribute presumes that point is at the assignment part of attr=\"value\".
-If point is inside the value-string, the quotes will be marked
-first anyway. Does not support html-attributes with spaces
-around the equal sign or unquotes attributes atm."
- (interactive)
- (when (or (looking-at "\\(\\s_\\|\\sw\\)*=")
- (er/looking-back-exact "="))
- (search-backward " ")
- (forward-char 1)
- (set-mark (point))
- (search-forward "=")
- (forward-sexp 1)
- (exchange-point-and-mark)))
-
-(defun er--looking-at-marked-tag ()
- "Is point looking at a tag that is entirely marked?"
- (and (looking-at "<")
- (>= (mark)
- (save-excursion
- (sgml-skip-tag-forward 1)
- (point)))))
-
-(defun er--inside-tag-p ()
- "Is point inside a tag?"
- (save-excursion
- (not (null (sgml-get-context)))))
-
-(defun er/mark-outer-tag ()
- "Mark from opening to closing tag, including the tags."
- (interactive)
- (when (and (er--inside-tag-p)
- (or (not (looking-at "<"))
- (er--looking-at-marked-tag)))
- (goto-char (aref (car (last (sgml-get-context))) 2)))
- (when (looking-at "<")
- (set-mark (point))
- (sgml-skip-tag-forward 1)
- (exchange-point-and-mark)))
-
-(defun er/mark-inner-tag ()
- "Mark the contents of an open tag, not including the tags."
- (interactive)
- (goto-char (aref (car (last (sgml-get-context))) 3))
- (set-mark (point))
- (backward-char 1)
- (sgml-skip-tag-forward 1)
- (search-backward "</")
- (exchange-point-and-mark))
-
-(defun er/add-html-mode-expansions ()
- "Adds HTML-specific expansions for buffers in html-mode"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(er/mark-html-attribute
- er/mark-inner-tag
- er/mark-outer-tag))))
-
-(er/enable-mode-expansions 'html-mode 'er/add-html-mode-expansions)
-(er/enable-mode-expansions 'rhtml-mode 'er/add-html-mode-expansions)
-(er/enable-mode-expansions 'nxhtml-mode 'er/add-html-mode-expansions)
-(er/enable-mode-expansions 'web-mode 'er/add-html-mode-expansions)
-
-(provide 'html-mode-expansions)
-
-;; html-mode-expansions.el ends here
+++ /dev/null
-;;; js-mode-expansions.el --- JS-specific expansions for expand-region
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Extra expansions for JavaScript that I've found useful so far:
-;;
-;; er/mark-js-function
-;; er/mark-js-object-property-value
-;; er/mark-js-object-property
-;; er/mark-js-if
-;; er/mark-js-inner-return
-;; er/mark-js-outer-return
-;;
-;; Feel free to contribute any other expansions for JavaScript at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/mark-js-function ()
- "Mark the current JavaScript function."
- (interactive)
- (condition-case nil
- (forward-char 8)
- (error nil))
- (word-search-backward "function")
- (while (or (er--point-inside-string-p)
- (er--point-is-in-comment-p))
- (word-search-backward "function"))
- (set-mark (point))
- (while (not (looking-at "{"))
- (forward-char))
- (forward-list)
- (exchange-point-and-mark))
-
-(defun er/mark-js-outer-return ()
- "Mark the current return statement, including return and ending semi-colon"
- (interactive)
- (condition-case nil
- (forward-char 6)
- (error nil))
- (word-search-backward "return")
- (while (or (er--point-inside-string-p)
- (er--point-is-in-comment-p))
- (word-search-backward "return"))
- (set-mark (point))
- (while (not (looking-at ";"))
- (if (looking-at "\\s(")
- (forward-list)
- (forward-char)))
- (forward-char)
- (exchange-point-and-mark))
-
-(defun er/mark-js-inner-return ()
- "Mark contents of the current return statement, not including return or semi-colon"
- (interactive)
- (condition-case nil
- (forward-char 6)
- (error nil))
- (word-search-backward "return")
- (while (or (er--point-inside-string-p)
- (er--point-is-in-comment-p))
- (word-search-backward "return"))
- (search-forward " ")
- (set-mark (point))
- (while (not (looking-at ";"))
- (if (looking-at "\\s(")
- (forward-list)
- (forward-char)))
- (exchange-point-and-mark))
-
-(defun er/mark-js-if ()
- "Mark the current if-statement."
- (interactive)
- (condition-case nil
- (forward-char 2)
- (error nil))
- (word-search-backward "if")
- (while (or (er--point-inside-string-p)
- (er--point-is-in-comment-p))
- (word-search-backward "if"))
- (set-mark (point))
- (while (not (looking-at "("))
- (forward-char))
- (forward-list)
- (while (not (looking-at "{"))
- (forward-char))
- (forward-list)
- (exchange-point-and-mark))
-
-(defun er/mark-js-object-property-value ()
- "Mark the current object property value, ie. from : to , or }"
- (interactive)
- (unless (er--point-inside-pairs-p)
- (error "Point is not inside an object"))
- (search-backward ":")
- (forward-char)
- (search-forward-regexp "[^\s]")
- (backward-char)
- (set-mark (point))
- (while (not (looking-at "[},]"))
- (if (looking-at "\\s(")
- (forward-list)
- (forward-char)))
- (when (er/looking-back-max "[\s\n]" 400)
- (search-backward-regexp "[^\s\n]")
- (forward-char))
- (exchange-point-and-mark))
-
-(defun er/mark-js-object-property ()
- "Mark js-object-property presumes that point is at the assignment part of key: value.
-If point is inside the value, that will be marked first anyway."
- (interactive)
- (when (or (looking-at "\"?\\(\\s_\\|\\sw\\| \\)*\":")
- (looking-at "\\(\\s_\\|\\sw\\)*:")
- (er/looking-back-max ": ?" 2))
- (search-backward-regexp "[{,]")
- (forward-char)
- (search-forward-regexp "[^\s\n]")
- (backward-char)
- (set-mark (point))
- (search-forward ":")
- (while (or (not (looking-at "[},]"))
- (er--point-inside-string-p))
- (if (looking-at "\\s(")
- (forward-list)
- (forward-char)))
- (when (er/looking-back-max "[\s\n]" 400)
- (search-backward-regexp "[^\s\n]")
- (forward-char))
- (exchange-point-and-mark)))
-
-(defun er/mark-js-call ()
- "Mark the current symbol (including dots) and then parens or squares."
- (interactive)
- (let ((symbol-regexp "\\(\\s_\\|\\sw\\|\\.\\)+"))
- (when (or (looking-at symbol-regexp)
- (er/looking-back-on-line symbol-regexp))
- (skip-syntax-backward "_w.")
- (when (looking-at "!")
- (forward-char 1))
- (set-mark (point))
- (when (looking-at symbol-regexp)
- (goto-char (match-end 0)))
- (if (looking-at "\\[\\|(")
- (forward-list))
- (exchange-point-and-mark))))
-
-(defun er/add-js-mode-expansions ()
- "Adds JS-specific expansions for buffers in js-mode"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(er/mark-js-function
- er/mark-js-object-property-value
- er/mark-js-object-property
- er/mark-js-if
- er/mark-js-inner-return
- er/mark-js-outer-return
- er/mark-js-call))))
-
-(er/enable-mode-expansions 'js-mode 'er/add-js-mode-expansions)
-(er/enable-mode-expansions 'js2-mode 'er/add-js-mode-expansions)
-(er/enable-mode-expansions 'js3-mode 'er/add-js-mode-expansions)
-
-(provide 'js-mode-expansions)
-
-;; js-mode-expansions.el ends here
+++ /dev/null
-;;; js2-mode-expansions.el --- Additional expansions for js2-mode
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Extra expansions specifically for js2-mode, since it has
-;; a semantic parser.
-;;
-;; Feel free to contribute any other expansions for JavaScript at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(declare-function js2-node-parent-stmt "js2-mode")
-(declare-function js2-node-at-point "js2-mode")
-(declare-function js2-node-abs-pos "js2-mode")
-(declare-function js2-node-len "js2-mode")
-
-(defun js2-mark-parent-statement ()
- (interactive)
- (let* ((parent-statement (if (not (er/looking-back-exact ";"))
- (js2-node-parent-stmt (js2-node-at-point))
- (forward-char -1)
- (js2-node-at-point)))
- (beg (js2-node-abs-pos parent-statement))
- (end (+ beg (js2-node-len parent-statement))))
- (goto-char beg)
- (set-mark end)))
-
-(defun er/add-js2-mode-expansions ()
- "Adds expansions for buffers in js2-mode"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(js2-mark-parent-statement))))
-
-(er/enable-mode-expansions 'js2-mode 'er/add-js2-mode-expansions)
-
-(provide 'js2-mode-expansions)
-
-;; js2-mode-expansions.el ends here
+++ /dev/null
-;;; jsp-expansions.el --- JSP-specific expansions for expand-region
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Extra expansions for editing JSP files. To be used in conjunction
-;; with the html-mode expansions
-;;
-;; er/mark-jstl-escape
-;;
-;; These expansions aren't loaded by default, so you'll have to explicitly
-;; ask for them in your init file with:
-;;
-;; (eval-after-load 'sgml-mode '(require 'jsp-expansions))
-;;
-;; Feel free to contribute any other expansions for JSP at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/mark-jstl-escape ()
- "Mark jstl-escape presumes that point is outside the brackets.
-If point is inside the brackets, they will be marked first anyway."
- (interactive)
- (when (or (looking-at "\\${")
- (er/looking-back-exact "$"))
- (forward-char 1)
- (search-backward "\$")
- (set-mark (point))
- (forward-char 1)
- (forward-list)
- (exchange-point-and-mark)))
-
-(defun er/add-jsp-expansions ()
- "Adds JSP-specific expansions to the buffer"
- (set (make-local-variable 'er/try-expand-list) (append
- er/try-expand-list
- '(er/mark-jstl-escape))))
-
-(er/enable-mode-expansions 'html-mode 'er/add-jsp-expansions)
-
-(provide 'jsp-expansions)
-
-;; jsp-expansions.el ends here
+++ /dev/null
-;;; latex-mode-expansions.el --- LaTeX-specific expansions for expand-region
-
-;; Copyright (C) 2012 Ivan Andrus
-
-;; Author: Ivan Andrus
-;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This is for AUCTeX, not the builtin latex-mode.
-
-;; Feel free to contribute any other expansions for LaTeX at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-;referenced free variables and functions defined in mode
-(defvar texmathp-why)
-(defvar texmathp-tex-commands1)
-(defvar texmathp-onoff-regexp)
-(defvar LaTeX-mode-hook)
-(declare-function LaTeX-mark-environment "latex")
-(declare-function texmathp "texmathp")
-
-(defun er/mark-LaTeX-inside-environment ()
- "Like `LaTeX-mark-environment' but marks the inside of the environment.
-Skips past [] and {} arguments to the environment."
- (interactive)
- (LaTeX-mark-environment)
- (when (looking-at "\\\\begin{")
- (forward-sexp 2)
- ;; Assume these are arguments
- (while (looking-at "[ \t\n]*[{[]")
- (forward-sexp 1))
- ;; Go to next line if there is nothing interesting on this one
- (skip-syntax-forward " ") ;; newlines are ">" i.e. end comment
- (when (looking-at "%\\|$")
- (forward-line))
- ;; Clean up the end portion
- (exchange-point-and-mark)
- (backward-sexp 2)
- (skip-syntax-backward " ")
- (exchange-point-and-mark)))
-
-(defun er/mark-LaTeX-math ()
- "Mark current math environment."
- (interactive)
- (when (texmathp)
- (let* ((string (car texmathp-why))
- (pos (cdr texmathp-why))
- (reason (assoc string texmathp-tex-commands1))
- (type (cadr reason)))
- (cond
- ((eq type 'env-on) ;; environments equation, align, etc.
- (er/mark-LaTeX-inside-environment))
- ((eq type 'arg-on) ;; \ensuremath etc.
- (goto-char pos)
- (set-mark (point))
- (forward-sexp 2)
- (exchange-point-and-mark))
- ((eq type 'sw-toggle) ;; $ and $$
- (goto-char pos)
- (set-mark (point))
- (forward-sexp 1)
- (exchange-point-and-mark))
- ((eq type 'sw-on) ;; \( and \[
- (re-search-forward texmathp-onoff-regexp)
- (set-mark pos)
- (exchange-point-and-mark))
- (t (error (format "Unknown reason to be in math mode: %s" type)))))))
-
-(defun er/add-latex-mode-expansions ()
- "Adds expansions for buffers in latex-mode"
- (set (make-local-variable 'er/try-expand-list)
- (append
- er/try-expand-list
- '(LaTeX-mark-environment
- LaTeX-mark-section
- er/mark-LaTeX-inside-environment
- er/mark-LaTeX-math))))
-
-(let ((latex-mode-hook LaTeX-mode-hook))
- (er/enable-mode-expansions 'latex-mode 'er/add-latex-mode-expansions)
- (setq LaTeX-mode-hook latex-mode-hook))
-
-(provide 'latex-mode-expansions)
-
-;; latex-mode-expansions.el ends here
+++ /dev/null
-;;; nxml-mode-expansions.el --- Nxml-specific expansions for expand-region
-
-;; Copyright (C) 2012 Ivan Andrus
-
-;; Author: Ivan Andrus
-;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Feel free to contribute any other expansions for Nxml at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'expand-region-core)
-(require 'html-mode-expansions)
-(require 'nxml-mode)
-
-(defun er/mark-nxml-tag ()
- "Marks one nxml element e.g. <p>"
- (interactive)
- (cond ((looking-at "<")
- (nxml-mark-token-after))
- ((er/looking-back-exact ">")
- (backward-char 1)
- (nxml-mark-token-after))
- ((er/looking-back-max "<[^<>]*" 1000)
- (nxml-mark-token-after))))
-
-(defun er/mark-nxml-element ()
- "Marks one nxml element e.g. <p>...</p>"
- (interactive)
- (if (not (looking-at "<[^/]"))
- (er/mark-nxml-containing-element)
- (set-mark (point))
- (nxml-forward-element)
- (exchange-point-and-mark)))
-
-(defun er/mark-nxml-containing-element ()
- "Marks one nxml element, but always e.g. <p>...</p>"
- (interactive)
- (nxml-up-element)
- (set-mark (point))
- (nxml-backward-element))
-
-(defun er/mark-nxml-inside-element ()
- "Marks the inside Nxml statement, eg. <p>...</p>"
- (interactive)
- (let ((nxml-sexp-element-flag nil))
- (nxml-up-element)
- (nxml-forward-balanced-item -1)
- (set-mark (point))
- (nxml-backward-up-element)
- (nxml-forward-balanced-item 1)))
-
-(defun er/inside-nxml-attribute-string? ()
- "Returns the attribute from `xmltok-attributes' array that
-point is in, or otherwise nil"
- (save-excursion
- (forward-char 1)
- (nxml-token-before))
- (cl-find-if (lambda (att)
- (and (<= (xmltok-attribute-value-start att) (point))
- (>= (xmltok-attribute-value-end att) (point))))
- xmltok-attributes))
-
-(defun er/mark-nxml-attribute-inner-string ()
- "Marks an attribute string"
- (interactive)
- (let ((attr (er/inside-nxml-attribute-string?)))
- (when attr
- (set-mark (xmltok-attribute-value-start attr))
- (goto-char (xmltok-attribute-value-end attr))
- (exchange-point-and-mark))))
-
-(defun er/mark-nxml-attribute-string ()
- "Marks an attribute string inside quotes."
- (interactive)
- (let ((attr (er/inside-nxml-attribute-string?)))
- (when attr
- (set-mark (1- (xmltok-attribute-value-start attr)))
- (goto-char (1+ (xmltok-attribute-value-end attr)))
- (exchange-point-and-mark))))
-
-(defun er/add-nxml-mode-expansions ()
- "Adds Nxml-specific expansions for buffers in nxml-mode"
- (interactive)
- (set (make-local-variable 'er/try-expand-list)
- (append
- '(nxml-mark-paragraph
- ;; nxml-mark-token-after ;; Marks the current tag, etc. It's a bit schizophrenic
- er/mark-nxml-tag
- er/mark-nxml-inside-element
- er/mark-nxml-element
- er/mark-nxml-containing-element
- er/mark-nxml-attribute-string
- er/mark-nxml-attribute-inner-string
- ;; Steal from html-mode-expansions
- er/mark-html-attribute)
- ;; some normal marks are more hindrance than help:
- (remove 'er/mark-method-call
- (remove 'er/mark-symbol-with-prefix
- (remove 'er/mark-symbol er/try-expand-list))))))
-
-(er/enable-mode-expansions 'nxml-mode 'er/add-nxml-mode-expansions)
-
-(provide 'nxml-mode-expansions)
-
-;; nxml-mode-expansions.el ends here
+++ /dev/null
-;;; octave-expansions.el --- octave-mode expansions for expand-region
-
-;; Copyright (C) 2012 Mark Hepburn
-
-;; Author: Mark Hepburn
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Feel free to contribute any other expansions for Octave at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(declare-function octave-mark-block "octave-mod")
-
-;;; Octave-mod received a major rewrite between versions 23 and 24 of
-;;; Emacs, for example using the new smie package instead of
-;;; hand-coding a lot of motion commands. Unfortunately for our
-;;; purposes here, in the process the behaviour of `octave-mark-block'
-;;; changed slightly. So, in order to behave identically across both
-;;; versions we need to check which is which in a few places and
-;;; adjust accordingly:
-(defconst er/old-octave-mod-p (fboundp 'octave-up-block))
-
-(defalias 'er/up-block
- (if er/old-octave-mod-p 'octave-up-block 'up-list))
-
-(defun er/octave-mark-up-block ()
- "Mark the containing block, assuming the current block has
-already been marked."
- (interactive)
- (when (use-region-p)
- (when (< (point) (mark))
- (exchange-point-and-mark))
- (er/up-block -1) ; -1 means backwards, ie to the front
- (octave-mark-block)))
-
-(defun er/octave-mark-block ()
- "Not for general use; this is a work-around for the different
-behaviour of `octave-mark-block' between emacs versions 23 and
-24."
- (interactive)
- (forward-word)
- (octave-mark-block))
-
-(defun er/add-octave-expansions ()
- "Adds octave/matlab-specific expansions for buffers in octave-mode"
- (let ((try-expand-list-additions (if er/old-octave-mod-p
- '(octave-mark-block
- er/octave-mark-up-block
- octave-mark-defun)
- '(octave-mark-block
- er/octave-mark-block
- er/octave-mark-up-block
- mark-defun))))
- (set (make-local-variable 'er/try-expand-list)
- (append er/try-expand-list try-expand-list-additions))))
-
-(er/enable-mode-expansions 'octave-mode 'er/add-octave-expansions)
-
-(provide 'octave-expansions)
-;;; octave-expansions.el ends here
+++ /dev/null
-;;; python-el-expansions.el --- Python-specific expansions for expand-region
-
-;; Copyright (C) 2012 Ivan Andrus
-
-;; Authors: Ivan Andrus, Felix Geller, @edmccard
-;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region python
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; For python.el included with GNU Emacs
-;; - Mark functionality taken from python.el:
-;; - `python-mark-block'
-;; - Additions implemented here:
-;; - `er/mark-python-statement'
-;; - `er/mark-inside-python-string'
-;; - `er/mark-outside-python-string'
-;; - Supports multi-line strings
-
-;; There is no need for a er/mark-python-defun since
-;; er/mark-python-block will mark it
-
-;; Feel free to contribute any other expansions for Python at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(require 'python)
-
-(declare-function python-beginning-of-string "python-mode")
-
-(defvar er--python-string-delimiter "'\"")
-
-(defun er/mark-python-statement ()
- "Marks one Python statement, eg. x = 3"
- (interactive)
- (python-nav-end-of-statement)
- (set-mark (point))
- (python-nav-beginning-of-statement))
-
-(defun er/mark-outside-python-string ()
- "Marks region outside a (possibly multi-line) Python string"
- (interactive)
- (python-beginning-of-string)
- (set-mark (point))
- (forward-sexp)
- (exchange-point-and-mark))
-
-(defun er/mark-inside-python-string ()
- "Marks region inside a (possibly multi-line) Python string"
- (interactive)
- (when (eq 'string (syntax-ppss-context (syntax-ppss)))
- (python-beginning-of-string)
- (let ((string-beginning (point)))
- (forward-sexp)
- (skip-chars-backward er--python-string-delimiter)
- (set-mark (point))
- (goto-char string-beginning)
- (skip-chars-forward er--python-string-delimiter))))
-
-(defun er/add-python-mode-expansions ()
- "Adds Python-specific expansions for buffers in python-mode"
- (let ((try-expand-list-additions '(er/mark-python-statement
- er/mark-inside-python-string
- er/mark-outside-python-string
- python-mark-block)))
- (set (make-local-variable 'expand-region-skip-whitespace) nil)
- (set (make-local-variable 'er/try-expand-list)
- (remove 'er/mark-inside-quotes
- (remove 'er/mark-outside-quotes
- (append er/try-expand-list try-expand-list-additions))))))
-
-(er/enable-mode-expansions 'python-mode 'er/add-python-mode-expansions)
-
-(provide 'python-el-expansions)
-
-;; python-el-expansions.el ends here
+++ /dev/null
-;;; python-el-fgallina-expansions.el --- fgallina/python.el-specific expansions for expand-region
-
-;; Copyright (C) 2012 Felix Geller
-
-;; Author: Felix Geller
-;; Keywords: marking region python
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; - Additions implemented here:
-;; - `er/mark-inside-python-string'
-;; - `er/mark-outside-python-string'
-;; - `er/mark-python-statement'
-;; - `er/mark-python-block'
-;; - `er/mark-outer-python-block'
-;; - `er/mark-python-block-and-decorator'
-;; - Supports multi-line strings
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(if (not (fboundp 'python-syntax-context))
- (defalias 'python-syntax-context 'python-info-ppss-context))
-(if (not (fboundp 'python-indent-offset))
- (defalias 'python-indent-offset 'python-indent))
-
-(defvar er--python-string-delimiter
- "'\""
- "Characters that delimit a Python string.")
-
-;; copied from @fgallina's python.el as a quick fix. The variable
-;; `python-rx-constituents' is not bound when we use the python-rx
-;; macro from here, so we have to construct the regular expression
-;; manually.
-(defvar er--python-block-start-regex
- (rx symbol-start
- (or "def" "class" "if" "elif" "else" "try"
- "except" "finally" "for" "while" "with")
- symbol-end)
- "Regular expression string to match the beginning of a Python block.")
-
-(defun er/mark-python-string (mark-inside)
- "Mark the Python string that surrounds point.
-
-If the optional MARK-INSIDE is not nil, only mark the region
-between the string delimiters, otherwise the region includes the
-delimiters as well."
- (let ((beginning-of-string (python-syntax-context 'string (syntax-ppss))))
- (when beginning-of-string
- (goto-char beginning-of-string)
- ;; Move inside the string, so we can use ppss to find the end of
- ;; the string.
- (skip-chars-forward er--python-string-delimiter)
- (while (python-syntax-context 'string (syntax-ppss))
- (forward-char 1))
- (when mark-inside (skip-chars-backward er--python-string-delimiter))
- (set-mark (point))
- (goto-char beginning-of-string)
- (when mark-inside (skip-chars-forward er--python-string-delimiter)))))
-
-(defun er/mark-inside-python-string ()
- "Mark the inside of the Python string that surrounds point.
-
-Command that wraps `er/mark-python-string'."
- (interactive)
- (er/mark-python-string t))
-
-(defun er/mark-outside-python-string ()
- "Mark the outside of the Python string that surrounds point.
-
-Command that wraps `er/mark-python-string'."
- (interactive)
- (er/mark-python-string nil))
-
-(defun er/mark-python-statement ()
- "Mark the Python statement that surrounds point."
- (interactive)
- (python-nav-end-of-statement)
- (set-mark (point))
- (python-nav-beginning-of-statement))
-
-(defun er/mark-python-block (&optional next-indent-level)
- "Mark the Python block that surrounds point.
-
-If the optional NEXT-INDENT-LEVEL is given, select the
-surrounding block that is defined at an indentation that is less
-than NEXT-INDENT-LEVEL."
- (interactive)
- (back-to-indentation)
- (let ((next-indent-level
- (or
- ;; Use the given level
- next-indent-level
- ;; Check whether point is at the start of a Python block.
- (if (looking-at er--python-block-start-regex)
- ;; Block start means that the next level is deeper.
- (+ (current-indentation) python-indent-offset)
- ;; Assuming we're inside the block that we want to mark
- (current-indentation)))))
- ;; Move point to next Python block start at the correct indent-level
- (while (>= (current-indentation) next-indent-level)
- (re-search-backward er--python-block-start-regex))
- ;; Mark the beginning of the block
- (set-mark (point))
- ;; Save indentation and look for the end of this block
- (let ((block-indentation (current-indentation)))
- (forward-line 1)
- (while (and
- ;; No need to go beyond the end of the buffer. Can't use
- ;; eobp as the loop places the point at the beginning of
- ;; line, but eob might be at the end of the line.
- (not (= (point-max) (point-at-eol)))
- ;; Proceed if: indentation is too deep
- (or (> (current-indentation) block-indentation)
- ;; Looking at an empty line
- (looking-at (rx line-start (* whitespace) line-end))
- ;; We're not looking at the start of a Python block
- ;; and the indent is deeper than the block's indent
- (and (not (looking-at er--python-block-start-regex))
- (> (current-indentation) block-indentation))))
- (forward-line 1)
- (back-to-indentation))
- ;; Find the end of the block by skipping comments backwards
- (python-util-forward-comment -1)
- (exchange-point-and-mark))))
-
-(defun er/mark-outer-python-block ()
- "Mark the Python block that surrounds the Python block around point.
-
-Command that wraps `er/mark-python-block'."
- (interactive)
- (er/mark-python-block (current-indentation)))
-
-(defun er/mark-python-block-and-decorator ()
- (interactive)
- (back-to-indentation)
- (if (or (er--python-looking-at-decorator) (er--python-looking-at-decorator -1))
- (progn
- (while (er--python-looking-at-decorator -1)
- (forward-line -1)
- (back-to-indentation)
- )
- (set-mark (point))
- (while (er--python-looking-at-decorator)
- (forward-line)
- )
- (python-nav-end-of-block)
- (exchange-point-and-mark))))
-
-(defun er--python-looking-at-decorator (&optional line-offset)
- (save-excursion
- (if line-offset
- (forward-line line-offset)
- )
- (back-to-indentation)
- (looking-at "@")
- ))
-
-(defun er/add-python-mode-expansions ()
- "Adds python-mode-specific expansions for buffers in python-mode"
- (let ((try-expand-list-additions '(
- er/mark-inside-python-string
- er/mark-outside-python-string
- er/mark-python-statement
- er/mark-python-block
- er/mark-python-block-and-decorator
- er/mark-outer-python-block
- )))
- (set (make-local-variable 'expand-region-skip-whitespace) nil)
- (set (make-local-variable 'er/try-expand-list)
- (remove 'er/mark-inside-quotes
- (remove 'er/mark-outside-quotes
- (append er/try-expand-list try-expand-list-additions))))))
-
-(er/enable-mode-expansions 'python-mode 'er/add-python-mode-expansions)
-
-(provide 'python-el-fgallina-expansions)
-
-;; python-el-fgallina-expansions.el ends here
+++ /dev/null
-;;; python-mode-expansions.el --- python-mode-specific expansions for expand-region
-
-;; Copyright (C) 2012 Felix Geller
-
-;; Author: Felix Geller
-;; Based on python-mode-expansions by: Ivan Andrus
-;; Keywords: marking region python
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Commentary:
-;; cf. https://github.com/magnars/expand-region.el/pull/18
-
-;; For python-mode: https://launchpad.net/python-mode
-;; - Mark functionality taken from python-mode:
-;; - `py-mark-expression'
-;; - `py-mark-statement'
-;; - `py-mark-block'
-;; - `py-mark-class'
-;; - Additions implemented here:
-;; - `er/mark-inside-python-string'
-;; - `er/mark-outside-python-string'
-;; - `er/mark-outer-python-block'
-;; - Supports multi-line strings
-;; - Supports incremental expansion of nested blocks
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defvar er--python-string-delimiter "'\"")
-
-(defalias 'py-goto-beyond-clause 'py-end-of-clause-bol)
-
-(declare-function py-in-string-p "python-mode")
-(declare-function py-beginning-of-block "python-mode")
-(declare-function py-end-of-block "python-mode")
-(declare-function py-mark-block-or-clause "python-mode")
-(declare-function py-end-of-clause-bol "python-mode")
-(defvar py-indent-offset)
-
-(defun er/mark-outside-python-string ()
- "Marks region outside a (possibly multi-line) Python string"
- (interactive)
- (let ((string-beginning (py-in-string-p)))
- (when string-beginning
- (goto-char string-beginning)
- (set-mark (point))
- (forward-sexp)
- (exchange-point-and-mark))))
-
-(defun er/mark-inside-python-string ()
- "Marks region inside a (possibly multi-line) Python string"
- (interactive)
- (let ((string-beginning (py-in-string-p)))
- (when string-beginning
- (goto-char string-beginning)
- (forward-sexp)
- (skip-chars-backward er--python-string-delimiter)
- (set-mark (point))
- (goto-char string-beginning)
- (skip-chars-forward er--python-string-delimiter))))
-
-(defun er--move-to-beginning-of-outer-python-block (start-column)
- "Assumes that point is in a python block that is surrounded by
-another that is not the entire module. Uses `py-indent-offset' to
-find the beginning of the surrounding block because
-`py-beginning-of-block-position' just looks for the previous
-block-starting key word syntactically."
- (while (> (current-column) (- start-column py-indent-offset))
- (forward-line -1)
- (py-beginning-of-block)))
-
-(defun er/mark-outer-python-block ()
- "Attempts to mark a surrounding block by moving to the previous
-line and selecting the surrounding block."
- (interactive)
- (let ((start-column (current-column)))
- (when (> start-column 0) ; outer block is the whole buffer
- (er--move-to-beginning-of-outer-python-block start-column)
- (let ((block-beginning (point)))
- (py-end-of-block)
- (set-mark (point))
- (goto-char block-beginning)))))
-
-(defun er/mark-x-python-compound-statement ()
- "Mark the current compound statement (if, while, for, try) and all clauses."
- (interactive)
- (let ((secondary-re
- (save-excursion
- (py-mark-block-or-clause)
- (cond ((looking-at "if\\|for\\|while\\|else\\|elif") "else\\|elif")
- ((looking-at "try\\|except\\|finally") "except\\|finally"))))
- start-col)
- (when secondary-re
- (py-mark-block-or-clause)
- (setq start-col (current-column))
- (while (looking-at secondary-re)
- (forward-line -1) (back-to-indentation)
- (while (> (current-column) start-col)
- (forward-line -1) (back-to-indentation)))
- (set-mark (point))
- (py-end-of-clause-bol) (forward-line) (back-to-indentation)
- (while (and (looking-at secondary-re)
- (>= (current-column) start-col))
- (py-end-of-clause-bol) (forward-line) (back-to-indentation))
- (forward-line -1) (end-of-line)
- (exchange-point-and-mark))))
-
-(defun er/add-python-mode-expansions ()
- "Adds python-mode-specific expansions for buffers in python-mode"
- (let ((try-expand-list-additions '(
- er/mark-inside-python-string
- er/mark-outside-python-string
- py-mark-expression
- py-mark-statement
- py-mark-block
- py-mark-def
- py-mark-clause
- er/mark-x-python-compound-statement
- er/mark-outer-python-block
- py-mark-class
- )))
- (set (make-local-variable 'expand-region-skip-whitespace) nil)
- (set (make-local-variable 'er/try-expand-list)
- (remove 'er/mark-inside-quotes
- (remove 'er/mark-outside-quotes
- (append er/try-expand-list try-expand-list-additions))))))
-
-(er/enable-mode-expansions 'python-mode 'er/add-python-mode-expansions)
-
-(provide 'python-mode-expansions)
-
-;; python-mode-expansions.el ends here
+++ /dev/null
-;;; ruby-mode-expansions.el --- ruby-specific expansions for expand-region
-
-;; Copyright (C) 2011 Magnar Sveen
-
-;; Author: Matt Briggs
-;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-
-;; LeWang:
-;;
-;; I think `er/ruby-backward-up' and `er/ruby-forward-up' are nifty
-;; functions in their own right.
-;;
-;; I would bind them to C-M-u and C-M-d respectively.
-
-;; Expansions:
-;;
-;;
-;; er/mark-ruby-block-up
-;;
-
-;;; Code:
-(require 'expand-region-core)
-(require 'ruby-mode)
-
-(defvar er/ruby-block-end-re
- (concat ruby-block-end-re "\\|}")
- "like ruby-mode's but also for '}'")
-
-(defun er/ruby-skip-past-block-end ()
- "If line is blockend, move point to next line."
- (when (looking-at er/ruby-block-end-re)
- (forward-line 1)))
-
-(defun er/ruby-end-of-block (&optional arg)
- "By default `ruby-end-of-block' goes to BOL of line containing end-re.
-
-This moves point to the next line to include the end of the block"
- (interactive "p")
- ;; Workaround for `ruby-end-of-block' in Emacs 23.
- (when (re-search-forward (concat "\\<\\(" ruby-block-beg-re "\\)\\>")
- (point-at-eol) t)
- (goto-char (match-beginning 0)))
- (ruby-end-of-block (or arg 1))
- (er/ruby-skip-past-block-end))
-
-(defun er/point-at-indentation ()
- "Return the point where current line's indentation ends."
- (save-excursion
- (back-to-indentation)
- (point)))
-
-(defun er/ruby-backward-up ()
- "a la `paredit-backward-up'"
- (interactive)
- ;; if our current line ends a block, we back a line, otherwise we
- (when (save-excursion
- (back-to-indentation)
- (looking-at-p ruby-block-end-re))
- (forward-line -1))
- (let ((orig-point (point))
- progress-beg
- progress-end)
-
- ;; cover the case when point is in the line of beginning of block
- (unless (progn (ruby-end-of-block)
- (ruby-beginning-of-block)
- ;; "Block beginning" is often not at indentation in Emacs 24.
- (< (er/point-at-indentation) orig-point))
- (cl-loop
- (ruby-beginning-of-block)
- (setq progress-beg (point))
- (when (= (point) (point-min))
- (cl-return))
- (ruby-end-of-block)
- (setq progress-end (if (looking-at-p er/ruby-block-end-re)
- (point-at-bol 0)
- (point-at-bol 1)))
- (goto-char progress-beg)
- (when (> progress-end orig-point)
- (cl-return))))))
-
-;;; This command isn't used here explicitly, but it's symmetrical with
-;;; `er/ruby-backward-up', and nifty for interactive use.
-(defun er/ruby-forward-up ()
- "a la `paredit-forward-up'"
- (interactive)
- (er/ruby-backward-up)
- (er/ruby-end-of-block))
-
-(defun er/get-ruby-block (&optional pos)
- "return (beg . end) of current block"
- (setq pos (or pos (point)))
- (save-excursion
- (goto-char pos)
- (let (beg end)
- (cons (progn
- (er/ruby-backward-up)
- (er/point-at-indentation))
- (progn
- (er/ruby-end-of-block)
- (point))))))
-
-(defun er/mark-ruby-block-up-1 ()
- (er/ruby-backward-up)
- (set-mark (er/point-at-indentation))
- (er/ruby-end-of-block)
- (exchange-point-and-mark))
-
-(defun er/mark-ruby-block-up (&optional no-recurse)
- "mark the next level up."
- (interactive)
- (if (use-region-p)
- (let* ((orig-end (region-end))
- (orig-beg (region-beginning))
- (orig-len (- orig-end orig-beg))
- (prev-block-point
- (or (save-excursion
- (goto-char orig-end)
- (forward-line 0)
- (back-to-indentation)
- (cond ((looking-at-p er/ruby-block-end-re)
- (point-at-bol 0))
- ((re-search-forward
- (concat "\\<\\(" ruby-block-beg-re "\\)\\>")
- (point-at-eol)
- t)
- (point-at-bol 2))) )
- (point)))
- (prev-block-info (er/get-ruby-block prev-block-point))
- (prev-block-beg (car prev-block-info))
- (prev-block-end (cdr prev-block-info))
- (prev-block-len (- prev-block-end prev-block-beg)))
- (if (and (>= orig-beg prev-block-beg)
- (<= orig-end prev-block-end)
- (< orig-len prev-block-len))
- ;; expand to previous block if it contains and grows current
- ;; region
- (progn
- (deactivate-mark)
- (goto-char prev-block-point)
- (or no-recurse
- (er/mark-ruby-block-up 'no-recurse)))
- (er/mark-ruby-block-up-1)))
- (er/mark-ruby-block-up-1)))
-
-(defun er/mark-ruby-instance-variable ()
- "Marks instance variables in ruby.
-Assumes that point is at the @ - if it is inside the word, that will
-be marked first anyway."
- (when (looking-at "@")
- (forward-char 1))
- (when (er/looking-back-exact "@")
- (er/mark-symbol)
- (forward-char -1)))
-
-(defun er/mark-ruby-heredoc ()
- "Marks a heredoc, since `er/mark-inside-quotes' assumes single quote chars."
- (let ((ppss (syntax-ppss)))
- (when (elt ppss 3)
- (let ((s-start (elt ppss 8)))
- (goto-char s-start)
- (when (save-excursion
- (beginning-of-line)
- (re-search-forward "<<\\(-?\\)['\"]?\\([a-zA-Z0-9_]+\\)" s-start nil))
- (let ((allow-indent (string= "-" (match-string 1)))
- (terminator (match-string 2))
- (heredoc-start (save-excursion
- (forward-line)
- (point))))
- (forward-sexp 1)
- (forward-line -1)
- (when (looking-at (concat "^" (if allow-indent "[ \t]*" "") terminator "$"))
- (set-mark heredoc-start)
- (exchange-point-and-mark))))))))
-
-(defun er/add-ruby-mode-expansions ()
- "Adds Ruby-specific expansions for buffers in ruby-mode"
- (set (make-local-variable 'er/try-expand-list)
- (remove 'er/mark-defun
- (append
- (default-value 'er/try-expand-list)
- '(er/mark-ruby-instance-variable
- er/mark-ruby-block-up
- er/mark-ruby-heredoc)))))
-
-(er/enable-mode-expansions 'ruby-mode 'er/add-ruby-mode-expansions)
-(provide 'ruby-mode-expansions)
+++ /dev/null
-;;; sml-mode-expansions.el --- Expansions for expand-region to be used in sml-mode
-
-;; Copyright (C) 2012 Alexis Gallagher
-
-;; Author: Alexis Gallagher
-;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Provides extra expansions for sml-mode:
-;; - various expression (case, if, let)
-;; - fun bindings
-;;
-;; Tested with sml-mode version 6.3
-;;
-;; Feel free to contribute any other expansions for SML at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(declare-function sml-find-matching-starter "sml-mode")
-
-;; TODO: comma-delimited elements within a list,tuple,record
-;; TODO: match expression, patterns
-;; TODO: individual field, record type
-;; TODO: head-or-tail, then cons expression
-
-(defun er/sml-mark-keyword-prefixed-expression ()
- "Mark the surrounding expression."
- (interactive)
- (progn
- (sml-find-matching-starter '("case" "let" "if" "raise"))
- (mark-sexp)))
-
-
-(defun er/add-sml-mode-expansions ()
- "Adds expansions for buffers in `sml-mode'."
- (set (make-local-variable 'er/try-expand-list)
- (append er/try-expand-list
- '(sml-mark-function
- er/sml-mark-keyword-prefixed-expression
- mark-sexp))))
-
-(er/enable-mode-expansions 'sml-mode 'er/add-sml-mode-expansions)
-
-(provide 'sml-mode-expansions)
-
-;; sml-mode-expansions.el ends here
+++ /dev/null
-;;; subword-mode-expansions.el --- Expansions for subword-mode to be used for CamelCase
-
-;; Copyright (C) 2014 Lefteris Karapetsas
-
-;; Author: Lefteris Karapetsas
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Provides extra expansions for subword mode so that when
-;; subword-mode is non-nil different words can be selected in CamelCase.
-;; Feel free to contribute any other expansions:
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(require 'subword)
-
-(defun er/mark-subword ()
- "Mark a subword, a part of a CamelCase identifier."
- (interactive)
- (when (and subword-mode
- expand-region-subword-enabled)
- (subword-right 1)
- (set-mark (point))
- (subword-left 1)))
-
-(defun er/add-subword-mode-expansions ()
- "Add expansions for buffers in `subword-mode'."
- (set (make-local-variable 'er/try-expand-list)
- (append er/try-expand-list
- '(er/mark-subword))))
-
-(er/enable-minor-mode-expansions 'subword-mode 'er/add-subword-mode-expansions)
-
-(provide 'subword-mode-expansions)
-;;; subword-mode-expansions.el ends here
+++ /dev/null
-;;; text-mode-expansions.el --- Expansions for expand-region to be used in text
-
-;; Copyright (C) 2012 Ivan Andrus
-
-;; Author: Ivan Andrus
-;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Feel free to contribute any other expansions for normal text at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/mark-text-sentence ()
- "Marks one sentence."
- (interactive)
- ;; The obvious
- ;; (backward-sentence 1) (mark-end-of-sentence 1)
- ;; doesn't work here because it's repeated and the selection keeps
- ;; growing by sentences, which isn't what's wanted.
- (forward-sentence 1)
- (set-mark (point))
- (backward-sentence 1))
-
-(defun er/mark-text-paragraph ()
- "Marks one paragraph."
- (interactive)
- (mark-paragraph)
- (skip-chars-forward er--space-str))
-
-(defun er/add-text-mode-expansions ()
- "Adds expansions for buffers in `text-mode' except for `html-mode'.
-Unfortunately `html-mode' inherits from `text-mode' and
-text-mode-expansions don't work well in `html-mode'."
- (unless (member major-mode expand-region-exclude-text-mode-expansions)
- (set (make-local-variable 'er/try-expand-list)
- (append
- er/try-expand-list
- '(er/mark-text-sentence
- er/mark-text-paragraph
- mark-page)))))
-
-(er/enable-mode-expansions 'text-mode 'er/add-text-mode-expansions)
-
-(provide 'text-mode-expansions)
-
-;; text-mode-expansions.el ends here
+++ /dev/null
-;;; the-org-mode-expansions.el --- Expansions for expand-region to be used in org-mode
-
-;; Copyright (C) 2012 Magnar Sveen
-
-;; Author: Magnar Sveen
-;; Based on text-mode-expansions by: Ivan Andrus
-;; Keywords: marking region
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; The file needs to be weirdly name (prefixed with the-) to avoid
-;; conflict with org-reload, which bases its functionality on the names
-;; of files, for some reason.
-;;
-;; Feel free to contribute any other expansions for org-mode at
-;;
-;; https://github.com/magnars/expand-region.el
-
-;;; Code:
-
-(require 'expand-region-core)
-(require 'org-macs)
-(require 'org-element)
-
-(declare-function org-up-element "org")
-(declare-function org-mark-subtree "org")
-
-(defun er/mark-org-element ()
- (interactive)
- (let* ((el (org-element-at-point))
- (begin (plist-get (cadr el) :begin))
- (end (plist-get (cadr el) :end)))
- (goto-char begin)
- (set-mark (point))
- (goto-char end)
- (exchange-point-and-mark)))
-
-(defun er/mark-org-element-parent ()
- (interactive)
- (let* ((el (plist-get (cadr (org-element-at-point)) :parent))
- (begin (plist-get (cadr el) :begin))
- (end (plist-get (cadr el) :end)))
- (when (and begin end)
- (goto-char begin)
- (set-mark (point))
- (goto-char end)
- (exchange-point-and-mark))))
-
-(defun er/mark-sentence ()
- "Marks one sentence."
- (interactive)
- (forward-char 1)
- (backward-sentence 1)
- (set-mark (point))
- (forward-sentence 1)
- (exchange-point-and-mark))
-
-(defun er/mark-paragraph ()
- "Marks one paragraph."
- (interactive)
- (mark-paragraph)
- (exchange-point-and-mark)
- (skip-chars-backward er--space-str)
- (exchange-point-and-mark)
- (skip-chars-forward er--space-str))
-
-(defun er/mark-org-code-block ()
- "Marks an org-code-block."
- (interactive)
- (let ((case-fold-search t)
- (re "#\\+begin_\\(\\sw+\\)"))
- (unless (looking-at re)
- (search-backward-regexp re))
- (set-mark (point))
- (search-forward (concat "#+end_" (match-string 1)))
- (exchange-point-and-mark)))
-
-(defun er/mark-org-parent ()
- "Marks a heading 1 level up from current subheading"
- (interactive)
- (org-up-element)
- (org-mark-subtree))
-
-(defun er/save-org-mode-excursion (action)
- "Save outline visibility while expanding in org-mode"
- (org-save-outline-visibility t
- (funcall action)))
-
-(defun er/add-org-mode-expansions ()
- "Adds org-specific expansions for buffers in org-mode"
- (set (make-local-variable 'er/try-expand-list)
- (append
- (remove #'er/mark-defun er/try-expand-list)
- '(org-mark-subtree
- er/mark-org-element
- er/mark-org-element-parent
- er/mark-org-code-block
- er/mark-sentence
- er/mark-org-parent
- er/mark-paragraph)))
- (set (make-local-variable 'er/save-mode-excursion)
- #'er/save-org-mode-excursion))
-
-(er/enable-mode-expansions 'org-mode 'er/add-org-mode-expansions)
-
-(provide 'the-org-mode-expansions)
+++ /dev/null
-;;; web-mode-expansions.el --- Thin layer for adapting fxbois's web-mode-mark-and-expand function
-;;; to expand-region
-
-;; Copyright (C) 2012 Rotem Yaari
-
-;; Authors: Rotem Yaari
-;; Based on, and makes use of web-mode.el by fxbois
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defun er/add-web-mode-expansions ()
- (set (make-local-variable 'er/try-expand-list)
- (cons 'web-mode-mark-and-expand er/try-expand-list)))
-
-(er/enable-mode-expansions 'web-mode 'er/add-web-mode-expansions)
-
-(provide 'web-mode-expansions)
+++ /dev/null
-;;; yaml-mode-expansions.el --- expansions for yaml mode
-
-;; Copyright (C) 2021 Aaron Gonzales
-
-;; Author: Aaron Gonzales
-;; Keywords: marking region yaml YAML expand
-
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; - Additions implemented here:
-;; - er/mark-yaml-key-value
-;; - er/mark-yaml-list-item
-;; - er/mark-yaml-block
-;; - er/mark-yaml-outer-block
-;; - er/mark-yaml-inner-block
-
-
-;;; Code:
-
-(require 'expand-region-core)
-
-(defconst yaml-indent 2)
-
-(unless (fboundp 'yaml-indent-offset)
- (defalias 'yaml-indent-offset 'yaml-indent))
-
-(defvar er--yaml-key-value-regex
- (rx (one-or-more
- (any "0-9A-Za-z"))
- ":"
- (zero-or-more " ")
- (one-or-more
- (any "0-9A-Za-z" " '_-"))))
-
-(defvar er--yaml-list-item-regex
- (rx (seq "- "
- (one-or-more
- (any "0-9A-Za-z" "\"':=_-")))))
-
-(defvar er--yaml-block-regex
- (rx (seq (zero-or-more
- (any " -"))
- (one-or-more
- (any "0-9A-Za-z" " '_-"))
- ":\n")))
-
-(defun er--get-regex-indentation-level (regex)
- "Return the indentation level of the code with respect to the REGEX passed."
- (when (looking-at regex)
- ;; Block start means that the next level is deeper.
- (+ (current-indentation) yaml-indent-offset)
- ;; Assuming we're inside the block that we want to mark
- (current-indentation)))
-
-(defun er/mark-yaml-line-base (regex)
- "Mark line of yaml file based on simple REGEX."
- (back-to-indentation)
- (when (looking-at regex)
- (set-mark (line-end-position))))
-
-(defun er/mark-yaml-block-static-base (regex)
- "Mark yaml block based on REGEX passed. NEXT-INDENT-LEVEL can be used to search outer blocks when necessary."
- ;; go bac to indentation so always can get regexp
- (back-to-indentation)
- ;; make sure the cursor is set inside the block
- ;; mark point at this higher code block
- (set-mark (point))
- ;; save level of this blocks indentation
- (let ((block-indentation (current-indentation)))
- (forward-line 1)
- (while (and
- ;; No need to go beyond the end of the buffer. Can't use
- ;; eobp as the loop places the point at the beginning of
- ;; line, but eob might be at the end of the line.
- (not (= (point-max) (point-at-eol)))
- ;; Proceed if: indentation is too deep
- (or (> (current-indentation) block-indentation)
- ;; Looking at an empty line
- (looking-at (rx line-start (* whitespace) line-end))
- ;; We're not looking at the start of a YAML block
- ;; and the indent is deeper than the block's indent
- (and (not (looking-at regex))
- (> (current-indentation) block-indentation))))
- (forward-line 1)
- (back-to-indentation))
- ;; Find the end of the block by skipping comments backwards
- (python-util-forward-comment -1)
- (exchange-point-and-mark))
- (back-to-indentation))
-
-(defun er/mark-yaml-block-base (regex &optional next-indent-level)
- "Mark yaml block based on REGEX passed. NEXT-INDENT-LEVEL can be used to search outer blocks when necessary."
- ;; go bac to indentation so always can get regexp
- (back-to-indentation)
- ;; make sure the cursor is set inside the block
- (let ((next-indent-level
- (or
- ;; Use the given level
- next-indent-level
- ;; used to mark current block
- (er--get-regex-indentation-level regex))))
- ;; if true then at start of block and wanna mark itself
- ;; else were are inside the block already and will mark it)))
- ;; move up the code unti a parent code block is reached
- (while (and (>= (current-indentation) next-indent-level)
- (not (eq (current-indentation) 0)))
- (re-search-backward regex (point-min) t)
- (back-to-indentation))
- ;; mark point at this higher code block
- (set-mark (point))
- ;; save level of this blocks indentation
- (let ((block-indentation (current-indentation)))
- (forward-line 1)
- (while (and
- ;; No need to go beyond the end of the buffer. Can't use
- ;; eobp as the loop places the point at the beginning of
- ;; line, but eob might be at the end of the line.
- (not (= (point-max) (point-at-eol)))
- ;; Proceed if: indentation is too deep
- (or (> (current-indentation) block-indentation)
- ;; Looking at an empty line
- (looking-at (rx line-start (* whitespace) line-end))
- ;; We're not looking at the start of a YAML block
- ;; and the indent is deeper than the block's indent
- (and (not (looking-at regex))
- (> (current-indentation) block-indentation))))
- (forward-line 1)
- (back-to-indentation))
- ;; Find the end of the block by skipping comments backwards
- (python-util-forward-comment -1)
- (exchange-point-and-mark)))
- (back-to-indentation))
-
-(defun er/mark-yaml-key-value ()
- "Mark a yaml key-value pair."
- (interactive)
- (er/mark-yaml-line-base er--yaml-key-value-regex))
-
-(defun er/mark-yaml-list-item ()
- "Mark a yaml list item."
- (interactive)
- (er/mark-yaml-line-base er--yaml-list-item-regex))
-
-(defun er/mark-yaml-inner-block ()
- "Mark the yaml contents of the block at point. Command that wraps `er/mark-yaml-block-base'."
- (interactive)
- (er/mark-yaml-block-base er--yaml-block-regex (current-indentation))
- (forward-line)
- (back-to-indentation))
-
-(defun er/mark-yaml-block ()
- "Mark the yaml block that point is currently at the top of. Command that wraps `er/mark-yaml-block-base'."
- (interactive)
- (er/mark-yaml-block-static-base er--yaml-block-regex))
-
-(defun er/mark-yaml-outer-block ()
- "Mark the outer yaml block that surrounds the block around point. Command that wraps `er/mark-yaml-block-base'."
- (interactive)
- (er/mark-yaml-block-base er--yaml-block-regex (current-indentation)))
-
-(defun er/add-yaml-mode-expansions ()
- "Add yaml-mode-specific expansions for buffers in yaml-mode."
- (let ((try-expand-list-additions '(er/mark-symbol
- er/mark-outside-quotes
- er/mark-yaml-list-item
- er/mark-yaml-key-value
- er/mark-yaml-block
- er/mark-yaml-outer-block
- er/mark-yaml-inner-block)))
- (set (make-local-variable 'expand-region-skip-whitespace) nil)
- (set (make-local-variable 'er/try-expand-list) try-expand-list-additions)))
-
-(er/enable-mode-expansions 'yaml-mode 'er/add-yaml-mode-expansions)
-
-(provide 'yaml-mode-expansions)
-
-;;; yaml-mode-expansions.el ends here
--- /dev/null
+;;; cc-mode-expansions.el --- C-specific expansions for expand-region
+
+;; Copyright (C) 2012 François Févotte
+
+;; Author: François Févotte
+;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Extra expansions for C-like modes that I've found useful so far:
+;;
+;; er/c-mark-statement
+;; Captures simple and more complex statements.
+;;
+;; er/c-mark-fully-qualified-name
+;; Captures identifiers composed of several '::'-separated parts.
+;;
+;; er/c-mark-function-call[-1|-2]
+;; Captures an identifier followed by a '()'-enclosed block.
+;;
+;; er/c-mark-statement-block[-1|-2]
+;; Captures a statement followed by a '{}'-enclosed block.
+;; This matches function definitions and if/for/... constructs.
+;;
+;; er/c-mark-vector-access[-1|-2]
+;; Captures an identifier followed by a '[]'-enclosed block.
+;;
+;; Feel free to contribute any other expansions for C at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(require 'er-basic-expansions)
+(require 'cc-cmds)
+
+(defun er/c-mark-statement ()
+ "Mark the current C statement.
+
+This function tries to ensure that pair-delimited substring are
+either fully inside or fully outside the statement."
+ (interactive)
+ (unless (use-region-p)
+ (set-mark (point)))
+
+ (if (< (point) (mark))
+ (exchange-point-and-mark))
+
+ ;; Contract the region a bit to make the
+ ;; er/c-mark-statement function idempotent
+ (when (>= (- (point) (mark)) 2)
+ (exchange-point-and-mark)
+ (forward-char)
+ (exchange-point-and-mark)
+ (backward-char))
+
+ (let (beg end)
+ ;; Determine boundaries of the outside-pairs region
+ (save-mark-and-excursion
+ (c-end-of-statement)
+ (er/mark-outside-pairs)
+ (setq beg (point)
+ end (mark)))
+
+ ;; Determine boundaries of the statement as given
+ ;; by c-beginning-of-statement/c-end-of-statement
+ (c-end-of-statement)
+ (exchange-point-and-mark)
+ (c-end-of-statement)(c-beginning-of-statement 1)
+
+ ;; If the two regions overlap, expand the region
+ (cond ((and (<= (point) beg)
+ (< (mark) end))
+ (set-mark end))
+ ((and (> (point) beg)
+ (>= (mark) end))
+ (goto-char beg)
+ (c-end-of-statement)
+ (c-beginning-of-statement 1)))))
+
+(defun er/c-mark-fully-qualified-name ()
+ "Mark the current C++ fully qualified identifier.
+
+This function captures identifiers composed of multiple
+'::'-separated parts."
+ (interactive)
+ (er/mark-symbol)
+ (when (use-region-p)
+ (when (> (point) (mark))
+ (exchange-point-and-mark))
+ (while (er/looking-back-exact "::")
+ (backward-char 2)
+ (skip-syntax-backward "_w"))
+ (exchange-point-and-mark)
+ (while (looking-at "::")
+ (forward-char 2)
+ (skip-syntax-forward "_w"))
+ (exchange-point-and-mark)))
+
+(defmacro er/c-define-construct (name mark-first-part open-brace doc)
+ (let ((docstring (make-symbol "docstring-tmp")))
+ (setq docstring
+ (concat
+ doc "\n\n"
+ "This function tries to mark a region consisting of two parts:\n"
+ (format " - the first part is marked using `%s'\n" (symbol-name mark-first-part))
+ (format " - the second part is a block beginning with '%s'\n\n" open-brace)))
+ `(progn
+ (defun ,(intern (concat (symbol-name name) "-1")) ()
+ ,(concat docstring
+ "This function assumes that point is in the first part and the\n"
+ "region is active.\n\n"
+ (format "See also `%s'." (concat (symbol-name name) "-2")))
+ (interactive)
+ (when (use-region-p)
+ (,mark-first-part)
+ (exchange-point-and-mark)
+ (let ((oldpos (point)))
+ (skip-syntax-forward " ")
+ (if (looking-at ,open-brace)
+ (progn (forward-sexp)
+ (exchange-point-and-mark))
+ (goto-char oldpos)))))
+ (defun ,(intern (concat (symbol-name name) "-2")) ()
+ ,(concat docstring
+ "This function assumes that the block constituting the second part\n"
+ "is already marked and active.\n\n"
+ (format "See also `%s'." (concat (symbol-name name) "-1")))
+ (interactive)
+ (when (use-region-p)
+ (when (> (point) (mark))
+ (exchange-point-and-mark))
+ (when (looking-at ,open-brace)
+ (let ((beg (point))
+ (end (progn (forward-sexp 1)
+ (point))))
+ (goto-char beg)
+ (skip-syntax-backward " ")
+ (backward-char)
+ (deactivate-mark)
+ (,mark-first-part)
+ (set-mark end))))))))
+
+(er/c-define-construct er/c-mark-function-call er/c-mark-fully-qualified-name "("
+ "Mark the current function call.")
+(er/c-define-construct er/c-mark-statement-block er/c-mark-statement "{"
+ "Mark the current block construct (like if, for, etc.)")
+(er/c-define-construct er/c-mark-vector-access er/c-mark-fully-qualified-name "\\["
+ "Mark the current vector access.")
+
+(defun er/add-cc-mode-expansions ()
+ "Adds expansions for buffers in c-mode."
+ (set (make-local-variable 'er/try-expand-list)
+ (append er/try-expand-list
+ '(er/c-mark-statement
+ er/c-mark-fully-qualified-name
+ er/c-mark-function-call-1 er/c-mark-function-call-2
+ er/c-mark-statement-block-1 er/c-mark-statement-block-2
+ er/c-mark-vector-access-1 er/c-mark-vector-access-2))))
+
+(er/enable-mode-expansions 'c-mode 'er/add-cc-mode-expansions)
+(er/enable-mode-expansions 'c++-mode 'er/add-cc-mode-expansions)
+(er/enable-mode-expansions 'objc-mode 'er/add-cc-mode-expansions)
+(er/enable-mode-expansions 'java-mode 'er/add-cc-mode-expansions)
+(er/enable-mode-expansions 'idl-mode 'er/add-cc-mode-expansions)
+(er/enable-mode-expansions 'pike-mode 'er/add-cc-mode-expansions)
+(er/enable-mode-expansions 'awk-mode 'er/add-cc-mode-expansions)
+
+(provide 'cc-mode-expansions)
+
+;; cc-mode-expansions.el ends here
--- /dev/null
+;;; clojure-mode-expansions.el --- Clojure-specific expansions for expand-region
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Extra expansions for clojure-mode:
+;;
+;; * `er/mark-clj-word` - includes dashes, but not slashes.
+;; * `er/mark-clj-regexp-literal`
+;; * `er/mark-clj-function-literal`
+;;
+;; Feel free to contribute any other expansions for Clojure at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(require 'er-basic-expansions)
+
+(defun er/mark-clj-word ()
+ "Mark the entire word around or in front of point, including dashes."
+ (interactive)
+ (let ((word-regexp "\\(\\sw\\|-\\)"))
+ (when (or (looking-at word-regexp)
+ (er/looking-back-on-line word-regexp))
+ (while (looking-at word-regexp)
+ (forward-char))
+ (set-mark (point))
+ (while (er/looking-back-on-line word-regexp)
+ (backward-char)))))
+
+(defun er/mark-clj-set-literal ()
+ "Mark clj-set-literal presumes that point is outside the brackets.
+If point is inside the brackets, those will be marked first anyway."
+ (interactive)
+ (when (or (looking-at "#{")
+ (er/looking-back-exact "#"))
+ (forward-char 1)
+ (search-backward "#")
+ (set-mark (point))
+ (search-forward "{")
+ (forward-char -1)
+ (forward-list 1)
+ (exchange-point-and-mark)))
+
+(defun er/mark-clj-regexp-literal ()
+ "Mark clj-regexp-literal presumes that point is outside the string.
+If point is inside the string, the quotes will be marked first anyway."
+ (interactive)
+ (when (or (looking-at "#\"")
+ (er/looking-back-exact "#"))
+ (forward-char 1)
+ (search-backward "#")
+ (set-mark (point))
+ (search-forward "\"")
+ (forward-char 1)
+ (er--move-point-forward-out-of-string)
+ (exchange-point-and-mark)))
+
+(defun er/mark-clj-function-literal ()
+ "Mark clj-function-literal presumes that point is outside the parens.
+If point is inside the parens, they will be marked first anyway."
+ (interactive)
+ (when (or (looking-at "#(")
+ (er/looking-back-exact "#"))
+ (forward-char)
+ (search-backward "#")
+ (set-mark (point))
+ (search-forward "(")
+ (backward-char)
+ (forward-list)
+ (exchange-point-and-mark)))
+
+(defun er/add-clojure-mode-expansions ()
+ "Adds clojure-specific expansions for buffers in clojure-mode"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(er/mark-clj-word
+ er/mark-clj-regexp-literal
+ er/mark-clj-set-literal
+ er/mark-clj-function-literal))))
+
+(er/enable-mode-expansions 'clojure-mode 'er/add-clojure-mode-expansions)
+(er/enable-mode-expansions 'nrepl-mode 'er/add-clojure-mode-expansions)
+
+(provide 'clojure-mode-expansions)
+
+;; clojure-mode-expansions.el ends here
--- /dev/null
+;;; cperl-mode-expansions.el --- perl-specific expansions for expand-region
+
+;; Copyright (C) 2012 Kang-min Liu
+
+;; Author: Kang-min Liu <gugodNOSPAMgugod.org>
+;; Keywords: marking region cperl
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/mark-cperl-variable-name ()
+ "Marks one perl variable"
+ (interactive)
+ (forward-word)
+ (backward-word)
+ (search-backward-regexp "[@$%]" (line-beginning-position))
+ (set-mark (point))
+ (forward-char)
+ (search-forward-regexp "[^a-z_]" (line-end-position))
+ (backward-char)
+ (exchange-point-and-mark))
+
+(defun er/mark-cperl-package-name ()
+ "Marks one perl package name"
+ (interactive)
+ (forward-sexp)
+ (backward-sexp)
+ (set-mark (point))
+ (forward-sexp)
+ (search-backward "::" (line-beginning-position))
+ (exchange-point-and-mark))
+
+(defun er/mark-cperl-subroutine ()
+ "Marks current subroutine body."
+ (interactive)
+ (end-of-defun)
+ (set-mark (point))
+ (beginning-of-defun))
+
+(defun er/add-cperl-mode-expansions ()
+ "Add cprel mode expansinos"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(er/mark-cperl-variable-name
+ er/mark-cperl-package-name
+ er/mark-cperl-subroutine
+ ))))
+
+(er/enable-mode-expansions 'cperl-mode 'er/add-cperl-mode-expansions)
+
+(provide 'cperl-mode-expansions)
+
+;; cperl-mode-expansions.el ends here
--- /dev/null
+;;; css-mode-expansions.el --- CSS-specific expansions for expand-region
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; For now I have only found the need for mark-css-declaration.
+;;
+;; Feel free to contribute any other expansions for CSS at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/mark-css-declaration ()
+ "Marks one CSS declaration, eg. font-weight: bold;"
+ (interactive)
+ (search-backward-regexp "[;{] ?" (line-beginning-position))
+ (forward-char)
+ (set-mark (point))
+ (search-forward ";" (line-end-position))
+ (exchange-point-and-mark))
+
+(defun er/add-css-mode-expansions ()
+ "Adds CSS-specific expansions for buffers in css-mode"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(er/mark-css-declaration))))
+
+(er/enable-mode-expansions 'css-mode 'er/add-css-mode-expansions)
+
+(provide 'css-mode-expansions)
+
+;; css-mode-expansions.el ends here
--- /dev/null
+;;; enh-ruby-mode-expansions.el --- Expansions for enh-ruby-mode
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; enh-ruby-mode doesn't use ruby-mode's mark-defun - it has its own.
+;;
+;; Feel free to contribute any other expansions for enh-ruby-mode at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(defun er/add-enh-ruby-mode-expansions ()
+ "Adds Ruby-specific expansions for buffers in enh-ruby-mode"
+ (require 'ruby-mode-expansions)
+
+ (set (make-local-variable 'er/try-expand-list) (append
+ (remove 'er/mark-defun er/try-expand-list)
+ '(er/mark-ruby-instance-variable
+ er/mark-ruby-block-up))))
+
+(er/enable-mode-expansions 'enh-ruby-mode 'er/add-enh-ruby-mode-expansions)
+
+(provide 'enh-ruby-mode-expansions)
--- /dev/null
+;;; er-basic-expansions.el --- Words, symbols, strings, et al
+
+;; Copyright (C) 2011-2013 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Expansions that are useful in any major mode.
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/mark-word ()
+ "Mark the entire word around or in front of point."
+ (interactive)
+ (let ((word-regexp "\\sw"))
+ (when (or (looking-at word-regexp)
+ (er/looking-back-on-line word-regexp))
+ (skip-syntax-forward "w")
+ (set-mark (point))
+ (skip-syntax-backward "w"))))
+
+(defun er/mark-symbol ()
+ "Mark the entire symbol around or in front of point."
+ (interactive)
+ (let ((symbol-regexp "\\s_\\|\\sw"))
+ (when (or (looking-at symbol-regexp)
+ (er/looking-back-on-line symbol-regexp))
+ (skip-syntax-forward "_w")
+ (set-mark (point))
+ (skip-syntax-backward "_w"))))
+
+(defun er/mark-symbol-with-prefix ()
+ "Mark the entire symbol around or in front of point, including prefix."
+ (interactive)
+ (let ((symbol-regexp "\\s_\\|\\sw")
+ (prefix-regexp "\\s'"))
+ (when (or (looking-at prefix-regexp)
+ (looking-at symbol-regexp)
+ (er/looking-back-on-line symbol-regexp))
+ (skip-syntax-forward "'")
+ (skip-syntax-forward "_w")
+ (set-mark (point))
+ (skip-syntax-backward "_w")
+ (skip-syntax-backward "'"))))
+
+;; Mark method call
+
+(defun er/mark-next-accessor ()
+ "Presumes that current symbol is already marked, skips over one
+period and marks next symbol."
+ (interactive)
+ (when (use-region-p)
+ (when (< (point) (mark))
+ (exchange-point-and-mark))
+ (let ((symbol-regexp "\\s_\\|\\sw"))
+ (when (looking-at "\\.")
+ (forward-char 1)
+ (skip-syntax-forward "_w")
+ (exchange-point-and-mark)))))
+
+(defun er/mark-method-call ()
+ "Mark the current symbol (including dots) and then paren to closing paren."
+ (interactive)
+ (let ((symbol-regexp "\\(\\s_\\|\\sw\\|\\.\\)+"))
+ (when (or (looking-at symbol-regexp)
+ (er/looking-back-on-line symbol-regexp))
+ (skip-syntax-backward "_w.")
+ (set-mark (point))
+ (when (looking-at symbol-regexp)
+ (goto-char (match-end 0)))
+ (if (looking-at "(")
+ (forward-list))
+ (exchange-point-and-mark))))
+
+;; Comments
+
+(defun er--point-is-in-comment-p ()
+ "t if point is in comment, otherwise nil"
+ (or (nth 4 (syntax-ppss))
+ (memq (get-text-property (point) 'face) '(font-lock-comment-face font-lock-comment-delimiter-face))))
+
+(defun er/mark-comment ()
+ "Mark the entire comment around point."
+ (interactive)
+ (when (er--point-is-in-comment-p)
+ (let ((p (point)))
+ (while (and (er--point-is-in-comment-p) (not (eobp)))
+ (forward-char 1))
+ (skip-chars-backward "\n\r")
+ (set-mark (point))
+ (goto-char p)
+ (while (er--point-is-in-comment-p)
+ (forward-char -1))
+ (forward-char 1))))
+
+;; Quotes
+
+(defun er--current-quotes-char ()
+ "The char that is the current quote delimiter"
+ (nth 3 (syntax-ppss)))
+
+(defalias 'er--point-inside-string-p 'er--current-quotes-char)
+
+(defun er--move-point-forward-out-of-string ()
+ "Move point forward until it exits the current quoted string."
+ (er--move-point-backward-out-of-string)
+ (forward-sexp))
+
+(defun er--move-point-backward-out-of-string ()
+ "Move point backward until it exits the current quoted string."
+ (goto-char (nth 8 (syntax-ppss))))
+
+(defun er/mark-inside-quotes ()
+ "Mark the inside of the current string, not including the quotation marks."
+ (interactive)
+ (when (er--point-inside-string-p)
+ (er--move-point-backward-out-of-string)
+ (forward-char)
+ (set-mark (point))
+ (er--move-point-forward-out-of-string)
+ (backward-char)
+ (exchange-point-and-mark)))
+
+(defun er/mark-outside-quotes ()
+ "Mark the current string, including the quotation marks."
+ (interactive)
+ (if (er--point-inside-string-p)
+ (er--move-point-backward-out-of-string)
+ (when (and (not (use-region-p))
+ (er/looking-back-on-line "\\s\""))
+ (backward-char)
+ (er--move-point-backward-out-of-string)))
+ (when (looking-at "\\s\"")
+ (set-mark (point))
+ (forward-char)
+ (er--move-point-forward-out-of-string)
+ (exchange-point-and-mark)))
+
+;; Pairs - ie [] () {} etc
+
+(defun er--point-inside-pairs-p ()
+ "Is point inside any pairs?"
+ (> (car (syntax-ppss)) 0))
+
+(defun er/mark-inside-pairs ()
+ "Mark inside pairs (as defined by the mode), not including the pairs."
+ (interactive)
+ (when (er--point-inside-pairs-p)
+ (goto-char (nth 1 (syntax-ppss)))
+ (set-mark (save-excursion
+ (forward-char 1)
+ (skip-chars-forward er--space-str)
+ (point)))
+ (forward-list)
+ (backward-char)
+ (skip-chars-backward er--space-str)
+ (exchange-point-and-mark)))
+
+(defun er--looking-at-pair ()
+ "Is point looking at an opening pair char?"
+ (looking-at "\\s("))
+
+(defun er--looking-at-marked-pair ()
+ "Is point looking at a pair that is entirely marked?"
+ (and (er--looking-at-pair)
+ (use-region-p)
+ (>= (mark)
+ (save-excursion
+ (forward-list)
+ (point)))))
+
+(defun er/mark-outside-pairs ()
+ "Mark pairs (as defined by the mode), including the pair chars."
+ (interactive)
+ (if (and (er/looking-back-on-line "\\s)+\\=")
+ (not (er--looking-at-pair)))
+ (ignore-errors (backward-list 1))
+ (skip-chars-forward er--space-str))
+ (when (and (er--point-inside-pairs-p)
+ (or (not (er--looking-at-pair))
+ (er--looking-at-marked-pair)))
+ (goto-char (nth 1 (syntax-ppss))))
+ (when (er--looking-at-pair)
+ (set-mark (point))
+ (forward-list)
+ (exchange-point-and-mark)))
+
+(require 'thingatpt)
+
+(defun er/mark-url ()
+ (interactive)
+ (end-of-thing 'url)
+ (set-mark (point))
+ (beginning-of-thing 'url))
+
+(defun er/mark-email ()
+ (interactive)
+ (end-of-thing 'email)
+ (set-mark (point))
+ (beginning-of-thing 'email))
+
+(defun er/mark-defun ()
+ "Mark defun around or in front of point."
+ (interactive)
+ (end-of-defun)
+ (skip-chars-backward er--space-str)
+ (set-mark (point))
+ (beginning-of-defun)
+ (skip-chars-forward er--space-str))
+
+;; Methods to try expanding to
+(setq er/try-expand-list
+ (append '(er/mark-word
+ er/mark-symbol
+ er/mark-symbol-with-prefix
+ er/mark-next-accessor
+ er/mark-method-call
+ er/mark-inside-quotes
+ er/mark-outside-quotes
+ er/mark-inside-pairs
+ er/mark-outside-pairs
+ er/mark-comment
+ er/mark-url
+ er/mark-email
+ er/mark-defun)
+ er/try-expand-list))
+
+(provide 'er-basic-expansions)
+;;; er-basic-expansions.el ends here
--- /dev/null
+;;; erlang-mode-expansions.el --- Erlang-specific expansions for expand-region
+
+;; Copyright (C) 2012 Gleb Peregud
+
+;; Author: Gleb Peregud
+;; Based on python-mode-expansions by: Ivan Andrus <darthandrusNOSPAMgmail.com>
+;; Keywords: marking region erlang
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Feel free to contribute any other expansions for Erlang at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Bugs:
+
+;; Doesn't handle many Erlang syntax constructs, just the basics
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/add-erlang-mode-expansions ()
+ "Adds Erlang-specific expansions for buffers in erlang-mode"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(erlang-mark-function
+ erlang-mark-clause))))
+
+(er/enable-mode-expansions 'erlang-mode 'er/add-erlang-mode-expansions)
+
+(provide 'erlang-mode-expansions)
+
+;; erlang-mode-expansions.el ends here
--- /dev/null
+;;; expand-region-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "cc-mode-expansions" "cc-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from cc-mode-expansions.el
+
+(register-definition-prefixes "cc-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "clojure-mode-expansions" "clojure-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from clojure-mode-expansions.el
+
+(register-definition-prefixes "clojure-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "cperl-mode-expansions" "cperl-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from cperl-mode-expansions.el
+
+(register-definition-prefixes "cperl-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "css-mode-expansions" "css-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from css-mode-expansions.el
+
+(register-definition-prefixes "css-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "enh-ruby-mode-expansions" "enh-ruby-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from enh-ruby-mode-expansions.el
+
+(register-definition-prefixes "enh-ruby-mode-expansions" '("er/add-enh-ruby-mode-expansions"))
+
+;;;***
+\f
+;;;### (autoloads nil "er-basic-expansions" "er-basic-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from er-basic-expansions.el
+
+(register-definition-prefixes "er-basic-expansions" '("er--" "er/mark-"))
+
+;;;***
+\f
+;;;### (autoloads nil "erlang-mode-expansions" "erlang-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from erlang-mode-expansions.el
+
+(register-definition-prefixes "erlang-mode-expansions" '("er/add-erlang-mode-expansions"))
+
+;;;***
+\f
+;;;### (autoloads nil "expand-region" "expand-region.el" (0 0 0 0))
+;;; Generated autoloads from expand-region.el
+
+(autoload 'er/expand-region "expand-region" "\
+Increase selected region by semantic units.
+
+With prefix argument expands the region that many times.
+If prefix argument is negative calls `er/contract-region'.
+If prefix argument is 0 it resets point and mark to their state
+before calling `er/expand-region' for the first time.
+
+\(fn ARG)" t nil)
+
+;;;***
+\f
+;;;### (autoloads nil "expand-region-core" "expand-region-core.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from expand-region-core.el
+
+(autoload 'er/contract-region "expand-region-core" "\
+Contract the selected region to its previous size.
+With prefix argument contracts that many times.
+If prefix argument is negative calls `er/expand-region'.
+If prefix argument is 0 it resets point and mark to their state
+before calling `er/expand-region' for the first time.
+
+\(fn ARG)" t nil)
+
+(register-definition-prefixes "expand-region-core" '("er--" "er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "expand-region-custom" "expand-region-custom.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from expand-region-custom.el
+
+(let ((loads (get 'expand-region 'custom-loads))) (if (member '"expand-region-custom" loads) nil (put 'expand-region 'custom-loads (cons '"expand-region-custom" loads))))
+
+(defvar expand-region-preferred-python-mode 'python "\
+The name of your preferred python mode")
+
+(custom-autoload 'expand-region-preferred-python-mode "expand-region-custom" t)
+
+(defvar expand-region-guess-python-mode t "\
+If expand-region should attempt to guess your preferred python mode")
+
+(custom-autoload 'expand-region-guess-python-mode "expand-region-custom" t)
+
+(defvar expand-region-autocopy-register "" "\
+If set to a string of a single character (try \"e\"), then the
+contents of the most recent expand or contract command will
+always be copied to the register named after that character.")
+
+(custom-autoload 'expand-region-autocopy-register "expand-region-custom" t)
+
+(defvar expand-region-skip-whitespace t "\
+If expand-region should skip past whitespace on initial expansion")
+
+(custom-autoload 'expand-region-skip-whitespace "expand-region-custom" t)
+
+(defvar expand-region-fast-keys-enabled t "\
+If expand-region should bind fast keys after initial expand/contract")
+
+(custom-autoload 'expand-region-fast-keys-enabled "expand-region-custom" t)
+
+(defvar expand-region-contract-fast-key "-" "\
+Key to use after an initial expand/contract to contract once more.")
+
+(custom-autoload 'expand-region-contract-fast-key "expand-region-custom" t)
+
+(defvar expand-region-reset-fast-key "0" "\
+Key to use after an initial expand/contract to undo.")
+
+(custom-autoload 'expand-region-reset-fast-key "expand-region-custom" t)
+
+(defvar expand-region-exclude-text-mode-expansions '(html-mode nxml-mode) "\
+List of modes which derive from `text-mode' for which text mode expansions are not appropriate.")
+
+(custom-autoload 'expand-region-exclude-text-mode-expansions "expand-region-custom" t)
+
+(defvar expand-region-smart-cursor nil "\
+Defines whether the cursor should be placed intelligently after expansion.
+
+If set to t, and the cursor is already at the beginning of the new region,
+keep it there; otherwise, put it at the end of the region.
+
+If set to nil, always place the cursor at the beginning of the region.")
+
+(custom-autoload 'expand-region-smart-cursor "expand-region-custom" t)
+
+(define-obsolete-variable-alias 'er/enable-subword-mode\? 'expand-region-subword-enabled "2019-03-23")
+
+(defvar expand-region-subword-enabled nil "\
+Whether expand-region should use subword expansions.")
+
+(custom-autoload 'expand-region-subword-enabled "expand-region-custom" t)
+
+(register-definition-prefixes "expand-region-custom" '("expand-region-"))
+
+;;;***
+\f
+;;;### (autoloads nil "feature-mode-expansions" "feature-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from feature-mode-expansions.el
+
+(register-definition-prefixes "feature-mode-expansions" '("er--block-between-keywords" "er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "html-mode-expansions" "html-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from html-mode-expansions.el
+
+(register-definition-prefixes "html-mode-expansions" '("er--" "er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "js-mode-expansions" "js-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from js-mode-expansions.el
+
+(register-definition-prefixes "js-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "js2-mode-expansions" "js2-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from js2-mode-expansions.el
+
+(register-definition-prefixes "js2-mode-expansions" '("er/add-js2-mode-expansions" "js2-mark-parent-statement"))
+
+;;;***
+\f
+;;;### (autoloads nil "jsp-expansions" "jsp-expansions.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from jsp-expansions.el
+
+(register-definition-prefixes "jsp-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "latex-mode-expansions" "latex-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from latex-mode-expansions.el
+
+(register-definition-prefixes "latex-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "nxml-mode-expansions" "nxml-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from nxml-mode-expansions.el
+
+(register-definition-prefixes "nxml-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "octave-expansions" "octave-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from octave-expansions.el
+
+(register-definition-prefixes "octave-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "python-el-expansions" "python-el-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from python-el-expansions.el
+
+(register-definition-prefixes "python-el-expansions" '("er--python-string-delimiter" "er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "python-el-fgallina-expansions" "python-el-fgallina-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from python-el-fgallina-expansions.el
+
+(register-definition-prefixes "python-el-fgallina-expansions" '("er--python-" "er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "python-mode-expansions" "python-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from python-mode-expansions.el
+
+(register-definition-prefixes "python-mode-expansions" '("er--" "er/" "py-goto-beyond-clause"))
+
+;;;***
+\f
+;;;### (autoloads nil "ruby-mode-expansions" "ruby-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from ruby-mode-expansions.el
+
+(register-definition-prefixes "ruby-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "sml-mode-expansions" "sml-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from sml-mode-expansions.el
+
+(register-definition-prefixes "sml-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "subword-mode-expansions" "subword-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from subword-mode-expansions.el
+
+(register-definition-prefixes "subword-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "text-mode-expansions" "text-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from text-mode-expansions.el
+
+(register-definition-prefixes "text-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "the-org-mode-expansions" "the-org-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from the-org-mode-expansions.el
+
+(register-definition-prefixes "the-org-mode-expansions" '("er/"))
+
+;;;***
+\f
+;;;### (autoloads nil "web-mode-expansions" "web-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from web-mode-expansions.el
+
+(register-definition-prefixes "web-mode-expansions" '("er/add-web-mode-expansions"))
+
+;;;***
+\f
+;;;### (autoloads nil "yaml-mode-expansions" "yaml-mode-expansions.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from yaml-mode-expansions.el
+
+(register-definition-prefixes "yaml-mode-expansions" '("er--" "er/" "yaml-indent"))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("expand-region-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; expand-region-autoloads.el ends here
--- /dev/null
+;;; expand-region-core.el --- Increase selected region by semantic units.
+
+;; Copyright (C) 2011-2013 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The core functionality of expand-region.
+
+;; See README.md
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+(require 'expand-region-custom)
+(declare-function er/expand-region "expand-region")
+
+(defvar er/history '()
+ "A history of start and end points so we can contract after expanding.")
+
+;; history is always local to a single buffer
+(make-variable-buffer-local 'er/history)
+
+(defvar er--space-str " \t\n")
+(defvar er--blank-list (append er--space-str nil))
+
+(set-default 'er--show-expansion-message nil)
+
+(defvar er/try-expand-list nil
+ "A list of functions that are tried when expanding.")
+
+(defvar er/save-mode-excursion nil
+ "A function to save excursion state when expanding.")
+
+(defun er--prepare-expanding ()
+ (when (and (er--first-invocation)
+ (not (use-region-p)))
+ (push-mark nil t) ;; one for keeping starting position
+ (push-mark nil t)) ;; one for replace by set-mark in expansions
+
+ (when (not transient-mark-mode)
+ (setq-local transient-mark-mode (cons 'only transient-mark-mode))))
+
+(defun er--copy-region-to-register ()
+ (when (and (stringp expand-region-autocopy-register)
+ (> (length expand-region-autocopy-register) 0))
+ (set-register (aref expand-region-autocopy-register 0)
+ (filter-buffer-substring (region-beginning) (region-end)))))
+
+;; save-mark-and-excursion in Emacs 25 works like save-excursion did before
+(eval-when-compile
+ (when (< emacs-major-version 25)
+ (defmacro save-mark-and-excursion (&rest body)
+ `(save-excursion ,@body))))
+
+(defmacro er--save-excursion (&rest body)
+ `(let ((action (lambda ()
+ (save-mark-and-excursion ,@body))))
+ (if er/save-mode-excursion
+ (funcall er/save-mode-excursion action)
+ (funcall action))))
+
+(defun er--expand-region-1 ()
+ "Increase selected region by semantic units.
+Basically it runs all the mark-functions in `er/try-expand-list'
+and chooses the one that increases the size of the region while
+moving point or mark as little as possible."
+ (let* ((p1 (point))
+ (p2 (if (use-region-p) (mark) (point)))
+ (start (min p1 p2))
+ (end (max p1 p2))
+ (try-list er/try-expand-list)
+ (best-start (point-min))
+ (best-end (point-max))
+ (set-mark-default-inactive nil))
+
+ ;; add hook to clear history on buffer changes
+ (unless er/history
+ (add-hook 'after-change-functions 'er/clear-history t t))
+
+ ;; remember the start and end points so we can contract later
+ ;; unless we're already at maximum size
+ (unless (and (= start best-start)
+ (= end best-end))
+ (push (cons p1 p2) er/history))
+
+ (when (and expand-region-skip-whitespace
+ (er--point-is-surrounded-by-white-space)
+ (= start end))
+ (skip-chars-forward er--space-str)
+ (setq start (point)))
+
+ (while try-list
+ (er--save-excursion
+ (ignore-errors
+ (funcall (car try-list))
+ (when (and (region-active-p)
+ (er--this-expansion-is-better start end best-start best-end))
+ (setq best-start (point))
+ (setq best-end (mark))
+ (when (and er--show-expansion-message (not (minibufferp)))
+ (message "%S" (car try-list))))))
+ (setq try-list (cdr try-list)))
+
+ (setq deactivate-mark nil)
+ ;; if smart cursor enabled, decide to put it at start or end of region:
+ (if (and expand-region-smart-cursor
+ (not (= start best-start)))
+ (progn (goto-char best-end)
+ (set-mark best-start))
+ (goto-char best-start)
+ (set-mark best-end))
+
+ (er--copy-region-to-register)
+
+ (when (and (= best-start (point-min))
+ (= best-end (point-max))) ;; We didn't find anything new, so exit early
+ 'early-exit)))
+
+(defun er--this-expansion-is-better (start end best-start best-end)
+ "t if the current region is an improvement on previous expansions.
+
+This is provided as a separate function for those that would like
+to override the heuristic."
+ (and
+ (<= (point) start)
+ (>= (mark) end)
+ (> (- (mark) (point)) (- end start))
+ (or (> (point) best-start)
+ (and (= (point) best-start)
+ (< (mark) best-end)))))
+
+;;;###autoload
+(defun er/contract-region (arg)
+ "Contract the selected region to its previous size.
+With prefix argument contracts that many times.
+If prefix argument is negative calls `er/expand-region'.
+If prefix argument is 0 it resets point and mark to their state
+before calling `er/expand-region' for the first time."
+ (interactive "p")
+ (if (< arg 0)
+ (er/expand-region (- arg))
+ (when er/history
+ ;; Be sure to reset them all if called with 0
+ (when (= arg 0)
+ (setq arg (length er/history)))
+
+ (when (not transient-mark-mode)
+ (setq-local transient-mark-mode (cons 'only transient-mark-mode)))
+
+ ;; Advance through the list the desired distance
+ (while (and (cdr er/history)
+ (> arg 1))
+ (setq arg (- arg 1))
+ (setq er/history (cdr er/history)))
+ ;; Reset point and mark
+ (let* ((last (pop er/history))
+ (start (car last))
+ (end (cdr last)))
+ (goto-char start)
+ (set-mark end)
+
+ (er--copy-region-to-register)
+
+ (when (eq start end)
+ (deactivate-mark)
+ (er/clear-history))))))
+
+(defun er/prepare-for-more-expansions-internal (repeat-key-str)
+ "Return bindings and a message to inform user about them"
+ (let ((msg (format "Type %s to expand again" repeat-key-str))
+ (bindings (list (cons repeat-key-str '(er/expand-region 1)))))
+ ;; If contract and expand are on the same binding, ignore contract
+ (unless (string-equal repeat-key-str expand-region-contract-fast-key)
+ (setq msg (concat msg (format ", %s to contract" expand-region-contract-fast-key)))
+ (push (cons expand-region-contract-fast-key '(er/contract-region 1)) bindings))
+ ;; If reset and either expand or contract are on the same binding, ignore reset
+ (unless (or (string-equal repeat-key-str expand-region-reset-fast-key)
+ (string-equal expand-region-contract-fast-key expand-region-reset-fast-key))
+ (setq msg (concat msg (format ", %s to reset" expand-region-reset-fast-key)))
+ (push (cons expand-region-reset-fast-key '(er/expand-region 0)) bindings))
+ (cons msg bindings)))
+
+(defun er/prepare-for-more-expansions ()
+ "Let one expand more by just pressing the last key."
+ (let* ((repeat-key (event-basic-type last-input-event))
+ (repeat-key-str (single-key-description repeat-key))
+ (msg-and-bindings (er/prepare-for-more-expansions-internal repeat-key-str))
+ (msg (car msg-and-bindings))
+ (bindings (cdr msg-and-bindings)))
+ (when repeat-key
+ (er/set-temporary-overlay-map
+ (let ((map (make-sparse-keymap)))
+ (dolist (binding bindings map)
+ (define-key map (read-kbd-macro (car binding))
+ `(lambda ()
+ (interactive)
+ (setq this-command `,(cadr ',binding))
+ (or (not expand-region-show-usage-message) (minibufferp) (message "%s" ,msg))
+ (eval `,(cdr ',binding))))))
+ t)
+ (or (not expand-region-show-usage-message) (minibufferp) (message "%s" msg)))))
+
+(if (fboundp 'set-temporary-overlay-map)
+ (fset 'er/set-temporary-overlay-map 'set-temporary-overlay-map)
+ ;; Backport this function from newer emacs versions
+ (defun er/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))))
+
+(defadvice keyboard-quit (before collapse-region activate)
+ (when (memq last-command '(er/expand-region er/contract-region))
+ (er/contract-region 0)))
+
+(defadvice minibuffer-keyboard-quit (around collapse-region activate)
+ (if (memq last-command '(er/expand-region er/contract-region))
+ (er/contract-region 0)
+ ad-do-it))
+
+(defadvice cua-cancel (before collapse-region activate)
+ (when (memq last-command '(er/expand-region er/contract-region))
+ (er/contract-region 0)))
+
+(defun er/clear-history (&rest args)
+ "Clear the history."
+ (setq er/history '())
+ (remove-hook 'after-change-functions 'er/clear-history t))
+
+(defsubst er--first-invocation ()
+ "t if this is the first invocation of er/expand-region or er/contract-region"
+ (not (memq last-command '(er/expand-region er/contract-region))))
+
+(defun er--point-is-surrounded-by-white-space ()
+ (and (or (memq (char-before) er--blank-list)
+ (eq (point) (point-min)))
+ (memq (char-after) er--blank-list)))
+
+(defun er/enable-mode-expansions (mode add-fn)
+ (add-hook (intern (format "%s-hook" mode)) add-fn)
+ (save-window-excursion
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when (derived-mode-p mode)
+ (funcall add-fn))))))
+
+(defun er/enable-minor-mode-expansions (mode add-fn)
+ (add-hook (intern (format "%s-hook" mode)) add-fn)
+ (save-window-excursion
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when (symbol-value mode)
+ (funcall add-fn))))))
+
+;; Some more performant version of `looking-back'
+
+(defun er/looking-back-on-line (regexp)
+ "Version of `looking-back' that only checks current line."
+ (looking-back regexp (line-beginning-position)))
+
+(defun er/looking-back-exact (s)
+ "Version of `looking-back' that only looks for exact matches, no regexp."
+ (string= s (buffer-substring (- (point) (length s))
+ (point))))
+
+(defun er/looking-back-max (regexp count)
+ "Version of `looking-back' that only check COUNT chars back."
+ (looking-back regexp (max 1 (- (point) count))))
+
+(provide 'expand-region-core)
+
+;;; expand-region-core.el ends here
--- /dev/null
+;;; expand-region-custom.el --- Increase selected region by semantic units.
+
+;; Copyright (C) 2012 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file holds customization variables.
+
+;;; Code:
+
+;;;###autoload
+(defgroup expand-region nil
+ "Increase selected region by semantic units."
+ :group 'tools)
+
+;;;###autoload
+(defcustom expand-region-preferred-python-mode 'python
+ "The name of your preferred python mode"
+ :group 'expand-region
+ :type '(choice (const :tag "Emacs' python.el" 'python)
+ (const :tag "fgallina's python.el" 'fgallina-python)
+ (const :tag "python-mode.el" 'python-mode)))
+
+;;;###autoload
+(defcustom expand-region-guess-python-mode t
+ "If expand-region should attempt to guess your preferred python mode"
+ :group 'expand-region
+ :type '(choice (const :tag "Guess" t)
+ (const :tag "Do not guess" nil)))
+
+(defun expand-region-guess-python-mode ()
+ "Guess the user's preferred python mode."
+ (setq expand-region-preferred-python-mode
+ (if (fboundp 'python-setup-brm)
+ 'python
+ 'fgallina-python)))
+
+;;;###autoload
+(defcustom expand-region-autocopy-register ""
+ "If set to a string of a single character (try \"e\"), then the
+contents of the most recent expand or contract command will
+always be copied to the register named after that character."
+ :group 'expand-region
+ :type 'string)
+
+;;;###autoload
+(defcustom expand-region-skip-whitespace t
+ "If expand-region should skip past whitespace on initial expansion"
+ :group 'expand-region
+ :type '(choice (const :tag "Skip whitespace" t)
+ (const :tag "Do not skip whitespace" nil)))
+
+;;;###autoload
+(defcustom expand-region-fast-keys-enabled t
+ "If expand-region should bind fast keys after initial expand/contract"
+ :group 'expand-region
+ :type '(choice (const :tag "Enable fast keys" t)
+ (const :tag "Disable fast keys" nil)))
+
+;;;###autoload
+(defcustom expand-region-contract-fast-key "-"
+ "Key to use after an initial expand/contract to contract once more."
+ :group 'expand-region
+ :type 'string)
+
+;;;###autoload
+(defcustom expand-region-reset-fast-key "0"
+ "Key to use after an initial expand/contract to undo."
+ :group 'expand-region
+ :type 'string)
+
+;;;###autoload
+(defcustom expand-region-exclude-text-mode-expansions
+ '(html-mode nxml-mode)
+ "List of modes which derive from `text-mode' for which text mode expansions are not appropriate."
+ :group 'expand-region
+ :type '(repeat (symbol :tag "Major Mode" unknown)))
+
+;;;###autoload
+(defcustom expand-region-smart-cursor nil
+ "Defines whether the cursor should be placed intelligently after expansion.
+
+If set to t, and the cursor is already at the beginning of the new region,
+keep it there; otherwise, put it at the end of the region.
+
+If set to nil, always place the cursor at the beginning of the region."
+ :group 'expand-region
+ :type '(choice (const :tag "Smart behaviour" t)
+ (const :tag "Standard behaviour" nil)))
+
+;;;###autoload
+(define-obsolete-variable-alias 'er/enable-subword-mode?
+ 'expand-region-subword-enabled "2019-03-23")
+
+;;;###autoload
+(defcustom expand-region-subword-enabled nil
+ "Whether expand-region should use subword expansions."
+ :group 'expand-region
+ :type '(choice (const :tag "Enable subword expansions" t)
+ (const :tag "Disable subword expansions" nil)))
+
+(defcustom expand-region-show-usage-message t
+ "Whether expand-region should show usage message."
+ :group 'expand-region
+ :type 'boolean)
+
+(provide 'expand-region-custom)
+
+;;; expand-region-custom.el ends here
--- /dev/null
+(define-package "expand-region" "20221030.957" "Increase selected region by semantic units." 'nil :commit "b70feaa644310dc2d599dc277cd20a1f2b6446ac" :authors
+ '(("Magnar Sveen" . "magnarsNOSPAMgmail.com"))
+ :maintainer
+ '("Magnar Sveen" . "magnarsNOSPAMgmail.com")
+ :keywords
+ '("marking" "region"))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
--- /dev/null
+;;; expand-region.el --- Increase selected region by semantic units.
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Expand region increases the selected region by semantic units. Just keep
+;; pressing the key until it selects what you want.
+
+;; An example:
+
+;; (setq alphabet-start "abc def")
+
+;; With the cursor at the `c`, it starts by marking the entire word `abc`, then
+;; expand to the contents of the quotes `abc def`, then to the entire quote
+;; `"abc def"`, then to the contents of the sexp `setq alphabet-start "abc def"`
+;; and finally to the entire sexp.
+
+;; You can set it up like this:
+
+;; (require 'expand-region)
+;; (global-set-key (kbd "C-=") 'er/expand-region)
+
+;; There's also `er/contract-region` if you expand too far.
+
+;; ## Video
+
+;; You can [watch an intro to expand-region at Emacs Rocks](http://emacsrocks.com/e09.html).
+
+;; ## Language support
+
+;; Expand region works fairly well with most languages, due to the general
+;; nature of the basic expansions:
+
+;; er/mark-word
+;; er/mark-symbol
+;; er/mark-method-call
+;; er/mark-inside-quotes
+;; er/mark-outside-quotes
+;; er/mark-inside-pairs
+;; er/mark-outside-pairs
+
+;; However, most languages also will benefit from some specially crafted
+;; expansions. For instance, expand-region comes with these extra expansions for
+;; html-mode:
+
+;; er/mark-html-attribute
+;; er/mark-inner-tag
+;; er/mark-outer-tag
+
+;; You can add your own expansions to the languages of your choice simply by
+;; creating a function that looks around point to see if it's inside or looking
+;; at the construct you want to mark, and if so - mark it.
+
+;; There's plenty of examples to look at in these files.
+
+;; After you make your function, add it to a buffer-local version of
+;; the `er/try-expand-list`.
+
+;; **Example:**
+
+;; Let's say you want expand-region to also mark paragraphs and pages in
+;; text-mode. Incidentally Emacs already comes with `mark-paragraph` and
+;; `mark-page`. To add it to the try-list, do this:
+
+;; (defun er/add-text-mode-expansions ()
+;; (make-variable-buffer-local 'er/try-expand-list)
+;; (setq er/try-expand-list (append
+;; er/try-expand-list
+;; '(mark-paragraph
+;; mark-page))))
+
+;; (er/enable-mode-expansions 'text-mode 'er/add-text-mode-expansions)
+
+;; Add that to its own file, and require it at the bottom of this one,
+;; where it says "Mode-specific expansions"
+
+;; **Warning:** Badly written expansions might slow down expand-region
+;; dramatically. Remember to exit quickly before you start traversing
+;; the entire document looking for constructs to mark.
+
+;; ## Contribute
+
+;; If you make some nice expansions for your favorite mode, it would be
+;; great if you opened a pull-request. The repo is at:
+
+;; https://github.com/magnars/expand-region.el
+
+;; Changes to `expand-region-core` itself must be accompanied by feature tests.
+;; They are written in [Ecukes](http://ecukes.info), a Cucumber for Emacs.
+
+;; To fetch the test dependencies:
+
+;; $ cd /path/to/expand-region
+;; $ git submodule init
+;; $ git submodule update
+
+;; Run the tests with:
+
+;; $ ./util/ecukes/ecukes features
+
+;; If you want to add feature-tests for your mode-specific expansions as well,
+;; that is utterly excellent.
+
+;; ## Contributors
+
+;; * [Josh Johnston](https://github.com/joshwnj) contributed `er/contract-region`
+;; * [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.
+;; * [Matt Briggs](https://github.com/mbriggs) contributed expansions for ruby-mode.
+;; * [Ivan Andrus](https://github.com/gvol) contributed expansions for python-mode, text-mode, LaTeX-mode and nxml-mode.
+;; * [Raimon Grau](https://github.com/kidd) added support for when transient-mark-mode is off.
+;; * [Gleb Peregud](https://github.com/gleber) contributed expansions for erlang-mode.
+;; * [fgeller](https://github.com/fgeller) and [edmccard](https://github.com/edmccard) contributed better support for python and its multiple modes.
+;; * [François Févotte](https://github.com/ffevotte) contributed expansions for C and C++.
+;; * [Roland Walker](https://github.com/rolandwalker) added option to copy the contents of the most recent action to a register, and some fixes.
+;; * [Damien Cassou](https://github.com/DamienCassou) added option to continue expanding/contracting with fast keys after initial expand.
+
+;; Thanks!
+
+;;; Code:
+
+(require 'expand-region-core)
+(require 'expand-region-custom)
+(require 'er-basic-expansions)
+
+;;;###autoload
+(defun er/expand-region (arg)
+ "Increase selected region by semantic units.
+
+With prefix argument expands the region that many times.
+If prefix argument is negative calls `er/contract-region'.
+If prefix argument is 0 it resets point and mark to their state
+before calling `er/expand-region' for the first time."
+ (interactive "p")
+ (if (< arg 1)
+ (er/contract-region (- arg))
+ (er--prepare-expanding)
+ (while (>= arg 1)
+ (setq arg (- arg 1))
+ (when (eq 'early-exit (er--expand-region-1))
+ (setq arg 0)))
+ (when (and expand-region-fast-keys-enabled
+ (not (memq last-command '(er/expand-region er/contract-region))))
+ (er/prepare-for-more-expansions))))
+
+(eval-after-load 'clojure-mode '(require 'clojure-mode-expansions))
+(eval-after-load 'css-mode '(require 'css-mode-expansions))
+(eval-after-load 'erlang-mode '(require 'erlang-mode-expansions))
+(eval-after-load 'feature-mode '(require 'feature-mode-expansions))
+(eval-after-load 'sgml-mode '(require 'html-mode-expansions)) ;; html-mode is defined in sgml-mode.el
+(eval-after-load 'rhtml-mode '(require 'html-mode-expansions))
+(eval-after-load 'nxhtml-mode '(require 'html-mode-expansions))
+(eval-after-load 'web-mode '(require 'web-mode-expansions))
+(eval-after-load 'js '(require 'js-mode-expansions))
+(eval-after-load 'js2-mode '(require 'js-mode-expansions))
+(eval-after-load 'js2-mode '(require 'js2-mode-expansions))
+(eval-after-load 'js3-mode '(require 'js-mode-expansions))
+(eval-after-load 'latex '(require 'latex-mode-expansions))
+(eval-after-load 'nxml-mode '(require 'nxml-mode-expansions))
+(eval-after-load 'octave-mod '(require 'octave-expansions))
+(eval-after-load 'octave '(require 'octave-expansions))
+(eval-after-load 'python '(progn
+ (when expand-region-guess-python-mode
+ (expand-region-guess-python-mode))
+ (if (eq 'python expand-region-preferred-python-mode)
+ (require 'python-el-expansions)
+ (require 'python-el-fgallina-expansions))))
+(eval-after-load 'python-mode '(require 'python-mode-expansions))
+(eval-after-load 'ruby-mode '(require 'ruby-mode-expansions))
+(eval-after-load 'org '(require 'the-org-mode-expansions))
+(eval-after-load 'cc-mode '(require 'cc-mode-expansions))
+(eval-after-load 'text-mode '(require 'text-mode-expansions))
+(eval-after-load 'cperl-mode '(require 'cperl-mode-expansions))
+(eval-after-load 'sml-mode '(require 'sml-mode-expansions))
+(eval-after-load 'enh-ruby-mode '(require 'enh-ruby-mode-expansions))
+(eval-after-load 'subword '(require 'subword-mode-expansions))
+(eval-after-load 'yaml-mode '(require 'yaml-mode-expansions))
+
+(provide 'expand-region)
+
+;;; expand-region.el ends here
--- /dev/null
+;;; feature-mode-expansions.el --- cucumber-specific expansions for expand-region
+
+;; Copyright (C) 2012 Raimon Grau
+
+;; Author: Raimon Grau
+;; Based on js-mode-expansions by: Raimon Grau <raimonsterNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+
+;; expanders to mark feature semantic objects like step or scenario
+;;
+;; Expansions:
+;;
+;;
+;; er/mark-feature-scenario
+;; er/mark-feature-step
+
+(require 'expand-region-core)
+
+(defun er--block-between-keywords (start-keywords-regexp &optional end-keywords-regexp)
+ (let* ((start-key-words (concat "^\\( \\)*" start-keywords-regexp))
+ (end-key-words (concat "^\\( \\)*" (or end-keywords-regexp start-keywords-regexp))))
+ (when (looking-at-p "[^\\s-]")
+ (skip-syntax-forward "w."))
+ (if (looking-at-p start-keywords-regexp)
+ (progn (beginning-of-line)
+ (exchange-point-and-mark))
+ (re-search-backward start-key-words)
+ (set-mark (point))
+ (re-search-forward start-key-words))
+ (unless (re-search-forward end-key-words (point-max) t)
+ (goto-char (point-max)))
+ (forward-line 0)
+ (exchange-point-and-mark)))
+
+(defun er/mark-feature-scenario ()
+ (interactive)
+ (er--block-between-keywords "\\(Background:\\|Scenario:\\|Feature:\\)"))
+
+(defun er/mark-feature-step ()
+ (interactive)
+ (er--block-between-keywords "\\(And\\|Given\\|When\\|Then\\)" "\\(And\\|Given\\|When\\|Then\\|Scenario:\\)"))
+
+(defun er/add-feature-mode-expansions ()
+ "Adds cucumber-specific expansions for buffers in feature-mode"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(er/mark-feature-scenario
+ er/mark-feature-step))))
+
+(er/enable-mode-expansions 'feature-mode 'er/add-feature-mode-expansions)
+
+(provide 'feature-mode-expansions)
--- /dev/null
+;;; html-mode-expansions.el --- HTML-specific expansions for expand-region
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Extra expansions for HTML that I've found useful so far:
+;;
+;; er/mark-html-attribute
+;; er/mark-inner-tag
+;; er/mark-outer-tag
+;;
+;; Feel free to contribute any other expansions for HTML at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(require 'sgml-mode)
+
+(defun er/mark-html-attribute ()
+ "Mark html-attribute presumes that point is at the assignment part of attr=\"value\".
+If point is inside the value-string, the quotes will be marked
+first anyway. Does not support html-attributes with spaces
+around the equal sign or unquotes attributes atm."
+ (interactive)
+ (when (or (looking-at "\\(\\s_\\|\\sw\\)*=")
+ (er/looking-back-exact "="))
+ (search-backward " ")
+ (forward-char 1)
+ (set-mark (point))
+ (search-forward "=")
+ (forward-sexp 1)
+ (exchange-point-and-mark)))
+
+(defun er--looking-at-marked-tag ()
+ "Is point looking at a tag that is entirely marked?"
+ (and (looking-at "<")
+ (>= (mark)
+ (save-excursion
+ (sgml-skip-tag-forward 1)
+ (point)))))
+
+(defun er--inside-tag-p ()
+ "Is point inside a tag?"
+ (save-excursion
+ (not (null (sgml-get-context)))))
+
+(defun er/mark-outer-tag ()
+ "Mark from opening to closing tag, including the tags."
+ (interactive)
+ (when (and (er--inside-tag-p)
+ (or (not (looking-at "<"))
+ (er--looking-at-marked-tag)))
+ (goto-char (aref (car (last (sgml-get-context))) 2)))
+ (when (looking-at "<")
+ (set-mark (point))
+ (sgml-skip-tag-forward 1)
+ (exchange-point-and-mark)))
+
+(defun er/mark-inner-tag ()
+ "Mark the contents of an open tag, not including the tags."
+ (interactive)
+ (goto-char (aref (car (last (sgml-get-context))) 3))
+ (set-mark (point))
+ (backward-char 1)
+ (sgml-skip-tag-forward 1)
+ (search-backward "</")
+ (exchange-point-and-mark))
+
+(defun er/add-html-mode-expansions ()
+ "Adds HTML-specific expansions for buffers in html-mode"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(er/mark-html-attribute
+ er/mark-inner-tag
+ er/mark-outer-tag))))
+
+(er/enable-mode-expansions 'html-mode 'er/add-html-mode-expansions)
+(er/enable-mode-expansions 'rhtml-mode 'er/add-html-mode-expansions)
+(er/enable-mode-expansions 'nxhtml-mode 'er/add-html-mode-expansions)
+(er/enable-mode-expansions 'web-mode 'er/add-html-mode-expansions)
+
+(provide 'html-mode-expansions)
+
+;; html-mode-expansions.el ends here
--- /dev/null
+;;; js-mode-expansions.el --- JS-specific expansions for expand-region
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Extra expansions for JavaScript that I've found useful so far:
+;;
+;; er/mark-js-function
+;; er/mark-js-object-property-value
+;; er/mark-js-object-property
+;; er/mark-js-if
+;; er/mark-js-inner-return
+;; er/mark-js-outer-return
+;;
+;; Feel free to contribute any other expansions for JavaScript at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/mark-js-function ()
+ "Mark the current JavaScript function."
+ (interactive)
+ (condition-case nil
+ (forward-char 8)
+ (error nil))
+ (word-search-backward "function")
+ (while (or (er--point-inside-string-p)
+ (er--point-is-in-comment-p))
+ (word-search-backward "function"))
+ (set-mark (point))
+ (while (not (looking-at "{"))
+ (forward-char))
+ (forward-list)
+ (exchange-point-and-mark))
+
+(defun er/mark-js-outer-return ()
+ "Mark the current return statement, including return and ending semi-colon"
+ (interactive)
+ (condition-case nil
+ (forward-char 6)
+ (error nil))
+ (word-search-backward "return")
+ (while (or (er--point-inside-string-p)
+ (er--point-is-in-comment-p))
+ (word-search-backward "return"))
+ (set-mark (point))
+ (while (not (looking-at ";"))
+ (if (looking-at "\\s(")
+ (forward-list)
+ (forward-char)))
+ (forward-char)
+ (exchange-point-and-mark))
+
+(defun er/mark-js-inner-return ()
+ "Mark contents of the current return statement, not including return or semi-colon"
+ (interactive)
+ (condition-case nil
+ (forward-char 6)
+ (error nil))
+ (word-search-backward "return")
+ (while (or (er--point-inside-string-p)
+ (er--point-is-in-comment-p))
+ (word-search-backward "return"))
+ (search-forward " ")
+ (set-mark (point))
+ (while (not (looking-at ";"))
+ (if (looking-at "\\s(")
+ (forward-list)
+ (forward-char)))
+ (exchange-point-and-mark))
+
+(defun er/mark-js-if ()
+ "Mark the current if-statement."
+ (interactive)
+ (condition-case nil
+ (forward-char 2)
+ (error nil))
+ (word-search-backward "if")
+ (while (or (er--point-inside-string-p)
+ (er--point-is-in-comment-p))
+ (word-search-backward "if"))
+ (set-mark (point))
+ (while (not (looking-at "("))
+ (forward-char))
+ (forward-list)
+ (while (not (looking-at "{"))
+ (forward-char))
+ (forward-list)
+ (exchange-point-and-mark))
+
+(defun er/mark-js-object-property-value ()
+ "Mark the current object property value, ie. from : to , or }"
+ (interactive)
+ (unless (er--point-inside-pairs-p)
+ (error "Point is not inside an object"))
+ (search-backward ":")
+ (forward-char)
+ (search-forward-regexp "[^\s]")
+ (backward-char)
+ (set-mark (point))
+ (while (not (looking-at "[},]"))
+ (if (looking-at "\\s(")
+ (forward-list)
+ (forward-char)))
+ (when (er/looking-back-max "[\s\n]" 400)
+ (search-backward-regexp "[^\s\n]")
+ (forward-char))
+ (exchange-point-and-mark))
+
+(defun er/mark-js-object-property ()
+ "Mark js-object-property presumes that point is at the assignment part of key: value.
+If point is inside the value, that will be marked first anyway."
+ (interactive)
+ (when (or (looking-at "\"?\\(\\s_\\|\\sw\\| \\)*\":")
+ (looking-at "\\(\\s_\\|\\sw\\)*:")
+ (er/looking-back-max ": ?" 2))
+ (search-backward-regexp "[{,]")
+ (forward-char)
+ (search-forward-regexp "[^\s\n]")
+ (backward-char)
+ (set-mark (point))
+ (search-forward ":")
+ (while (or (not (looking-at "[},]"))
+ (er--point-inside-string-p))
+ (if (looking-at "\\s(")
+ (forward-list)
+ (forward-char)))
+ (when (er/looking-back-max "[\s\n]" 400)
+ (search-backward-regexp "[^\s\n]")
+ (forward-char))
+ (exchange-point-and-mark)))
+
+(defun er/mark-js-call ()
+ "Mark the current symbol (including dots) and then parens or squares."
+ (interactive)
+ (let ((symbol-regexp "\\(\\s_\\|\\sw\\|\\.\\)+"))
+ (when (or (looking-at symbol-regexp)
+ (er/looking-back-on-line symbol-regexp))
+ (skip-syntax-backward "_w.")
+ (when (looking-at "!")
+ (forward-char 1))
+ (set-mark (point))
+ (when (looking-at symbol-regexp)
+ (goto-char (match-end 0)))
+ (if (looking-at "\\[\\|(")
+ (forward-list))
+ (exchange-point-and-mark))))
+
+(defun er/add-js-mode-expansions ()
+ "Adds JS-specific expansions for buffers in js-mode"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(er/mark-js-function
+ er/mark-js-object-property-value
+ er/mark-js-object-property
+ er/mark-js-if
+ er/mark-js-inner-return
+ er/mark-js-outer-return
+ er/mark-js-call))))
+
+(er/enable-mode-expansions 'js-mode 'er/add-js-mode-expansions)
+(er/enable-mode-expansions 'js2-mode 'er/add-js-mode-expansions)
+(er/enable-mode-expansions 'js3-mode 'er/add-js-mode-expansions)
+
+(provide 'js-mode-expansions)
+
+;; js-mode-expansions.el ends here
--- /dev/null
+;;; js2-mode-expansions.el --- Additional expansions for js2-mode
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Extra expansions specifically for js2-mode, since it has
+;; a semantic parser.
+;;
+;; Feel free to contribute any other expansions for JavaScript at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(declare-function js2-node-parent-stmt "js2-mode")
+(declare-function js2-node-at-point "js2-mode")
+(declare-function js2-node-abs-pos "js2-mode")
+(declare-function js2-node-len "js2-mode")
+
+(defun js2-mark-parent-statement ()
+ (interactive)
+ (let* ((parent-statement (if (not (er/looking-back-exact ";"))
+ (js2-node-parent-stmt (js2-node-at-point))
+ (forward-char -1)
+ (js2-node-at-point)))
+ (beg (js2-node-abs-pos parent-statement))
+ (end (+ beg (js2-node-len parent-statement))))
+ (goto-char beg)
+ (set-mark end)))
+
+(defun er/add-js2-mode-expansions ()
+ "Adds expansions for buffers in js2-mode"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(js2-mark-parent-statement))))
+
+(er/enable-mode-expansions 'js2-mode 'er/add-js2-mode-expansions)
+
+(provide 'js2-mode-expansions)
+
+;; js2-mode-expansions.el ends here
--- /dev/null
+;;; jsp-expansions.el --- JSP-specific expansions for expand-region
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Extra expansions for editing JSP files. To be used in conjunction
+;; with the html-mode expansions
+;;
+;; er/mark-jstl-escape
+;;
+;; These expansions aren't loaded by default, so you'll have to explicitly
+;; ask for them in your init file with:
+;;
+;; (eval-after-load 'sgml-mode '(require 'jsp-expansions))
+;;
+;; Feel free to contribute any other expansions for JSP at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/mark-jstl-escape ()
+ "Mark jstl-escape presumes that point is outside the brackets.
+If point is inside the brackets, they will be marked first anyway."
+ (interactive)
+ (when (or (looking-at "\\${")
+ (er/looking-back-exact "$"))
+ (forward-char 1)
+ (search-backward "\$")
+ (set-mark (point))
+ (forward-char 1)
+ (forward-list)
+ (exchange-point-and-mark)))
+
+(defun er/add-jsp-expansions ()
+ "Adds JSP-specific expansions to the buffer"
+ (set (make-local-variable 'er/try-expand-list) (append
+ er/try-expand-list
+ '(er/mark-jstl-escape))))
+
+(er/enable-mode-expansions 'html-mode 'er/add-jsp-expansions)
+
+(provide 'jsp-expansions)
+
+;; jsp-expansions.el ends here
--- /dev/null
+;;; latex-mode-expansions.el --- LaTeX-specific expansions for expand-region
+
+;; Copyright (C) 2012 Ivan Andrus
+
+;; Author: Ivan Andrus
+;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This is for AUCTeX, not the builtin latex-mode.
+
+;; Feel free to contribute any other expansions for LaTeX at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+;referenced free variables and functions defined in mode
+(defvar texmathp-why)
+(defvar texmathp-tex-commands1)
+(defvar texmathp-onoff-regexp)
+(defvar LaTeX-mode-hook)
+(declare-function LaTeX-mark-environment "latex")
+(declare-function texmathp "texmathp")
+
+(defun er/mark-LaTeX-inside-environment ()
+ "Like `LaTeX-mark-environment' but marks the inside of the environment.
+Skips past [] and {} arguments to the environment."
+ (interactive)
+ (LaTeX-mark-environment)
+ (when (looking-at "\\\\begin{")
+ (forward-sexp 2)
+ ;; Assume these are arguments
+ (while (looking-at "[ \t\n]*[{[]")
+ (forward-sexp 1))
+ ;; Go to next line if there is nothing interesting on this one
+ (skip-syntax-forward " ") ;; newlines are ">" i.e. end comment
+ (when (looking-at "%\\|$")
+ (forward-line))
+ ;; Clean up the end portion
+ (exchange-point-and-mark)
+ (backward-sexp 2)
+ (skip-syntax-backward " ")
+ (exchange-point-and-mark)))
+
+(defun er/mark-LaTeX-math ()
+ "Mark current math environment."
+ (interactive)
+ (when (texmathp)
+ (let* ((string (car texmathp-why))
+ (pos (cdr texmathp-why))
+ (reason (assoc string texmathp-tex-commands1))
+ (type (cadr reason)))
+ (cond
+ ((eq type 'env-on) ;; environments equation, align, etc.
+ (er/mark-LaTeX-inside-environment))
+ ((eq type 'arg-on) ;; \ensuremath etc.
+ (goto-char pos)
+ (set-mark (point))
+ (forward-sexp 2)
+ (exchange-point-and-mark))
+ ((eq type 'sw-toggle) ;; $ and $$
+ (goto-char pos)
+ (set-mark (point))
+ (forward-sexp 1)
+ (exchange-point-and-mark))
+ ((eq type 'sw-on) ;; \( and \[
+ (re-search-forward texmathp-onoff-regexp)
+ (set-mark pos)
+ (exchange-point-and-mark))
+ (t (error (format "Unknown reason to be in math mode: %s" type)))))))
+
+(defun er/add-latex-mode-expansions ()
+ "Adds expansions for buffers in latex-mode"
+ (set (make-local-variable 'er/try-expand-list)
+ (append
+ er/try-expand-list
+ '(LaTeX-mark-environment
+ LaTeX-mark-section
+ er/mark-LaTeX-inside-environment
+ er/mark-LaTeX-math))))
+
+(let ((latex-mode-hook LaTeX-mode-hook))
+ (er/enable-mode-expansions 'latex-mode 'er/add-latex-mode-expansions)
+ (setq LaTeX-mode-hook latex-mode-hook))
+
+(provide 'latex-mode-expansions)
+
+;; latex-mode-expansions.el ends here
--- /dev/null
+;;; nxml-mode-expansions.el --- Nxml-specific expansions for expand-region
+
+;; Copyright (C) 2012 Ivan Andrus
+
+;; Author: Ivan Andrus
+;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Feel free to contribute any other expansions for Nxml at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'expand-region-core)
+(require 'html-mode-expansions)
+(require 'nxml-mode)
+
+(defun er/mark-nxml-tag ()
+ "Marks one nxml element e.g. <p>"
+ (interactive)
+ (cond ((looking-at "<")
+ (nxml-mark-token-after))
+ ((er/looking-back-exact ">")
+ (backward-char 1)
+ (nxml-mark-token-after))
+ ((er/looking-back-max "<[^<>]*" 1000)
+ (nxml-mark-token-after))))
+
+(defun er/mark-nxml-element ()
+ "Marks one nxml element e.g. <p>...</p>"
+ (interactive)
+ (if (not (looking-at "<[^/]"))
+ (er/mark-nxml-containing-element)
+ (set-mark (point))
+ (nxml-forward-element)
+ (exchange-point-and-mark)))
+
+(defun er/mark-nxml-containing-element ()
+ "Marks one nxml element, but always e.g. <p>...</p>"
+ (interactive)
+ (nxml-up-element)
+ (set-mark (point))
+ (nxml-backward-element))
+
+(defun er/mark-nxml-inside-element ()
+ "Marks the inside Nxml statement, eg. <p>...</p>"
+ (interactive)
+ (let ((nxml-sexp-element-flag nil))
+ (nxml-up-element)
+ (nxml-forward-balanced-item -1)
+ (set-mark (point))
+ (nxml-backward-up-element)
+ (nxml-forward-balanced-item 1)))
+
+(defun er/inside-nxml-attribute-string? ()
+ "Returns the attribute from `xmltok-attributes' array that
+point is in, or otherwise nil"
+ (save-excursion
+ (forward-char 1)
+ (nxml-token-before))
+ (cl-find-if (lambda (att)
+ (and (<= (xmltok-attribute-value-start att) (point))
+ (>= (xmltok-attribute-value-end att) (point))))
+ xmltok-attributes))
+
+(defun er/mark-nxml-attribute-inner-string ()
+ "Marks an attribute string"
+ (interactive)
+ (let ((attr (er/inside-nxml-attribute-string?)))
+ (when attr
+ (set-mark (xmltok-attribute-value-start attr))
+ (goto-char (xmltok-attribute-value-end attr))
+ (exchange-point-and-mark))))
+
+(defun er/mark-nxml-attribute-string ()
+ "Marks an attribute string inside quotes."
+ (interactive)
+ (let ((attr (er/inside-nxml-attribute-string?)))
+ (when attr
+ (set-mark (1- (xmltok-attribute-value-start attr)))
+ (goto-char (1+ (xmltok-attribute-value-end attr)))
+ (exchange-point-and-mark))))
+
+(defun er/add-nxml-mode-expansions ()
+ "Adds Nxml-specific expansions for buffers in nxml-mode"
+ (interactive)
+ (set (make-local-variable 'er/try-expand-list)
+ (append
+ '(nxml-mark-paragraph
+ ;; nxml-mark-token-after ;; Marks the current tag, etc. It's a bit schizophrenic
+ er/mark-nxml-tag
+ er/mark-nxml-inside-element
+ er/mark-nxml-element
+ er/mark-nxml-containing-element
+ er/mark-nxml-attribute-string
+ er/mark-nxml-attribute-inner-string
+ ;; Steal from html-mode-expansions
+ er/mark-html-attribute)
+ ;; some normal marks are more hindrance than help:
+ (remove 'er/mark-method-call
+ (remove 'er/mark-symbol-with-prefix
+ (remove 'er/mark-symbol er/try-expand-list))))))
+
+(er/enable-mode-expansions 'nxml-mode 'er/add-nxml-mode-expansions)
+
+(provide 'nxml-mode-expansions)
+
+;; nxml-mode-expansions.el ends here
--- /dev/null
+;;; octave-expansions.el --- octave-mode expansions for expand-region
+
+;; Copyright (C) 2012 Mark Hepburn
+
+;; Author: Mark Hepburn
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Feel free to contribute any other expansions for Octave at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(declare-function octave-mark-block "octave-mod")
+
+;;; Octave-mod received a major rewrite between versions 23 and 24 of
+;;; Emacs, for example using the new smie package instead of
+;;; hand-coding a lot of motion commands. Unfortunately for our
+;;; purposes here, in the process the behaviour of `octave-mark-block'
+;;; changed slightly. So, in order to behave identically across both
+;;; versions we need to check which is which in a few places and
+;;; adjust accordingly:
+(defconst er/old-octave-mod-p (fboundp 'octave-up-block))
+
+(defalias 'er/up-block
+ (if er/old-octave-mod-p 'octave-up-block 'up-list))
+
+(defun er/octave-mark-up-block ()
+ "Mark the containing block, assuming the current block has
+already been marked."
+ (interactive)
+ (when (use-region-p)
+ (when (< (point) (mark))
+ (exchange-point-and-mark))
+ (er/up-block -1) ; -1 means backwards, ie to the front
+ (octave-mark-block)))
+
+(defun er/octave-mark-block ()
+ "Not for general use; this is a work-around for the different
+behaviour of `octave-mark-block' between emacs versions 23 and
+24."
+ (interactive)
+ (forward-word)
+ (octave-mark-block))
+
+(defun er/add-octave-expansions ()
+ "Adds octave/matlab-specific expansions for buffers in octave-mode"
+ (let ((try-expand-list-additions (if er/old-octave-mod-p
+ '(octave-mark-block
+ er/octave-mark-up-block
+ octave-mark-defun)
+ '(octave-mark-block
+ er/octave-mark-block
+ er/octave-mark-up-block
+ mark-defun))))
+ (set (make-local-variable 'er/try-expand-list)
+ (append er/try-expand-list try-expand-list-additions))))
+
+(er/enable-mode-expansions 'octave-mode 'er/add-octave-expansions)
+
+(provide 'octave-expansions)
+;;; octave-expansions.el ends here
--- /dev/null
+;;; python-el-expansions.el --- Python-specific expansions for expand-region
+
+;; Copyright (C) 2012 Ivan Andrus
+
+;; Authors: Ivan Andrus, Felix Geller, @edmccard
+;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region python
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; For python.el included with GNU Emacs
+;; - Mark functionality taken from python.el:
+;; - `python-mark-block'
+;; - Additions implemented here:
+;; - `er/mark-python-statement'
+;; - `er/mark-inside-python-string'
+;; - `er/mark-outside-python-string'
+;; - Supports multi-line strings
+
+;; There is no need for a er/mark-python-defun since
+;; er/mark-python-block will mark it
+
+;; Feel free to contribute any other expansions for Python at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(require 'python)
+
+(declare-function python-beginning-of-string "python-mode")
+
+(defvar er--python-string-delimiter "'\"")
+
+(defun er/mark-python-statement ()
+ "Marks one Python statement, eg. x = 3"
+ (interactive)
+ (python-nav-end-of-statement)
+ (set-mark (point))
+ (python-nav-beginning-of-statement))
+
+(defun er/mark-outside-python-string ()
+ "Marks region outside a (possibly multi-line) Python string"
+ (interactive)
+ (python-beginning-of-string)
+ (set-mark (point))
+ (forward-sexp)
+ (exchange-point-and-mark))
+
+(defun er/mark-inside-python-string ()
+ "Marks region inside a (possibly multi-line) Python string"
+ (interactive)
+ (when (eq 'string (syntax-ppss-context (syntax-ppss)))
+ (python-beginning-of-string)
+ (let ((string-beginning (point)))
+ (forward-sexp)
+ (skip-chars-backward er--python-string-delimiter)
+ (set-mark (point))
+ (goto-char string-beginning)
+ (skip-chars-forward er--python-string-delimiter))))
+
+(defun er/add-python-mode-expansions ()
+ "Adds Python-specific expansions for buffers in python-mode"
+ (let ((try-expand-list-additions '(er/mark-python-statement
+ er/mark-inside-python-string
+ er/mark-outside-python-string
+ python-mark-block)))
+ (set (make-local-variable 'expand-region-skip-whitespace) nil)
+ (set (make-local-variable 'er/try-expand-list)
+ (remove 'er/mark-inside-quotes
+ (remove 'er/mark-outside-quotes
+ (append er/try-expand-list try-expand-list-additions))))))
+
+(er/enable-mode-expansions 'python-mode 'er/add-python-mode-expansions)
+
+(provide 'python-el-expansions)
+
+;; python-el-expansions.el ends here
--- /dev/null
+;;; python-el-fgallina-expansions.el --- fgallina/python.el-specific expansions for expand-region
+
+;; Copyright (C) 2012 Felix Geller
+
+;; Author: Felix Geller
+;; Keywords: marking region python
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; - Additions implemented here:
+;; - `er/mark-inside-python-string'
+;; - `er/mark-outside-python-string'
+;; - `er/mark-python-statement'
+;; - `er/mark-python-block'
+;; - `er/mark-outer-python-block'
+;; - `er/mark-python-block-and-decorator'
+;; - Supports multi-line strings
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(if (not (fboundp 'python-syntax-context))
+ (defalias 'python-syntax-context 'python-info-ppss-context))
+(if (not (fboundp 'python-indent-offset))
+ (defalias 'python-indent-offset 'python-indent))
+
+(defvar er--python-string-delimiter
+ "'\""
+ "Characters that delimit a Python string.")
+
+;; copied from @fgallina's python.el as a quick fix. The variable
+;; `python-rx-constituents' is not bound when we use the python-rx
+;; macro from here, so we have to construct the regular expression
+;; manually.
+(defvar er--python-block-start-regex
+ (rx symbol-start
+ (or "def" "class" "if" "elif" "else" "try"
+ "except" "finally" "for" "while" "with")
+ symbol-end)
+ "Regular expression string to match the beginning of a Python block.")
+
+(defun er/mark-python-string (mark-inside)
+ "Mark the Python string that surrounds point.
+
+If the optional MARK-INSIDE is not nil, only mark the region
+between the string delimiters, otherwise the region includes the
+delimiters as well."
+ (let ((beginning-of-string (python-syntax-context 'string (syntax-ppss))))
+ (when beginning-of-string
+ (goto-char beginning-of-string)
+ ;; Move inside the string, so we can use ppss to find the end of
+ ;; the string.
+ (skip-chars-forward er--python-string-delimiter)
+ (while (python-syntax-context 'string (syntax-ppss))
+ (forward-char 1))
+ (when mark-inside (skip-chars-backward er--python-string-delimiter))
+ (set-mark (point))
+ (goto-char beginning-of-string)
+ (when mark-inside (skip-chars-forward er--python-string-delimiter)))))
+
+(defun er/mark-inside-python-string ()
+ "Mark the inside of the Python string that surrounds point.
+
+Command that wraps `er/mark-python-string'."
+ (interactive)
+ (er/mark-python-string t))
+
+(defun er/mark-outside-python-string ()
+ "Mark the outside of the Python string that surrounds point.
+
+Command that wraps `er/mark-python-string'."
+ (interactive)
+ (er/mark-python-string nil))
+
+(defun er/mark-python-statement ()
+ "Mark the Python statement that surrounds point."
+ (interactive)
+ (python-nav-end-of-statement)
+ (set-mark (point))
+ (python-nav-beginning-of-statement))
+
+(defun er/mark-python-block (&optional next-indent-level)
+ "Mark the Python block that surrounds point.
+
+If the optional NEXT-INDENT-LEVEL is given, select the
+surrounding block that is defined at an indentation that is less
+than NEXT-INDENT-LEVEL."
+ (interactive)
+ (back-to-indentation)
+ (let ((next-indent-level
+ (or
+ ;; Use the given level
+ next-indent-level
+ ;; Check whether point is at the start of a Python block.
+ (if (looking-at er--python-block-start-regex)
+ ;; Block start means that the next level is deeper.
+ (+ (current-indentation) python-indent-offset)
+ ;; Assuming we're inside the block that we want to mark
+ (current-indentation)))))
+ ;; Move point to next Python block start at the correct indent-level
+ (while (>= (current-indentation) next-indent-level)
+ (re-search-backward er--python-block-start-regex))
+ ;; Mark the beginning of the block
+ (set-mark (point))
+ ;; Save indentation and look for the end of this block
+ (let ((block-indentation (current-indentation)))
+ (forward-line 1)
+ (while (and
+ ;; No need to go beyond the end of the buffer. Can't use
+ ;; eobp as the loop places the point at the beginning of
+ ;; line, but eob might be at the end of the line.
+ (not (= (point-max) (point-at-eol)))
+ ;; Proceed if: indentation is too deep
+ (or (> (current-indentation) block-indentation)
+ ;; Looking at an empty line
+ (looking-at (rx line-start (* whitespace) line-end))
+ ;; We're not looking at the start of a Python block
+ ;; and the indent is deeper than the block's indent
+ (and (not (looking-at er--python-block-start-regex))
+ (> (current-indentation) block-indentation))))
+ (forward-line 1)
+ (back-to-indentation))
+ ;; Find the end of the block by skipping comments backwards
+ (python-util-forward-comment -1)
+ (exchange-point-and-mark))))
+
+(defun er/mark-outer-python-block ()
+ "Mark the Python block that surrounds the Python block around point.
+
+Command that wraps `er/mark-python-block'."
+ (interactive)
+ (er/mark-python-block (current-indentation)))
+
+(defun er/mark-python-block-and-decorator ()
+ (interactive)
+ (back-to-indentation)
+ (if (or (er--python-looking-at-decorator) (er--python-looking-at-decorator -1))
+ (progn
+ (while (er--python-looking-at-decorator -1)
+ (forward-line -1)
+ (back-to-indentation)
+ )
+ (set-mark (point))
+ (while (er--python-looking-at-decorator)
+ (forward-line)
+ )
+ (python-nav-end-of-block)
+ (exchange-point-and-mark))))
+
+(defun er--python-looking-at-decorator (&optional line-offset)
+ (save-excursion
+ (if line-offset
+ (forward-line line-offset)
+ )
+ (back-to-indentation)
+ (looking-at "@")
+ ))
+
+(defun er/add-python-mode-expansions ()
+ "Adds python-mode-specific expansions for buffers in python-mode"
+ (let ((try-expand-list-additions '(
+ er/mark-inside-python-string
+ er/mark-outside-python-string
+ er/mark-python-statement
+ er/mark-python-block
+ er/mark-python-block-and-decorator
+ er/mark-outer-python-block
+ )))
+ (set (make-local-variable 'expand-region-skip-whitespace) nil)
+ (set (make-local-variable 'er/try-expand-list)
+ (remove 'er/mark-inside-quotes
+ (remove 'er/mark-outside-quotes
+ (append er/try-expand-list try-expand-list-additions))))))
+
+(er/enable-mode-expansions 'python-mode 'er/add-python-mode-expansions)
+
+(provide 'python-el-fgallina-expansions)
+
+;; python-el-fgallina-expansions.el ends here
--- /dev/null
+;;; python-mode-expansions.el --- python-mode-specific expansions for expand-region
+
+;; Copyright (C) 2012 Felix Geller
+
+;; Author: Felix Geller
+;; Based on python-mode-expansions by: Ivan Andrus
+;; Keywords: marking region python
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Commentary:
+;; cf. https://github.com/magnars/expand-region.el/pull/18
+
+;; For python-mode: https://launchpad.net/python-mode
+;; - Mark functionality taken from python-mode:
+;; - `py-mark-expression'
+;; - `py-mark-statement'
+;; - `py-mark-block'
+;; - `py-mark-class'
+;; - Additions implemented here:
+;; - `er/mark-inside-python-string'
+;; - `er/mark-outside-python-string'
+;; - `er/mark-outer-python-block'
+;; - Supports multi-line strings
+;; - Supports incremental expansion of nested blocks
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defvar er--python-string-delimiter "'\"")
+
+(defalias 'py-goto-beyond-clause 'py-end-of-clause-bol)
+
+(declare-function py-in-string-p "python-mode")
+(declare-function py-beginning-of-block "python-mode")
+(declare-function py-end-of-block "python-mode")
+(declare-function py-mark-block-or-clause "python-mode")
+(declare-function py-end-of-clause-bol "python-mode")
+(defvar py-indent-offset)
+
+(defun er/mark-outside-python-string ()
+ "Marks region outside a (possibly multi-line) Python string"
+ (interactive)
+ (let ((string-beginning (py-in-string-p)))
+ (when string-beginning
+ (goto-char string-beginning)
+ (set-mark (point))
+ (forward-sexp)
+ (exchange-point-and-mark))))
+
+(defun er/mark-inside-python-string ()
+ "Marks region inside a (possibly multi-line) Python string"
+ (interactive)
+ (let ((string-beginning (py-in-string-p)))
+ (when string-beginning
+ (goto-char string-beginning)
+ (forward-sexp)
+ (skip-chars-backward er--python-string-delimiter)
+ (set-mark (point))
+ (goto-char string-beginning)
+ (skip-chars-forward er--python-string-delimiter))))
+
+(defun er--move-to-beginning-of-outer-python-block (start-column)
+ "Assumes that point is in a python block that is surrounded by
+another that is not the entire module. Uses `py-indent-offset' to
+find the beginning of the surrounding block because
+`py-beginning-of-block-position' just looks for the previous
+block-starting key word syntactically."
+ (while (> (current-column) (- start-column py-indent-offset))
+ (forward-line -1)
+ (py-beginning-of-block)))
+
+(defun er/mark-outer-python-block ()
+ "Attempts to mark a surrounding block by moving to the previous
+line and selecting the surrounding block."
+ (interactive)
+ (let ((start-column (current-column)))
+ (when (> start-column 0) ; outer block is the whole buffer
+ (er--move-to-beginning-of-outer-python-block start-column)
+ (let ((block-beginning (point)))
+ (py-end-of-block)
+ (set-mark (point))
+ (goto-char block-beginning)))))
+
+(defun er/mark-x-python-compound-statement ()
+ "Mark the current compound statement (if, while, for, try) and all clauses."
+ (interactive)
+ (let ((secondary-re
+ (save-excursion
+ (py-mark-block-or-clause)
+ (cond ((looking-at "if\\|for\\|while\\|else\\|elif") "else\\|elif")
+ ((looking-at "try\\|except\\|finally") "except\\|finally"))))
+ start-col)
+ (when secondary-re
+ (py-mark-block-or-clause)
+ (setq start-col (current-column))
+ (while (looking-at secondary-re)
+ (forward-line -1) (back-to-indentation)
+ (while (> (current-column) start-col)
+ (forward-line -1) (back-to-indentation)))
+ (set-mark (point))
+ (py-end-of-clause-bol) (forward-line) (back-to-indentation)
+ (while (and (looking-at secondary-re)
+ (>= (current-column) start-col))
+ (py-end-of-clause-bol) (forward-line) (back-to-indentation))
+ (forward-line -1) (end-of-line)
+ (exchange-point-and-mark))))
+
+(defun er/add-python-mode-expansions ()
+ "Adds python-mode-specific expansions for buffers in python-mode"
+ (let ((try-expand-list-additions '(
+ er/mark-inside-python-string
+ er/mark-outside-python-string
+ py-mark-expression
+ py-mark-statement
+ py-mark-block
+ py-mark-def
+ py-mark-clause
+ er/mark-x-python-compound-statement
+ er/mark-outer-python-block
+ py-mark-class
+ )))
+ (set (make-local-variable 'expand-region-skip-whitespace) nil)
+ (set (make-local-variable 'er/try-expand-list)
+ (remove 'er/mark-inside-quotes
+ (remove 'er/mark-outside-quotes
+ (append er/try-expand-list try-expand-list-additions))))))
+
+(er/enable-mode-expansions 'python-mode 'er/add-python-mode-expansions)
+
+(provide 'python-mode-expansions)
+
+;; python-mode-expansions.el ends here
--- /dev/null
+;;; ruby-mode-expansions.el --- ruby-specific expansions for expand-region
+
+;; Copyright (C) 2011 Magnar Sveen
+
+;; Author: Matt Briggs
+;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+
+;; LeWang:
+;;
+;; I think `er/ruby-backward-up' and `er/ruby-forward-up' are nifty
+;; functions in their own right.
+;;
+;; I would bind them to C-M-u and C-M-d respectively.
+
+;; Expansions:
+;;
+;;
+;; er/mark-ruby-block-up
+;;
+
+;;; Code:
+(require 'expand-region-core)
+(require 'ruby-mode)
+
+(defvar er/ruby-block-end-re
+ (concat ruby-block-end-re "\\|}")
+ "like ruby-mode's but also for '}'")
+
+(defun er/ruby-skip-past-block-end ()
+ "If line is blockend, move point to next line."
+ (when (looking-at er/ruby-block-end-re)
+ (forward-line 1)))
+
+(defun er/ruby-end-of-block (&optional arg)
+ "By default `ruby-end-of-block' goes to BOL of line containing end-re.
+
+This moves point to the next line to include the end of the block"
+ (interactive "p")
+ ;; Workaround for `ruby-end-of-block' in Emacs 23.
+ (when (re-search-forward (concat "\\<\\(" ruby-block-beg-re "\\)\\>")
+ (point-at-eol) t)
+ (goto-char (match-beginning 0)))
+ (ruby-end-of-block (or arg 1))
+ (er/ruby-skip-past-block-end))
+
+(defun er/point-at-indentation ()
+ "Return the point where current line's indentation ends."
+ (save-excursion
+ (back-to-indentation)
+ (point)))
+
+(defun er/ruby-backward-up ()
+ "a la `paredit-backward-up'"
+ (interactive)
+ ;; if our current line ends a block, we back a line, otherwise we
+ (when (save-excursion
+ (back-to-indentation)
+ (looking-at-p ruby-block-end-re))
+ (forward-line -1))
+ (let ((orig-point (point))
+ progress-beg
+ progress-end)
+
+ ;; cover the case when point is in the line of beginning of block
+ (unless (progn (ruby-end-of-block)
+ (ruby-beginning-of-block)
+ ;; "Block beginning" is often not at indentation in Emacs 24.
+ (< (er/point-at-indentation) orig-point))
+ (cl-loop
+ (ruby-beginning-of-block)
+ (setq progress-beg (point))
+ (when (= (point) (point-min))
+ (cl-return))
+ (ruby-end-of-block)
+ (setq progress-end (if (looking-at-p er/ruby-block-end-re)
+ (point-at-bol 0)
+ (point-at-bol 1)))
+ (goto-char progress-beg)
+ (when (> progress-end orig-point)
+ (cl-return))))))
+
+;;; This command isn't used here explicitly, but it's symmetrical with
+;;; `er/ruby-backward-up', and nifty for interactive use.
+(defun er/ruby-forward-up ()
+ "a la `paredit-forward-up'"
+ (interactive)
+ (er/ruby-backward-up)
+ (er/ruby-end-of-block))
+
+(defun er/get-ruby-block (&optional pos)
+ "return (beg . end) of current block"
+ (setq pos (or pos (point)))
+ (save-excursion
+ (goto-char pos)
+ (let (beg end)
+ (cons (progn
+ (er/ruby-backward-up)
+ (er/point-at-indentation))
+ (progn
+ (er/ruby-end-of-block)
+ (point))))))
+
+(defun er/mark-ruby-block-up-1 ()
+ (er/ruby-backward-up)
+ (set-mark (er/point-at-indentation))
+ (er/ruby-end-of-block)
+ (exchange-point-and-mark))
+
+(defun er/mark-ruby-block-up (&optional no-recurse)
+ "mark the next level up."
+ (interactive)
+ (if (use-region-p)
+ (let* ((orig-end (region-end))
+ (orig-beg (region-beginning))
+ (orig-len (- orig-end orig-beg))
+ (prev-block-point
+ (or (save-excursion
+ (goto-char orig-end)
+ (forward-line 0)
+ (back-to-indentation)
+ (cond ((looking-at-p er/ruby-block-end-re)
+ (point-at-bol 0))
+ ((re-search-forward
+ (concat "\\<\\(" ruby-block-beg-re "\\)\\>")
+ (point-at-eol)
+ t)
+ (point-at-bol 2))) )
+ (point)))
+ (prev-block-info (er/get-ruby-block prev-block-point))
+ (prev-block-beg (car prev-block-info))
+ (prev-block-end (cdr prev-block-info))
+ (prev-block-len (- prev-block-end prev-block-beg)))
+ (if (and (>= orig-beg prev-block-beg)
+ (<= orig-end prev-block-end)
+ (< orig-len prev-block-len))
+ ;; expand to previous block if it contains and grows current
+ ;; region
+ (progn
+ (deactivate-mark)
+ (goto-char prev-block-point)
+ (or no-recurse
+ (er/mark-ruby-block-up 'no-recurse)))
+ (er/mark-ruby-block-up-1)))
+ (er/mark-ruby-block-up-1)))
+
+(defun er/mark-ruby-instance-variable ()
+ "Marks instance variables in ruby.
+Assumes that point is at the @ - if it is inside the word, that will
+be marked first anyway."
+ (when (looking-at "@")
+ (forward-char 1))
+ (when (er/looking-back-exact "@")
+ (er/mark-symbol)
+ (forward-char -1)))
+
+(defun er/mark-ruby-heredoc ()
+ "Marks a heredoc, since `er/mark-inside-quotes' assumes single quote chars."
+ (let ((ppss (syntax-ppss)))
+ (when (elt ppss 3)
+ (let ((s-start (elt ppss 8)))
+ (goto-char s-start)
+ (when (save-excursion
+ (beginning-of-line)
+ (re-search-forward "<<\\(-?\\)['\"]?\\([a-zA-Z0-9_]+\\)" s-start nil))
+ (let ((allow-indent (string= "-" (match-string 1)))
+ (terminator (match-string 2))
+ (heredoc-start (save-excursion
+ (forward-line)
+ (point))))
+ (forward-sexp 1)
+ (forward-line -1)
+ (when (looking-at (concat "^" (if allow-indent "[ \t]*" "") terminator "$"))
+ (set-mark heredoc-start)
+ (exchange-point-and-mark))))))))
+
+(defun er/add-ruby-mode-expansions ()
+ "Adds Ruby-specific expansions for buffers in ruby-mode"
+ (set (make-local-variable 'er/try-expand-list)
+ (remove 'er/mark-defun
+ (append
+ (default-value 'er/try-expand-list)
+ '(er/mark-ruby-instance-variable
+ er/mark-ruby-block-up
+ er/mark-ruby-heredoc)))))
+
+(er/enable-mode-expansions 'ruby-mode 'er/add-ruby-mode-expansions)
+(provide 'ruby-mode-expansions)
--- /dev/null
+;;; sml-mode-expansions.el --- Expansions for expand-region to be used in sml-mode
+
+;; Copyright (C) 2012 Alexis Gallagher
+
+;; Author: Alexis Gallagher
+;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides extra expansions for sml-mode:
+;; - various expression (case, if, let)
+;; - fun bindings
+;;
+;; Tested with sml-mode version 6.3
+;;
+;; Feel free to contribute any other expansions for SML at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(declare-function sml-find-matching-starter "sml-mode")
+
+;; TODO: comma-delimited elements within a list,tuple,record
+;; TODO: match expression, patterns
+;; TODO: individual field, record type
+;; TODO: head-or-tail, then cons expression
+
+(defun er/sml-mark-keyword-prefixed-expression ()
+ "Mark the surrounding expression."
+ (interactive)
+ (progn
+ (sml-find-matching-starter '("case" "let" "if" "raise"))
+ (mark-sexp)))
+
+
+(defun er/add-sml-mode-expansions ()
+ "Adds expansions for buffers in `sml-mode'."
+ (set (make-local-variable 'er/try-expand-list)
+ (append er/try-expand-list
+ '(sml-mark-function
+ er/sml-mark-keyword-prefixed-expression
+ mark-sexp))))
+
+(er/enable-mode-expansions 'sml-mode 'er/add-sml-mode-expansions)
+
+(provide 'sml-mode-expansions)
+
+;; sml-mode-expansions.el ends here
--- /dev/null
+;;; subword-mode-expansions.el --- Expansions for subword-mode to be used for CamelCase
+
+;; Copyright (C) 2014 Lefteris Karapetsas
+
+;; Author: Lefteris Karapetsas
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides extra expansions for subword mode so that when
+;; subword-mode is non-nil different words can be selected in CamelCase.
+;; Feel free to contribute any other expansions:
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(require 'subword)
+
+(defun er/mark-subword ()
+ "Mark a subword, a part of a CamelCase identifier."
+ (interactive)
+ (when (and subword-mode
+ expand-region-subword-enabled)
+ (subword-right 1)
+ (set-mark (point))
+ (subword-left 1)))
+
+(defun er/add-subword-mode-expansions ()
+ "Add expansions for buffers in `subword-mode'."
+ (set (make-local-variable 'er/try-expand-list)
+ (append er/try-expand-list
+ '(er/mark-subword))))
+
+(er/enable-minor-mode-expansions 'subword-mode 'er/add-subword-mode-expansions)
+
+(provide 'subword-mode-expansions)
+;;; subword-mode-expansions.el ends here
--- /dev/null
+;;; text-mode-expansions.el --- Expansions for expand-region to be used in text
+
+;; Copyright (C) 2012 Ivan Andrus
+
+;; Author: Ivan Andrus
+;; Based on js-mode-expansions by: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Feel free to contribute any other expansions for normal text at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/mark-text-sentence ()
+ "Marks one sentence."
+ (interactive)
+ ;; The obvious
+ ;; (backward-sentence 1) (mark-end-of-sentence 1)
+ ;; doesn't work here because it's repeated and the selection keeps
+ ;; growing by sentences, which isn't what's wanted.
+ (forward-sentence 1)
+ (set-mark (point))
+ (backward-sentence 1))
+
+(defun er/mark-text-paragraph ()
+ "Marks one paragraph."
+ (interactive)
+ (mark-paragraph)
+ (skip-chars-forward er--space-str))
+
+(defun er/add-text-mode-expansions ()
+ "Adds expansions for buffers in `text-mode' except for `html-mode'.
+Unfortunately `html-mode' inherits from `text-mode' and
+text-mode-expansions don't work well in `html-mode'."
+ (unless (member major-mode expand-region-exclude-text-mode-expansions)
+ (set (make-local-variable 'er/try-expand-list)
+ (append
+ er/try-expand-list
+ '(er/mark-text-sentence
+ er/mark-text-paragraph
+ mark-page)))))
+
+(er/enable-mode-expansions 'text-mode 'er/add-text-mode-expansions)
+
+(provide 'text-mode-expansions)
+
+;; text-mode-expansions.el ends here
--- /dev/null
+;;; the-org-mode-expansions.el --- Expansions for expand-region to be used in org-mode
+
+;; Copyright (C) 2012 Magnar Sveen
+
+;; Author: Magnar Sveen
+;; Based on text-mode-expansions by: Ivan Andrus
+;; Keywords: marking region
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The file needs to be weirdly name (prefixed with the-) to avoid
+;; conflict with org-reload, which bases its functionality on the names
+;; of files, for some reason.
+;;
+;; Feel free to contribute any other expansions for org-mode at
+;;
+;; https://github.com/magnars/expand-region.el
+
+;;; Code:
+
+(require 'expand-region-core)
+(require 'org-macs)
+(require 'org-element)
+
+(declare-function org-up-element "org")
+(declare-function org-mark-subtree "org")
+
+(defun er/mark-org-element ()
+ (interactive)
+ (let* ((el (org-element-at-point))
+ (begin (plist-get (cadr el) :begin))
+ (end (plist-get (cadr el) :end)))
+ (goto-char begin)
+ (set-mark (point))
+ (goto-char end)
+ (exchange-point-and-mark)))
+
+(defun er/mark-org-element-parent ()
+ (interactive)
+ (let* ((el (plist-get (cadr (org-element-at-point)) :parent))
+ (begin (plist-get (cadr el) :begin))
+ (end (plist-get (cadr el) :end)))
+ (when (and begin end)
+ (goto-char begin)
+ (set-mark (point))
+ (goto-char end)
+ (exchange-point-and-mark))))
+
+(defun er/mark-sentence ()
+ "Marks one sentence."
+ (interactive)
+ (forward-char 1)
+ (backward-sentence 1)
+ (set-mark (point))
+ (forward-sentence 1)
+ (exchange-point-and-mark))
+
+(defun er/mark-paragraph ()
+ "Marks one paragraph."
+ (interactive)
+ (mark-paragraph)
+ (exchange-point-and-mark)
+ (skip-chars-backward er--space-str)
+ (exchange-point-and-mark)
+ (skip-chars-forward er--space-str))
+
+(defun er/mark-org-code-block ()
+ "Marks an org-code-block."
+ (interactive)
+ (let ((case-fold-search t)
+ (re "#\\+begin_\\(\\sw+\\)"))
+ (unless (looking-at re)
+ (search-backward-regexp re))
+ (set-mark (point))
+ (search-forward (concat "#+end_" (match-string 1)))
+ (exchange-point-and-mark)))
+
+(defun er/mark-org-parent ()
+ "Marks a heading 1 level up from current subheading"
+ (interactive)
+ (org-up-element)
+ (org-mark-subtree))
+
+(defun er/save-org-mode-excursion (action)
+ "Save outline visibility while expanding in org-mode"
+ (org-save-outline-visibility t
+ (funcall action)))
+
+(defun er/add-org-mode-expansions ()
+ "Adds org-specific expansions for buffers in org-mode"
+ (set (make-local-variable 'er/try-expand-list)
+ (append
+ (remove #'er/mark-defun er/try-expand-list)
+ '(org-mark-subtree
+ er/mark-org-element
+ er/mark-org-element-parent
+ er/mark-org-code-block
+ er/mark-sentence
+ er/mark-org-parent
+ er/mark-paragraph)))
+ (set (make-local-variable 'er/save-mode-excursion)
+ #'er/save-org-mode-excursion))
+
+(er/enable-mode-expansions 'org-mode 'er/add-org-mode-expansions)
+
+(provide 'the-org-mode-expansions)
--- /dev/null
+;;; web-mode-expansions.el --- Thin layer for adapting fxbois's web-mode-mark-and-expand function
+;;; to expand-region
+
+;; Copyright (C) 2012 Rotem Yaari
+
+;; Authors: Rotem Yaari
+;; Based on, and makes use of web-mode.el by fxbois
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defun er/add-web-mode-expansions ()
+ (set (make-local-variable 'er/try-expand-list)
+ (cons 'web-mode-mark-and-expand er/try-expand-list)))
+
+(er/enable-mode-expansions 'web-mode 'er/add-web-mode-expansions)
+
+(provide 'web-mode-expansions)
--- /dev/null
+;;; yaml-mode-expansions.el --- expansions for yaml mode
+
+;; Copyright (C) 2021 Aaron Gonzales
+
+;; Author: Aaron Gonzales
+;; Keywords: marking region yaml YAML expand
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; - Additions implemented here:
+;; - er/mark-yaml-key-value
+;; - er/mark-yaml-list-item
+;; - er/mark-yaml-block
+;; - er/mark-yaml-outer-block
+;; - er/mark-yaml-inner-block
+
+
+;;; Code:
+
+(require 'expand-region-core)
+
+(defconst yaml-indent 2)
+
+(unless (fboundp 'yaml-indent-offset)
+ (defalias 'yaml-indent-offset 'yaml-indent))
+
+(defvar er--yaml-key-value-regex
+ (rx (one-or-more
+ (any "0-9A-Za-z"))
+ ":"
+ (zero-or-more " ")
+ (one-or-more
+ (any "0-9A-Za-z" " '_-"))))
+
+(defvar er--yaml-list-item-regex
+ (rx (seq "- "
+ (one-or-more
+ (any "0-9A-Za-z" "\"':=_-")))))
+
+(defvar er--yaml-block-regex
+ (rx (seq (zero-or-more
+ (any " -"))
+ (one-or-more
+ (any "0-9A-Za-z" " '_-"))
+ ":\n")))
+
+(defun er--get-regex-indentation-level (regex)
+ "Return the indentation level of the code with respect to the REGEX passed."
+ (when (looking-at regex)
+ ;; Block start means that the next level is deeper.
+ (+ (current-indentation) yaml-indent-offset)
+ ;; Assuming we're inside the block that we want to mark
+ (current-indentation)))
+
+(defun er/mark-yaml-line-base (regex)
+ "Mark line of yaml file based on simple REGEX."
+ (back-to-indentation)
+ (when (looking-at regex)
+ (set-mark (line-end-position))))
+
+(defun er/mark-yaml-block-static-base (regex)
+ "Mark yaml block based on REGEX passed. NEXT-INDENT-LEVEL can be used to search outer blocks when necessary."
+ ;; go bac to indentation so always can get regexp
+ (back-to-indentation)
+ ;; make sure the cursor is set inside the block
+ ;; mark point at this higher code block
+ (set-mark (point))
+ ;; save level of this blocks indentation
+ (let ((block-indentation (current-indentation)))
+ (forward-line 1)
+ (while (and
+ ;; No need to go beyond the end of the buffer. Can't use
+ ;; eobp as the loop places the point at the beginning of
+ ;; line, but eob might be at the end of the line.
+ (not (= (point-max) (point-at-eol)))
+ ;; Proceed if: indentation is too deep
+ (or (> (current-indentation) block-indentation)
+ ;; Looking at an empty line
+ (looking-at (rx line-start (* whitespace) line-end))
+ ;; We're not looking at the start of a YAML block
+ ;; and the indent is deeper than the block's indent
+ (and (not (looking-at regex))
+ (> (current-indentation) block-indentation))))
+ (forward-line 1)
+ (back-to-indentation))
+ ;; Find the end of the block by skipping comments backwards
+ (python-util-forward-comment -1)
+ (exchange-point-and-mark))
+ (back-to-indentation))
+
+(defun er/mark-yaml-block-base (regex &optional next-indent-level)
+ "Mark yaml block based on REGEX passed. NEXT-INDENT-LEVEL can be used to search outer blocks when necessary."
+ ;; go bac to indentation so always can get regexp
+ (back-to-indentation)
+ ;; make sure the cursor is set inside the block
+ (let ((next-indent-level
+ (or
+ ;; Use the given level
+ next-indent-level
+ ;; used to mark current block
+ (er--get-regex-indentation-level regex))))
+ ;; if true then at start of block and wanna mark itself
+ ;; else were are inside the block already and will mark it)))
+ ;; move up the code unti a parent code block is reached
+ (while (and (>= (current-indentation) next-indent-level)
+ (not (eq (current-indentation) 0)))
+ (re-search-backward regex (point-min) t)
+ (back-to-indentation))
+ ;; mark point at this higher code block
+ (set-mark (point))
+ ;; save level of this blocks indentation
+ (let ((block-indentation (current-indentation)))
+ (forward-line 1)
+ (while (and
+ ;; No need to go beyond the end of the buffer. Can't use
+ ;; eobp as the loop places the point at the beginning of
+ ;; line, but eob might be at the end of the line.
+ (not (= (point-max) (point-at-eol)))
+ ;; Proceed if: indentation is too deep
+ (or (> (current-indentation) block-indentation)
+ ;; Looking at an empty line
+ (looking-at (rx line-start (* whitespace) line-end))
+ ;; We're not looking at the start of a YAML block
+ ;; and the indent is deeper than the block's indent
+ (and (not (looking-at regex))
+ (> (current-indentation) block-indentation))))
+ (forward-line 1)
+ (back-to-indentation))
+ ;; Find the end of the block by skipping comments backwards
+ (python-util-forward-comment -1)
+ (exchange-point-and-mark)))
+ (back-to-indentation))
+
+(defun er/mark-yaml-key-value ()
+ "Mark a yaml key-value pair."
+ (interactive)
+ (er/mark-yaml-line-base er--yaml-key-value-regex))
+
+(defun er/mark-yaml-list-item ()
+ "Mark a yaml list item."
+ (interactive)
+ (er/mark-yaml-line-base er--yaml-list-item-regex))
+
+(defun er/mark-yaml-inner-block ()
+ "Mark the yaml contents of the block at point. Command that wraps `er/mark-yaml-block-base'."
+ (interactive)
+ (er/mark-yaml-block-base er--yaml-block-regex (current-indentation))
+ (forward-line)
+ (back-to-indentation))
+
+(defun er/mark-yaml-block ()
+ "Mark the yaml block that point is currently at the top of. Command that wraps `er/mark-yaml-block-base'."
+ (interactive)
+ (er/mark-yaml-block-static-base er--yaml-block-regex))
+
+(defun er/mark-yaml-outer-block ()
+ "Mark the outer yaml block that surrounds the block around point. Command that wraps `er/mark-yaml-block-base'."
+ (interactive)
+ (er/mark-yaml-block-base er--yaml-block-regex (current-indentation)))
+
+(defun er/add-yaml-mode-expansions ()
+ "Add yaml-mode-specific expansions for buffers in yaml-mode."
+ (let ((try-expand-list-additions '(er/mark-symbol
+ er/mark-outside-quotes
+ er/mark-yaml-list-item
+ er/mark-yaml-key-value
+ er/mark-yaml-block
+ er/mark-yaml-outer-block
+ er/mark-yaml-inner-block)))
+ (set (make-local-variable 'expand-region-skip-whitespace) nil)
+ (set (make-local-variable 'er/try-expand-list) try-expand-list-additions)))
+
+(er/enable-mode-expansions 'yaml-mode 'er/add-yaml-mode-expansions)
+
+(provide 'yaml-mode-expansions)
+
+;;; yaml-mode-expansions.el ends here