New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

key-translation-map not honored in Evil O state #177

Open
TheBB opened this Issue Jul 13, 2012 · 3 comments

Comments

Projects
None yet
1 participant
@TheBB
Member

TheBB commented Jul 13, 2012

Originally reported by: epich (Bitbucket: epich, GitHub: epich)


Background:

Because C-c is one way of escaping in Vim, and because it is more ergonomic than C-g, I aim to use it for escaping insert state and keyboard-quit. I use this in my .emacs .

(defun my-esc (prompt)
  "Functionality for escaping generally.  Includes exiting Evil insert state and C-g binding. "
  (cond
   ((or (evil-insert-state-p) (evil-motion-state-p)) [escape])
   ;; This is the best way I could infer for now to have C-c work during evil-read-key.
   ((eq overriding-terminal-local-map evil-read-key-map) (keyboard-quit) (kbd ""))
   (t (kbd "C-g"))))
(define-key key-translation-map (kbd "C-c") 'my-esc)
(set-quit-char "C-c")

(As an aside, I've also created: (define-key evil-motion-state-map "cc" mode-specific-map) so I have my own means of getting the usual keymap bound to C-c.)

I've found this works in all cases except when I'm in the Operator Pending state.

Problem details:

When I do: d or = I enter the operator pending state and find C-g successfully exits.

However, I find that when I use C-c instead of C-g, it doesn't keyboard-quit. The output in the minibuffer indicates it is using C-c for key lookup and finding it bound to another keymap (presumably the global one). Why is the key-translation-map not translating the C-c to C-g before the key lookup in this Evil state?

Workaround:

I get the behavior I seek when I put this in my .emacs: (define-key evil-operator-state-map (kbd "C-c") 'keyboard-quit).


@TheBB

This comment has been minimized.

Show comment
Hide comment
@TheBB

TheBB Jul 13, 2012

Member

Original comment by Frank Fischer (Bitbucket: lyro, GitHub: lyro):


Operator state is somehow special. When a command is called its interactive statement is responsible for getting the motion. This implies that the key sequence for the motion is read while the command is about being executed. In order to do this evil reads the key sequence manually and translates it using the currently active keymaps. I do not know for sure but it may be possible that this approach does not respect key-translation-map, which would explain the problem (if you're interested, the corresponding code is in the function evil-read-motion in file evil-common.el)

Member

TheBB commented Jul 13, 2012

Original comment by Frank Fischer (Bitbucket: lyro, GitHub: lyro):


Operator state is somehow special. When a command is called its interactive statement is responsible for getting the motion. This implies that the key sequence for the motion is read while the command is about being executed. In order to do this evil reads the key sequence manually and translates it using the currently active keymaps. I do not know for sure but it may be possible that this approach does not respect key-translation-map, which would explain the problem (if you're interested, the corresponding code is in the function evil-read-motion in file evil-common.el)

@TheBB

This comment has been minimized.

Show comment
Hide comment
@TheBB

TheBB Jul 13, 2012

Member

Original comment by epich (Bitbucket: epich, GitHub: epich):


I looked it over a little and found evil-read-motion calls evil-keypress-parser, then reads events iteratively using read-event. I put (read-event) in scratch and evaluated it. Inputting C-c returned 3 in the minibuffer and C-g quit the input. The Elisp manual (http://www.gnu.org/software/emacs/manual/html_mono/elisp.html#Translation-Keymaps) says that read-key-sequence uses the key-translation-map. I put (read-key-sequence) in scratch and evaluated it. Whether I type C-c or C-g, I see "^G" displayed in the minibuffer. Would read-key-sequence be appropriate for Evil to use in operator pending state?

Member

TheBB commented Jul 13, 2012

Original comment by epich (Bitbucket: epich, GitHub: epich):


I looked it over a little and found evil-read-motion calls evil-keypress-parser, then reads events iteratively using read-event. I put (read-event) in scratch and evaluated it. Inputting C-c returned 3 in the minibuffer and C-g quit the input. The Elisp manual (http://www.gnu.org/software/emacs/manual/html_mono/elisp.html#Translation-Keymaps) says that read-key-sequence uses the key-translation-map. I put (read-key-sequence) in scratch and evaluated it. Whether I type C-c or C-g, I see "^G" displayed in the minibuffer. Would read-key-sequence be appropriate for Evil to use in operator pending state?

@TheBB

This comment has been minimized.

Show comment
Hide comment
@TheBB

TheBB Jul 17, 2012

Member

Original comment by Frank Fischer (Bitbucket: lyro, GitHub: lyro):


Maybe, but there are probably some difficulties. First, evil advices read-key-sequence for some recording in the repeat system so there may be some interference. Second, using read-event allows to handle the escape-key (in terminals) specifically. Using read-key-sequence instead would require some other tricks because it only returns complete key sequences (one would have to add a special command bound to ESC to intercept the escape key and possibly re-read to complete input sequence in case of another event arriving, i.e. a M- combination. Maybe the evil-esc can be used, but I don't know.)

Another possibility would be to stay with read-event but do the translation manually. But this is not necessarily easier to do right.

Member

TheBB commented Jul 17, 2012

Original comment by Frank Fischer (Bitbucket: lyro, GitHub: lyro):


Maybe, but there are probably some difficulties. First, evil advices read-key-sequence for some recording in the repeat system so there may be some interference. Second, using read-event allows to handle the escape-key (in terminals) specifically. Using read-key-sequence instead would require some other tricks because it only returns complete key sequences (one would have to add a special command bound to ESC to intercept the escape key and possibly re-read to complete input sequence in case of another event arriving, i.e. a M- combination. Maybe the evil-esc can be used, but I don't know.)

Another possibility would be to stay with read-event but do the translation manually. But this is not necessarily easier to do right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment