Como posso testar plug-ins e incluí-los somente se eles existirem no .vimrc?

14

No meu .vimrceu estou tentando usar ftplugine, obviamente, usar alguns comandos relacionados a isso sob a suposição de que ele foi carregado com sucesso. No entanto, agora encontrei algumas máquinas antigas que não têm o plug-in instalado. De alguma forma, posso tornar o carregamento desse plug-in condicional e adicionar filetype ondiretivas semelhantes no mesmo bloco condicional?

Vi que existem condições para esquemas de cores e a versão Vim, mas não vi um exemplo que verifique o plug-in (ou não o reconheça).

NB: Seja gentil, eu sou iniciante em VimScript.

0xC0000022L
fonte
1
Observe que os plug-ins são carregados após o seu ~/.vimrc, portanto, você não poderá testar os efeitos de um plug-in dentro dele, a ~/.vimrcmenos que teste a existência do arquivo do plug-in ou adie o teste até que os plug-ins tenham sido carregados com um comando automático, como VimEnter.
garyjohn
@garyjohn: aha, isso é interessante. Porque isso meio que contradiz a resposta existente. Você poderia escrever como resposta?
0xC0000022L
Editei minha resposta para abordar um pouco essa questão.
Qqx
Meu comentário não contradiz a resposta do qqx; deveria chamar a atenção para um ponto que poderia ser esquecido se alguém não lesse a resposta do qqx com cuidado ou fizesse inferências incorretas. A resposta foi boa para começar e é ainda mais clara agora.
garyjohn

Respostas:

19

Você pode agrupar esse bloco em uma condição que usa a exists()função para verificar se uma variável, comando ou função definida pelo plug-in é conhecida pelo vim.

Aqui estão alguns bits que eu tenho nos arquivos em ~ / .vim:

" after/plugin/speeddating.vim
if exists(':SpeedDatingFormat')
    SpeedDatingFormat %-d %B %Y
endif

" ftplugin/ruby.vim
if exists('g:loaded_surround') && !exists('b:surround_'.char2nr(':'))
  let b:surround_{char2nr(':')} = ":\r"
endif

Observe que os bits acima estão em arquivos que são avaliados após plugins normais, aqui um ftplugin e um arquivo no after/plugindiretório

Outra opção seria usar blocos try / catch, embora isso exija pelo menos o vim 7.0:

if v:version >= 700
    try
        runtime bundle/pathogen/autoload/pathogen.vim
        call pathogen#infect()
    catch
    endtry
endif

Uma vez que algo na tryseção desse bloco falhar, ele pulará para a catchseção. Como a catchseção está vazia, ela continuará com o restante do arquivo de inicialização após a endtryinstrução.

Como isso está carregando o código manualmente, em vez de depender de um plug-in já carregado, isso pode ser feito no próprio arquivo .vimrc.

qqx
fonte
Você poderia adicionar os requisitos de versão para a tryconstrução? O velho Vim entenderia isso? Ou seja, quando foi introduzido. Obrigado e +1 por enquanto.
0xC0000022L
1
Adicionei informações sobre a versão necessária.
Qqx
Acho que a última solução com a verificação da versão trydeve funcionar. Muito obrigado. Vamos ver se outra resposta ainda chegará. Caso contrário, é claro que vou aceitar o seu.
0xC0000022L 15/02
ah, é claro que isso desabilita o plug-in nas versões 6.x. Hmmm ... precisa encontrar algo melhor, mas isso funcionará enquanto isso. Obrigado.
0xC0000022L 15/02
Ainda existe outra alternativa :silent! {cmd}, que suprime o erro quando {cmd}não existe. Isso funciona mesmo no Vim 6.
Ingo Karkat
7

Meu método preferido é apenas verificar a existência do arquivo de plug-in. Eu acho isso mais simples.

if !empty(glob("path/to/plugin.vim"))
   echo "File exists."
endif
user3751385
fonte
4

Eu queria conseguir isso enquanto mantinha minha configuração do Vim em conjunto .vimrc, em vez de em vários after/diretórios. Esta é a solução que eu vim com:

  1. Verifique a existência de cada plug-in, verificando qualquer comando único que ele fornece exists()e defina suas opções, se existir. (Isso é exatamente como na resposta aceita.)

  2. Coloque todas as opções definidas da maneira acima em uma função (chamada SetPluginOptionsNow()no meu código).

  3. Chame essa função no VimEnterevento, que é acionado ao entrar em uma nova sessão do Vim - mas crucialmente, depois que todos os plugins foram carregados. Por esse motivo, nossas exists()verificações podem verificar as funções do plug-in sem problemas.

Aqui está uma amostra dessa parte da minha .vimrc.

""" PLUGIN-SPECIFIC OPTIONS
" These are "supposed to be" set in after/plugin directory, but then
" cross-platform synchronization would get even messier. So, au VimEnter it is. 

function! SetPluginOptionsNow()


    " NERDTree Options
    if exists(":NERDTree")
        map <F10> :NERDTreeToggle<CR>
    endif

    " Syntastic Options
    if exists(":SyntasticCheck")
        let g:syntastic_stl_format = '[Syntax: line:%F (%e+%w)]'
        set statusline+=%#warningmsg#
        set statusline+=%{SyntasticStatuslineFlag()}
        set statusline+=%*
        " and so on...

endfunction

au VimEnter * call SetPluginOptionsNow()
""" END OF PLUGIN-SPECIFIC OPTIONS
sundar - Restabelecer Monica
fonte
esta resposta não é legal com vim-airlines. Em particular, aguardar o evento VimEnter especificar coisas como airline_themeparece induzir vários erros ... Não sei ao certo por quê.
StevieP
3

Ainda existe outra alternativa :silent! {cmd}, que suprime o erro quando {cmd}não existe. O principal benefício é que é um pequeno comando único. Isso funciona mesmo no Vim 6 e é ótimo para coisas opcionais.

Por exemplo, é usado por plugins que usam repeat.vim de Tim Pope para tornar os mapeamentos repetíveis.

Ingo Karkat
fonte
Algo como !silent runtime ftplugin/man.vim | filetype on | filetype plugin on | filetype indent ontrabalhar para desligar todos os comandos após o !silentou é sempre específico para o próximo comando?
0xC0000022L
Não é :silent!, !silente se aplica a todos os comandos contidos, exceto quando :unsilenté usado em algum lugar interno. (Mas isso é raro.)
Ingo Karkat
Opa, difícil de corrigir agora no comentário. Mas entendi. Obrigado.
0xC0000022L
1

Inicialmente publicado em outra pergunta: /programming//a/48178537/2843583

Apenas como alternativa, você também pode usar um regexp para decidir se o plugin disponível está no seu runtimepath:

if &rtp =~ 'plugin-name'
    ...
endif

Isso tem a vantagem de funcionar com plug-ins que possuem apenas código vimscript no autoloaddiretório, que por sua vez não pode ser detectado quando o .vimrc é analisado inicialmente, pois os snippets de carregamento automático são carregados no momento de uma chamada de função.

bergercookie
fonte