当 Emacs 缓冲区自动还原时,仅突出显示新添加的行

Highlight only newly added lines when the Emacs buffer is auto-reverted

我有一个 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 属性可视化地在 "semantic" 行块之间放置一条水平线。

我希望在恢复缓冲区时(每 5 秒)自动插入那条水平线,但是在不断更新的巨大日志文件上处理可能会变得太大。截至目前,每次我们调用该命令时,都会从头开始扫描整个文件...

那我怎么才能意识到这一点呢? (有了Emacs,毫无疑问是...)

首先,不能保证缓冲区每 5 秒恢复一次。从 Emacs 24.4 开始,autorevert 使用文件通知,这意味着只要文件在磁盘上发生更改,就会恢复缓冲区。如果你想抑制这个,设置 auto-revert-use-notify 为 nil。

此外,这取决于您要如何还原日志文件。我想你使用 auto-revert-tail-mode。该模式调用包含在before-revert-hookafter-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)