Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 13, 2021 10:18 am GMT

vim y el quickfix list: saltar a una ubicacin, buscar y reemplazar en mltiples archivos, y otras curiosidades

En esta ocasin cubriremos una funcionalidad avanzada de vim, la lista de cambios rpidos, A.K.A. the quickfix list. Aprenderemos cmo usarla para buscar (y reemplazar) un patrn en mltiples archivos y tambin para saltar rpidamente a la ubicacin de un error generado por un comando externo.

Quickfix list

Es una modalidad especial de vim en donde se muestra una lista de posiciones, es decir filas y columnas en un archivo. El propsito de esta lista es guardar las posiciones que se encuentran en los mensajes de error que genera un compilador. De esta forma uno puede saltar rpidamente a esta ubicacin, arreglar el problema y luego ir al siguiente o intentar compilar nuevamente.

Puede que suene como una funcionalidad limitada, pero no teman, como todo en vim hay ms de lo que aparenta a simple vista. Esta lista de cambios puede generarse por varios mtodos. Para empezar tenemos algunos comandos que pueden generarla automticamente, entre ellos est :make, :vimgrep y :grep. Adicionalmente, es posible generarla de manera programtica usando la funcion setqflist, lo que nos da una flexibilidad increble.

Debo mencionar que cuando hablo del quickfix list me refiero solamente a la lista de posiciones, deben saber que esta lista puede mostrarse de dos formas. Tenemos el quickfix window y el location list. Estas son bsicamente "ventanas" donde se muestra la lista de posiciones. El quickfix window es "global", es decir que slo podemos tener una en la sesin activa de vim. Por otro lado, podemos tener mltiples location list asociados a diferentes ventanas en una misma sesin.

Saltar a una ubicacin

Para comenzar vamos a explorar el comando :make, es la manera en la que vim invoca un compilador. El nombre les parece familiar? Eso es porque vim asume que estaremos trabajando con la herramienta make. Pueden hacer una prueba si lo tienen instalado en su sistema. Crean un archivo llamado Makefile y colocan lo siguiente:

.PHONY: test otratest:  @echo 'hola'otra:  @echo 'otra'

No cubrir en detalle cmo funciona make pero si quieren saber cmo utilizarlo para automatizar tareas pueden leer este artculo (en ingls).

Al invocar el comando :make deberan obtener algo como esto.

hola(1 de 1): hola

Por defecto make ejecutar la primera "tarea" que vea en nuestro Makefile. Bien, pero entonces Cmo hacemos para ejecutar otra? Podemos proveer ms argumentos al comando, de esta manera :make [argumento]. Si intentan ejecutar :make otra deberan ver esto.

otra(1 de 1): otra

Interesante, pero esos comandos no generan ningn error. Despus de ver estos mensajes no ocurre nada.

Ya que vim sabe cmo "leer" los errores del compilador gcc vamos a ver un ejemplo usando el lenguaje C.

Un ejemplo en C

Creamos un archivo llamado hello.c, en l ponemos el siguiente contenido.

#include <stdio.h>int main() {   printf("Hola, Mundo!
"); return 0;}

Aqu no hay ningn error. Podemos compilar y ejecutarlo tranquilamente usando make. As que el siguiente paso ser crear un Makefile.

.PHONY: run-hellorun-hello:  gcc -Wall -o hello hello.c  ./hello  rm ./hello 

Todo est en su lugar. Ahora podemos ejecutar el comando :make --silent run-hello. Si todo sale bien vim les mostrar su hola mundo.

Hola, Mundo!(1 de 1): Hola, Mundo!

Si introducimos un error esto es lo que deberamos obtener.

