¿Por qué: bd # elimina el búfer actual cuando no existe un búfer alternativo?

9

Así es como reproduzco el comportamiento que estoy observando.

Primero, ingreso este comando:

echo aaaaa > a
vim a

En Vim, ingreso estos comandos:

:ls
:e #
:echo bufname('#')

Aquí está la salida de los tres comandos anteriores:

:ls
  1 %a   "a"                            line 1

:e #
E194: No alternate file name to substitute for '#'

:echo bufname('#')

El bufname('#')comando no produce salida.

Ahora ingreso este comando:

:bd #

El búfer actual se elimina y se reemplaza con un búfer "[Sin nombre]":

:ls
  2 %a   "[No Name]"                    line 1

Esperaba recibir el E194error al ejecutar :bd #. ¿Por qué eliminó el búfer actual en su lugar?

Estoy usando VIM - Vi IMproved 8.0.

Aprendiz solitario
fuente
1
Ese es un punto interesante. Puede mencionar en su pregunta que este también es el caso NVIM v0.3.0-dev, lo verifiqué.
Klaus
@LoneLearner Realmente no respondí esto debido a la recompensa, pero si vas a ofrecer uno, sería bueno si lo otorgases a una respuesta que merezca ... por desgracia, no has iniciado sesión casi un semana y el período de recompensa ha terminado ...
B Layer
1
@BLayer Lo siento, olvidé otorgar la recompensa. Has escrito una respuesta fantástica. Una vez que tenga suficientes puntos en este sitio de Stack Exchange, comenzaré otra recompensa por esta pregunta y le otorgaré la recompensa. Espero que eso solucione mi error. Gracias por la gran respuesta que has escrito.
Aprendiz solitario el
@LoneLearner Hola, de nada y no te preocupes. Agradezco tu comentario. No te preocupes por la recompensa. Como dije, no se trataba de los puntos. Solo quería avisarle la próxima vez que ofrezca una recompensa. Pon los puntos desde aquí hacia eso. ¡Salud!
Capa B el

Respuestas:

7

Evidencia

Debido a que no hay un archivo alternativo, en realidad solo está ejecutando simplemente ol ' :bd, eliminando el búfer actual ... pruébelo sin #y verá que el resultado es el mismo. Algo similar sucede con :buffer, :sbuffery al menos un par de otros comandos que aceptan #como argumento: se comportan silenciosamente como si no se hubieran pasado argumentos.

En el mismo sentido, si se intenta :bunload #obtiene este error: E90: Cannot unload last buffer. Corre :bunloadsin argumentos y, una vez más, obtendrás el mismo resultado.

Los documentos

Entonces tenemos evidencia de que #está siendo reemplazado por "nada" (probablemente una cadena vacía). ¿A dónde vamos desde aquí? Revisé los archivos de ayuda por un tiempo tratando de encontrar mención de este comportamiento. No había nada explícito pero :h cmdline-linesdice (desplazarse hacia abajo una página o dos) ...

Cuando se usa el carácter '%' o '#' donde se espera un nombre de archivo, se expanden al nombre de archivo actual y alternativo.

Lo leí como Vim poniendo a #través de la expand()función (es decir expand('#')) o al menos el mismo código subyacente utilizado allí.

:h expand() dice:

Expandir .. palabras clave especiales. .. Cuando se usa '%' o '#', y el nombre de archivo actual o alternativo no está definido, se usa una cadena vacía.

Suena familiar.

El código

Ahora nada de lo anterior es definitivo o da una idea de por qué. así que pasé más tiempo cavando ... esta vez en el código. Mi C está muy oxidado y no tengo ninguna buena herramienta instalada, pero logré encontrar una función que haga algunas configuraciones para :bdeletellamar do_bufdel(). Esto envía argumentos de línea de comando a través de los buflist_findpat()cuales, si #se encuentra, devuelve el valor curwin->w_alt_fnum. Ese es el "número de búfer" del búfer alternativo ... que no puede ser un valor positivo en nuestro escenario. (No se verifica si el archivo alt es válido / existe antes de que se seleccione ese valor de retorno).

Retroceder en do_bufdel()una verificación se realiza contra ese valor de retorno para un número de búfer menor que 0, en cuyo caso se rompe el bucle de procesamiento de parámetros. Eso daría como resultado que no se presenten parámetros al :bdeletecódigo central ... que está en línea con mis intuiciones anteriores.

¿Que sigue?

Parece estar funcionando según lo diseñado, ya que no vi nada que pareciera un error claro. Posiblemente pecado de omisión, sin embargo ... un caso de esquina que se ha pasado por alto y, por lo tanto, no tiene un manejo elegante. Pero solo los desarrolladores que escribieron esto lo saben con certeza. Entonces, el paso final sería tratar de obtener su opinión. Como Christian B. dijo, preguntar en la lista vim-dev es el camino a seguir.

(Tenga en cuenta que buflist_findpat()es una función de utilidad por lo que no requeriría un esfuerzo de imaginación para suponer que :bunload, :buffer, etc., están usando, también ... que explicaría su comportamiento común con respecto a #.)

Capa B
fuente
Creo que una función más para simplemente verificar si existe un buffer expandido o no haría el trabajo. ¿Estás seguro de que esto se suponía que era por diseño? Creo que esto debería aparecer como un error.
Klaus
Creo que tu investigación es correcta. Por cierto: no creo que esto sea realmente un error.
Christian Brabandt
Acabo de reformular un poco mi conclusión ... no parece un error difícil. OTOH, si uno lo piensa, podría concluir que necesita un mejor manejo. Probablemente solo el desarrollador lo sepa con certeza.
B Layer
Sí, uno podría preguntar en la lista vim-dev para asegurarse.
Christian Brabandt