Comment puis-je exécuter un autocmd lors du démarrage de Vim sans fichier, un fichier inexistant ou un fichier vierge (mais pas lors du démarrage avec un fichier existant)?

11

Je voudrais exécuter un autocmd dans les scénarios suivants lorsque je démarre Vim:

  • Sans nom de fichier spécifié.
  • Lorsque le fichier est nouveau.
  • Lorsque le fichier existe mais est complètement vide.

Dans les trois cas ci-dessus, je voudrais exécuter un autocmd; en particulier, je voudrais démarrer le mode d'insertion automatiquement uniquement pour les scénarios ci-dessus (et non lorsque j'ouvre un fichier qui existe déjà et n'est pas vide).


METTRE À JOUR:

J'ai essayé de placer ce qui suit dans mon _vimrc, mais pas de chance (en plus je ne sais pas s'il y a une fonction dans vim qui compte le nombre de caractères dans un fichier (pour voir si c'est zéro) avant de l'ouvrir:

if @% == "" || filereadable(@%)
  autocmd BufRead,BufNewFile * startinsert
endif
John Sonderson
la source
Non, ce n'est pas un doublon. Je veux que vi démarre en mode d'insertion UNIQUEMENT POUR LES TROIS SCÉNARIOS QUE J'AI MENTIONNÉS.
John Sonderson
3
D'accord, je suis désolé mais ça ressemblait vraiment à un doublon. ;-) J'ai modifié un peu votre question pour clarifier les différences.
Martin Tournoij
2
@JohnSonderson le premier lien vous indique comment trouver si aucun nom de fichier n'est donné, le second peut être adapté en utilisant à la normalplace de exec.
muru
1
Le fichier vimrc n'est lu qu'une seule fois : au démarrage de Vim. Le contenu d'autocmd est exécuté à chaque fois qu'il est déclenché. Donc, l' ifinstruction ne doit pas être autour de l'autocmd, si elle doit être à l' intérieur de l'autocmd, elle sera donc exécutée à chaque fois que l'autocmd est déclenché.
Martin Tournoij

Réponses:

10

Cela fonctionne pour les 3 de vos cas pour moi:

function InsertIfEmpty()
    if @% == ""
        " No filename for current buffer
        startinsert
    elseif filereadable(@%) == 0
        " File doesn't exist yet
        startinsert
    elseif line('$') == 1 && col('$') == 1
        " File is empty
        startinsert
    endif
endfunction

au VimEnter * call InsertIfEmpty()

Ceux-ci pourraient probablement être condensés dans la dernière vérification d'un fichier vide, car aucun nom de fichier ou un fichier qui n'existe pas ne démarre généralement en tant que tampons vides. Cependant, il est probablement possible que certains autres plugins pré-remplissent certaines choses dans l'un des deux premiers cas (comme certains plugins de modèles), il est donc préférable de vérifier les trois.

Le premier test que vous avez déjà eu.

Le deuxième test doit vérifier filereadablela valeur de zéro (n'existe pas) pour décider si elle est nouvelle (contrairement à ce que vous aviez).

Le dernier test vérifie que le numéro de la dernière ligne du fichier est 1 (qui est aussi la première ligne, ce qui signifie qu'il n'y a qu'une seule ligne), et que le numéro de colonne de fin de ligne (colonne après le dernier caractère de la ligne) est 1, ce qui signifie qu'il y a 0 caractères. S'il n'y a qu'une seule ligne contenant 0 caractère, le fichier doit être vide.

Une dernière remarque: la façon dont vous avez vos déclarations dans la question peut entraîner des résultats surprenants. À savoir, vous définissez BufReadet BufNewFileuniquement si les conditions sont remplies au démarrage, mais ces commandes automatiques existent pour le reste de votre session. Donc, si vous deviez démarrer sur un fichier vide, qui définit ces commandes, chaque fichier suivant ouvert (nouveau ou non, vide ou non) démarrerait en mode insertion.

L'autocommande VimEnterest exécutée à la fin du démarrage de Vim et une seule fois pour toute la session. De cette façon, vos tests ne s'exécutent que lorsque vous démarrez Vim et pas à tout autre moment.

John O'M.
la source