在* compilation *窗口中强调当前错误


12

当运行compile命令并跳转到“下一个错误”时,emacs通过在* compilation *缓冲区的左侧边缘放置一个指向右的黑色小三角形,来标识当前错误的行。这很好,但是我的老眼睛想要一个更大胆的指示器。此处的基本目标是能够快速直观地识别emacs将哪一行识别为当前编译器错误。我想到的一些解决方案:

  1. 当前错误的另一面(例如更大)。
  2. 当前错误的背景颜色不同(类似于hl-line-mode)。
  3. 一个更大的三角形。

但我也欢迎其他想法。

有人可以帮我吗?

Answers:


2

我想要实现相同的目标,因为在编译缓冲区中找到当前错误消息通常很痛苦。此解决方案基于Drew的建议,使用a next-error-hook突出显示错误消息。目前,它仅突出显示错误消息中的第一行,但是我发现这已经足够了。

(defcustom next-error-message-highlight-p nil
  "If non-nil, highlight the current error message in the ‘next-error’ buffer"
  :type 'boolean
  :group 'next-error
  :version "??")

(defface next-error-message
  '((t (:inherit highlight)))
  "Face used to highlight the current error message in the ‘next-error’ buffer"
  :group 'next-error
  :version "??")

(defvar next-error-message-highlight-overlay
  nil
  "Overlay highlighting the current error message in the ‘next-error’ buffer")

