Getting smartparens wrapping to work in evil-visual-state
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?
On 27.11.2016 14:27, ivan wrote:
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?
You probably need to write your own command that inserts both characters at the beginning and the end of the region. Something like this might work: (defconst my-pairs-alist '((?( . ?)) (?{ . ?}) (?[ . ?]))) (evil-define-operator my-wrap (beg end type) (interactive "<R>") (let* ((ch last-command-event) (pair (or (assoc ch my-pairs-alist) (rassoc ch my-pairs-alist)))) ;; Other characters a paired literally, e.g. " (unless pair (unless (characterp ch) (user-error "Cannot pair key %s" ch)) (setq pair (cons ch ch))) (save-excursion (goto-char end) (insert-char (cdr pair)) (goto-char beg) (insert-char (car pair))))) (define-key evil-visual-state-map "(" 'my-wrap) (define-key evil-visual-state-map ")" 'my-wrap) (define-key evil-visual-state-map "[" 'my-wrap) (define-key evil-visual-state-map "]" 'my-wrap) (define-key evil-visual-state-map "{" 'my-wrap) (define-key evil-visual-state-map "}" 'my-wrap) (define-key evil-visual-state-map "\"" 'my-wrap) (define-key evil-visual-state-map "'" 'my-wrap) Bind `my-wrap` to whatever key should be paired. Maybe " or ' are not so good because this would shadow register and mark access. Frank
I do this: (define-key evil-normal-state-map "o" nil) (define-key evil-visual-state-map "o" nil) (defmacro my-define-insert-pair-key-binding (open-char close-char) "Define key binding for inserting a pair." `(define-key evil-normal-state-map ,(format "o%c" open-char) (lambda (&optional parg) (interactive "*P") (insert-pair parg ,open-char ,close-char)))) (my-define-insert-pair-key-binding ?\" ?\") (my-define-insert-pair-key-binding ?\' ?\') (my-define-insert-pair-key-binding ?\( ?\)) (my-define-insert-pair-key-binding ?\[ ?\]) (my-define-insert-pair-key-binding ?\{ ?\}) (my-define-insert-pair-key-binding ?\< ?\>) No reason you need to use "o", but this means if region is active and I type o[ then the region is enclosed in []. Same for quotes and other brackets. On Mon, Nov 28, 2016 at 6:33 AM, Frank Fischer <[email protected]
wrote:
On 27.11.2016 14:27, ivan wrote:
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?
You probably need to write your own command that inserts both characters at the beginning and the end of the region. Something like this might work:
(defconst my-pairs-alist '((?( . ?)) (?{ . ?}) (?[ . ?])))
(evil-define-operator my-wrap (beg end type) (interactive "<R>") (let* ((ch last-command-event) (pair (or (assoc ch my-pairs-alist) (rassoc ch my-pairs-alist)))) ;; Other characters a paired literally, e.g. " (unless pair (unless (characterp ch) (user-error "Cannot pair key %s" ch)) (setq pair (cons ch ch))) (save-excursion (goto-char end) (insert-char (cdr pair)) (goto-char beg) (insert-char (car pair)))))
(define-key evil-visual-state-map "(" 'my-wrap) (define-key evil-visual-state-map ")" 'my-wrap) (define-key evil-visual-state-map "[" 'my-wrap) (define-key evil-visual-state-map "]" 'my-wrap) (define-key evil-visual-state-map "{" 'my-wrap) (define-key evil-visual-state-map "}" 'my-wrap) (define-key evil-visual-state-map "\"" 'my-wrap) (define-key evil-visual-state-map "'" 'my-wrap)
Bind `my-wrap` to whatever key should be paired. Maybe " or ' are not so good because this would shadow register and mark access.
Frank
_______________________________________________ implementations-list mailing list [email protected] https://lists.ourproject.org/cgi-bin/mailman/listinfo/implementations-list
participants (3)
-
Barry OReilly -
Frank Fischer -
ivan