evil-god-state icon indicating copy to clipboard operation
evil-god-state copied to clipboard

Can't use evil-god-state in visual mode

Open sebastiansturm opened this issue 11 years ago • 8 comments

Hi,

it seems that (set-mark) automatically activates visual mode, so I can't use evil-god-state in visual mode (using evil-20141206.849). Any suggestions on how to fix this? thanks, Sebastian

sebastiansturm avatar Dec 07 '14 18:12 sebastiansturm

FWIW, it seems that the issue can be fixed by adding the following lines to the (evil-visual-state-p) branch of evil-execute-in-god-state:

(remove-hook 'activate-mark-hook 'evil-visual-activate-hook t)
(add-hook 'post-command-hook
    #'(lambda () (add-hook 'activate-mark-hook 'evil-visual-activate-hook nil t)))

I think I can live with that kludge if no further issues arise, although it seems like a pretty heavyweight fix. Do you have any ideas on how to do this more elegantly?

sebastiansturm avatar Dec 07 '14 18:12 sebastiansturm

Here's something I tried (as an Elisp newb):

(defun evil-execute-in-god-state ()
  "Execute the next command in God state."
  (interactive)
  (add-hook 'pre-command-hook #'evil-god-fix-last-command t)
  (add-hook 'post-command-hook #'evil-stop-execute-in-god-state t)
  (setq evil-execute-in-god-state-buffer (current-buffer))
  (setq evil-god-last-command last-command)
  (cond
   ((evil-visual-state-p)
    (let ((mrk (mark))
          (pnt (point)))
      (set-mark mrk)
      (goto-char pnt))
    (backward-char)
    (evil-god-state))
   (t
    (evil-god-state)))
  (evil-echo "Switched to God state for the next command ..."))

Basically, I moved the god mode invocation down, out of the let. This lets evil god state work correctly in visual state, however the cursor will move right one character on invocation, so I stuck a backward-char in there. It seems to work for me.

EDIT: @sebastiansturm's fix works better.

darkfeline avatar Dec 18 '14 06:12 darkfeline

Here's another fix that seems to work:

https://github.com/darkfeline/evil-god-state/commit/c4f59b7cc7cf8e89c66be6208b0bc76733e13596

It nukes a few lines of code, but I haven't had any adverse effects so far.

darkfeline avatar Dec 20 '14 09:12 darkfeline

Hmm, I've never actually tried to switch to god-state from visual-state, but it certainly does not work right..

It looks to me that the culprit is actually evil's evil-visual-activate-hook, which explicitly checks for visual, insert, or emacs state before continuing. If I add a check for god state

(defun evil-visual-activate-hook (&optional command)
  "Enable Visual state if the region is activated."
  (unless (evil-visual-state-p)
    (evil-delay nil
        ;; the activation may only be momentary, so re-check
        ;; in `post-command-hook' before entering Visual state
        '(unless (or (evil-visual-state-p)
                     (evil-insert-state-p)
                     (evil-emacs-state-p)
                     (evil-god-state-p))
           (when (and (region-active-p)
                      (not deactivate-mark))
             (evil-visual-state)))
      'post-command-hook nil t
      "evil-activate-visual-state")))

then everything seems to work as expected.

So I think the right thing to do would be to send a patch upstream to evil that checks for a configurable set of states rather than a hardcoded set. That way we can just add god-state to that list (and any other custom states can do the same).

Does that make sense? If so I'll happily put together a patch for the evil folks and let you know what they say :)

gridaphobe avatar Dec 21 '14 04:12 gridaphobe

Makes sense, and probably explains the weird behavior while I was experimenting with evil-god-state.

While you're here, could you explain what https://github.com/gridaphobe/evil-god-state/blob/master/evil-god-state.el#L93 is for (the (not (use-region-p))?

and https://github.com/gridaphobe/evil-god-state/blob/master/evil-god-state.el#L111 could possibly be replaced with Evil's evil-visual-expand-region, which sets the region to the visual selection, which seems better than doing set mark and point ourselves?

darkfeline avatar Dec 21 '14 11:12 darkfeline

@darkfeline (not (use-region-p)) is required to make evil exit visual-state if you run a command that deactivates the region (e.g. kill-region). use-region-p tells us if the region is active.

evil-visual-expand-region doesn't work here because we have to reset the active region after entering god-state, which means we're no longer in visual-state and the visual-state variables evil-visual-expand-region have been unset (presumably, I didn't dig too deeply but it doesn't work :)

gridaphobe avatar Dec 22 '14 23:12 gridaphobe

@gridaphobe Thanks

darkfeline avatar Dec 23 '14 01:12 darkfeline

This is still an issue for me in 2019. Is there any solution?

alienbogart avatar Jul 21 '19 22:07 alienbogart