Object oriented or buffered local text objects for evil?

Q: in Emacs, how do I make object-specific key bindings for text objects in evil

?

It is possible to bind a key in a specific state (normal, insert, etc.) in a specific mode, as shown in the following example:

(evil-define-key 'normal org-mode "a" 'some-command)

      

However, it is not clear to me how to bind a key to a specific mode to evil-outer-text-objects-map

(or its equivalent -inner-

). Alternatively, it is also unclear how the keys in these maps can be bound locally locally via the mode hook.

Doesn't look like it evil-local-set-key

will do this because it expects state (normal, insert, etc.) as the first argument and is not relevant to the task.

It is also unclear how to use local-set-key

in this case, since it expects a key and command as arguments, but does not take a map as an argument.

+3


source to share


2 answers


While reading the mailing list, someone mentioned that it is better to bind bindings in eval-after-load

instead of hooks, so here it goes:

(eval-after-load "<mode>"
  '(progn
     <object-definition>))

      

As for defining new text objects, I have to recommend this function from @ gordon-gustafson :



(defmacro define-and-bind-text-object (key start-regex end-regex)
  (let ((inner-name (make-symbol "inner-name"))
        (outer-name (make-symbol "outer-name")))
    `(progn
      (evil-define-text-object ,inner-name (count &optional beg end type)
        (evil-select-paren ,start-regex ,end-regex beg end type count t))
      (evil-define-text-object ,outer-name (count &optional beg end type)
        (evil-select-paren ,start-regex ,end-regex beg end type count nil))
      (define-key evil-inner-text-objects-map ,key (quote ,inner-name))
      (define-key evil-outer-text-objects-map ,key (quote ,outer-name)))))

      

So the part <object-definitions>

will become:

(define-and-bind-text-object "<key>" "<start-regex>" "<end-regex>")

      

+2


source


It's a bit late, but for the first part of your question, you can use local maps, for example:

(defun my-elisp-mode-configuration ()
  (with-eval-after-load 'evil
    (define-key evil-visual-state-local-map "ie" 'sp-evil-i-sexp)
    (define-key evil-operator-state-local-map "ie" 'sp-evil-i-sexp)))

(add-hook 'emacs-lisp-mode-hook #'my-elisp-mode-configuration)

      

In this example, I bind the "inner" statement to the sp-evil-i-sexp custom text object for elisp mode only.

Coming to your second question; evil overrides local maps, so using a local key is not enough. You can use instead:



  • local evil cards with hooks; as evil-normal state-local map as in the previous example
  • use evil-qualifier-key; ie: (evil-define-key 'normal emacs-lisp-mode-map (kbd " ") 'my-leader)

    Please note that you cannot override Evil bindings in this way, except for those who do not work or work globally or locally. Use the first method if you want to override Evil bindings.
  • And there is evil-make-overriding-map

    one that forces the local map to override the Evil bindings, but that is rarely you want because you want hjkl to work at least, but is useful for modes like dired, which makes evil less sense.

Footnote: There is nothing special about Evil statements or text objects from an Emacs perspective. They are simply associated with cards. For example: the key i is bound to the map of evil-inner-text-objects which includes text objects like w, as in:

(define-key evil-visual-state-map "i" evil-inner-text-objects-map)
(define-key evil-inner-text-objects-map "w" 'evil-inner-word)

      

You can find these lines in evil-maps.el

+2


source







All Articles