hello.c: In function main:hello.c:4:28: error: expected ; before return    printf("Hola, Mundo!
") ^ ; return 0; ~~~~~~make: *** [Makefile:7: run-hello] Error 1(2 de 8): error: expected ; before return

Luego de ver el mensaje notarn que vim los llev automticamente a la ubicacin del error (no es genial?). Para visualizar el quickfix window tenemos que ejecutar el comando :copen, el cual debera mostrarle esto.

|| hello.c: In function main:hello.c|4 col 28| error: expected ; before return                  ||     printf("Hola, Mundo!
")|| ^|| ;|| return 0;|| ~~~~~~make: *** [Makefile|7| run-hello] Error 1

Para cerrar el quickfix window se utiliza el comando :cclose.

Presten atencin a esta lnea.

hello.c|4 col 28| error: expected ; before return

Aqu vim nos est sealando el archivo, la lnea y la columna donde gcc dice que est nuestro error, as como tambin el mensaje de error. Es en este punto donde arreglamos el desperfecto e intentamos compilar nuevamente. En su mayora ese sera el flujo de trabajo que queremos cuando usamos el quickfix list.

Muy bonito, y qu pasa si no usamos gcc? Y si normalmente trabajamos con Node.js? vim podra manejar eso tambin? S, con algo de ayuda.

errorformat

Si empiezan a experimentar con diferentes compiladores e interpretes se darn cuenta rpidamente que vim no puede leer de manera apropiada todos los tipos de errores. Para sobrepasar esta limitacin vim nos ofrece algo llamado errorformat, una variable con la cual podemos especificar el formato del error que genera un comando externo, de esta forma vim puede reconocerlo cuando se encuentre en el quickfix list.

Ahora intentemos hacer que vim entienda los errores que genera node. Vamos a crear un archivo llamado greeting.js, en l vamos a tener un "hola mundo" con un error.

console.log(greeting);const greeting = 'Hola, Mundo!';

En nuestro habitual Makefile creamos otra tarea.

run-greeting:  node ./greeting.js

Si ejecutamos :make --silent run-greeting obtendremos este resultado.

console.log(greeting);            ^ReferenceError: Cannot access 'greeting' before initialization    at Object.<anonymous> (/tmp/test/greeting.js:1:13)    at Module._compile (internal/modules/cjs/loader.js:1063:30)    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)    at Module.load (internal/modules/cjs/loader.js:928:32)    at Function.Module._load (internal/modules/cjs/loader.js:769:14)    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)    at internal/main/run_main_module.js:17:47make: *** [Makefile:4: run-greeting] Error 1

vim intentar llevarnos al lugar donde est el error pero probablemente falle miserablemente. En mi caso particular, me lleva a un archivo que no existe.

Para arreglar esto tenemos que decirle a vim cmo leer ese mensaje. Una manera de hacerlo sera esta.

set errorformat=%E%.%#ReferenceError:\ %m,%Z%.%#%at\ Object.<anonymous>\ (%f:%l:%c)

Lo que hacemos es especificar qu "forma" tiene cada linea en el mensaje error. Cada linea tiene su propio formato y debemos separarlos con una coma. Entonces tenemos que.

%E%.%#ReferenceError:\ %m

Y

%Z%.%#%at\ Object.<anonymous>\ (%f:%l:%c)

Son dos expresiones distintas que le dicen a vim cmo leer el error. Le estoy diciendo dnde puede encontrar el tipo de error (ReferenceError) y dnde est la informacin sobre la ruta y la ubicacin del error. Ya que esas dos piezas de informacin se encuentran en dos lineas diferentes debo tener dos expresiones separadas por una coma.

Para mejorar la legibilidad tambin podemos escribirlo de esta manera.

set errorformat=%E%.%#ReferenceError:\ %mset errorformat+=%Z%.%#%at\ Object.<anonymous>\ (%f:%l:%c)

Noten que as no tenemos que colocar la coma al final de cada expresin. Pero an tenemos que colocar un \ antes de cada caracter que vim considere especial (como un espacio en blanco) para no generar un conflicto entre la sintaxis de vim y el formato del error. An hay otra forma que tambin podemos usar.

let &errorformat =   \ '%E%.%#ReferenceError: %m,' .  \ '%Z%.%#at Object.<anonymous> (%f:%l:%c)'

Al usar let tenemos la posibilidad de crear nuestro formato usando una cadena de texto, sin generar conflictos entre vim y el errorformat. Para mejorar la legibilidad he puesto cada expresin en su propia linea tomando ventaja del operador . para concatenar cadenas de texto.

Ahora al intentar ejecutar :make --silent run-greeting vim debera llevarnos al lugar exacto donde node dice que est el error. Y en el quickfix window debera mostrarnos esto.

|| /tmp/test/greeting.js:1|| console.log(greeting);||             ^|| greeting.js|1 col 13 error| Cannot access 'greeting' before initialization||     at Module._compile (internal/modules/cjs/loader.js:1063:30)||     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)||     at Module.load (internal/modules/cjs/loader.js:928:32)||     at Function.Module._load (internal/modules/cjs/loader.js:769:14)||     at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)||     at internal/main/run_main_module.js:17:47|| make: *** [Makefile:4: run-greeting] Error 1

