подчеркнуть текущую ошибку в окне * compilation *

12

При запуске команды компиляции и переходе к «следующей ошибке» emacs идентифицирует строку текущей ошибки, помещая маленький черный треугольник, указывающий вправо, в левую границу буфера * compilation * . Это хорошо, но мои старые глаза хотели бы более смелый индикатор. Фундаментальная цель здесь - иметь возможность быстро визуально идентифицировать, какая строка Emacs идентифицирует как текущую ошибку компилятора. Некоторые решения, которые приходят на ум:

  1. другое лицо для текущей ошибки (например, больше).
  2. другой цвет фона для текущей ошибки (что-то вроде hl-line-mode).
  3. больший треугольник.

но я открыт и для других идей.

Кто-нибудь может мне помочь?

Spacemoose
источник

Ответы:

2

Я хотел добиться того же самого, так как часто было трудно найти текущее сообщение об ошибке в буфере компиляции. Это решение основано на предложении Дрю использовать 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)

Демо-версия:

демонстрация

erjoalgo
источник
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)
lawlist
источник
Это выглядит очень многообещающе. Я попробую это завтра (собираюсь спать здесь).
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один раз включить в этом буфере. Выполнение, как показано выше, является излишним, но это не повредит. Вы можете подумать, что вы можете просто добавить fooк grep-mode-hookили compilation-mode-hook. Но когда эти ловушки вызываются, есть нет next-error-last-buffer.)

Замечания:

  1. Существует два пользовательских параметра, которые управляют способами указания попадания в исходном буфере (не в буфере компиляции): next-error-highlightи next-error-highlight-no-select. Они предлагают одинаковые возможности, но используются разными командами. Возможности включают использование стрелки или выделение совпадения на определенное время.

  2. Но нет такой опции, управляющей индикацией текущего попадания в буфер *compilation*. Таким образом, Emacs предлагает две опции (где одной, вероятно, будет достаточно) для исходного буфера, но нет опции для буфера компиляции.

Вы могли бы рассмотреть вопрос о подаче запроса на улучшающем, чтобы получить подобный вариант для компиляции (включая Grep) буфер: M-x report-emacs-bug. Использование ловушки с вашей собственной функцией для подсветки - это нормально, но в этом нет необходимости.


И если вы просто хотите изменить индикатор бахромы, вы можете сделать это (используйте любое растровое изображение бахромы, которое вы хотите, вместо filled-rectangle- см. (Elisp) Битовые карты бахромы для списка предопределенных):

(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помещает текущую строку ошибки в верхнюю строку окна для буфера *compilation*. Есть конечно global-hl-line-mode, но ваша жалоба / вопрос был якобы о *compilation*буфере. Вопрос становится менее понятным, не более (ИМХО).
Дрю
Когда вы компилируете в emacs с ошибками, выполните next-error. В исходном буфере курсор будет находиться у источника ошибки, а маленький черный треугольник указывает на текущее сообщение об ошибке компилятора в буфере компиляции . Текущая ошибка обычно не является самой верхней строкой буфера (я только что провел эксперимент в 24.5.1). Я считаю, что визуально нужно искать черный треугольник. hl-line-mode выделяет только строку активного буфера, который является исходным буфером. Я не хочу прыгать в буфер компиляции просто чтобы найти строку.
Spacemoose
Я думал, что вы вызываете следующую ошибку в буфере *compilation*. Если нет, то вам нужно включить функцию next-error-hookдля выделения (или чего-либо еще) в буфере*compilation* . Я обновил ответ с примером.
Дрю
Ваш быстрый и грязный пример отвечает пункту 2 OP, который именно то, что я искал. Прокрутка буфера компиляции так, что активная строка находится сверху (что допустимо, только если левые поля имеют размер 0), заставила меня потерять контекст (так как строки над ошибкой имеют смысл), поэтому мне пришлось установить compilation-context-lines. В результате, на данный момент выбранную ошибку было трудно найти. Ваше решение спасло меня.
Готье