Como posso executar um autocmd ao iniciar o Vim sem um arquivo, um arquivo inexistente ou um arquivo em branco (mas não ao iniciar com um arquivo existente)?

11

Gostaria de executar um autocmd nos seguintes cenários ao iniciar o Vim:

  • Sem nenhum nome de arquivo especificado.
  • Quando o arquivo é novo.
  • Quando o arquivo existe, mas está completamente em branco.

Nos três casos acima, eu gostaria de executar um autocmd; especificamente, gostaria de iniciar o modo de inserção automaticamente apenas para os cenários acima (e não quando estou abrindo um arquivo que já existe e não está em branco).


ATUALIZAR:

Eu tentei colocar o seguinte no meu _vimrc, mas sem sorte (além disso, não tenho certeza se existe uma função no vim que conte o número de caracteres em um arquivo (para ver se é zero) antes de abri-lo:

if @% == "" || filereadable(@%)
  autocmd BufRead,BufNewFile * startinsert
endif
John Sonderson
fonte
Não, isso não é uma duplicata. Eu quero que o vi inicie no modo de inserção SOMENTE PARA OS TRÊS CENÁRIOS QUE MENCIONEI.
John Sonderson
3
Certo, sinto muito, mas parecia realmente um duplamente. ;-) Editei sua pergunta um pouco para deixar as diferenças mais claras.
Martin Tournoij 13/03/2015
2
@JohnSonderson o primeiro link informa como descobrir se nenhum nome de arquivo é fornecido, o segundo pode ser adaptado usando em normalvez de exec.
Muru
11
O arquivo vimrc é lido apenas uma vez : quando o Vim inicia. O conteúdo do autocmd é executado toda vez que é acionado. Portanto, a ifinstrução não deve estar ao redor do autocmd, se estiver dentro do autocmd, para que seja executada toda vez que o autocmd for acionado.
Martin Tournoij 15/03/2015

Respostas:

10

Isso funciona para todos os três casos para mim:

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()

Provavelmente, isso pode ser condensado apenas na última verificação de um arquivo vazio, já que nenhum nome de arquivo ou arquivo que não existe geralmente inicia como buffers vazios. No entanto, provavelmente é possível que algum outro plug-in preencha algumas coisas em um dos dois primeiros casos (como alguns plug-ins de modelo), portanto, é melhor verificar os três.

O primeiro teste que você já teve.

O segundo teste precisa verificar filereadableo valor de zero (não existe) para decidir se é novo (oposto ao que você tinha).

O último teste verifica se o número da última linha do arquivo é 1 (que também é a primeira linha, o que significa que há apenas uma linha) e o número da coluna do final da linha (coluna após o último caractere em a linha) é 1, o que significa que existem 0 caracteres. Se houver apenas 1 linha com 0 caracteres, o arquivo deverá estar vazio.

Uma observação final: a maneira como você coloca suas declarações na pergunta pode resultar em alguns resultados surpreendentes. Ou seja, você está definindo BufReade BufNewFilesomente se as condições forem atendidas na inicialização, mas esses comandos automáticos existem para o restante da sua sessão. Portanto, se você iniciar um arquivo vazio, que define esses comandos, todos os arquivos subseqüentes abertos (novos ou não, vazios ou não) serão iniciados no modo de inserção.

O comando automático VimEnteré executado no final da inicialização do Vim e apenas uma vez durante toda a sessão. Dessa forma, seus testes só são executados quando você inicia o Vim e não em nenhum outro momento.

John O'M.
fonte