Noten que ya no aparece ReferenceError, y tampoco la lnea que va debajo. Esa parte especfica del mensaje ha sido reemplazada por esto.

greeting.js|1 col 13 error| Cannot access 'greeting' before initialization

Si les aparece as es porque el formato en el errorformat funcion.

Pero tenemos un problema, y es que esas dos expresiones slo funcionaran con el tipo de error ReferenceError. Si queremos abarcar otros tipos de errores haramos algo como esto.

let &errorformat =   \ '%E%.%#AssertionError %m,' .  \ '%E%.%#TypeError: %m,' .  \ '%E%.%#ReferenceError: %m,' .  \ '%E%.%#SyntaxError: %m,' .  \ '%E%.%#RangeError: %m,' .  \ '%Z%.%#at Object.<anonymous> (%f:%l:%c),' .  \ '%-G%.%#'

Tokens especiales

Ahora probablemente quieren saber sobre la sintaxis que he usado en este formato. Especficamente, qu son todos esas cosas con %. Vamos a dar un repaso sobre esos "tokens" especiales.

  • %f: Indica la ubicacin de la ruta del archivo donde se encuentra el error.

  • %l: Indica la lnea donde se encuentra el error.

  • %c: Indica la columna donde se encuentra el error.

  • %m: Se usa para indicar la ubicacin del contenido del mensaje. En nuestro ejemplo lo usamos para asignar la cadena de texto que viene inmediatamente despus del tipo de error.

  • %E: Indica el inicio de un mensaje de error que abarca mltiples lneas. La letra E le dice a vim que esto es un error. Tambin podemos sealar mensajes de advertencia (%W), mensajes informativos (%I) generales (%G).

  • %Z: Indica que es la ltima lnea del mensaje.

  • %.%#: Esto es un comodn, bascamente coincide con todo. En otras palabras, significa "cualquier cosa." Por ejemplo, la expresin %Z%.%#at Object.<anonymous> (%f:%l:%c) puede leerse de la siguiente forma: La ltima lnea de este mensaje (%Z) puede comenzar con cualquier cosa (%.%#) seguido de at Object.<anonymous> y entre parntesis el archivo (%f), un nmero de lnea (%l) y la columna (%c).

  • %-: Le indica a vim que no debe incluir este fragmento en el quickfix window. Entonces la expresin %-G se puede leer como "no incluyas este mensaje." En nuestro ejemplo usamos %-G%.%# que bascamente le dice a vim "ignora todo lo dems." Ya que %.%# es una expresin que coincide con todo lo colocamos de ltimo.

Si quieren saber con ms detalle lo que pueden hacer con errorformat pueden ejecutar el comando :help errorformat.

makeprg

Ya saben que con un poco de esfuerzo podemos hacer que vim lea cualquier tipo de error pero la configuracin actual an nos tiene atados a make. No tiene que ser as. Podemos cambiar el comando externo que vim ejecuta cuando invocamos :make.

Digamos que queremos usar node directamente, para lograr nuestro objetivo slo tenemos que modificar la variable makeprg.

set makeprg=node

O tambin.

let &makeprg = 'node'

Ahora en lugar de usar :make --silet run-greeting podemos ejecutar :make ./greeting.js :make % si estamos editando greeting.js.

Buscar

El quickfix list no solamente es til para saltar a un error, tambin puede ser un mecanismo conveniente con el cual podemos explorar un proyecto. Mencion antes que vim nos ofrece los comandos :grep y :vimgrep, ellos pueden crear un quickfix list con los resultados de una bsqueda.

vimgrep

Con este comando podremos hacer uso del mecanismo de bsqueda que viene incorporado en vim. Est diseado para ser similar a la herramienta grep, con la pequea diferencia que usa el "intrprete de expresiones regulares" de vim. En otras palabras, con :vimgrep podemos buscar un patrn (una expresin regular) en mltiples archivos. Se usa de la siguiente manera:

:vimgrep /<patrn>/ <archivos>

Los / no son estrictamente obligatorios, pero es una buena idea incluirlos si el patrn que estn buscando contiene algn caracter que cause conflicto con la sintaxis de vim. Por ejemplo:

:vimgrep /create table/ db/**/*.sql

