Existe uma maneira de desativar o foldexpr durante o preenchimento automático?

7

Percebi que o método fold do vim afeta a eficiência do preenchimento automático, por exemplo, C-Né lento e C-X Lhorrivelmente lento em arquivos de tamanho médio com foldexprs relativamente caros .

Não consigo ver o valor de ter o foldexpr consultado durante a execução automática, por isso, gostaria de desabilitar isso de alguma forma para obter o preenchimento automático utilizável de volta.

Alguma sugestão?


EDIT: Caso de teste

Um caso de teste: sem plugins; e somente isso, que deve ser a função foldexpr mais mínima possível (e é completamente inútil, exceto para contar as invocações) em .vimrc:

let g:c = 0 
function! Myfoldexpr() 
   let g:c = 1 + g:c 
   return '0' 
endfunction

Agora inicie o vim com um documento em branco. Copiaremos as primeiras 100 linhas do arquivo de ajuda do Vim e, em seguida, executaremos a linha de preenchimento automático, escolhendo a 10ª sugestão, e veremos quantas vezes o foldexpr foi chamado.

:help
y100j:q
P:set foldexpr=Myfoldexpr()
:set fdm=expr
O<C-X><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><C-L><Esc>
:echo g:c
2088

Agora, esse é um arquivo de 100 linhas, com linhas relativamente curtas e o foldexpr foi chamado 2088 vezes (embora 100 deles sejam feitos na primeira configuração do foldexpr). O foldexpr eficiente é obviamente bom, mas nós programadores solicitamos muito do foldexpr, portanto eles são necessariamente não triviais e, quando o tempo de execução é multiplicado por vários milhares, você escolhe entre o preenchimento automático ou o recuo para obter produtividade. Sendo ganancioso / preguiçoso, eu gostaria de poder usar os dois! Além de tentar reescrever vários plugins dobráveis ​​baseados em foldexpr bastante bem estabelecidos (eu tentei reescrever o dobramento de php e depois de dias tentando otimizá-lo para um estado viável, desisti do foldexpr para php), talvez haja uma maneira de usar um mapeamento para ativar fdm=manualantes do preenchimento automático ou algo assim?

artfulrobot
fonte
Você já pensou em postar na lista vim_dev?
Lcd047
Vou postar nada de volta útil aqui, mas aqui está a lista vim_dev postagem
artfulrobot
Eu acho que seu caso de teste está errado. Se eu criar um arquivo de teste e adicionar algum texto (apenas fazendo iHello<Esc>, a g:cvariável também é aumentada para 20, então o oWorld<Esc>faz 38... Assim, o número de avaliações foldexprparece não estar relacionado ao uso da conclusão ... Tente carregar o Vim com um mínimo de vimrc arquivo e ver se o problema persistir, pode ser outra definição ou um plugin.
Martin Tournoij
"Não vejo o valor de consultar o foldexpr durante a execução automática" , bem, você está inserindo texto; então o Vim precisa recalcular quais linhas dobrar.
Martin Tournoij
O caso de teste é deliberadamente estúpido, retornando =. Mas apenas pela ordem de grandeza você pode ver que algo está acontecendo. No segundo comentário, Sim, mas acho que deveria fazer isso no final de um candidato a inserção (como faz para p), acho que o que está fazendo é fazê-lo por caractere do candidato a inserção.
Artfulrobot

Respostas:

4

Há algum tempo, tive um problema com a dobragem de sintaxe do PHP, onde a digitação {interferia nas dobras subsequentes até que eu digitasse o fechamento correspondente }. Encontrei uma sugestão em algum lugar (acho que estava no Vim Wiki) para definir temporariamente o método de dobra para manual enquanto estava no modo de inserção. Não sei se isso é uma proposta suficiente para dar uma resposta ao invés de um comentário, mas o código nos comentários é desencorajado e, possivelmente, você pode adaptá-lo às suas circunstâncias. Aqui estão as duas linhas relevantes do meu .vimrc.

autocmd InsertEnter * if !exists('w:last_fdm') | let w:last_fdm=&foldmethod | setlocal foldmethod=manual | endif
autocmd InsertLeave,WinLeave * if exists('w:last_fdm') | let &l:foldmethod=w:last_fdm | unlet w:last_fdm | endif
jjaderberg
fonte
2

talvez haja uma maneira de usar um mapeamento para ativar fdm=manualantes do preenchimento automático ou algo assim?

Bem, isso faz o seguinte:

inoremap <C-x> <Esc>:setlocal foldmethod=manual<CR>a<C-x>
autocmd CompleteDone * :setlocal foldmethod=expr
autocmd InsertLeave * :setlocal foldmethod=expr

Nós remapear <C-x>a primeira série do foldmethodque manualantes de chamar <C-x>, e com os CompleteDonee InsertLeaveautocomandos que redefini-la para expr.

Eu testei isso pressionando <C-l>11 vezes; meus g:cvalores:

  • Após a inicialização do Vim: 202
  • Com este truque: 408
  • Sem esse truque: 2130

Como eu disse nos comentários: esse hack não deve ser necessário. Você mencionou " foldexprs relativamente caros ", suspeito que esse seja o verdadeiro problema; Não posso ter certeza, é claro, porque você não publicou a sua foldexpr, mas acho que vale a pena fazer uma nova pergunta sobre isso ( "Como posso tornar esse foldexpr mais rápido?" ).

Martin Tournoij
fonte
Obrigado, vai tentar isso. Quanto a foldexpr específico, consulte github.com/tmhedberg/SimpylFold para python e github.com/swekaj/php-foldexpr.vim para php. Mas sim, nós dois concordamos que é outra questão!
Artfulrobot
@artfulrobot O Python foldexprtambém é bastante lento para mim ... Não tenho certeza de que isso possa ser aprimorado neste caso específico, portanto, essa solução alternativa pode ser a melhor opção aqui: - / Não sabe por que o PHP foldexpr é necessário? Não pode o arquivo de sintaxe fazer isso (este é geralmente mais rápido)
Martin Tournoij