2013-08-07 5 views
7

Sto provando a creare un nuovo oggetto di testo in Evil. Ad esempio, l'oggetto di testo iw seleziona solo sottoinsiemi di stringhe contenenti trattini. Voglio che il nuovo oggetto di testo abbini le parole con qualsiasi carattere non spaziale. Quello che ho ottenuto finora è:Emacs Modalità cattiva: come creare un nuovo oggetto di testo per selezionare le parole con caratteri non spaziali?

(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) 

Questo codice non riesce a far corrispondere correttamente le parole alla fine di una riga. Funziona con le parole all'inizio di una riga grazie a \ n.

Ho provato molte cose che non funzionavano. Il guaio per me è che quando qualcosa non funziona, non so se è dovuto a una regexp sbagliata oa limitazioni nell'intervallo male-regexp. Ad esempio, utilizzando \ s- riporta un errore, che sembra essere una limitazione nel Male.

risposta

1

La regexp corretta è "\ |.? $". Il codice seguente implementa un nuovo oggetto di testo che corrisponde a qualsiasi carattere non spaziale.

(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

Aggiungo che il male corrente ha già un textobject WORD interno legato a 'i W'. – PythonNut

+0

haha ​​non l'ho trovato con le ricerche sul web ... dovrei leggere il manuale di vim uno di questi giorni. Grazie – lionel

13

Aggiornamento: evil-regexp-range was recently replaced with evil-select-paren. Questo funziona sul male attuale e ha lo stesso utilizzo di quello vecchio:

(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))))) 

risposta originale:

Se si finisce per definire più di un nuovo oggetto di testo, la ripetizione può ottenere fastidioso, soprattutto se si desidera legare sia gli oggetti interni che quelli esterni. Se si colpisce la barriera, provate questo:

(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))))) 

Usage:

; 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") 

(Questo è più di quanto si voleva, ma lascio qui in caso aiuta qualcuno :)

+1

Grazie per questo! Spesso mi sono ritrovato a desiderare di avere un oggetto di testo, ad es. associare la dichiarazione C++ senza parsing - ad es. matching '_foo :: bar :: baz _()', incluso ':' ma ignorando '()'. La tua soluzione lo ha reso molto semplice: '(define-and-bind-text-object" k "" [[: space:] \ (\)] "" [[: space:] \ (\)] ")'. Muchos gracias! –

+1

Sembra che "male-regexp-range' sia stato rimosso dalle versioni più recenti di Evil - Credo che ora dobbiamo usare" evil –

7

Non penso che sia necessario creare un nuovo oggetto di testo. Il male include l'oggetto testo simbolo. La sintassi del simbolo è definita dalla modalità principale e in genere include trattini, numeri, caratteri di sottolineatura e altri caratteri non spazi bianchi.

L'oggetto di testo simbolo è associato a o. La definizione è evil-maps.el at Bitbucket

+1

hmm no. L'oggetto di testo che stavo cercando è effettivamente implementato in vim/evil, ma come @PythonNut ha detto in un commento, è legato a 'W'. E per alcuni casi, questa implementazione funziona meglio della regexp che ho postato. – lionel

+0

lionel è corretto, questo non risponde esattamente alla domanda - ma 'o' è molto utile, grazie JoeS! –