• Stars
    star
    114
  • Rank 300,929 (Top 7 %)
  • Language
    Emacs Lisp
  • Created about 8 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Add/Change/Delete pairs based on `expand-region', similar to `evil-surround'.

embrace.el

http://melpa.org/packages/embrace-badge.svg http://stable.melpa.org/packages/embrace-badge.svg

Add/Change/Delete pairs based on expand-region.

For evil-surround integration, see evil-embrace.

Overview

This package is heavily inspired by evil-surround (which is a port of the vim plugin surround.vim). But instead of using evil and its text objects, this package relies on another excellent package expand-region.

For Emacs users who donโ€™t like evil and thus donโ€™t use evil-surround, embrace provides similar commands that can be found in evil-surround. Evil is absolutely not required. For evil-surround users, embrace can make your evil-surround commands even better! (Have you noticed that evil-surround doesnโ€™t work on many custom pairs?)

Usage

There are three commands: embrace-add, embrace-change and embrace-delete that can add, change, and delete surrounding pairs respectively. You can bind these commands to your favorite key bindings.

There is also a dispatch command embrace-commander. After invoking embrace-commander, you can hit:

  • a for embrace-add
  • c for embrace-change
  • d for embrace-delete

Example

It might be a little hard for users who have no experience in evil and evil-surround to understand what embrace can do. So letโ€™s give an example to show what embrace can do fist. You can look at the following sections to see the meaning of key bindings. In this example, I bind C-, to embrace-commander. Assume we have following text in c-mode and the cursor position is indicated by |:

fo|o

Press C-, a w ' to add โ€ to the current word:

'fo|o'