Aqu estaramos realizando una bsqueda del patrn create table en un directorio llamado db, y seleccionando especficamente todos los archivos que terminen con la extensin .sql.

Los delimitadores del patrn de bsqueda no tienen que ser /. Pueden ser cualquier caracter que vim no considere un "identificador," pueden encontrar ms detalles en la documentacin de vim :help isident. Esto puede resultar til si / ya se encuentra en nuestro patrn. Si estuviramos buscando una ruta en nuestro cdigo podramos hacer algo as.

:vimgrep #/home/user/code# scripts/*.sh

Pero qu pasa si queremos ignorar algn directorio de nuestra bsqueda? Hay algo que pueden hacer. Para empezar, podran intentar usar la opcin wildignore. Algo as.

:set wildignore=*/cache/*,*/tmp/*

Hasta donde tengo entendido esto le dice a vim que ignore los directorios cache y tmp de cualquier expansin de ruta o autocompletado. Por ejemplo, al buscar, si usamos un patrn como este **/*.js vim no incluir ningn directorio que contenga en su ruta /cache/ o /tmp/. Entonces, :vimgrep no buscar en esos directorios porque tcnicamente nunca los recibe como parmetro. Quiere decir tambin que esta opcin no es especfica para :vimgrep, tambin puede afectar otros comandos.

Algunas preguntas en stackoverflow sugieren que este mtodo puede que no funcione. En ese caso podramos intentar con una expresin encerrada en (acento grave), las cuales se usan para invocar un comando en nuestro "shell." Podemos hacer cosas interesantes como buscar slo en los archivos que son manejados por git.

:vimgrep /function/ `git ls-files`

En el caso de :vimgrep cualquier comando externo que nos devuelva una lista de archivos es vlido.

grep

Ya habrn notado que vim por defecto asume que tenemos a nuestra disposicin ciertas herramientas. Vimos que por ejemplo asume que tenemos instalado make. Ahora vamos a explorar el comando :grep, que es la manera de vim de integrarse con la herramienta de bsqueda grep. En su mayora funciona igual que :vimgrep con la diferencia de que todos los argumentos deben ser compatibles con la sintaxis de grep. Por ejemplo.

:grep -r "create table" db/**/*.sql

Noten que no estoy usando / sino comillas dobles y le aado el parmetro -r (para habilitar la bsqueda recursiva en directorios), esto es porque el comando :grep lo que hace es invocar un "shell" no interactivo para ejecutar el programa grep y le pasa todos los argumentos tal cual como los escribimos.

Ahora surge la pregunta Cundo debemos usar :grep por encima de :vimgrep? Resulta que :grep es ms rpido y eficiente que :vimgrep. Entonces, :grep es la mejor opcin si tienen que buscar en muchos archivos o archivos que son tienen mucho contenido.

Por otro lado podramos preguntarnos Qu ventajas tiene :vimgrep sobre :grep? No mucho dira yo. Lo primero sera que la sintaxis para las expresiones regulares es la misma que usa vim, si estn familiarizados con esa sintaxis pueden tomar ventaja de sus bondades. Tambin, :vimgrep funciona de manera consistente en todas las plataformas.

Qu pasa si nos encontramos en una plataforma que no tiene instalado grep? :grep con su configuracin por defecto no funcionara. Pero al igual que :make, con :grep podemos modificar el comando externo que vim ejecuta, usando la variable grepprg. Digamos que no tenemos grep sino ripgrep instalado en nuestro sistema, en ese caso podremos hacer esto.

set grepprg=rg\ --vimgrep\ --smart-case\ --follow

Con esto vim usar rg con los parmetros especificados para realizar las bsquedas cuando nosotros usemos :grep.

Invitado especial: FZF

La ltima herramienta de bsqueda que voy a mencionar es fzf.vim. Este es un plugin que nos proporciona una especie de interfaz en la que podemos realizar bsquedas de manera interactiva. No entrar en detalle de cmo funciona o se usa. Slo les dir un tip que yo descubr mucho tiempo despus de empezar a usarlo.

Curiosamente, tambin podemos poblar el quickfix list usando FZF, especficamente con los comandos Rg y Ag. Despus de realizar una bsqueda y se encuentren con su lista de resultados, pueden seleccionar mltiples items (con la tecla tab para seleccionar uno o Alt + a para seleccionar todos) y presionar enter. Eso es todo. Despus el quickfix list debera tener todo lo que ustedes seleccionaron. Esto resulta muy til cuando quieren ejecutar comandos slo en unas partes del cdigo usando :cdo.

