Pourquoi: bd # supprime-t-il le tampon actuel alors qu'il n'existe aucun autre tampon?

9

Voici comment je reproduis le comportement que j'observe.

Tout d'abord, j'entre cette commande:

echo aaaaa > a
vim a

Dans Vim, j'entre ces commandes:

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

Voici la sortie des trois commandes ci-dessus:

:ls
  1 %a   "a"                            line 1

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

:echo bufname('#')

La bufname('#')commande ne produit aucune sortie.

Maintenant j'entre cette commande:

:bd #

Le tampon actuel est supprimé et il est remplacé par un tampon "[No Name]":

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

Je m'attendais à obtenir l' E194erreur lors de l'exécution :bd #. Pourquoi at-il plutôt supprimé le tampon actuel?

J'utilise VIM - Vi IMproved 8.0.

Apprenant solitaire
la source
1
C'est un point intéressant. Vous pouvez mentionner dans votre question que c'est également le cas NVIM v0.3.0-dev, j'ai vérifié.
klaus
@LoneLearner Je n'ai pas vraiment répondu à cette question à cause de la prime mais si vous en offrez une, ce serait bien si vous l'attribuiez à une réponse méritante ... hélas, vous ne vous êtes pas connecté presque semaine et la période de prime est terminée ...
Couche B
1
@BLayer Désolé, j'ai oublié d'attribuer la prime. Vous avez écrit une réponse fantastique. Une fois que j'aurai suffisamment de points sur ce site Stack Exchange, je vais commencer une autre prime pour cette question et vous attribuer la prime. J'espère que cela corrigera mon erreur. Merci pour l'excellente réponse que vous avez écrite.
Lone Learner
@LoneLearner Hé, vous êtes les bienvenus et pas de soucis. J'apprécie votre commentaire. Ne vous inquiétez pas de la prime. Comme je l'ai dit, ce n'était pas une question de points. Je voulais juste vous donner une idée de la prochaine fois que vous offririez une prime. Mettez les points d'ici vers cela. À votre santé!
Couche B du

Réponses:

7

Preuve

Parce qu'il n'y a pas de fichier alternatif, vous exécutez simplement plain ol ' :bd, supprimant le tampon actuel ... essayez-le sans #et vous verrez que le résultat est le même. Une chose similaire se produit avec :buffer, :sbufferet au moins quelques autres commandes qui acceptent #comme argument: elles se comportent silencieusement comme si aucun argument n'était passé.

Dans le même sens, si vous essayez de :bunload #vous obtenez cette erreur: E90: Cannot unload last buffer. Exécutez :bunloadsans arguments et, encore une fois, vous obtiendrez le même résultat.

Les documents

Nous avons donc des preuves qui #sont remplacées par "rien" (probablement une chaîne vide). Où allons-nous à partir d'ici? J'ai fouillé les fichiers d'aide pendant un certain temps en essayant de trouver la mention de ce comportement. Il n'y avait rien d'explicite mais :h cmdline-linesdit (faites défiler une page ou deux) ...

Lorsque le caractère '%' ou '#' est utilisé là où un nom de fichier est attendu, ils sont étendus au nom de fichier actuel et alternatif.

Je l'ai lu comme Vim mettant à #travers la expand()fonction (ie expand('#')) ou au moins le même code sous-jacent utilisé là-bas.

:h expand() dit:

Développez .. mots-clés spéciaux. .. Lorsque vous utilisez '%' ou '#' et que le nom de fichier actuel ou alternatif n'est pas défini, une chaîne vide est utilisée.

Sonne familier.

Le code

Maintenant, rien de ce qui précède n'est définitif ou ne donne une idée de pourquoi? donc j'ai passé plus de temps à creuser ... cette fois dans le code. Mon C est très rouillé et je n'ai pas de bons outils installés mais j'ai réussi à trouver une fonction qui fait une configuration pour :bdeleteappelé do_bufdel(). Cela envoie des arguments de ligne de commande par buflist_findpat()lesquels, s'il #est rencontré, renvoie une valeur curwin->w_alt_fnum. C'est le "numéro de tampon" du tampon alternatif ... qui ne peut pas être une valeur positive dans notre scénario. (Il n'y a pas de vérification pour savoir si le fichier alt est valide / existe avant que cette valeur de retour ne soit sélectionnée.)

Un retour en arrière dans do_bufdel()une vérification est effectué par rapport à cette valeur de retour pour un numéro de tampon inférieur à 0, auquel cas la boucle de traitement des paramètres est interrompue. Cela n'entraînerait aucun paramètre présenté au :bdeletecode de base ... ce qui correspond exactement à mes intuitions précédentes.

Et après?

Il semble fonctionner comme prévu car je n'ai rien vu qui ressemblait à un bug clair. Peut-être un péché d'omission, cependant ... un cas d'angle qui a été négligé et n'a donc aucune manipulation gracieuse. Mais seuls les développeurs qui ont écrit cela savent avec certitude. La dernière étape serait donc d'essayer d'obtenir leur avis. Comme l'a dit Christian B., demander sur la liste vim-dev est la voie à suivre.

(Notez que buflist_findpat()est une fonction d'utilité de sorte qu'il ne nécessiterait pas un étirement de l'imagination de supposer que :bunload, :bufferetc. utilisent, aussi ... qui expliquerait leur comportement commun par rapport à #.)

Couche B
la source
Je pense qu'une fonction de plus pour simplement vérifier si un tampon étendu existe ou non ferait l'affaire. Êtes-vous sûr que c'était censé être prévu? Je pense que cela devrait être répertorié comme un bug.
klaus
Je pense que vos recherches sont correctes. BTW: Je ne pense pas que ce soit en fait un bug.
Christian Brabandt
Je viens de reformuler un peu ma conclusion ... cela ne ressemble pas à un bug dur. OTOH, si on y pense, on pourrait conclure qu'il a besoin d'une meilleure manipulation. Seul le développeur est probablement au courant.
B Layer
Ouais, on pourrait demander sur la liste vim-dev pour être sûr.
Christian Brabandt