Tengo un problema que puedo pensar en dos enfoques generales para resolver, pero no sé detalles para ninguno de los enfoques.
...
Level 1: cũng also
Level 1: và and
Level 1: như like; such as
Level 2: các plural marker
Level 2: của belonging to
...
Para cada línea que comience "Nivel n" quiero insertar un número, comenzando con "01". Por simplicidad, antepongamos el número.
Enfoque 1: seleccione manualmente todas las líneas con el mismo nivel. Invocar magia pronto voy a aprender.
Enfoque 2: escriba una búsqueda y reemplace que coincida con todas las líneas con un nivel determinado que en cada coincidencia incluya un número en el texto de reemplazo, que se incrementa en uno con cada coincidencia.
Encontré preguntas similares en StackOverflow o en otros sitios de Vim, pero cada uno parece tener uno o más de los siguientes problemas:
- Se trata de insertar el número de línea actual en lugar de un número arbitrario pero incremental.
- No pone a cero el número.
- En realidad, no funciona para las selecciones en mi Vim 7.4 que se ejecuta en Windows 7. (Estas dan como resultado el error
E481: No range allowed
).
Estoy ejecutando gVim en Windows con mswin.vim, pero una solución que funcione en todas las instalaciones de Villa de Vanilla sin tener que personalizar la configuración podría ser la mejor.
Respuestas:
Similar a la respuesta en https://vi.stackexchange.com/a/818/227 , puede usar el comando global.
Con él, puede indicar a vim que busque líneas que coincidan con un patrón y luego ejecutar comandos en él.
En su caso, desea anteponer texto a las líneas que comienzan con "Nivel N:", por lo que nuestro comando global podría ser
Usar el comando sustituto (reemplazo de expresión regular) para el comando
Los comandos son más divertidos. Por lo general, me gusta hacer un reemplazo de expresión regular para cosas como esta, ya que es fácil de usar variables.
Ejemplo para tu pregunta
Cómo funciona
En la sección de reemplazo de un comando de sustitución puede ser una expresión.
Lo primero que haremos es establecer una variable
i
para que sea el número inicial. Elegí 1, pero cualquier número servirá.let i = 1
Luego ejecutamos nuestro comando global, que nos prepara para hacer una acción en líneas coincidentes.
g/^Level \d:/
Haremos que nuestro comando global inserte el valor e incremente nuestro contador usando el comando de sustitución y el comando let.
s/^/\=printf("%02d ", i)/ | let i = i+1
La expresión regular del comando de sustitución encuentra el comienzo de la línea
^
y la reemplaza con una expresión, y nuestra expresión será el resultado de una impresión formateada. Al igual que en el lenguaje C, el printf de vim toma parámetros de formato.%02d
significa convertir un argumento como si fuera un número decimald
, ocupando al menos 2 espacios2
y rellenar con 00
. Para obtener detalles y otras opciones de conversión (incluido el formato de punto flotante), consulte:help printf
. Le damos a printf nuestra variable de conteoi
y nos da01
la primera vez,02
la segunda, etc. Esto se usa mediante el comando de sustitución para reemplazar el comienzo de la línea, insertando efectivamente el resultado de printf al principio.Nota que puse un espacio después de la d:
"%02d "
. No lo solicitó en la pregunta (y no vi resultados de ejemplo), pero sospeché que deseaba separar el número de la palabra "Nivel". Elimine el espacio de la cadena dada a printf para tener el número insertado justo al lado de la L en el Nivel.Finalmente, eso
let i = i + 1
incrementa nuestro contador después de cada sustitución.Esto se puede aplicar generalmente para reemplazar partes de líneas que coinciden con otros criterios con datos funcionales arbitrarios.
Usar comandos normales combinados
Esto es bueno para inserciones simples o edición compleja. Al igual que con el sustituto, usaremos global para coincidir, pero en lugar de la sustitución de expresiones regulares, ejecutaremos una serie de operaciones como si fueran escritas por el usuario.
Ejemplo para tu pregunta
Cómo funciona
Los valores utilizados son muy similares al sustituto (todavía estamos usando printf para formatear nuestro número para que sea 0 rellenado con 2 dígitos), pero la operación es diferente.
Aquí usamos el comando execute, que toma una cadena y la ejecuta como un comando ex (
:help :exe
). Construimos una cadena que combina "normal! I" con nuestros datos, que será "normal! I01" la primera vez y "normal! I02" la segunda vez, etc.El
normal
comando realiza operaciones como si estuviera en modo normal. En este ejemplo, nuestro comando normal esI
, que se inserta al comienzo de la línea. Si lo hubiéramos usadodd
, eliminaría la línea,o
abriría una nueva línea después de la línea coincidente. Es como si escribieraI
(o cualquier otra operación) usted mismo en modo normal. Usamos el!
afternormal
para asegurarnos de que no haya mapeos en nuestro camino. Ver:help :normal
.Lo que se inserta entonces es el valor de nuestra printf, como en el primer ejemplo de uso de sustituto.
Este método puede ser más sofisticado que regex, porque puede hacer cosas como
execute "normal! ^2wy" . i . "th$p"
ir al principio del texto^
, avanzar 2 palabras2w
, tirar hasta el carácter de la 'h'y" . i . "th
, moverse al final de la línea$
y pegarp
.Esto es casi como ejecutar una macro, pero en realidad no usa un registro y puede combinar cadenas de cualquier expresión. Esto me parece muy poderoso.
Enfoque donde cada nivel tiene su propio contador
Es posible que desee que cada nivel obtenga su propio contador. Si conoce el número máximo de niveles con anticipación, puede hacer lo siguiente (agregar código adicional para encontrar el nivel más alto podría no ser demasiado difícil, pero haría que esta respuesta fuera demasiado larga. Esto es cada vez más larga).
Primero, liberemos i, en caso de que ya lo hayamos usado como un entero. No podemos convertir i en una lista, tenemos que crearlo de esa manera.
A continuación, establezcamos i como una lista que contiene el número de niveles. Mostraste 2 en tu pregunta, pero supongamos 10 por diversión. Dado que la indexación de la lista está basada en 0, y no quiero molestarme en corregir 1 basada en su lista, crearemos suficientes elementos (11) y nunca usaremos el índice 0.
A continuación, necesitamos una forma de obtener el número de nivel. Afortunadamente, el sustituto también está disponible como una función, por lo que le daremos nuestra línea y extraeremos el número de nivel
substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")
Como ahora es una lista de 11
1
s (cada índice es el contador de nuestro nivel), ahora podemos ajustar cualquiera de los ejemplos anteriores para usar el resultado de esta sustitución:Mediante comando sustituto:
Por comando normal:
Entrada de ejemplo:
Salida de ejemplo:
fuente
Puede construir desde https://stackoverflow.com/a/4224454/15934 para poner a cero sus números.
Pero para simplificar la acción de los números de relleno, elegiría un par de funciones y un comando:
Luego, seleccione sus líneas y escriba
:PrependNumber
(verá:'<,'>PrependNumber
. [Nota: El comando toma un parámetro opcional: el patrón antes del cual se insertará el número]fuente
line(".")
significa "usar el número de línea actual"? Ese era mi problema 1. con respuestas anteriores que pude encontrar.$HOME/vimfiles/plugin/whatevernameyouwish.vim
. O incluso su$HOME/_vimrc
(nombre de archivo de Windows) si lo prefiere (en una primera vez). Si no está seguro de qué $ HOME hay en su máquina, pregúntele a Vim qué cree que es ->:echo $HOME
:source
si el script vim está instalado correctamente en el directorio correcto ({rtp} / plugin, o {rtp} / ftplugin / {filetype} / ftplugin para complementos específicos de tipo de archivo).:source
es con lo que tuvimos que jugar hace más de una década y media.Podrías abordarlo grabando una macro. Comenzando con su archivo original, anteponga la primera instancia con el número.
Mueva el cursor hacia
01
, selecciónelo y tírelo conyiw
. Ahora desea registrar sus acciones desde este punto.qq/^Level 1<CR>P<C-A>A<space><esc>0yiwq
qq
Iniciar una macro en el registro q/^Level 1<CR>
Busque una línea que comience con "Nivel 1"P
pegar antes del cursor (contiene su número)<C-A>
incrementa el númeroA<space><esc>
Insertar un espacio después del número0
Ir al inicioyiw
tirar del número actualq
Fin de la macroLuego repita esta macro usando
@q
.fuente
<C-A>
control + a? Eso selecciona todo en Vim en Windows.