Envie a saída do processo para o buffer * Messages *, mas ignore a área de eco

9

É possível enviar a saída de um filtro de processo para o *Messages*buffer e suprimir que a saída de mensagem apareça na área de eco, para que eu possa usar simultaneamente os comandos interativos sem ter que minibuffer-promptser apagado pela saída do filtro de subpress em andamento?

(defun rsync-process-filter (proc string)
  (when (not (or
      (string-match "files...\r" string)
      (string-match "files to consider\n" string)))
    (message "%s" string)))

EDIT (3 de janeiro de 2015): A seguir, há um link para uma pergunta semelhante; no entanto, ainda não consegui fazê-lo funcionar com uma cadeia de processos em que a cadeia exata é desconhecida - o título do segmento é: Emacs - Desativar algumas mensagens Minibuffer :

/superuser/669701/emacs-disable-some-minibuffer-messages

lista de leis
fonte
Eu não acho que você pode. Por que não fazer logon em um buffer diferente? É o que a maioria dos modos que lidam com processos faz ...
lunaryorn 02/01
@ lunaryorn - Obrigado pela sugestão - um buffer dedicado é uma opção válida para resolver o problema. Existem algumas saídas de processo que tenho preferência pessoal para serem enviadas para o *Messages*buffer - os projetos relacionados à sincronização são um deles. Ainda existem algumas coisas que eu não tentei ( porque pensei que poderia haver uma solução interna ), como tornar o *Messages*buffer temporariamente gravável inhibit-read-onlye usar insertat point-max- não sei se isso será exibido em a área de eco também. Vou trabalhar nisso novamente esta noite. . .
lawlist
Uma nota de interesse é que as funções C para mensagens são muito separadas por preocupações de "eco" e "registro", mas essa distinção não é exposta ao elisp. Talvez você possa M-x report-emacs-buge solicite isso como um recurso?
phils
@phils | @ lunaryorn: Consegui alcançar o efeito desejado usando (let ((inhibit-read-only t)) (with-current-buffer (get-buffer-create "*Messages*") (goto-char (point-max)) (insert string)))e publiquei uma resposta preliminar, que será elegível para aceitação após o término do período de espera obrigatório na pergunta do usuário. Eu entrou com um pedido de recurso com report-emacs-bug: debbugs.gnu.org/cgi/bugreport.cgi?bug=19495
lawlist
lawlist: eu não sugeriria essa abordagem porque você pode entrar em conflito com a lógica para lidar com mensagens duplicadas etc. (Mas também pode ser bom; eu realmente não sei.) Você provavelmente deveria usar (messages-buffer)para obter o buffer , se você (point-max)seguir esse método e observe que nem sempre será o início de uma nova linha (por exemplo, use C-g).
phils

Respostas:

3

Você pode suprimir a exibição no minibuffer configurando minibuffer-message-timeoutpara 0.

Por exemplo, eu uso algo assim em alguns lugares em que quero alternar para um modo menor enquanto estiver em um prompt de minibuffer (como ido find-file) sem ser interrompido por uma mensagem 'mode enabled':

(let ((minibuffer-message-timeout 0))
    (toggle-some-mode))
glucas
fonte
Obrigado pela sugestão; no entanto, isso não atingiu o efeito desejado. A impressão de saída do processo em andamento com (let ((minibuffer-message-timeout 0)) (message "%s" string))ainda é exibida na área de eco / minibuffer ao digitar funções interativas como execute-extended-commandou switch-to-buffer-other-window- ou seja, as conclusões imediatas e sugeridas são apagadas pelas mensagens de saída do processo.
lawlist
3

Primeiro rascunho preliminar (3 de janeiro de 2015): Rascunho inicial revisado com base no comentário útil de @phils sobre o uso da função messages-bufferpara localizar ou criar o buffer apropriado (e colocá-lo no messages-buffer-mode); e, adicionou uma verificação para saber se point-maxestá no início da linha (se não estiver, insira uma nova linha antes de inserir a sequência de mensagens).

EDIT (4 de janeiro de 2015): Existem situações em que a sequência inserida pode não necessariamente terminar em uma nova linha, e a função messagenão possui uma verificação para garantir que está no início de uma nova linha, por isso cuidamos disso nesta função. Assim, a qualquer momento em que messagea linha é inserida, a linha começa no lado esquerdo do buffer.

(defun rsync-process-filter (proc string)
  (let ((inhibit-read-only t))
    (when (not (or
        (string-match "files...\r" string)
        (string-match "files to consider\n" string)))
      (with-current-buffer (messages-buffer)
        (goto-char (point-max))
        (when (not (bolp))
          (insert "\n"))
        (insert string)
        (when (not (bolp))
          (insert "\n"))))))
lista de leis
fonte
2

Analisando a documentação message, parece que deve ser possível alcançar o que você deseja chamando a mensagem com um nilargumento imediatamente após chamar messageo conteúdo desejado. A partir da doutrina demessage

Se o primeiro argumento for nulo ou a sequência vazia, a função limpará qualquer mensagem existente; isso permite que o conteúdo do minibuffer seja exibido.

Portanto, modificar sua função para algo como o seguinte deve funcionar

(defun rsync-process-filter (proc string)
  (when (not (or
      (string-match "files...\r" string)
      (string-match "files to consider\n" string)))
    (message "%s" string)
    (message nil)))

Eu testei fazendo o seguinte

(defun test ()
  (message "%s" "Test")
  (message nil))

(run-at-time 5 5 #'test)

E parece que funciona

Iqbal Ansari
fonte
Obrigado pela sugestão. Essa ideia, quando testada com uma saída do processo em execução no *Messages*buffer e depois chamando o comando interativo execute-extended-command, mostra o seguinte: o prompt interativo (ou seja, M-xe quaisquer conclusões parciais) e a saída do processo - ou seja, os dois retornam e adiante na velocidade da luz, mas a oscilação entre os dois é discernível. Parece ser esse o caso, porque o processo específico em questão está constantemente emitindo novas mensagens e essa nova mensagem está sendo exibida por uma fração de segundo na área de eco.
lawlist