Sostituisci con puro vimscript (senza `: s`)


12

Ho il seguente nel mio vimrc:

func! AddSpaceBeforeEqual()
  s/\([a-z)_0-9"'\[\]]\)=/\1 =/ge
endfunc

Sto usando Vint per sfilacciare il mio Vimrc e ho ricevuto il seguente avviso:

ProhibitCommandWithUnintendedSideEffect Evita i comandi con effetti collaterali indesiderati. Evitare di usare: s [ubstitute] mentre sposta il cursore e stampa i messaggi di errore. Preferisci funzioni (come search ()) più adatte agli script. Per molti comandi vim, esistono funzioni che fanno la stessa cosa con meno effetti collaterali. Vedere: help Functions () per un elenco di funzioni integrate. Guida allo stile di Google Vimscript

Tuttavia, non penso che siano un modo per fare la sostituzione senza usare il :scomando.

Ad esempio, la search()funzione fornisce le linee corrispondenti a un modello, ma non è possibile effettuare la sostituzione. La substitute()funzione opera su una stringa e non sostituisce un intero file.

Dovrei implementare un metodo sostitutivo da solo o sono un modo più intelligente di riscrivere la mia funzione?

Risposte:


10

Ecco un'implementazione semplicistica della tua funzione, scritta con substitute():

function! AddSpaceBeforeEqualInWholeBuffer()
    let l = 1
    for line in getline(1,"$")
        call setline(l, substitute(line, '\([^= ]\)=', '\1 =', "g"))
        let l = l + 1
    endfor
endfunction

Regola il modello di ricerca a piacere.


10

Il motivo per cui ti avverte di effetti collaterali non intenzionali è perché :substitutesposta il cursore e sovrascrive la ricerca precedente (se utilizzata al di fuori di una funzione) . Tuttavia, questo non significa che non dovresti usarlo, poiché puoi invertire gli effetti collaterali di :substitute. Ad esempio, ecco una funzione che ho creato che utilizza il comando substitute per eliminare gli spazi bianchi finali:

function! StripTrailingWhitespace()
    " Save cursor position
    let l:save = winsaveview()
    " Remove trailing whitespace
    %s/\s\+$//e
    " Move cursor to original position
    call winrestview(l:save)
    echo "Stripped trailing whitespace"
endfunction

Nota che puoi anche usare il :markcomando per salvare la posizione del cursore, ma ciò significa anche che sovrascriverai il segno che decidi di usare. Non ho mai usato Vint prima, ma un consiglio sulle linters è che puoi prendere i loro avvertimenti con un granello di sale. In questo caso, è vero che :substituteha effetti collaterali, ma sono effetti collaterali che possono essere prevenuti. Inoltre, in realtà non esiste un modo migliore per eseguire una ricerca e sostituirla in un file.


6
Il termine di ricerca utilizzato per ultimo viene ripristinato automaticamente dopo aver lasciato una funzione, pertanto il salvataggio e il ripristino non dovrebbero essere richiesti quando lo si utilizza all'interno di una funzione. Vedi:help function-search-undo
Martin Tournoij il

1
piuttosto usa winsaveview () / winrestview () invece del cursore ()
Christian Brabandt,

1

Il :scomando è un puro approccio Vimscript.

La mia ipotesi è che l'avvertimento significhi solo che il cursore sarà probabilmente posizionato in modo errato dopo il suo utilizzo (che è possibile aggirare utilizzando la winsaveview()funzione prima e il winrestview()comando dopo il suo utilizzo). Inoltre, è necessario occuparsi dei possibili errori che potrebbero verificarsi. Questo di solito viene gestito usando la ebandiera. Inoltre è necessario occuparsi di alcune impostazioni come l' gdefaultimpostazione, che inverte il significato della gbandiera.

Bisogna prendersi cura di quei dettagli e questa è probabilmente la causa principale di quegli avvertimenti. Ma ciò non significa evitare l'uso del :scomando. Va benissimo usare il :scomando, se si desidera sostituire qualcosa nel buffer corrente.

(Nota, si potrebbe ovviamente passare in rassegna tutte le linee e usare un approccio search () / getline () / setline (). Ma di solito è più lento.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.