I've been migrating from Vim to Emacs in evil mode, and I'd like to use smartparens. I know there's a port of surround.vim, but I've always found surround.vim awkward to use, so I'd like to explore an alternative approach.

I particularly like smartparens' take on wrapping -- select a region and type ( to wrap it in parens. This seems especially nice in concert with expand-region.

But in evil-visual-state, ( is bound to evil-backward-sentence-begin. The binding originates in evil-motion-state-map, which both normal and visual states inherit from. I've tried a few ways to rebind ( to self-insert-command in order to let smartparens do its thing, but so far nothing I've tried has worked:

(define-key evil-visual-state-map (kbd "(") 'self-insert-command)
(define-key evil-motion-state-map (kbd "(") 'self-insert-command)
(define-key evil-motion-state-map (kbd "(") nil)
(evil-define-key 'visual evil-visual-state-map (kbd "(") 'self-insert-command)

How can I properly configure this?

  • Try sp-self-insert-command – Dan Nov 24 '16 at 22:59
  • @Dan sp-self-insert-command doesn't seem to exist, at least in the latest verison of smartparens. Is that something from an older version? – ivan Nov 25 '16 at 16:49

self-insert-command is intended for characters that do produce themselves. it seems this is not what you want, since you want the current region (visual selection) to be to be wrapped. try something like this:

(evil-define-operator wrap-with-parens (beg end)
  (goto-char beg)
  (insert "(")
  (goto-char (1+ end))
  (insert ")"))

(evil-define-key 'visual global-map
  (kbd "(") 'wrap-with-parens)

but imho evil-surround + visual mode is more powerful and flexible: make a visual selection, activate evil-surround, press the paren you want and it will take care of inserting the surrounding pair, optionally with spaces, and so on.

the default binding in visual mode is S, so S( and S) will wrap with (...). S[ and lots of others will work too.

| improve this answer | |

You can use the helper fucntion sp-wrap-with-pair to trigger wrapping behaviour of SP: either next expression or region if one is active. To use concrete pair, use a lambda like so

(lambda (&optional arg) (interactive "P") (sp-wrap-with-pair "("))

I'm not sure which map to put this in evil.

However, there are lots of "ports" of smartparens for evil, called evil-smartparens and similar, look over github a bit, I'm sure at least one of those works.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.