gVim encontrar / reemplazar con contador

¿Hay alguna manera de insertar el valor de algún tipo de variable de contador en gVim search / replace?

por ejemplo, convertir este documento:

   

a este documento resultante:

    

Me imagino que el comando sería algo así como:

 :%s/^\(\s*<SomeElement Id="\)F\(".*\)$/\1\2/g 

Estoy usando una comstackción de Windows muy reciente, de su instalador provisto. Prefiero no instalar ninguna herramienta adicional.

Además, idealmente me gustaría evitar tener que instalar scripts para respaldar esto, pero estoy dispuesto a hacerlo si es la única forma de hacerlo.

Las instrucciones de Vim wiki parecen ser la solución más fácil (al menos para mí).

El siguiente ejemplo reemplaza todas las ocurrencias de PATTERN con REPLACE_[counter] ( REPLACE_1 , REPLACE_2 etc.):

 :let i=1 | g/PATTERN/s//\='REPLACE_'.i/ | let i=i+1 

Para responder a la pregunta, podría verse así:

 :let i=1 | g/SomeElement Id="F"/s//\='SomeElement Id="'.i.'"'/ | let i=i+1 

Es posible tener un contador que se pueda boost usando un sustituto con una característica de expresión (ver :help sub-replace-\= ). Dado que el constructo \= permite solo expresiones, el comando :let está prohibido de usar y, por lo tanto, no se pudo establecer una variable de la forma habitual. Sin embargo, hay un truco simple para cambiar el valor de una variable en expresión si esa variable es una lista o un diccionario. En ese caso, su contenido podría ser modificado por la función map() . De esta manera, la sustitución del caso descrito en la pregunta se vería de la siguiente manera. 1

 :let n=[0] | %s/Id="F"/\='Id="'.map(n,'v:val+1')[0].'"'/g 

O mejor, 2

 :let n=[0] | %s/Id="\zsF\ze"/\=map(n,'v:val+1')/g 

Este breve one-liner resuelve completamente el problema.

Para reemplazos frecuentes como el anterior, uno puede definir una función auxiliar

 function! Inc(x) let a:x[0] += 1 return a:x[0] endfunction 

y hacer comandos de sustitución aún más cortos,

 :%s/Id="\zsF\ze"/\=Inc(n)/g 

1 La parte difícil aquí está en la parte sustituta del reemplazo. Dado que comienza con \= el rest se interpreta como una expresión de Vim. Por lo tanto, 'Id="'.map(n, 'v:val+1').'"' Es una expresión ordinaria. Aquí una cadena literal 'Id="' se concatenó (usando el operador . ) Con el valor de retorno de la función llamada map(n, 'v:val+1') , y con otra cadena, '"' . El map función espera dos argumentos: una lista (como en este caso) o un diccionario, y una cadena que contiene una expresión que debe evaluarse para cada uno de los elementos en la lista o diccionario dados. Variable especial v:val denota un elemento de lista individual. Por lo tanto, la cadena 'v:val+1' se evaluará a un elemento de lista aumentado en uno.

2 Los átomos del patrón \zs y \ze se utilizan para establecer el inicio y el final del patrón a reemplazar, respectivamente (consulte :help /\zs y :help /\ze ). De esta forma, toda la parte de búsqueda del comando sustituto se corresponde, pero solo se reemplaza la parte entre \zs y \ze . Esto evita concatenaciones torpes en la expresión sustituta.

Hmm esto es un poco complicado. Esto es lo que obtuve hasta ahora. Pruebe estos 2 comandos de mapa en una sesión de vim:

 :nmap %% :let X=11G!! :nmap !! /^\s*:s/F"/\=X.'"'/:let X=X+1!! 

Una vez que esté allí, presione %% para comenzar la parte divertida 🙂

Hace su archivo dado como:

     

Explicación:

El primer comando nmap es mapear siguiendo secuencias a las pulsaciones de teclado %% :

  • inicializando la variable X a 1
  • moviéndose al inicio del primer archivo
  • llamando a otra tecla asignada !!

¡El segundo comando nmap está mapeando secuencias siguiendo las pulsaciones de teclas !! :

  • Busque la siguiente aparición del patrón ^\s*
  • Si se encuentra el patrón anterior, busque y reemplace F" por la variable X y una cita "
  • incrementar la variable vim X en 1
  • Recursivamente se llama a sí mismo haciendo una llamada a !!
  • Punto único se utiliza para la concatenación de cadenas en vim, muy similar a php

Estas llamadas recursivas se detienen cuando el patrón ^\s* ya no se encuentra en el archivo.

Solución muy simple He tenido que hacer esto varias veces.

 :let i=1 | g/^\(\s* 

Basado en el siguiente consejo. http://gdwarner.blogspot.com/2009/01/vim-search-and-replace-with-increment.html

Ponlo en tu vimrc o ejecútalo en tu sesión actual:

 function! Inc(x) let a:x[0] += 1 return a:x[0] endfunction function IncReplace(pos, behind, ahead, rep) let poss=a:pos-1 let n=[poss] execute '%s/' . a:behind . '\zs' . a:rep . '\ze' . a:ahead . '/\=Inc(n)/g' endfunction 

Luego ejecute :call IncReplace(1, 'Id="', '"', 'F')

El primer argumento es el número desde el que desea comenzar, el segundo es lo que desea que coincida con el número, el tercero es lo que desea hacer coincidir antes del número y el cuarto es lo que realmente desea reemplazar.

Tal vez el complemento increment.vim ayudará

    Intereting Posts