Відправити вихідний процес у буфер * Повідомлення *, але обійти область ехо


9

Чи можна надіслати вихід з процесора-фільтра в *Messages*буфер і придушити виведення повідомлення, яке з’явиться в області ехо, таким чином, що я в змозі одночасно використовувати інтерактивні команди, не minibuffer-promptстираючись поточним виходом фільтра підпреса?

(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 січня 2015 р.): Далі йде посилання на подібне запитання, однак я ще не зміг змусити його працювати з рядком процесу, де невідомий точний рядок - назва потоку: Emacs - Вимкнення деяких повідомлень про мінібуфер :

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


Я не думаю, що ти можеш. Чому б просто не увійти в інший буфер? Ось, що робить більшість режимів, які стосуються процесів…
місячник

@lunaryorn - Дякую за пропозицію - виділений буфер - це дійсний варіант вирішення проблеми. Є декілька результатів процесів, які я особисто бажаю надсилати до *Messages*буфера - проекти, пов'язані з синхронізацією, є одним із них. Є ще кілька речей, які я не пробував ( тому що я думав, що можливо було вбудоване рішення ), наприклад, зробити *Messages*буфер тимчасово доступним для запису inhibit-read-onlyта використовувати insertпри point-max- я не знаю, чи з’явиться це в також область ехо. Я буду працювати над цим знову цього вечора. . .
законник

Цікавою є те, що функції C для обміну повідомленнями сильно розділені проблемами "відлуння" та "ведення журналів", але це відмінність не піддається елісп. Можливо, ви могли б M-x report-emacs-bugзапитати це як функцію?
філ

@phils | @lunaryorn: Я зміг досягти бажаного ефекту за допомогою, (let ((inhibit-read-only t)) (with-current-buffer (get-buffer-create "*Messages*") (goto-char (point-max)) (insert string)))і я опублікував проект відповіді, який буде придатний для прийняття після закінчення обов'язкового періоду очікування на власне запитання користувача. Я подав запит на функцію за адресоюreport-emacs-bug : debbugs.gnu.org/cgi/bugreport.cgi?bug=19495
законник

lawlist: Я не збирався пропонувати такий підхід, тому що ви можете зіткнутися з логікою обробки дублікатів повідомлень і т. д. (Але це також може бути добре; я насправді не знаю.) Ви, ймовірно, повинні використовувати (messages-buffer)для отримання буфера , якщо ви дотримуєтесь цього методу, і зауважте, що (point-max)не завжди буде початком нового рядка (наприклад, використання C-g).
phils

Відповіді:


3

Ви можете придушити показ в мінібуфері, встановивши minibuffer-message-timeout0.

Наприклад, я використовую щось подібне в кількох місцях, де я хочу переключити другорядний режим, перебуваючи у запиті мінібуфера (наприклад, ido find-file), не перериваючись повідомленням "включеного режиму":

(let ((minibuffer-message-timeout 0))
    (toggle-some-mode))

Дякую за пропозицію; однак це не дозволило досягти бажаного ефекту. Триваючий вихід процесу друку з (let ((minibuffer-message-timeout 0)) (message "%s" string))ще відображається в луні-області / мінібуфер при введенні інтерактивних функцій , таких як execute-extended-commandабо switch-to-buffer-other-window- тобто, стрімкі і пропоновані поповнення стираються вихідні процесу повідомлень.
законник

3

Перший грубий проект (3 січня 2015 р.): Переглянута початкова чернетка на основі корисного коментаря @phils щодо використання функції messages-bufferдля пошуку або створення відповідного буфера (і введення його в messages-buffer-mode); і, додав перевірку, чи point-maxє на початку рядка (якщо ні, то вставити новий рядок перед тим, як вставити рядок повідомлення).

EDIT (4 січня 2015 р.): Є ситуації, коли вставлена ​​рядок може необов'язково закінчуватися в новому рядку, а функція messageне має перевірки, щоб переконатися, що вона знаходиться на початку нового рядка, тому ми беремо це в цій функції. Таким чином, у будь-якій точці, коли messageвставляється нова лінія, зазначена лінія почнеться зліва від буфера.

(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"))))))

2

Переглядаючи docstring, messageсхоже, слід досягти того, що ви хочете, зателефонувавши в повідомлення з nilаргументом відразу після дзвінка messageз потрібним вмістом. З доктрину оmessage

Якщо перший аргумент є нульовим або порожнім рядком, функція очищає будь-яке існуюче повідомлення; це дозволяє показувати вміст мінібуфера.

Тож модифікація вашої функції на щось подібне повинно працювати

(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)))

Я перевірив це, зробивши наступне

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

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

І, здається, працює


Дякую за пропозицію. Ця ідея, коли тестується з запущеним процесом виводу в *Messages*буфер і потім викликає інтерактивну команду execute-extended-command, показує наступне: інтерактивне запит (тобто, M-xі будь-які часткові завершення) і вихід з процесу, тобто два перемикання назад і вперед зі швидкістю світла, але мерехтіння між ними помітно. Це, мабуть, так, тому що конкретний процес, який розглядається, постійно розплітає нові повідомлення, і це повідомлення виводиться на частку секунди в області ехо.
законник
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.