let b:commentChar='//'
: Esto crea una variable en vim. el b
aquí se refiere al alcance, que en este caso está contenido en el búfer, es decir, el archivo abierto actualmente. Sus caracteres de comentario son cadenas y deben estar entre comillas, las comillas no son parte de lo que se sustituirá al alternar comentarios.
autocmd BufNewFile,BufReadPost *...
: Los comandos automáticos se disparan en diferentes cosas, en este caso, se disparan cuando un nuevo archivo o el archivo de lectura termina con una cierta extensión. Una vez activado, ejecute el siguiente comando, que nos permite cambiar elcommentChar
de archivo dependiendo. Hay otras formas de hacer esto, pero son más confusas para los novatos (como yo).
function! Docomment()
: Las funciones se declaran comenzando function
y terminando con endfunction
. Las funciones deben comenzar con una capital. los !
asegura que esta función sobrescribe los anteriores funciones definidas como Docomment()
con esta versión de Docomment()
. Sin el !
, tuve errores, pero eso podría deberse a que estaba definiendo nuevas funciones a través de la línea de comando vim.
execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
: Ejecutar llama a un comando. En este caso, estamos ejecutando substitute
, que puede tomar un rango (por defecto, esta es la línea actual), como %
para todo el búfer o '<,'>
para la sección resaltada. ^\s*
es regex para que coincida con el inicio de una línea seguida de cualquier cantidad de espacio en blanco, que luego se agrega a (debido a &
). El .
que aquí se utiliza para la concatenación de cadenas, ya que escape()
no se puede ajustar entre comillas. escape()
le permite escapar del personaje commentChar
que coincide con los argumentos (en este caso, \
y/
) al anteponerlos con un \
. Después de esto, volvemos a concatenar con el final de nuestra substitute
cadena, que tiene ele
bandera. Esta bandera nos permite fallar en silencio, lo que significa que si no encontramos una coincidencia en una línea determinada, no gritaremos al respecto. En general, esta línea nos permite poner un carácter de comentario seguido de un espacio justo antes del primer texto, lo que significa que mantenemos nuestro nivel de sangría.
execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
: Esto es similar a nuestro último gran comando largo. Único a este, tenemos \v
, lo que asegura que no tenemos que escapar de nuestro ()
, y 1
, que se refiere al grupo que hicimos con nuestro ()
. Básicamente, estamos haciendo coincidir una línea que comienza con cualquier cantidad de espacio en blanco y luego nuestro carácter de comentario seguido de cualquier cantidad de espacio en blanco, y solo mantenemos el primer conjunto de espacios en blanco. Nuevamente, e
dejemos de fallar en silencio si no tenemos un carácter de comentario en esa línea.
let l:line=getpos("'<")[1]
: establece una variable muy similar a lo que hicimos con nuestro carácter de comentario, pero se l
refiere al ámbito local (local para esta función). getpos()
obtiene la posición de, en este caso, el inicio de nuestro resaltado, y el[1]
significa que solo nos importa el número de línea, no otras cosas como el número de columna.
if match(getline(l:line), '^\s*'.b:commentChar)>-1
: ya sabes cómo if
funciona. match()
verifica si lo primero contiene lo segundo, por lo que tomamos la línea en la que comenzamos a resaltar y verificamos si comienza con un espacio en blanco seguido de nuestro carácter de comentario. match()
devuelve el índice donde esto es cierto, y -1
si no se encontraron coincidencias. Como if
evalúa todos los números distintos de cero para que sean verdaderos, tenemos que comparar nuestra salida para ver si es mayor que -1. La comparación en vim
devuelve 0 si es falso y 1 si es verdadero, que es lo que if
quiere ver para evaluar correctamente.
vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>
: vnoremap
significa asignar el siguiente comando en modo visual, pero no asignarlo de forma recursiva (es decir, no cambiar ningún otro comando que pueda usarse de otras maneras). Básicamente, si eres un novato vim, siempre úsalo noremap
para asegurarte de no romper cosas. <silent>
significa "No quiero tus palabras, solo tus acciones" y le dice que no imprima nada en la línea de comando. <C-r>
es lo que estamos asignando, que es ctrl + r en este caso (tenga en cuenta que todavía puede usar Cr normalmente para "rehacer" en modo normal con esta asignación). C-u
es un poco confuso, pero básicamente se asegura de que no pierdas el rastro de tu resaltado visual (según esta respuesta , tu comando comienza con '<,'>
lo que queremos).call
aquí solo le dice a vim que ejecute la función que nombramos, y se <cr>
refiere a enter
presionar el botón. Tenemos que presionarlo una vez para llamar realmente a la función (de lo contrario, simplemente escribimos call function()
en la línea de comando, y debemos presionarlo nuevamente para que nuestros sustitutos pasen por todo el camino (no estoy seguro de por qué, pero lo que sea).