Press C-, a q { to add {} to outside of the quotes:

{'fo|o'}

Press C-, c ' " to change the โ€ to โ€œโ€:

{"fo|o"}

Press C-, c { t, and then enter the tag: body class=โ€page-bodyโ€, to change the {} to a tag:

<body class="page-body">"fo|o"</body>

Press C-, c t f, and enter the function name bar to change the tag to a function call:

bar("fo|o")

Press C-, d f to remove the function call:

"fo|o"

If youโ€™re an evil-surround user, you might notice that the last command canโ€™t be achieved by evil-surround. However, it works in embrace! And yes, you can find even more examples in which evil-surround doesnโ€™t work while embrace works!

Screencasts

For non evil-mode users, use the following settings (they will be explained later):

(global-set-key (kbd "C-,") #'embrace-commander)
(add-hook 'org-mode-hook #'embrace-org-mode-hook)

Open an org-mode file, we can perform the following pair changing:

./screencasts/embrace.gif

For evil-mode users, here is a similar screencast (see evil-embrace for more details):

https://github.com/cute-jumper/evil-embrace.el/blob/master/screencasts/evil-embrace.gif

And we have a friendly help system (Yes, it is based on some simplified code from which-key):

Help to select a semantic unit:

./screencasts/help_unit.png

Help to delete a pair:

./screencasts/help.png

embrace-change and embrace-delete

These two commands can change and delete the surround pair respectively. For evil-surround users, embrace-change is similar to cs and embrace-delete is similar to ds.

The surrounding pair is specified by a key, which is very similar to the key used for Vimโ€™s text objects. For example, ( stands for the surrounding pair ( and ), and { stands for the surrouding pair, { and }. The default key mappings are shown below:

KeyLeftright
(โ€(โ€โ€)โ€
)โ€( โ€โ€ )โ€
{โ€{โ€โ€}โ€
}โ€{ โ€โ€ }โ€
[โ€[โ€โ€]โ€
]โ€[ โ€โ€ ]โ€
>โ€œ<โ€โ€œ>โ€
โ€œโ€œ"โ€โ€œ"โ€
โ€˜โ€œ'โ€โ€œ'โ€
tโ€œ<foo bar=100>โ€โ€œ</foo>โ€
fโ€œfunc(โ€โ€)โ€

Note that for t and f key, the real content is based on the userโ€™s input.

embrace-add

This command is similar to evil-surroundโ€™s ys command. We need to enter a key for the semantic unit to which we want to add a surrounding pair. The semantic unit is marked by the functions provided by expand-region.

Here is the default mapping:

keymark function
wer/mark-word
ser/mark-symbol
der/mark-defun
per/mark-outside-pairs
Per/mark-inside-pairs
qer/mark-outside-quotes
Qer/mark-inside-quotes
.er/mark-sentence
her/mark-paragraph

After pressing a key to select the semantic unit, you can press another key to add the surrounding pair, which is the same as embrace-change and embrace-delete.

Customization

Adding More Semantic Units

You can modify the variable embrace-semantic-units-alist and note that this variable is buffer-local so it is better to change the value in a hook:

(add-hook 'text-mode-hook
    (lambda ()
       (add-to-list 'embrace-semantic-units-alist '(?e . er/mark-email))))

Adding More Surrounding Pairs

Use the command embrace-add-pair to add a pair:

(embrace-add-pair key left right)

The change is also buffer-local, so wrap it in a hook function:

(add-hook 'LaTeX-mode-hook
    (lambda ()
       (embrace-add-pair ?e "\\begin{" "}")))

If you want add something like the t key for the tag, you can look at the function embrace-add-pair-regexp in the source code, and if youโ€™re planning to use embrace-add-pair-regexp, you should also use embrace-build-help to build the user-friendly help message.

Note that if youโ€™re using embrace-add-pair to add an existing key, then it will replace the old one.

Disable Help Message

If you find the help message annoying, use the following code to disable it:

(setq embrace-show-help-p nil)

Example Settings

I recommend binding a convenient key for embrace-commander. For example,

(global-set-key (kbd "C-,") #'embrace-commander)

We have defined several example hook functions that provide additional key bindings which can be used in different major modes. Right now there are hooks for LaTeX-mode and org-mode:

LaTeX-mode:

KeyLeftRight
=\verb\vert|
~\texttt{}
/\emph{}
*\textbf{}

org-mode:

KeyLeftRight
===
~~~
///
***
___
+++
k@@html:<kbd>@@@@html:</kbd>@@

ruby-mode (and enh-ruby-mode):

KeyLeftRight
ddoend
##{}

To use them:

(add-hook 'LaTeX-mode-hook 'embrace-LaTeX-mode-hook)
(add-hook 'org-mode-hook 'embrace-org-mode-hook)
(add-hook 'ruby-mode-hook 'embrace-ruby-mode-hook) ;; or 'enh-ruby-mode-hook

The code for the three hooks above (which are defined in embrace.el):

(defun embrace-LaTeX-mode-hook ()
  (dolist (lst '((?= "\\verb|" . "|")
                 (?~ "\\texttt{" . "}")
                 (?/ "\\emph{" . "}")
                 (?* "\\textbf{" . "}")))
    (embrace-add-pair (car lst) (cadr lst) (cddr lst))))
(defun embrace-org-mode-hook ()
  (dolist (lst '((?= "=" . "=")
                 (?~ "~" . "~")
                 (?/ "/" . "/")
                 (?* "*" . "*")
                 (?_ "_" . "_")
                 (?+ "+" . "+")
                 (?k "@@html:<kbd>@@" . "@@html:</kbd>@@")))
    (embrace-add-pair (car lst) (cadr lst) (cddr lst))))
(defun embrace-ruby-mode-hook ()
  (dolist (lst '((?# "#{" "}")
                 (?d "do" "end")))
    (embrace-add-pair (car lst) (cadr lst) (caddr lst))))

You can define and use your own hook function similar to the code above.

Welcome to add some settings for more major modes.

For evil-surround Users

Where embrace is better

From the previous example, you can see that embrace actually replicates all the funcionalities provided in evil-surround and it can even do more than evil-surround. Actually, they are quite different. Since embrace uses expand-region behind the scene, you can expect it to work as long as expand-region works. Unlike evil-surround, which is restricted to the pre-defined text objects, embrace can define nearly arbitrary surrounding pairs and three core commands always work. On the contratry, you get nearly no customization in evil-surround: custom pairs donโ€™t work in cs or ds if you donโ€™t have a corresponding text object defined (they work in ys).

TL;DR: embrace is more customizable.

Why not use together?

Sure! You can make embrace and evil-surround work together. Look at evil-embrace!

Contributions

This package is still in early stage, but it is quite usable right now. More functions can be added and the evil integration is not perfect yet. Contributions are always welcome!

Related Packages

More Repositories

1

fcitx.el

Better fcitx integration for Emacs.
Emacs Lisp
125
star
2

parsec.el

A parser combinator library for Emacs Lisp, similar to Haskell's Parsec library.
Emacs Lisp
118
star
3

gscholar-bibtex

Retrieve BibTeX entries from Google Scholar, ACM Digital Library, IEEE Xplore and DBLP
Emacs Lisp
103
star
4

ace-pinyin

Jump to Chinese character by pinyin with `avy' or `ace-jump-mode`
Emacs Lisp
84
star
5

emacs-firefox-controller

An improved Firefox controller for Emacs
Emacs Lisp
82
star
6

bing-dict.el

Minimalists' Bing dictionary for Emacs
Emacs Lisp
53
star
7

evil-embrace.el

Evil integration of embrace.el
Emacs Lisp
46
star
8

org-table-sticky-header

Sticky header for org-mode tables
Emacs Lisp
34
star
9

ace-jump-helm-line

Ace-jump to a candidate in helm window
Emacs Lisp
33
star
10

pinyinlib.el

Elisp library for converting first letter of Pinyin to Simplified/Traditional Chinese characters
Emacs Lisp
32
star
11

avy-zap

Zap to char using `avy'
Emacs Lisp
28
star
12

epipe

A fork of vipe to support emacsclient
Perl
27
star
13

fcitx-remote-for-windows

A fake fcitx-remote for Windows
C++
22
star
14

helm-ext

Extensions to helm (dirty hacks)
Emacs Lisp
19
star
15

evil-find-char-pinyin

Evil's f/F/t/T/evil-snipe commands with Pinyin support
Emacs Lisp
16
star
16

ace-flyspell

Jump to and correct spelling errors using ace-jump-mode and flyspell
Emacs Lisp
13
star
17

org2elcomment

Convert Org file to Elisp comments
Emacs Lisp
10
star
18

company-qml

Emacs company-mode backend for QML
Emacs Lisp
10
star
19

.emacs.d

Emacs config with an Evil editor
Emacs Lisp
9
star
20

plasma-rss-indicator

RSS indicator for Plasma 5
QML
9
star
21

BachelorThesis

Bachelor's final project
Scala
5
star
22

monad.el

(WIP) Toy implementation of monads in Emacs Lisp
Emacs Lisp
4
star
23

gmpl-mode

Major mode for editing GMPL (MathProg) files
Emacs Lisp
3
star
24

renren-indicator

Send notifications when news comes out in Renren.
Python
1
star
25

emacs-word-of-the-day

Show "Word of the Day" from 15 online sources in Emacs
Emacs Lisp
1
star
26

StudyRoomFinder

Helping students to find out available study rooms in Tsinghua University.
Python
1
star
27

KISS

Kiss: Insanely Simple/Stupid Scripts (for personal use only)
Ruby
1
star
28

XiamiDownloader

A naive(or not) music downloader for www.xiami.com
Python
1
star
29

cute-jumper.github.io

Personal blog using org-mode and Jekyll-Bootstrap
CSS
1
star
30

texmf

My own \LaTeX{} class files and macro packages
TeX
1
star
31

NerdishDoubanFM

A nerd-ish command line Douban FM client written in Python.
Python
1
star