2013-08-07 36 views
7

我試圖在邪惡中創建一個新的文本對象。例如,文本對象iw將僅選擇包含連字符的字符串的子集。我希望新的文本對象與任何非空格字符匹配單詞。到目前爲止我得到的是:Emacs邪惡模式:如何創建一個新的文本對象來選擇任何非空格字符的單詞?

(evil-define-text-object evil-inner-space (count &optional beg end type) 
    "Select inner space." 
    :extend-selection nil 
    (evil-regexp-range count beg end type "[ \n]" " " t)) 

(define-key evil-inner-text-objects-map " " 'evil-inner-space) 

此代碼無法正確匹配行末尾的單詞。 \ n感謝\ n在行首開始的單詞。

我嘗試了很多不起作用的東西。對我來說麻煩的是,當某些東西不起作用時,我不知道它是由於錯誤的正則表達式還是由於邪惡正則表達式範圍的限制。例如,使用\ s-報告一個錯誤,這在Evil中似乎是一個限制。

回答

1

正確的正則表達式是「\ |。?$」。以下代碼實現了與任何非空格字符匹配的新文本對象。

(evil-define-text-object evil-inner-space (count &optional beg end type) 
    "Select inner space." 
    :extend-selection nil 
    (evil-regexp-range count beg end type "[ \n]" " \\|.?$" t)) 
+2

我會補充說,當前的邪惡已經有一個內部的WORD textobject綁定到'我W'。 – PythonNut

+0

哈哈我沒有在網絡搜索中找到這個...我應該閱讀vim手冊中的一個這些天。謝謝 – lionel

13

更新evil-regexp-range was recently replaced with evil-select-paren。這適用於當前的邪惡,並具有相同的使用與舊:

(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 nil)) 
     (evil-define-text-object ,outer-name (count &optional beg end type) 
     (evil-select-paren ,start-regex ,end-regex beg end type count t)) 
     (define-key evil-inner-text-objects-map ,key (quote ,inner-name)) 
     (define-key evil-outer-text-objects-map ,key (quote ,outer-name))))) 

原來的答案:

如果最終定義不止一個新的文本對象,重複可以得到煩人,特別是如果你想綁定內部和外部對象。如果你打的障礙,試試這個:

(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-regexp-range count beg end type ,start-regex ,end-regex t)) 
     (evil-define-text-object ,outer-name (count &optional beg end type) 
     (evil-regexp-range count beg end type ,start-regex ,end-regex nil)) 
     (define-key evil-inner-text-objects-map ,key (quote ,inner-name)) 
     (define-key evil-outer-text-objects-map ,key (quote ,outer-name))))) 

用法:

; between dollar signs: 
(define-and-bind-text-object "$" "\\$" "\\$") 

; between pipe characters: 
(define-and-bind-text-object "|" "|" "|") 

; from regex "b" up to regex "c", bound to k (invoke with "vik" or "vak"): 
(define-and-bind-text-object "k" "b" "c") 

(這比你想要更多,但它可以幫助別人:)

+1

謝謝!我經常發現自己希望自己有一個文本對象,例如匹配C++聲明而不咬人 - 例如匹配'_foo :: bar :: baz _()',包括':'但忽略'()'。你的解決方案非常簡單:'(define-and-bind-text-object「k」「[[:space:] \(\)]」「[[:space:] \(\)]」)'。 Muchos gracias! –

+1

看起來'evil-regexp-range'已經從最新版本的Evil中移除 - 我相信我們現在需要使用'evil –

7
我會離開這裏的情況下,

我不認爲你需要創建一個新的文本對象。邪惡包括符號文本對象。符號語法由主模式定義,通常包含連字符,數字,下劃線和其他非空白字符。

符號文本對象綁定到o。定義在evil-maps.el at Bitbucket

+1

hmm no。我正在尋找的文本對象實際上是在vim/evil中實現的,但正如@PythonNut在評論中所說的,它綁定到'W'。在某些情況下,這個實現比我發佈的正則表達式更好。 – lionel

+0

lionel是正確的,這並不完全回答這個問題 - 但是'o'非常有用,謝謝JoeS! –

相關問題