J'ai un autocmd pour les fichiers TeX et Markdown pour enregistrer le fichier automatiquement. Rien d'inhabituel:
autocmd CursorHold *.tex,*.md w
Cependant, à mesure que les paramètres personnalisés de ces fichiers augmentaient, je les ai séparés ftplugin/tex.vim
et ftplugin/markdown.vim
:
" ftplugin/tex.vim
autocmd CursorHold *.tex w
" ftplugin/markdown.vim
autocmd CursorHold *.md w
Maintenant, ces fichiers proviennent uniquement des fichiers appropriés, donc la correspondance de modèle est redondante. Apparemment, autocmd
s peut être tampon local. De :h autocmd-buffer-local
:
Buffer-local autocommands are attached to a specific buffer. They are useful
if the buffer does not have a name and when the name does not match a specific
pattern. But it also means they must be explicitly added to each buffer.
Instead of a pattern buffer-local autocommands use one of these forms:
<buffer> current buffer
<buffer=99> buffer number 99
<buffer=abuf> using <abuf> (only when executing autocommands)
<abuf>
Cela semble être destiné à une telle utilisation. Maintenant, les deux ftplugin/tex.vim
et ftplugin/markdown.vim
peuvent avoir:
autocmd CursorHold <buffer> w
Je ne suis pas vraiment préoccupé par l'extension réelle tant que le type de fichier est correct, donc cela me permet d'avoir à se soucier *.md
et *.markdown
et quelles que soient les autres extensions sont valables pour Markdown.
Cette utilisation est-elle <buffer>
correcte? Y a-t-il des pièges dont je devrais être conscient? Est-ce que les choses vont mal tourner si j'essuie un tampon et en ouvre un autre (j'espère que les chiffres ne se heurteront pas, mais…)?
up
(abréviation de:update
) serait mieux quew
dans votre autocmd (évitez les écritures inutiles).w
échoué. À plusieurs reprises.:up
ne fait rien dans ce cas. :)Réponses:
Je pense que c'est correct, mais vous avez juste besoin de l'envelopper dans un augroup, et effacer ce dernier, pour vous assurer que l'autocmd ne sera pas dupliqué à chaque fois que vous exécutez une commande qui recharge le même tampon.
Comme vous l'avez expliqué, le modèle spécial
<buffer>
vous permet de vous fier au mécanisme de détection de type de fichier intégré, implémenté à l'intérieur du fichier$VIMRUNTIME/filetype.vim
.Dans ce fichier, vous pouvez trouver les autocmds intégrés de Vim qui sont responsables de la définition du type de fichier correct pour tout tampon donné. Par exemple, pour le démarque:
Dans votre plugin de type de fichier, vous pouvez copier les mêmes modèles pour chaque autocmd que vous installez. Par exemple, pour enregistrer automatiquement le tampon lorsque votre curseur n'a pas bougé pendant quelques secondes:
Mais
<buffer>
est beaucoup moins verbeux:De plus, si un jour une autre extension est valide et
$VIMRUNTIME/filetype.vim
est mise à jour pour l'inclure, vos autocmds ne seront pas informés. Et vous devrez mettre à jour tous leurs modèles dans vos plugins de type de fichier.Je ne suis pas sûr mais je ne pense pas que Vim puisse réutiliser le numéro de tampon d'un tampon effacé. Je n'ai pas trouvé la section pertinente de l'aide, mais j'ai trouvé ce paragraphe sur vim.wikia.com :
De plus, comme @ Tumbler41 l'a expliqué, lorsque vous effacez un tampon, ses autocmds sont supprimés. De
:h autocmd-buflocal
:Si vous voulez vous vérifier, vous pouvez le faire en augmentant le niveau de verbosité de Vim à 6. Vous pouvez le faire temporairement, juste pour une commande, en utilisant le
:verbose
modificateur. Ainsi, à l'intérieur de votre tampon de démarque, vous pouvez exécuter:Ensuite, si vous consultez les messages de Vim:
Vous devriez voir une ligne ressemblant à ceci:
Où
42
était le numéro de votre tampon de démarque.Il y a 3 situations que je considérerais comme des pièges et qui impliquent le schéma spécial
<buffer>
. Dans deux d'entre eux,<buffer>
peut être un problème, dans l'autre, c'est une solution.Piège 1
Tout d'abord, vous devez être prudent avec la façon dont vous effacez les augroups de vos autocmds tampon-local. Vous devez être familiarisé avec cet extrait:
Donc, vous pourriez être tenté de l'utiliser pour vos autocmds tampon-local, non modifié, comme ceci:
Mais cela aura un effet indésirable. La première fois que vous chargez un tampon de démarque, appelons-le
A
, son autocmd sera correctement installé. Ensuite, lorsque vous rechargerezA
, l'autocmd sera supprimé (à cause deautocmd!
) et réinstallé. Ainsi, l'augroup empêchera correctement la duplication de l'autocmd.Supposons maintenant que vous chargiez un 2e tampon de démarque, appelons-le
B
, dans une 2e fenêtre. TOUS les autocmds du augroup seront effacés: c'est l'autocmd deA
et celui deB
. Ensuite, un seul autocmd sera installé pourB
.Ainsi, lorsque vous apportez des modifications
B
et attendez quelques secondes pourCursorHold
être renvoyé, il sera automatiquement enregistré. Mais si vous revenez àA
et faites la même chose, le tampon ne sera pas enregistré. En effet, la dernière fois que vous avez chargé un tampon de démarque, il y avait un déséquilibre entre ce que vous avez supprimé et ce que vous avez ajouté. Vous avez supprimé plus que ce que vous avez ajouté.La solution est de ne pas supprimer TOUS autocommandes, mais seulement ceux du tampon courant, en passant le motif spécial
<buffer>
à:autocmd!
:Notez que vous pouvez remplacer
CursorHold
par une étoile pour correspondre à n'importe quel événement de la ligne qui supprime les autocmds:De cette façon, vous n'avez pas besoin de spécifier tous les événements que vos autocmds écoutent lorsque vous souhaitez effacer le groupe.
Piège 2
Il y a un autre écueil, mais cette fois
<buffer>
- ci ce n'est pas le problème, c'est la solution.Lorsque vous incluez une option locale dans un plugin de type de fichier, vous le faites probablement comme ceci:
Cela fonctionnera comme prévu pour les options locales du tampon, mais pas toujours pour les options locales de la fenêtre. Pour illustrer le problème, vous pouvez essayer l'expérience suivante. Créez le fichier
~/.vim/after/ftdetect/potion.vim
et écrivez à l'intérieur:Ce fichier définira automatiquement le type
potion
de fichier pour tout fichier dont l'extension est.pn
. Vous n'avez pas besoin de l'envelopper dans un augroup car, pour ce type de fichier particulier, Vim le fera automatiquement (voir:h ftdetect
).Si les répertoires intermédiaires n'existent pas sur votre système, vous pouvez les créer.
Ensuite, créez le plugin de type de fichier
~/.vim/after/ftplugin/potion.vim
, et à l'intérieur, écrivez:Par défaut, dans un
potion
fichier, ce paramètre entraînera l'affichage des caractères de tabulation en tant que^I
et la fin des lignes en tant que$
.Maintenant, créez un minimum
vimrc
;/tmp/vimrc
écrire à l' intérieur :... pour activer les plugins de type de fichier.
Créez également un fichier de potion
/tmp/pn.pn
et un fichier aléatoire/tmp/file
. Dans le fichier de potion, écrivez quelque chose:Dans le fichier aléatoire, écrivez le chemin d'accès au fichier de potion
/tmp/pn.pn
:Maintenant, démarrez Vim avec un minimum d'initialisations, juste en recherchant le
vimrc
, et ouvrez les deux fichiers dans des fenêtres verticales:Vous devriez voir 2 fenêtres verticales. Le fichier de potion à gauche affiche la fin des lignes avec des signes dollar, le fichier aléatoire à droite ne les affiche pas du tout.
Donnez le focus au fichier aléatoire et appuyez sur
gf
pour afficher le fichier de potion dont le chemin se trouve sous le curseur. Vous voyez maintenant le même tampon de potion dans la fenêtre de droite, mais cette fois, la fin des lignes ne s'affiche pas avec des signes dollar. Et si vous tapez:setlocal list?
, Vim devrait répondre avecnolist
:Toute la chaîne d'événements:
... ne s'est pas produit, car le premier d'entre eux
BufRead
, ne s'est pas produit lorsque vous avez appuyégf
. Le tampon était déjà chargé.Cela peut sembler inattendu, car lorsque vous avez ajouté à l'
setlocal list
intérieur de votre plugin de type de fichier de potion, vous avez peut-être pensé qu'il activerait l''list'
option dans n'importe quelle fenêtre affichant un tampon de potion.Le problème n'est pas spécifique à ce nouveau type de
potion
fichier. Vous pouvez également en faire l'expérience avec unmarkdown
fichier.Ce n'est pas spécifique à l'
'list'
option non plus. Vous pouvez faire l' expérience avec d' autres paramètres de la fenêtre locale, comme'conceallevel'
,'foldmethod'
,'foldexpr'
,'foldtitle'
, ...Ce n'est pas spécifique à la
gf
commande non plus. Vous pouvez en faire l'expérience avec d'autres commandes qui peuvent changer le tampon affiché dans la fenêtre courante: marque globale,C-o
(reculer dans la liste des fenêtres locale),,:b {buffer_number}
...Pour résumer, les options locales de la fenêtre seront correctement définies, si et seulement si:
BufRead
devra être viré):split
(dans ce cas, elle doit hériter des options window-local de la fenêtre où la commande a été exécutée)Sinon, les options locales de la fenêtre risquent de ne pas être correctement définies.
Une solution possible serait de les définir non pas directement à partir d'un plugin de type de fichier, mais à partir d'un autocmd installé dans ce dernier, qui l'écouterait
BufWinEnter
. Cet événement doit être déclenché chaque fois qu'un tampon est affiché dans une fenêtre.Ainsi, par exemple, au lieu d'écrire ceci:
Vous écririez ceci:
Et ici, vous retrouvez le motif spécial
<buffer>
.Piège 3
Si vous modifiez le type de fichier de votre tampon, les autocmds resteront. Si vous souhaitez les supprimer, vous devez configurer
b:undo_ftplugin
(voir:h undo_ftplugin
) et y inclure cette commande:Cependant, n'essayez pas de supprimer l'augroup lui-même, car il pourrait toujours y avoir des tampons de démarque contenant des autocmds.
FWIW, voici l'extrait UltiSnips que j'utilise pour définir
b:undo_ftplugin
:Et voici un exemple de valeur que j'ai dans
~/.vim/after/ftplugin/awk.vim
:En remarque, je comprends pourquoi vous avez posé la question, car lorsque j'ai cherché toutes les lignes où le motif spécial
<buffer>
était utilisé dans les fichiers par défaut de Vim:Je n'ai trouvé que 9 correspondances (vous pouvez en trouver plus ou moins, j'utilise la version 8.0 de Vim, avec des correctifs jusqu'à
134
). Et parmi les 9 correspondances, 7 sont dans la documentation, seulement 2 sont réellement originaires. Vous devriez les trouver dans $ VIMRUNTIME / syntax / dircolors.vim :Je ne sais pas si cela peut causer un problème, mais ils ne sont pas à l' intérieur d' un augroup, ce qui signifie que chaque fois que vous rechargerez un tampon dont le type de fichier est
dircolors
(il arrive si vous modifiez un fichier nommé.dircolors
,.dir_colors
ou dont les extrémités de chemin avec/etc/DIR_COLORS
), le plugin de syntaxe ajoutera un nouvel autocmd tampon local.Vous pouvez le vérifier comme ceci:
La dernière commande devrait afficher ceci:
Maintenant, rechargez le tampon et demandez à nouveau quels sont les autocmds tampon-local pour le tampon actuel:
Cette fois, vous verrez:
Après chaque rechargement du fichier,
s:reset_colors()
ets:preview_color('.')
sera appelé un temps supplémentaire, chaque fois que l' un des casCursorHold
,CursorHoldI
,CursorMoved
,CursorMovedI
est tiré.Ce n'est probablement pas un gros problème, car même après avoir rechargé un
dircolors
fichier plusieurs fois, je n'ai pas vu de ralentissement notable ou de comportement inattendu de Vim.Si c'est un problème pour vous, vous pouvez contacter le responsable du plugin de syntaxe, mais en attendant, si vous souhaitez empêcher la duplication des autocmds, vous pouvez créer votre propre plugin de syntaxe pour les
dircolors
fichiers, en utilisant le fichier~/.vim/syntax/dircolors.vim
. À l'intérieur, vous importeriez le contenu du plugin de syntaxe d'origine:Ensuite, dans ce dernier, vous emballeriez simplement les autocmds dans un augroup que vous effaceriez. Donc, vous remplaceriez ces lignes:
... avec ceux-ci:
Notez que si vous avez créé votre
dircolors
plug-in de syntaxe avec le fichier~/.vim/after/syntax/dircolors.vim
, cela ne fonctionnerait pas, car le plug-in de syntaxe par défaut proviendrait auparavant. En utilisant~/.vim/syntax/dircolors.vim
, votre plugin de syntaxe sera sourced avant celui par défaut, et il définira la variable buffer-localb:current_syntax
, ce qui empêchera le plugin de syntaxe par défaut d'être sourced car il contient cette garde:La règle générale semble être: utiliser les répertoires
~/.vim/ftplugin
et~/.vim/syntax
pour créer un plugin de type / syntaxe de fichier personnalisé et empêcher que le prochain plugin (pour le même type de fichier) dans le chemin d'exécution soit sourcé (y compris ceux par défaut). Et l' utilisation~/.vim/after/ftplugin
,~/.vim/after/syntax
non pas pour empêcher les autres plug - ins d'être source, mais juste pour avoir le dernier mot sur la valeur de certains paramètres.la source
autocmd!
withautocmd! CursorHold <buffer>
inaugroup
blocks est un piège particulièrement critique - et aurait dû être souligné dès le départ. Néanmoins ... c'est un investissement manifestement incroyable de temps, d'efforts et de larmes sanglantes.