summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoritai33 <itai3397@gmail.com>2020-05-24 15:28:09 +0300
committerGitHub <noreply@github.com>2020-05-24 09:28:09 -0300
commit4d6cc94df074b2e1a2806c23f01513ed29b6e243 (patch)
tree8d4967fa90166e3b5dcd49e9ee5ae5d699e97dd1
parent9b0b17f06cef9bac81ee4800d121265e54718a17 (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.el26
-rw-r--r--readme.org39
-rw-r--r--test/evil-surround-test.el67
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)
diff --git a/readme.org b/readme.org
index ea2cafb..349a8de 100644
--- a/readme.org
+++ b/readme.org
@@ -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")