Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/emacs-evil/evil-surround
you will be surrounded (surround.vim for evil, the extensible vi layer)
https://github.com/emacs-evil/evil-surround
Last synced: about 1 month ago
JSON representation
you will be surrounded (surround.vim for evil, the extensible vi layer)
- Host: GitHub
- URL: https://github.com/emacs-evil/evil-surround
- Owner: emacs-evil
- License: other
- Created: 2011-08-12T21:15:10.000Z (over 13 years ago)
- Default Branch: master
- Last Pushed: 2024-03-25T08:52:23.000Z (9 months ago)
- Last Synced: 2024-03-26T10:05:34.761Z (9 months ago)
- Language: Emacs Lisp
- Homepage:
- Size: 160 KB
- Stars: 611
- Watchers: 19
- Forks: 59
- Open Issues: 10
-
Metadata Files:
- Readme: readme.org
- License: license.md
Awesome Lists containing this project
README
[[https://user-images.githubusercontent.com/8352747/33807810-91656488-ddc3-11e7-8029-985f28471a47.png][https://user-images.githubusercontent.com/8352747/33807810-91656488-ddc3-11e7-8029-985f28471a47.png]]
[[https://travis-ci.org/emacs-evil/evil-surround.svg?branch=master][https://travis-ci.org/emacs-evil/evil-surround.svg?branch=master]]
[[https://melpa.org/#/evil-surround][https://melpa.org/packages/evil-surround-badge.svg]]
[[https://stable.melpa.org/#/evil-surround][file:https://stable.melpa.org/packages/evil-surround-badge.svg]]
[[https://www.gnu.org/licenses/gpl-3.0.en.html][https://img.shields.io/badge/license-GPLv3-blue.svg]]This package emulates [[https://github.com/tpope/vim-surround][surround.vim]] by [[https://github.com/tpope][Tim Pope]]. The functionality is wrapped into a minor mode.
This package uses [[https://github.com/emacs-evil/evil][Evil]] as its vi layer.
* Installation
To enable it through [[https://github.com/jwiegley/use-package][use-package]], add the following lines to =~/.emacs= or =~/.emacs.d/init.el=:
#+BEGIN_SRC emacs-lisp
(use-package evil-surround
:ensure t
:config
(global-evil-surround-mode 1))
#+END_SRCAlternatively, you can add the =evil-surround.el= file to your load-path and add =(require 'evil-surround)= to your init file.
Also, instead of enabling it globally, you can also enable =surround-mode= for a given major mode by adding =turn-on-surround-mode= to the mode hook.
* Usage
** Add surroundingYou can surround in visual-state with =S= or =gS=.
Or in normal-state with =ys= or =yS=.** Change surrounding
You can change a surrounding with =cs=.
** Delete surrounding
You can delete a surrounding with =ds=.
** Add new surround pairs
A surround pair is this (trigger char with textual left and right
strings):#+BEGIN_SRC emacs-lisp
(?> . ("<" . ">"))
#+END_SRCor this (trigger char and calling a function):
#+BEGIN_SRC emacs-lisp
(?< . surround-read-tag)
#+END_SRCYou can add new by adding them to =evil-surround-pairs-alist=.
For more information do: =C-h v evil-surround-pairs-alist=.=evil-surround-pairs-alist= is a buffer local variable, which means that
you can have different surround pairs in different modes. By default =<=
is used to insert a tag, in C++ this may not be useful - but inserting
angle brackets is, so you can add this:#+BEGIN_SRC emacs-lisp
(add-hook 'c++-mode-hook (lambda ()
(push '(?< . ("< " . " >")) evil-surround-pairs-alist)))
#+END_SRCDon't worry about having two entries for =<= surround will take the
first.Or in Emacs Lisp modes using ` to enter ` ' is quite useful, but not
adding a pair of ` (the default behavior if no entry in
=evil-surround-pairs-alist= is present), so you can do this:#+BEGIN_SRC emacs-lisp
(add-hook 'emacs-lisp-mode-hook (lambda ()
(push '(?` . ("`" . "'")) evil-surround-pairs-alist)))
#+END_SRCwithout affecting your Markdown surround pairs, where the default is useful.
To change the default =evil-surround-pairs-alist= you have to use =setq-default=,
for example to remove all default pairs:#+BEGIN_SRC emacs-lisp
(setq-default evil-surround-pairs-alist '())
#+END_SRCor to add a pair that surrounds with two ` if you enter ~:
#+BEGIN_SRC emacs-lisp
(setq-default evil-surround-pairs-alist
(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:
#+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)
(let ((inner-name (make-symbol (concat "evil-inner-" name)))
(outer-name (make-symbol (concat "evil-a-" name))))
`(progn
(evil-define-text-object ,inner-name (count &optional beg end type)
(evil-select-paren ,start-regex ,end-regex beg end type count nil))
(evil-define-text-object ,outer-name (count &optional beg end type)
(evil-select-paren ,start-regex ,end-regex beg end type count t))
(define-key evil-inner-text-objects-map ,key #',inner-name)
(define-key evil-outer-text-objects-map ,key #',outer-name))))(define-and-bind-quoted-text-object "pipe" "|" "|" "|")
(define-and-bind-quoted-text-object "slash" "/" "/" "/")
(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=, 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_SRCnote 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=.
For more information do: =C-h v evil-surround-operator-alist=.By default, surround works with =evil-change= and =evil-delete=.
To add support for the evil-paredit package,
you need to add =evil-paredit-change= and =evil-paredit-delete=
to =evil-surround-operator-alist=, like so:#+BEGIN_SRC emacs-lisp
(add-to-list 'evil-surround-operator-alist
'(evil-paredit-change . change))
(add-to-list 'evil-surround-operator-alist
'(evil-paredit-delete . delete))
#+END_SRC* Examples
Here are some usage examples (taken from [[https://github.com/tpope/vim-surround][surround.vim]]):
Press =cs"'= inside
#+BEGIN_EXAMPLE
"Hello world!"
#+END_EXAMPLEto change it to
#+BEGIN_EXAMPLE
'Hello world!'
#+END_EXAMPLENow press =cs'= to change it to
#+BEGIN_EXAMPLE
Hello world!
#+END_EXAMPLETo go full circle, press =cst"= to get
#+BEGIN_EXAMPLE
"Hello world!"
#+END_EXAMPLETo remove the delimiters entirely, press =ds"=.
#+BEGIN_EXAMPLE
Hello world!
#+END_EXAMPLENow with the cursor on "Hello", press =ysiw]= (=iw= is a text object).
#+BEGIN_EXAMPLE
[Hello] world!
#+END_EXAMPLELet's make that braces and add some space (use =}= instead of ={= for no
space): =cs]{=#+BEGIN_EXAMPLE
{ Hello } world!
#+END_EXAMPLENow wrap the entire line in parentheses with =yssb= or =yss)=.
#+BEGIN_EXAMPLE
({ Hello } world!)
#+END_EXAMPLERevert to the original text: =ds{ds)=
#+BEGIN_EXAMPLE
Hello world!
#+END_EXAMPLEEmphasize hello: =ysiw=
#+BEGIN_SRC html
Hello world!
#+END_SRCFinally, let's try out visual mode. Press a capital V (for linewise
visual mode) followed by =S=.
#+BEGIN_SRC html
Hello world!
#+END_SRCSuppose you want to call a function on your visual selection or a text
object. You can simply press =f= instead of the aforementioned keys and
are then prompted for a functionname in the minibuffer, like with the
tags. So with:#+BEGIN_EXAMPLE
"Hello world!"
#+END_EXAMPLE... after selecting the string, then pressing =Sf=, entering =print= and
pressing return you would get#+BEGIN_SRC c
print("Hello world!")
#+END_SRC* FAAQ (frequently actually asked questions)
** Why does =vs= no longer surround?This is due to an upstream change in =vim-surround=. It happened in this [[https://github.com/tpope/vim-surround/commit/6f0984a][commit]]. See the
discussion in [[https://github.com/timcharper/evil-surround/pull/48][this]] pull request for more details.
* Contributing
- you are encouraged to test your changes in a standard environment with a clean emacs using just the needed plugins.** interactively
#+BEGIN_SRC sh
# open a shell and go to the evil-surround directory, after cloning it
# this is a clean emacs with just the absolute minimum dependencies needed to test evil-surround interactivelly.
make
make emacs# now load evil-surround/test/evil-surround-test.el and M-x ert and run the tests
#+END_SRC** command
#+BEGIN_SRC sh
# open a shell and go to the evil-surround directory, after cloning it
# this commands ensure that the tests are using a clean emacs with just the absolute minimum dependencies needed.
make
make test
#+END_SRC* Credits
Credits and many [[https://github.com/emacs-evil/evil/issues/842][thanks]] go to [[http://github.com/timcharper][Tim Harper]], the original mantainer of the package.
* LICENSE- [[https://www.gnu.org/licenses/gpl-3.0.en.html][GNU General Public License v3]]
#+BEGIN_SRC text
GNU General Public License v3
Copyright (C) 2010 - 2017 Tim Harper
Copyright (c) 2018 - 2020 The evil-surround Contributors
#+END_SRC