Выделяйте только недавно добавленные строки, когда буфер Emacs автоматически возвращается
У меня есть команда Emacs, которая добавляет разделительную строку в лог-файлах, когда между метками времени, найденными на 2 последовательных строках, находится более 3 секунд:
(defun log-mode-display-separator-line ()
"Separate blocks of log lines with an horizontal line."
(interactive)
(save-excursion
(goto-char (point-min))
(let (last ov)
(while (re-search-forward "[0-9]\{4\}-[01][1-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]" nil t)
(when last
(when (> (- (float-time (date-to-time (match-string 0)))
(float-time (date-to-time last)))
3)
(setq ov (make-overlay (line-beginning-position) (line-end-position)))
(overlay-put ov 'face 'log-mode-separator-face)))
(setq last (match-string 0))))))
log-mode-separator-face
использует атрибут overline, чтобы визуально поместить горизонтальную линию между "семантическими" блоками строк.
Я хотел бы, чтобы эта горизонтальная линия автоматически вставлялась при возврате буфера (каждые 5 секунд), но обработка может стать слишком большой для огромных файлов журнала, которые постоянно обновляются. Теперь каждый раз, когда мы вызываем эту команду, весь файл сканируется с самого начала...
Как же мне тогда это осознать? (С Emacs, без сомнения, так и есть...)
1 ответ:
Во-первых, нет никакой гарантии, что буфер возвращается каждые 5 секунд. Начиная с Emacs 24.4, autorevert использует уведомления о файлах, что означает, что буфер возвращается всякий раз, когда файл изменяется на диске. Если вы хотите подавить это, установите
auto-revert-use-notify
равным нулю.Далее, это зависит от того, как вы хотите вернуть свой файл журнала. Я полагаю, вы используете
auto-revert-tail-mode
. Этот режим вызывает функции крючка, содержащиеся вbefore-revert-hook
иafter-revert-hook
. В качестве стратегии я бы написал функцию дляafter-revert-hook
, которая подчеркивает последнее строка в буфере, подлежащая возврату. Что-то вроде этого:(defun my-auto-revert-tail-mode-display-separator-line () "Separate blocks of log lines with an horizontal line." (save-excursion (goto-char (point-max)) (while (and (= (line-beginning-position) (line-end-position)) (> (point) (point-min))) (forward-line -1)) (let ((ov (make-overlay (line-beginning-position) (line-end-position)))) (overlay-put ov 'face 'underline)))) (add-hook 'after-revert-hook 'my-auto-revert-tail-mode-display-separator-line)