diff options
| author | itai33 <itai3397@gmail.com> | 2020-05-24 15:28:09 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-24 09:28:09 -0300 |
| commit | 4d6cc94df074b2e1a2806c23f01513ed29b6e243 (patch) | |
| tree | 8d4967fa90166e3b5dcd49e9ee5ae5d699e97dd1 | |
| parent | 9b0b17f06cef9bac81ee4800d121265e54718a17 (diff) | |
Add surround text objects from local keymap (#165)
* add local keymap support
* add tests for local keymap
* document local keymap support in readme
| -rw-r--r-- | evil-surround.el | 26 | ||||
| -rw-r--r-- | readme.org | 39 | ||||
| -rw-r--r-- | test/evil-surround-test.el | 67 |
3 files changed, 123 insertions, 9 deletions
diff --git a/evil-surround.el b/evil-surround.el index 018a5b6..bd80d30 100644 --- a/evil-surround.el +++ b/evil-surround.el @@ -1,13 +1,13 @@ ;;; evil-surround.el --- emulate surround.vim from Vim ;; Copyright (C) 2010 - 2017 Tim Harper -;; Copyright (C) 2018 - 2019 The evil-surround.el Contributors +;; Copyright (C) 2018 - 2020 The evil-surround.el Contributors ;; Licensed under the same terms as Emacs (GPLv3) ;; ;; Author: Tim Harper <timcharper at gmail dot com> -;; Vegard Øye <vegard_oye at hotmail dot com> +;; Vegard Øye <vegard_oye at hotmail dot com> ;; Current Maintainer: ninrod (github.com/ninrod) ;; Created: July 23 2011 ;; Version: 1.0.3 @@ -180,11 +180,22 @@ This is a cons cell (LEFT . RIGHT), both strings." (t (cons (format "%c" char) (format "%c" char)))))) +(defvar-local evil-surround-local-outer-text-object-map-list nil + "Buffer-local list of outer text object keymaps that are added to + evil-surround") + +(defvar-local evil-surround-local-inner-text-object-map-list nil + "Buffer-local list of inner text object keymaps that are added to + evil-surround") + (defun evil-surround-outer-overlay (char) "Return outer overlay for the delimited range represented by CHAR. This overlay includes the delimiters. See also `evil-surround-inner-overlay'." - (let ((outer (lookup-key evil-outer-text-objects-map (string char)))) + (let ((outer (lookup-key + (make-composed-keymap + evil-surround-local-outer-text-object-map-list + evil-outer-text-objects-map) (string char)))) (when (functionp outer) (setq outer (funcall outer)) (when (evil-range-p outer) @@ -209,7 +220,10 @@ See also `evil-surround-inner-overlay'." "Return inner overlay for the delimited range represented by CHAR. This overlay excludes the delimiters. See also `evil-surround-outer-overlay'." - (let ((inner (lookup-key evil-inner-text-objects-map (string char)))) + (let ((inner (lookup-key + (make-composed-keymap + evil-surround-local-inner-text-object-map-list + evil-inner-text-objects-map) (string char)))) (when (functionp inner) (setq inner (funcall inner)) (when (evil-range-p inner) @@ -279,8 +293,8 @@ overlays OUTER and INNER, which are passed to `evil-surround-delete'." (defun evil-surround-interactive-setup () (setq evil-inhibit-operator t) - (list (assoc-default evil-this-operator - evil-surround-operator-alist))) + (list (assoc-default evil-this-operator + evil-surround-operator-alist))) (defun evil-surround-setup-surround-line-operators () (define-key evil-operator-shortcut-map "s" 'evil-surround-line) @@ -95,7 +95,7 @@ or to add a pair that surrounds with two ` if you enter ~: (push '(?~ . ("``" . "``")) evil-surround-pairs-alist)) #+END_SRC ** Add new surround pairs through creation of evil objects - - You can create new evil objects that will be respected by evil-surround. Just use the following code: +You can create new evil objects that will be respected by evil-surround. Just use the following code: #+BEGIN_SRC emacs-lisp ;; this macro was copied from here: https://stackoverflow.com/a/22418983/4921402 (defmacro define-and-bind-quoted-text-object (name key start-regex end-regex) @@ -111,9 +111,44 @@ or to add a pair that surrounds with two ` if you enter ~: (define-and-bind-quoted-text-object "pipe" "|" "|" "|") (define-and-bind-quoted-text-object "slash" "/" "/" "/") - (define-and-bind-quoted-text-object "dollar" "*" "*" "*") + (define-and-bind-quoted-text-object "asterisk" "*" "*" "*") (define-and-bind-quoted-text-object "dollar" "$" "\\$" "\\$") ;; sometimes your have to escape the regex #+END_SRC +** Add surround pairs for buffer-local text objects +Buffer-local text objects are useful for mode specific text objects that you +don't want polluting the global keymap. To make these objects work with +=evil-surround=, the do the following (for example to bind pipes to =Q=): + + +#+BEGIN_SRC emacs-lisp + (defvar evil-some-local-inner-keymap (make-sparse-keymap) + "Inner text object test keymap") + (defvar evil-some-local-outer-keymap (make-sparse-keymap) + "Outer text object keymap") + (define-key evil-some-local-inner-keymap "Q" #'evil-inner-pipe) + (define-key evil-some-local-outer-keymap "Q" #'evil-a-pipe) + (define-key evil-visual-state-local-map "iQ" #'evil-inner-pipe) + (define-key evil-operator-state-local-map "iQ" #'evil-inner-pipe) + (define-key evil-visual-state-local-map "aQ" #'evil-a-pipe) + (define-key evil-operator-state-local-map "aQ" #'evil-a-pipe) + (setq evil-surround-local-inner-text-object-map-list (list evil-some-local-inner-keymap)) + (setq evil-surround-local-outer-text-object-map-list (list evil-some-local-outer-keymap)) + (setq-local evil-surround-pairs-alist (append '((?Q "|" . "|")) evil-surround-pairs-alist)) +#+END_SRC + +note that the binding to =evil-some-local-(inner|outer)-keymap= is purely for organizational perpouses, you can skip that step and do: + + +#+BEGIN_SRC emacs-lisp + (define-key evil-visual-state-local-map "iQ" #'evil-inner-pipe) + (define-key evil-operator-state-local-map "iQ" #'evil-inner-pipe) + (define-key evil-visual-state-local-map "aQ" #'evil-a-pipe) + (define-key evil-operator-state-local-map "aQ" #'evil-a-pipe) + (setq evil-surround-local-inner-text-object-map-list (list (lookup-key evil-operator-state-local-map "i"))) + (setq evil-surround-local-outer-text-object-map-list (list (lookup-key evil-operator-state-local-map "a"))) + (setq-local evil-surround-pairs-alist (append '((?Q "|" . "|")) evil-surround-pairs-alist)) +#+END_SRC + ** Add new supported operators You can add support for new operators by adding them to =evil-surround-operator-alist=. diff --git a/test/evil-surround-test.el b/test/evil-surround-test.el index 2f40d4a..73d4b69 100644 --- a/test/evil-surround-test.el +++ b/test/evil-surround-test.el @@ -252,7 +252,72 @@ (test-widened-buffer "[w]ord" ("ysiwb") - "[(]word)"))) + "[(]word)" + )) + (ert-info ("create buffer local text object and surround binding") + (evil-test-buffer + "QQw[o]rdQQ soup" + (turn-on-evil-surround-mode) + (evil-define-text-object evil-surround-test-inner-QQ (count &optional beg end type) + "Test text object" + :extend-selection nil + (evil-select-paren "QQ" "QQ" + beg end type count nil)) + (evil-define-text-object evil-surround-test-a-QQ (count &optional beg end type) + :extend-selection nil + (evil-select-paren "QQ" "QQ" + beg end type count t)) + (evil-define-text-object evil-surround-test-inner-NN (count &optional beg end type) + "Test text object" + :extend-selection nil + (evil-select-paren "NN" "NN" + beg end type count nil)) + (evil-define-text-object evil-surround-test-a-NN (count &optional beg end type) + :extend-selection nil + (evil-select-paren "NN" "NN" + beg end type count t)) + + (defvar evil-surround-test-inner-text-objects-map (make-sparse-keymap) + "Inner text object test keymap") + (defvar evil-surround-test-outer-text-objects-map (make-sparse-keymap) + "Outer text object keymap") + (define-key evil-surround-test-inner-text-objects-map "Q" #'evil-surround-test-inner-QQ) + (define-key evil-surround-test-outer-text-objects-map "Q" #'evil-surround-test-a-QQ) + (define-key evil-visual-state-local-map "iQ" #'evil-surround-test-inner-QQ) + (define-key evil-operator-state-local-map "iQ" #'evil-surround-test-inner-QQ) + (define-key evil-visual-state-local-map "aQ" #'evil-surround-test-a-QQ) + (define-key evil-operator-state-local-map "aQ" #'evil-surround-test-a-QQ) + (define-key evil-visual-state-local-map "iN" #'evil-surround-test-inner-NN) + (define-key evil-operator-state-local-map "iN" #'evil-surround-test-inner-NN) + (define-key evil-visual-state-local-map "aN" #'evil-surround-test-a-NN) + (define-key evil-operator-state-local-map "aN" #'evil-surround-test-a-NN) + (setq evil-surround-local-inner-text-object-map-list (list evil-surround-test-inner-text-objects-map )) + (setq evil-surround-local-outer-text-object-map-list (list evil-surround-test-outer-text-objects-map )) + (setq evil-surround-local-inner-text-object-map-list (list (lookup-key evil-operator-state-local-map "i"))) + (setq evil-surround-local-outer-text-object-map-list (list (lookup-key evil-operator-state-local-map "a"))) + (setq-local evil-surround-pairs-alist (append '((?Q "QQ" . "QQ") (?N "NN" . "NN")) evil-surround-pairs-alist)) + ("dsQ") + "word soup" + ("cswQ") + "QQwordQQ soup" + ("daQ") + " soup" + ("ysawQ") + "QQ soupQQ" + ("csQb") + "( soup)" + ("csbN") + "NN soupNN" + )) + (ert-info ("check that the previous binding was in fact local") + (evil-test-buffer + "QQw[o]rdQQ soup" + (turn-on-evil-surround-mode) + ("dsQ") + "QQwordQQ soup" + ("cswQ") + "QQQwordQQQ soup"))) + (ert-deftest evil-surround-tag-from-macro () (ert-info ("tag surround in macro") |