Reemplazar

Hablando de :cdo, voy a mostrarles una de las cosas ms tiles que podemos hacer ese comando: buscar y reemplazar un patrn en mltiples archivos. Una tarea bastante comn, y seguramente se han preguntado cmo pueden hacerlo usando vim. La respuesta a eso es el quickfix list y el comando :cdo.

En el caso ms simple donde queremos reemplazar cada instancia de un patrn esto es lo que hacemos:

  • Paso 1:

Buscamos nuestro patrn usando :grep, :vimgrep o cualquier otro comando que pueda generar un quickfix list.

  • Paso 2 (opcional):

Abrimos el quickfix window usando el comando :copen.

  • Paso 3:

Usamos el comando :cdo para ejecutar una accin sobre cada item en el quickfix list. En este caso la accin que queremos hacer es sustituir y en vim lo hacemos con esta sintaxis s/{patrn}/{reemplazo}.

Imaginemos que en nuestro quickfix list tenemos los resultados de esta bsqueda.

:vimgrep node **/*.js

Una vez que tengamos los resultados lo que haremos ser reemplazar node con deno y para eso usamos este comando.

:cdo s/node/deno/ | update

Lo que va a pasar es que vim ejecutar el comando s/node/deno | update en cada item de nuestro quickfix list. En realidad :cdo puede ejecutar cualquier comando vlido de vim. En nuestro ejemplo en concreto lo usamos para hacer dos cosas, reemplazar el texto node y guardar los cambios en el archivo.

Caso avanzado

Digamos que tenemos los resultados de una bsqueda y por supuesto queremos hacer una substitucin, pero tambin queremos filtrar los resultados. En otras palabras queremos reemplazar un patrn pero no queremos reemplazar todas las instancias de ese patrn. Cmo haramos? En ese caso lo que podemos hacer es modificar el quickfix list para que refleje slo los resultados que queremos reemplazar.

Este proceso requiere algo de esfuerzo por nuestra parte. Para empezar necesitamos decirle a vim cmo leer el quickfix list, para que podemos crear versiones modificadas de un quickfix list que existente. Para lograr nuestro objetivo necesitamos agregrar un patrn al errorformat. Entonces en su .vimrc pueden colocar algo como esto.

set errorformat+=%f\|%l\ col\ %c\|%m

An con esto no pueden modificar el quickfix list, vim no los dejar. Cuando quieran eliminar algn resultado deben hacer que el buffer donde est el quickfix list sea modificable. Deben ejecutar este comando.

:set modifiable

Luego eliminan los items que ustedes quieran, pero no ejecuten :cdo todava. Tienen que asegurarse de crear un quickfix list basado en los resultados que quieren. Entonces, luego de hacer sus modificaciones en el buffer ejecutan este comando.

:cgetbuffer

Lo siguiente es asegurarse que estn usando la versin actualizada del quickfix list abriendo y cerrando el quickfix window. Creo que este paso es opcional, pero a m no me gusta arriesgarme. Ejecutan :cclose y luego :copen.

Por ltimo ejecutan el comando para sustituir.

Aqu les dejo un demo de todo el proceso.

Ver en asciinema.

Mejorando la experiencia

Como habrn notado el uso del quickfix list en ocasiones no es muy intuitivo que digamos. Pero podemos mejorarlo. Puedo darles algunas sugerencias que pueden colocar en su .vimrc.

  • Un mejor grep.

Lo primero sera crear un comando que ejecute el comando de bsqueda y que luego abra el quickfix window automticamente. Por suerte para nosotros la documentacin nos da una sugerencia, esta de aqu:

command! -nargs=+ Grep execute 'silent grep! <args>' | copen

Pueden cambiar grep por vimgrep si eso desean. Lo importante aqu es que ahora podrn invocar el comando :Grep (con G mayscula) para realizar sus bsquedas.

  • Navegar por los resultados.

Podramos "navegar" por los items del quickfix list sin siquiera abrir el quickfix window de una manera cmoda con estos atajos.

" Ir a la ubicacin anteriornnoremap [q :cprev<CR>" Ir a la siguiente ubicacinnnoremap ]q :cnext<CR>
  • Manejo de la ventana.

Si tienden a usar el quickfix window con frecuencia ser mejor que se creen unos atajos para abrir y cerrarlo con ms facilidad.

" Mostrar el quickfix windownnoremap <Leader>co :copen<CR>" Ocultar el quickfix windownnoremap <Leader>cc :cclose<CR>
  • El errorformat.

Vamos a asegurarnos de que vim siempre pueda leer el formato del quickfix list si queremos actualizarlo.

augroup quickfix_mapping    autocmd!    autocmd filetype qf setlocal errorformat+=%f\|%l\ col\ %c\|%maugroup END
  • Atajos

Tambin necesitamos atajos que funcionen slo en el quickfix window. Ya saben, para hacer ms cmoda la navegacin y tambin hacer que el "caso avanzado" que les present no sea tan engorroso.

function! QuickfixMapping()  " Ir a la ubicacin anterior y mantenerse en el quickfix window  nnoremap <buffer> K :cprev<CR>zz<C-w>w  " Ir a la siguiente ubicacin y mantenerse en el quickfix window  nnoremap <buffer> J :cnext<CR>zz<C-w>w  " Haz que el quickfix list sea modificable  nnoremap <buffer> <leader>u :set modifiable<CR>  " Actualiza el quickfix window  nnoremap <buffer> <leader>w :cgetbuffer<CR>:cclose<CR>:copen<CR>  " Buscar y reemplazar  nnoremap <buffer> <leader>r :cdo s/// \| update<C-Left><C-Left><Left><Left><Left>endfunctionaugroup quickfix_mapping    autocmd!    autocmd filetype qf call QuickfixMapping()augroup END
  • Ahora todo junto.
" Comando Grep que busca y abre el quickfix windowcommand! -nargs=+ Grep execute 'silent grep! <args>' | copen" Ir a la ubicacin anteriornnoremap [q :cprev<CR>" Ir a la siguiente ubicacinnnoremap ]q :cnext<CR>" Mostrar el quickfix windownnoremap <Leader>co :copen<CR>" Ocultar el quickfix windownnoremap <Leader>cc :cclose<CR>function! QuickfixMapping()  " Ir a la ubicacin anterior y mantenerse en el quickfix window  nnoremap <buffer> K :cprev<CR>zz<C-w>w  " Ir a la siguiente ubicacin y mantenerse en el quickfix window  nnoremap <buffer> J :cnext<CR>zz<C-w>w  " Haz que el quickfix list sea modificable  nnoremap <buffer> <leader>u :set modifiable<CR>  " Actualiza el quickfix window  nnoremap <buffer> <leader>w :cgetbuffer<CR>:cclose<CR>:copen<CR>  " Buscar y reemplazar  nnoremap <buffer> <leader>r :cdo s/// \| update<C-Left><C-Left><Left><Left><Left>endfunctionaugroup quickfix_mapping  autocmd!  " Asignar los atajos especficos para el quickfix window  autocmd filetype qf call QuickfixMapping()  " Agregar formato para modificar el quickfix list  autocmd filetype qf setlocal errorformat+=%f\|%l\ col\ %c\|%maugroup END

Plugins

Si estn dispuestos y saben cmo instalar plugins en vim yo recomendara estos:

Este hace que el quickfix window tenga un comportamiento ms intuitivo. Por ejemplo, puede hacer que se abra automticamente cuando ejecutamos :grep, :vimgrep e incluso :make sin tener que crear otros comandos. Pero si queremos disfrutar de algunas de sus bondades tenemos que crear nuestros propios atajos.

  • Abrir o cerrar el quickfix window.
nmap <Leader>cc <Plug>(qf_qf_toggle)
  • Navegar por los resultados
" Ir a la ubicacin anteriornmap [q <Plug>(qf_qf_previous)zz" Ir a la siguiente ubicacinnmap ]q <Plug>(qf_qf_next)zzfunction! QuickfixMapping()  " Ir a la ubicacin anterior y mantenerse en el quickfix window  nmap <buffer> K <Plug>(qf_qf_previous)zz<C-w>w  " Ir a la siguiente ubicacin y mantenerse en el quickfix window  nmap <buffer> J <Plug>(qf_qf_next)zz<C-w>wendfunctionaugroup quickfix_mapping    autocmd!    autocmd filetype qf call QuickfixMapping()augroup END

La diferencia entre estos comandos y los que trae vim por defecto es que los de vim-qf no dan error cuando llegamos al final de la lista. Es decir que si estamos visualizando el ltimo item y usamos ]q para ir al siguiente, en lugar de tener un error este comando nos lleva al primer item del quickfix list.

Este plugin hace que todos los comandos que ejecutamos en el "caso avanzado" queden obsoletos. Nos da la posibilidad de modificar el quickfix window como un buffer normal. Pero eso no es todo, cada cambio que guardemos quedar "reflejado" en el archivo original.

Tomemos el ejemplo que mostr en el demo. Digamos que tenemos esto en el quickfix list.

./test dir/a-file.txt|1 col 11| nnoremap <leader>f :FZF./test dir/a-file.txt|2 col 11| nnoremap <leader>ff :FZF<CR>./test dir/a-file.txt|3 col 11| nnoremap <leader>fh :History<CR>./test dir 2/another-file.txt|1 col 11| nnoremap <leader>? :Maps<CR>./test dir 2/another-file.txt|2 col 11| nnoremap <leader>bb :Buffers<CR>

Y digamos que modifico el primer y cuarto item en la lista de manera manual.

- ./test dir/a-file.txt|1 col 11| nnoremap <leader>f :FZF+ ./test dir/a-file.txt|1 col 11| nnoremap <AAA>f :FZF  ./test dir/a-file.txt|2 col 11| nnoremap <leader>ff :FZF<CR>  ./test dir/a-file.txt|3 col 11| nnoremap <leader>fh :History<CR>- ./test dir 2/another-file.txt|1 col 11| nnoremap <leader>? :Maps<CR>+ ./test dir 2/another-file.txt|1 col 11| nnoremap <BBB>? :Maps<CR>  ./test dir 2/another-file.txt|2 col 11| nnoremap <leader>bb :Buffers<CR>

Si guardo estos cambios con el comando :write (o :w para abreviar) se quedarn reflejados en sus lugares respectivos en cada archivo. Esto resulta sumamente poderoso porque ahora la flexibilidad del quickfix list est limitada a nuestro conocimiento sobre vim.

Cualquier truco que conozcan para modificar varios fragmentos de cdigo deberan funcionar con este plugin. Por ejemplo si queremos replicar el mismo efecto que mostr en el demo anterior lo que tenemos que hacer es esto:

  • Borramos las lneas que no queremos modificar.
./test dir/a-file.txt|1 col 11| nnoremap <leader>f :FZF./test dir/a-file.txt|3 col 11| nnoremap <leader>fh :History<CR>./test dir 2/another-file.txt|1 col 11| nnoremap <leader>? :Maps<CR>
  • Usamos el comando de substitucin "normal."
:%s/leader/localleader/g

Despus de eso el quickfix list debera quedar en este estado.

./test dir/a-file.txt|1 col 11| nnoremap <localleader>f :FZF./test dir/a-file.txt|3 col 11| nnoremap <localleader>fh :History<CR>./test dir 2/another-file.txt|1 col 11| nnoremap <localleader>? :Maps<CR>
  • Guardamos el cambio.
:write

Y eso es todo.

Conclusin

Nos hemos familiarizado con el quickfix list y sus utilidades ms comunes.

Sabemos que podemos usar :make para invocar cualquier compilador o comando externo que pueda ejecutar nuestro cdigo y darnos mensajes de error. Tenemos las herramientas para hacer que vim entienda un mensaje de error y pueda incorporar la informacin relevante al quickfix list.

Vimos que podemos usar :vimgrep y :grep para buscar patrones en mltiples archivos. Tambin pudimos explorar diferentes formas de reemplazar el texto que estamos buscando, con casos simples y otros un poco ms complejos. Con estos casos pudimos aprender cmo hacer la sustitucin sin usar plugins y tambin cmo hacerlo con la ayuda de un par de plugins.

Por ltimo aprendimos sobre comandos, mtodos y configuraciones que podemos agregar en nuestro .vimrc para hacer que la experiencia al usar el quickfix list sea ms placentera e intuitiva.

Fuentes

Gracias por su tiempo. Si este artculo les pareci til y quieren apoyar mis esfuerzos para crear ms contenido, pueden dejar una propina en buymeacoffee .

buy me a coffee


Original Link: https://dev.to/vonheikemen/vim-y-el-quickfix-list-saltar-a-una-ubicacion-buscar-y-reemplazar-en-multiples-archivos-y-otras-curiosidades-13n4

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To