4

Code faster by extending Emacs EVIL text object

 2 years ago
source link: http://blog.binchen.org/posts/code-faster-by-extending-emacs-evil-text-object/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Code faster by extending Emacs EVIL text object

I use EVIL text object a lot. For example, press vi( to select the code snippet inside parenthesis.

I could also press vib to do exactly same thing as vi( because below code in EVIL's evil-maps.el,

(define-key evil-outer-text-objects-map "b" 'evil-a-paren)
(define-key evil-inner-text-objects-map "b" 'evil-inner-paren)

As a full stack web developer, I often need select the snippet inside "[]", "{}", "()", "<>". So I prefer using vig to replace vi[, vi{, vi(, and vi<.

Here is my new text object,

(defun my-evil-paren-range (count beg end type inclusive)
  "Get minimum range of paren text object.
COUNT, BEG, END, TYPE is used.  If INCLUSIVE is t, the text object is inclusive."
  (let* ((parens '("()" "[]" "{}" "<>"))
         range
         found-range)
    (dolist (p parens)
      (condition-case nil
          (setq range (evil-select-paren (aref p 0) (aref p 1) beg end type count inclusive))
        (error nil))
      (when range
        (cond
         (found-range
          (when (< (- (nth 1 range) (nth 0 range))
                   (- (nth 1 found-range) (nth 0 found-range)))
            (setf (nth 0 found-range) (nth 0 range))
            (setf (nth 1 found-range) (nth 1 range))))
         (t
          (setq found-range range)))))
    found-range))

(evil-define-text-object my-evil-a-paren (count &optional beg end type)
  "Select a paren."
  :extend-selection t
  (my-evil-paren-range count beg end type t))

(evil-define-text-object my-evil-inner-paren (count &optional beg end type)
  "Select 'inner' paren."
  :extend-selection nil
  (my-evil-paren-range count beg end type nil))

(define-key evil-inner-text-objects-map "g" #'my-evil-inner-paren)
(define-key evil-outer-text-objects-map "g" #'my-evil-a-paren)

In above code,

  • my-evil-paren-range returns the minimum range of text objects "[", "{", "(", and "<".
  • EVIL api evil-define-text-object is used to define a text object whose range is returned by my-evil-paren-range
  • In evil-outer-text-objects-map the text object shortcut "g" is defined

As you can see, understanding my personal workflow and knowing a bit Lisp does make me code faster.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK