Issue #254 open

# Evil interacts badly with yasnippet when text selected with visual-line state

edgimar
created an issue

When using yasnippet (https://github.com/capitaomorte/yasnippet), if I have a snippet like the following:

# name: \begin{environment} ... \end{environment}
# key: begin
# --
\begin{${1:environment}} yas/selected-text$0
\end{\$1}


then if I select some lines in visual-line state and do M-x yas-insert-snippet, choosing the snippet above, then the first line of the snippet is highlighted, with the cursor at the beginning of 'environment'. At this point, evil is still in visual-state for a few seconds, and then returns (without any user-interaction) to normal-state, whereupon the cursor-position is moved to the beginning of the line.

The desired behavior would be like it behaves if evil-mode is disabled, and I select a couple of lines and then execute the yas-insert-snippet function. In this case, the final cursor-position remains on the first character of 'environment', and subsequent typing will be mirrored in the \end{} line.

I don't know if this is a bug in Evil or in yasnippet, but I don't know how to determine this. In any case, as it currently is, it seems impossible to use Evil's visual-line state selections with yasnippet.

Note that I am able to get visual-state selections do work if I use:

(add-hook 'yas-before-expand-snippet-hook (lambda ()
(evil-insert-state)))


But, if this hook is active, and I try the snippet with visual-line state selections, then the selections are deleted.

1. repo owner
• changed status to open

Hm, it seems as if Evil's region adjustment does not work well with yasnippet. The problem is that Evil restores the original position of point and mark after the command yas-snippet-insert finishes. This needs some additional work, because currently there is no way to inhibit this behaviour. But if you modify your hook so that it sets the (Emacs) region appropriately after switching to insert state, it should work as expected:

(add-hook 'yas-before-expand-snippet-hook
#'(lambda()
(when (evil-visual-state-p)
(let ((p (point))
(m (mark)))
(evil-insert-state)
(goto-char p)
(set-mark m)))))

2. reporter

Just to confirm, I've tested your modified hook, and it does work as a 'workaround' for the present time.