Eu uso o Emacs com o Geiser para invadir algum código do esquema. Como eu estou brincando no REPL, às vezes avalio expressões que resultam em muita saída, geralmente todas em uma linha.
Por exemplo, eu apenas brinquei com SRFI-41 (streams) e criei um fluxo de caracteres a partir de um arquivo grande; forcei o fluxo e Geiser vomitou todo o conteúdo do arquivo como um fluxo de caracteres no meu buffer. Quase imediatamente, o Emacs parou, à medida que mais e mais caracteres foram anexados à linha de saída, e não importa quanto tempo continuei pressionando C-g
ou C-c C-c
não consegui fazer o Emacs (ou Geiser) parar.
Isso interrompeu toda a sessão do Emacs, já que o Emacs agora ignora completamente minha opinião, pensando que ele precisa dar prioridade à impressão desse enorme fluxo de caracteres em uma linha em um buffer Geiser REPL que não responde.
Existe algo que eu possa fazer para proteger minha sessão do Emacs da minha curiosidade destrutiva? (Por que o Emacs fica tão lento ao exibir linhas muito longas?) Posso definir um limite para linhas longas e dizer ao Emacs que não há problema em simplesmente não tentar exibir linhas muito longas?
fonte
yes
em um,ansi-term
por exemplo, tem um efeito semelhante (mas não tão horrível). Realmente, é apenas o volume de texto que dá uma pausa no emacs.yes
em um emulador de terminal VTE atinge o máximo de todos os núcleos da minha CPU, portanto, não o usaria como exemplo.Respostas:
Como já respondido nos comentários, o Emacs se torna muito lento em sua reexibição de longas filas é um problema bem conhecido . Consertá-lo seria muito bom, mas precisa de muita reflexão para ser realizado corretamente. Tenho uma ideia de como isso pode ser realizado com base na seção 6.3 deste documento (basicamente, armazene informações da linha visual no buffer atual e atualize-a na inserção de espaço em branco, propriedades de exibição, alterações de janela etc.) e use essas informações em o código de reexibição para evitar a varredura o tempo todo), mas não estou familiarizado o suficiente com os C internos para removê-lo.
Existem soluções alternativas. Os mais óbvios seriam ajustar os parâmetros relacionados à exibição (como ativar o truncamento de linha visual na instância gráfica do Emacs, usar um Emacs não gráfico para fazer isso automaticamente, desativar os recursos do Bidi etc.) e pré-processar o conteúdo do arquivo que você ' re-lendo. Um menos óbvio é o pós-processamento automático dos arquivos, seja truncando suas linhas ou adicionando propriedades de texto que tornam as linhas mais curtas do que realmente são. Para transformar isso em uma resposta mais interessante, apresentarei um truque bastante feio da opção anterior que funcionará apenas nos
comint
modos derivados:Isso define
my-comint-shorten-long-lines
uma função que utiliza uma sequência possivelmente composta de muitas linhas e usa o poder das expressões regulares para substituir qualquer linha com um comprimento de 80 caracteres ou mais por uma versão reduzida que exibe o texto original ao passar o mouse sobre ela. Quando usado como gancho,comint-preoutput-filter-functions
ele filtra toda acomint
saída antes de ser exibida.No entanto, esta versão do hack tem uma fraqueza bastante séria. Nos modos em que a fonte básica está em andamento (como, por exemplo
M-x ielm
), ela cortará alegremente as linhas que fazem parte de uma cadeia de caracteres e, dessa forma, tipificará tudo até a próxima citação como string! Não é isso que queremos e pode ser corrigido com um pouco mais de domínio sobre expressões regulares (mas presumivelmente entrará em um REPL para uma linguagem como Python). Enquanto estamos nisso, vamos destacar a saída reduzida também:Isso é um pouco melhor, mas ainda feio. Pairar sobre a saída de algo como
find /
inM-x shell
não é atraente (idealmente, queremos exibir apenas a linha não abreviada, nem todas as saídas), a detecção de strings é rudimentar na melhor das hipóteses e o truncamento pode ser indicado melhor com elipses em vez de especificar tudo. Além disso, não é garantido que o texto recebido não seja transformado em lotes. Tudo isso grita por executar a etapa de processamento em um buffer temporário, mas será deixado para o leitor como exercício (ou o autor como possível postagem no blog).fonte
Como isso aconteceu com o Python da mesma forma, a solução em python-mode.el, https://launchpad.net/python-mode , é conectar-se ao processo diretamente, não através do modo de comint.
Confia em
start-process
e process-send-stringPor exemplo, consulte funções
py--start-fast-process
epy--fast-send-string-intern
fonte