One
? ¿donut
? Bueno, estos nombre podrían ser obvios para el desarrollador o desarrolladora que escribieran el código hace tiempo, pero ahora esas personas ya no están aquí y te corresponde a ti entender estas líneas de código tan enrevesadas. Una manera de ayudar a entender esto es seguir el código fuente donde One
y donut
están definidas.fzf
como con grep
(o vimgrep
), pero en este caso es más rápido utilizar etiquetas.Ctrl-]
estando en el modo normal. Dentro del archivo two.rb
, ve a la línea donde aparece one.donut
y posiciona el cursor encima de la palabra donut
. Pulsa Ctrl-]
.R
le dice a ctags que ejecute un escaneo desde tu ubicación actual (.
). Ahora se debería poder ver un archivo tags
en tu directorio actual. Dentro del archivo verás algo parecido a esto:!TAG_FILE...
) son normalmente controlados por el generador ctags. No entraré en detalle sobre eso aquí, pero ¡no dudes en echar un vistazo a su documentación! La lista de etiquetas es una lista de todas las definiciones indexadas por ctags.two.rb
, y coloca el cursor encima de la palabra donut
, y escribe Ctrl-]
. Vim te llevará al archivo one.rb
a la línea donde está def donut
. ¡Eureka! ¿Pero cómo hizo esto Vim?donut
:tagname
, un nombre de archivo de la etiqueta o tagfile
, una dirección de etiqueta o tagaddress
y opciones de la etiqueta. (N. del T: Me referiré por sus nombres en inglés porque quizás es la nomenclatura más utilizada en los tutoriales y por quienes lo usan).donut
es el tagname
. Cuando tu cursor está encima de la palabra "donut", Vim busca el archivo dentro del archivo de la etiqueta una línea que contenga la cadena "donut".one.rb
es el tagfile
. Vim busca un archivo llamado one.rb
./^ def donut$/
es el tagaddress
. /.../
es un indicador patrón. ^
es un patrón para el primer elemento de una línea. Está seguido por dos espacios y después la cadena def donut
. Finalmente, $
es el patrón para el último elemento de una línea.f class:One
es la opción de la etiqueta que le dice a Vim que la función donut
es una función (f
) y es parte de la clase One
.donut
:One
es el tagname
. Ten en cuenta que con las etiquetas, el primer escaneo tiene en cuenta las mayúsculas y minúsculas. Si tienes One
y one
en la lista, Vim priorizará One
sobre one
.one.rb
es el tagfile
. Vim buscará un archivo one.rb
./^class One$/
es el patrón de tagaddress
. Vim buscará una línea que comience (^
) con class
y termine ($
) con One
.c
es una de las opciones de etiqueta posible. Como One
es una clase de Ruby y no un procedimiento, lo marca con una c
.tags
, es creado después de ejecutar ctags -R .
. ¿Cómo sabe Vim dónde buscar el archivo de etiquetas?:set tags?
, podrás ver tags=./tags,tags
(dependiendo de tus ajustes de Vim, esto podría ser diferente). Aquí Vim busca todas las etiquetas en la ruta del archivo actual para el caso de ./tags
y dentro del directorio actual (la raíz de tu proyecto) para el caso de tags
../tags
, Vim primero buscará un archivo de etiquetas dentro de la ruta de tu archivo actual independientemente de lo anidado que esté, después buscará un archivo de etiquetas del directorio actual (la raíz del proyecto). Vim detiene la búsqueda después de encontrar la primera coincidencia.'tags'
ha dicho tags=./tags,tags,/user/iggy/mytags/tags
, entonces Vim también buscará en el directorio /user/iggy/mytags
un archivo de etiquetas después de finalizar la búsqueda en los directorios ./tags
y tags
. No es necesario que almacenes tu archivo de etiquetas dentro de tu proyecto, puedes mantenerlo de manera separada.node_modules
pueden ser muy grandes. Imagina si tienes cinco subproyectos y cada uno contiene su propio directorio node_modules
. Si ejecutas ctags -R .
, ctags tratará de escanear todos los cinco node_modules
. Probablemente quizás no necesites ejecutar ctags en node_modules
.node_modules
, ejecuta:exclude
múltiples veces:--exclude
es la opción que debes utilizar.Ctrl-]
, pero vamos a aprender unos cuantos trucos más. La tecla para saltar a una etiqueta Ctrl-]
tiene un modo alternativo para la línea de comandos: :tag mi-etiqueta
. Si ejecutas lo siguiente:donut
, de igual manera que si hubieras pulsado Ctrl-]
en una cadena donde aparezca "donut". También puedes autocompletar el argumento con la tecla <Tab>
:one.rb
tenemos lo siguiente:two.rb
:ctags -R .
ya que ahora aparecen muchos procedimientos nuevos. Tienes dos instancias del procedimiento pancake
. Si estás dentro del archivo two.rb
y pulsas Ctrl-]
, ¿qué es lo que ocurriría?def pancake
dentro de two.rb
, no a def pancake
dentro de one.rb
. Esto es debido a que Vim ve el procedimiento pancake
dento del archivo two.rb
como de mayor prioridad que el del procedimiento dentro del archivo pancake
.pancake
dentro de two.rb
sobre el procedimiento pancake
dentro del archivo one.rb
. Hay algunas excepciones a esta lista de prioridades que acabamos de ver, dependiendo de tus ajustes de 'tagcase'
, 'ignorecase'
y 'smartcase'
, pero no las veremos en este caso. Si estás interesado en aprender más, echa un vistazo a este capítulo de la ayuda de Vim :h tag-priority
.pancake
que está dentro del archivo one.rb
y no a la que está dentro del archivo two.rb
. Para hacer eso, puedes utilizar :tselect
. Ejecuta:2
y después pulsas <Enter>
, Vim saltará al procedimiento del archivo one.rb
. Si escribes 1
y pulsas <Enter>
, Vim saltará al archivo two.rb
.pri
. En esta vemos F C
en la primera ocurrencia y F
en la segunda. Esto es lo utiliza Vim para determinar la prioridad de la etiqueta. F C
significa que ha encontrado una coincidencia completa (en inglés fully-matched F
) de una etiqueta global en el archivo actual (en inglés current C
). Si solo aparece F
esto significa que solo ha encontrado una etiqueta de una coincidencia completa. F C
siempre tiene una prioridad mayor que F
.:tselect donut
, Vim también te preguntará que escojas una etiqueta de las disponibles, aunque solo hay una opción para escoger. ¿Hay alguna manera apropiada para hacer que Vim solo pregunte qué etiqueta escoger cuando haya múltiples entre las que escoger y que salte inmediatamente a una etiqueta cuando solo haya una opción?:tjump
. Ejecuta:donut
en el archivo one.rb
, de manera similar a si ejecutáramos :tag donut
. Ahora ejecuta::tselect pancake
. Con tjump
tienes lo mejor de ambos métodos.tjump
: g Ctrl-]
. Personalmente me gusta más utilizar g Ctrl-]
que Ctrl-]
.Ctrl-X
como un submodo para realizar varias acciones de autocompletado. Un submodo de autocompletado que no mencioné fue Ctrl-]
. Si pulsas Ctrl-X Ctrl-]
mientras estás en el modo insertar, Vim utilizará el archivo de etiquetas para el autocompletado.Ctrl-X Ctrl-]
, verás lo siguiente::tags
. Si primero habías hecho un salto a la etiqueta pancake
, seguido por donut
y ejecutas :tags
, verás lo siguiente:>
. Muestra tu posición actual en la pila. Para retrasar un puesto el puntero de la posición hasta el elemento anterior, puedes ejecutar el comando :pop
. Pruébalo y después vuelve a ejecutar :tags
de nuevo:>
ahora está en la línea dos, apuntando al elemento donut
. Ejecuta pop
una vez más y comprueba de nuevo la posición con el comando :tags
:Ctrl-T
para conseguir el mismo efecto que si ejecutaras :pop
.pancake
y ahora se llama waffle
, el archivo de etiquetas no sabe que el procedimiento pancake
había sido cambiado de nombre. Todavía es almacenado como pancake
en la lista de etiquetas. Tienes que ejecutar ctags -R .
para crear y actualizar el archivo de etiquetas. Volver a crear un nuevo archivo de etiquetas puede ser una tarea incómoda.autocmd
) para ejecutar cualquier comando ante la aparición de un evento. Puedes utilizar esto para generar etiquetas cada vez que guardes el archivo. Ejecuta:autocmd
es el método de comandos automáticos de Vim. Acepta cualquier nombre de evento, patrón de archivo y un comando.BufWritePost
es un evento para guardar un buffer. Cada vez que guardas un archivo, se lanza un evento BufWritePost
..rb
es el patrón de archivo para archivos ruby (rb
).silent
es parte del comando que estás pasando al comando automático. Sin este, Vim mostrará press ENTER or type command to continue
cada vez que se dispare el comando automático.!ctags -R .
es el comando a ejecutar. Recuerda que !cmd
desde dentro del propio Vim ejecuta cualquier comando de la terminal.ctags -R .
.two.rb
:waffle
es parte de las etiquetas. ¡Conseguido!functionFood
, podrás leerlo fácilmente saltando a la parte del código donde está definido. Dentro de este, también puedes descubrir que también llama a functionBreakfast
. Vas hasta su definición y descubre que a su vez llama a functionPancake
. El gráfico de saltos y llamadas tendría el siguiente esquema::h tags
. Ahora que ya sabes utilizar las etiquetas, vamos a explorar otra funcionalidad diferente: el plegado o folding por su término en inglés.