Como detectar pressionamentos de tecla que não editam o buffer?

8

Qual é a melhor maneira de detectar pressionamentos de tecla (por exemplo, através de um gancho) que não editam o buffer? Quero dizer coisas como setas para apontar movimento, chamadas para beginning-of-bufferetc.

A razão para isso é que estou trabalhando em algumas ycmdligações para o emacs e gostaria de poder detectar (pelo menos heuristicamente) quando o usuário parou de editar e está se movendo pelo buffer. É um bom momento para enviar o conteúdo do buffer para análise. O cliente vim faz isso quando o usuário sai do modo de inserção e estou tentando emular esse comportamento.

Abingham
fonte
8
Você pode estar interessado em períodos de inatividade para esse tipo de coisa: gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html
Giordano
2
Outra ideia (ou um refinamento da idéia com cronômetros inativos): aconselhe self-insert-commanda cancelar e reagendar um cronômetro em vez de usar um cronômetro inativo. Dessa forma, mesmo que o usuário faça algo, o cronômetro não será redefinido, a menos que "algo" seja inserção de texto.
mbork
2
mbork: after-change-functionsé um mecanismo geral para reagir a alterações de texto.
Phs #
1
Use a post-command-hook. Isso será acionado em tudo, portanto, você pode precisar filtrar o que o acionou antes de executar qualquer ação que desejar.
Malabarba 3/11
1
Não tenho certeza se é relevante para esse problema específico, mas a buffer-chars-modified-tickfunção pode ser útil.
Jon O.

Respostas:

2

Adicione os seguintes ganchos:

  • Para pre-command-hook, defina alguma variável sentinela como t- isso indica que o comando não foi alterado.
  • Para after-change-functions, defina esse valor sentinela como nil. (É um gancho, apenas não soa como um; obrigado a @phils por apontar isso.)
  • Para post-command-hook, verifique este valor sentinela e execute sua função.

Isso pode ou não funcionar, dependendo da ordem de execução. Caso contrário, informe-me nos comentários abaixo.


Quando sair do trabalho, vou postar um exemplo.

Sean Allred
fonte
Eu tenho que ir para o trabalho agora…
Sean Allred 03/11
2
Não aconselhe a inserção automática. Uso após-Mudança-funções
Malabarba
Vou dar uma chance quando tiver uma chance.
abingham
4
@abingham Como regra geral, os ganchos são preferíveis aos conselhos. Os ganchos foram projetados especificamente para você anexar funções, enquanto os conselhos são maneiras de anexar algo em locais inesperados. Nesse caso em particular, também não é aconselhável aconselhar algumas funções muito fundamentais, porque interage de maneira não confiável com a compilação de bytes.
Malabarba 3/11
2
Eu acho que Sean quis se referir post-self-insert-hook(essa parte da resposta parece estar confundindo esse assunto com aconselhamento self-insert-command). De qualquer forma, acho que você geralmente preferiria after-change-functionsporque realmente faz o que deseja (como a inserção automática não é o único tipo de pressionamento de tecla que modifica o buffer).
Phd #
0

Apenas um pensamento -

Isso realmente não deve ser sobre "pressionamentos de teclas", mas sobre comandos - não importa como eles sejam executados, não ? Se bem entendi, você está realmente procurando uma maneira de saber se um determinado comando que é chamado modifica o buffer.

Nesse caso, talvez faça algo assim:

  • Coloque uma função em pre-command-hookque (1) registre o valor atual de (buffer-modified-p)e (2) use set-modified-ppara tornar o buffer não modificado.

  • Coloque uma função em post-command-hookque (1) verifica se o comando modificou o buffer (comparando o valor registrado com o novo valor atual de (buffer-modified-p)) e, em seguida, age de acordo; e (2) se o novo valor é nilredefinido para o valor anterior à alteração usando set-modified-p.

Tipo de mão pesada (verifica cada comando que é chamado), mas pode valer a pena tentar.

Se a parte " age de acordo " é apenas uma opção não operacional para todos os comandos de modificação de buffer e se também é uma operação não operacional para muitos comandos que não modificam (por exemplo, porque você fez isso apenas em um comando não modificado anterior), pelo menos você não fará a ação " agir adequadamente " mais do que o necessário. Mas a parte de verificação por si só pode ser cara / exagerada (desacelera demais as coisas) - tente ver.

Desenhou
fonte