(make-variable-buffer-local 'next-error-message-highlight-overlay)

(defun next-error-message-highlight ()
  "Highlight the current error message in the ‘next-error’ buffer."
  (when next-error-message-highlight-p
    (with-current-buffer next-error-last-buffer
      (when next-error-message-highlight-overlay
        (delete-overlay next-error-message-highlight-overlay))
      (save-excursion
        (goto-char (point))
        (let ((ol (make-overlay (line-beginning-position) (line-end-position))))
          ;; do not override region highlighting
          (overlay-put ol 'priority -50)
          (overlay-put ol 'face 'next-error-message)
          (overlay-put ol 'window (get-buffer-window))
          (setf next-error-message-highlight-overlay ol))))))

(add-hook 'next-error-hook 'next-error-message-highlight)

用法:

(setq next-error-message-highlight-p t)

演示:

演示


1

这是一个如何修改出现在*compilation*缓冲区(例如*grep*结果缓冲区)左边缘的位图图像的示例:

(define-fringe-bitmap 'custom-right-arrow [128 192 96 48 24 48 96 192 128] 9 8 'center)

(put 'overlay-arrow-position 'overlay-arrow-bitmap 'custom-right-arrow)

这是如何设置边缘位图颜色的示例:

(defface right-triangle-face
  '((t (:background "red" :foreground "yellow")))
  "Face for `right-triangle-face`.")

(set-fringe-bitmap-face 'right-triangle 'right-triangle-face)

这是如何创建自己的条纹位图的示例:

;; AUTHOR:  Nikolaj Schumacher -- https://github.com/nschum/fringe-helper.el
;;
(defun fringe-helper-convert (&rest strings)
"Convert STRINGS into a vector usable for `define-fringe-bitmap'.
Each string in STRINGS represents a line of the fringe bitmap.
Periods (.) are background-colored pixel; Xs are foreground-colored. The
fringe bitmap always is aligned to the right. If the fringe has half
width, only the left 4 pixels of an 8 pixel bitmap will be shown.
For example, the following code defines a diagonal line.
\(fringe-helper-convert
\"XX......\"
\"..XX....\"
\"....XX..\"
\"......XX\"\)"
  (unless (cdr strings)
  ;; only one string, probably with newlines
    (setq strings (split-string (car strings) "\n")))
  (apply 'vector
    (mapcar
      (lambda (str)
        (let ((num 0))
          (dolist (c (string-to-list str))
            (setq num (+ (* num 2) (if (eq c ?.) 0 1))))
          num))
      strings)))

(define-fringe-bitmap 'backslash (fringe-helper-convert
  "XX......"
  "XX......"
  " XX....."
  ".XX....."
  "..XX...."
  "..XX...."
  "...XX..."
  "...XX..."
  "....XX.."
  "....XX.."
  ".....XX."
  ".....XX.") nil nil 'center)

这看起来很有希望。明天我会尝试一下(在这里就寝)。
Spacemoose

1

是否不next-error滚动编译错误缓冲区,以便当前错误显示为窗口的第一行?

如果不是,是否至少将光标放在当前错误行上?如果是这样,并且光标对您来说不够可见,请考虑使用hl-line-mode突出显示当前行。或者考虑使用库crosshairs突出显示当前行和当前列。


发表评论后更新

我以为你next-error在缓冲中调用*compilation*。如果这样做,则该行将滚动到顶部,如我所述。

但是,如果你正在调用next-error的外部缓冲*compilation*,那么你需要使用next-error-hook到,在缓冲区*compilation*中,突出显示当前行或条纹或什么的,以任何方式你喜欢。

这是一个简单的例子:

(defun foo ()
  "..."
  (with-current-buffer next-error-last-buffer
    (hl-line-mode 1)))

(add-hook 'next-error-hook 'foo)

(当然,您实际上只需要hl-line-mode在该缓冲区中打开一次即可。如上所示执行该操作是很过头的,但是并没有什么伤害。您可能会认为您可以只添加foogrep-mode-hookcompilation-mode-hook。但是当调用这些钩子时,不next-error-last-buffer。)

注意:

  1. 有两个用户选项可控制在源缓冲区(而非编译缓冲区)中指示命中的方式:next-error-highlightnext-error-highlight-no-select。它们提供相同的可能性,但是它们由不同的命令使用。可能性包括使用边缘箭头或突出显示特定时间的匹配项。

  2. 但是没有这样的选项可以控制缓冲区中当前命中的指示*compilation*。因此,Emacs为源缓冲区提供了两个选项(其中一个可能就足够了),而为编译缓冲区没有提供任何选项。

您可能会考虑提交增强请求,以获取编译(包括grep)缓冲区的类似选项:M-x report-emacs-bug。可以将钩子与您自己的函数一起使用以突出显示是可以的,但不是必须的。


而且,如果您只想更改边缘指示器,则可以执行此操作(使用所需的任何边缘位图,而不是filled-rectangle-请参见(消除)边缘位图以获取预定义的列表):

(defun bar ()
  (with-current-buffer next-error-last-buffer
    (unless (eq 'filled-rectangle (cdr (assq 'overlay-arrow fringe-indicator-alist)))
      (setq fringe-indicator-alist
            (cons '(overlay-arrow . filled-rectangle) fringe-indicator-alist)))))

(add-hook 'next-error-hook 'bar)

更新#2:

我刚刚发现,如果您关闭显示左边缘的功能,那么您将看到我开头所描述的行为:滚动窗口以将当前错误放在顶部。这是另一种可能性。(这是我在设置中看到的行为,因为我没有显示条纹。)

我刚刚报告了此行为有一个错误(#20829)。重要的是(当前,直到错误修复),当您执行C-x `next-error)时,左边缘是否在所选窗口中显示。(当前)仅显示编译缓冲区的窗口不显示左边缘是不够的。


编译缓冲区的滚动似乎像emacs的其余部分一样工作-当“点”(对于编译缓冲区,当前错误)移动到某个点时,屏幕滚动。对于大屏幕数据,这使得很难发现错误。hl-line-mode的行为会很好,但只会突出显示当前缓冲区(我可以覆盖它吗?)-因此,突出显示发生错误的代码行,但没有错误数据。十字准线似乎对列和行执行相同的操作,而我不需要。
Spacemoose

至少我还是不清楚。对我来说,next-error将当前错误行放在buffer窗口的顶部*compilation*。当然有global-hl-line-mode,但是您的投诉/问题据说是关于*compilation*缓冲区的。问题变得越来越不清楚,而不是更多(恕我直言)。
Drew

当在带错误的emacs中编译时,执行next-error。在源缓冲区中,您的光标将位于错误的源头,并且有一个小的黑色三角形指示编译缓冲区中的当前编译器错误消息。当前的错误通常不是缓冲区的最上面一行(我刚刚在24.5.1中进行了实验)。我发现寻找黑色三角形在视觉上很繁琐。hl-line-mode仅突出显示活动缓冲区的行,即源缓冲区。我不想跳到编译缓冲区只是为了找到这一行。
Spacemoose

我以为你在缓冲中调用了下一个错误*compilation*。如果不是,那么您需要启用一个函数next-error-hook在buffer中*compilation*进行突出显示(或其他操作)。我用一个例子更新了答案。
德鲁

您简单又肮脏的示例回答了OP的第2点,这正是我所要的。滚动编译缓冲区,使活动行位于顶部(仅当左边缘的大小为0时才有效)使我失去上下文(因为错误上方的行有意义),因此必须进行设置compilation-context-lines。结果,当前选择的错误很难找到。您的解决方案救了我。
Gauthier
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.