Remplacer par pur vimscript (sans `: s`)

12

J'ai les éléments suivants dans mon vimrc:

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

J'utilise Vint à peluches mon vimrc, et a obtenu l'avertissement suivant:

ProhibitCommandWithUnintendedSideEffect Évitez les commandes avec des effets secondaires involontaires. Évitez d'utiliser: s [ubstitute] car il déplace le curseur et imprime des messages d'erreur. Préférez les fonctions (telles que search ()) mieux adaptées aux scripts. Pour de nombreuses commandes vim, il existe des fonctions qui font la même chose avec moins d'effets secondaires. Voir: fonctions d'aide () pour une liste des fonctions intégrées. Guide de style Google Vimscript

Cependant, je ne pense pas que ce soit un moyen de faire la substitution sans utiliser la :scommande.

Par exemple, la search()fonction donne les lignes correspondant à un modèle, mais il n'y a aucun moyen de faire une substitution. La substitute()fonction fonctionne sur une chaîne et ne se substitue pas à un fichier entier.

Dois-je implémenter une méthode de remplacement moi-même, ou est-ce un moyen plus intelligent de réécrire ma fonction?

edi9999
la source

Réponses:

10

Voici une implémentation simpliste de votre fonction, écrite avec substitute():

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

Ajustez le motif de recherche au goût.

romainl
la source
10

La raison pour laquelle il vous avertit des effets secondaires involontaires est parce :substitutequ'il déplace le curseur et écrase la recherche précédente (s'il est utilisé en dehors d'une fonction) . Cependant, cela ne signifie pas que vous ne devriez pas l'utiliser, car vous pouvez inverser les effets secondaires de :substitute. Par exemple, voici une fonction que j'ai créée qui utilise la commande de substitution pour supprimer les espaces de fin:

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

Notez que vous pouvez également utiliser la :markcommande pour enregistrer la position du curseur, mais cela signifie également que vous écraserez la marque que vous décidez d'utiliser. Je n'ai jamais utilisé de vint auparavant, mais une astuce sur les linters est que vous pouvez prendre leurs avertissements avec un grain de sel. Dans ce cas, il est vrai que :substitutecela a des effets secondaires, mais ce sont des effets secondaires qui peuvent être évités. De plus, il n'y a vraiment pas de meilleure façon de faire une recherche et de remplacer un fichier de toute façon.

Arbre à feuilles persistantes
la source
6
Le dernier terme de recherche utilisé est automatiquement restauré après avoir quitté une fonction, de sorte que l'enregistrement et la restauration ne devraient pas être nécessaires lors de son utilisation dans une fonction. Voir:help function-search-undo
Martin Tournoij
1
utilisez plutôt winsaveview () / winrestview () au lieu du curseur ()
Christian Brabandt
1

La :scommande est une approche Vimscript pure.

Je suppose que l'avertissement signifie uniquement que le curseur sera très probablement mal positionné après son utilisation (que vous pouvez contourner en utilisant la winsaveview()fonction avant et la winrestview()commande après son utilisation). Vous devez également prendre soin des erreurs possibles qui pourraient survenir. Ceci est généralement géré à l'aide du edrapeau. Il faut également prendre soin de certains paramètres comme le gdefaultparamètre, qui inverse la signification du gdrapeau.

Il faut prendre soin de ces détails et c'est probablement la cause première de ces avertissements. Mais cela ne signifie pas pour autant d'éviter l'utilisation de la :scommande. Il est tout à fait correct d'utiliser la :scommande si vous souhaitez remplacer quelque chose dans le tampon actuel.

(Remarque, on pourrait bien sûr parcourir toutes les lignes et utiliser une approche search () / getline () / setline (). Mais cela est généralement plus lent.)

Christian Brabandt
la source