Betonen Sie den aktuellen Fehler im Fenster * Kompilierung *

12

Wenn Sie den Kompilierungsbefehl ausführen und zum 'nächsten Fehler' springen, identifiziert emacs die Zeile des aktuellen Fehlers, indem Sie ein kleines schwarzes Dreieck, das nach rechts zeigt, in den linken Rand des * Kompilierungspuffers * setzen . Das ist schön, aber meine alten Augen möchten einen mutigeren Indikator. Das grundlegende Ziel hierbei ist es, schnell visuell identifizieren zu können, welche Zeilen-Emacs als aktueller Compilerfehler identifiziert werden. Einige Lösungen, die mir in den Sinn kommen:

  1. ein anderes Gesicht für den aktuellen Fehler (zum Beispiel größer).
  2. eine andere Hintergrundfarbe für den aktuellen Fehler (so etwas wie hl-line-mode).
  3. ein größeres Dreieck.

aber ich bin auch offen für andere ideen.

Kann mir jemand helfen?

Spacemoose
quelle

Antworten:

2

Ich wollte das Gleiche erreichen, da es oft schmerzhaft war, die aktuelle Fehlermeldung im Kompilierungspuffer zu finden. Diese Lösung basiert auf Drews Vorschlag, next-error-hookdie Fehlermeldung mit a hervorzuheben. Derzeit wird nur die erste Zeile in der Fehlermeldung hervorgehoben, aber ich finde, dass dies gut genug ist.

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

Verwendung:

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

Demo:

Demo

Erjoalgo
quelle
1

Hier ist ein Beispiel für das Ändern des Bitmap-Bilds, das im linken Bereich des *compilation*Puffers angezeigt wird (z. B. im *grep*Ergebnispuffer):

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

Hier ist ein Beispiel für das Festlegen der Farben von Randbitmaps:

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

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

Hier ist ein Beispiel, wie Sie Ihre eigene Randbitmap erstellen:

;; 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)
Gesetzesliste
quelle
Das sieht sehr vielversprechend aus. Ich werde es morgen ausprobieren (Schlafenszeit hier).
Spacemoose
1

next-errorScrollt der Kompilierungsfehlerpuffer nicht , sodass der aktuelle Fehler als erste Zeile des Fensters angezeigt wird?

Wenn nicht, setzt es den Cursor nicht zumindest auf die aktuelle Fehlerzeile? Wenn dies der Fall ist und der Cursor für Sie nicht sichtbar genug ist, können Sie hl-line-modedie aktuelle Zeile mit markieren. Oder verwenden Sie die Bibliothek crosshairs, um die aktuelle Zeile und die aktuelle Spalte hervorzuheben.


Update nach deinem Kommentar

Ich dachte, Sie rufen next-errorim Puffer auf *compilation*. Wenn Sie das tun, wird die Zeile wie oben beschrieben nach oben gescrollt.

Aber wenn Sie den Aufruf next-erroraußerhalb Puffer , *compilation*dann müssen Sie verwenden , next-error-hookum, in Puffer*compilation* , markieren Sie die aktuelle Zeile oder Fransen oder was auch immer, in welcher Weise auch immer Sie mögen.

Hier ist ein schnelles und schmutziges Beispiel:

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

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

(Natürlich müssen Sie hl-line-modesich in diesem Puffer wirklich nur einmal einschalten . Es ist übertrieben, es wie oben gezeigt zu tun, aber es tut nicht weh. Sie könnten denken, Sie könnten nur foozu grep-mode-hookoder hinzufügen compilation-mode-hook. Aber wenn diese Hooks aufgerufen werden, gibt es nein next-error-last-buffer.)

Hinweis:

  1. Es gibt zwei Benutzeroptionen, die steuern, wie der Treffer im Quellpuffer (nicht im Kompilierungspuffer) angezeigt wird : next-error-highlightund next-error-highlight-no-select. Sie bieten die gleichen Möglichkeiten, werden jedoch von verschiedenen Befehlen verwendet. Die Möglichkeiten umfassen die Verwendung eines Randpfeils oder das Hervorheben der Übereinstimmung für eine bestimmte Zeit.

  2. Es gibt jedoch keine solche Option, die die Anzeige des aktuellen Treffers im Puffer steuert *compilation*. Daher bietet Emacs zwei Optionen (wobei eine wahrscheinlich ausreichen würde) für den Quellpuffer, jedoch keine Option für den Kompilierungspuffer.

Sie können eine Erweiterungsanforderung einreichen, um eine ähnliche Option für den Kompilierungspuffer (einschließlich grep) zu erhalten : M-x report-emacs-bug. Die Verwendung eines Hakens mit eigener Funktion zur Durchführung der Hervorhebung ist in Ordnung, sollte jedoch nicht erforderlich sein.


Und wenn Sie nur die Streifenanzeige ändern möchten, können Sie dies tun (was auch immer verwenden fringe Bitmap Sie wollen, statt filled-rectangle- siehe (elisp) Fringe Bitmaps für eine Liste der vordefinierten sind):

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

Update Nr. 2:

Ich habe gerade festgestellt, dass Sie beim Ausschalten des linken Randes das Verhalten sehen, das ich am Anfang beschrieben habe: Das Fenster wird gescrollt, um den aktuellen Fehler oben zu platzieren. Das ist also eine andere Möglichkeit. (Es ist das Verhalten, das ich in meinem Setup sehe, da ich keine Ränder zeige.)

Es gibt einen Fehler in diesem Verhalten, den ich gerade gemeldet habe ( # 20829 ). Was zählt (derzeit bis der Fehler behoben ist), ist, ob der linke Rand im ausgewählten Fenster angezeigt wird, wenn Sie dies tun C-x `( next-error). Es reicht (derzeit) nicht aus, dass das Fenster mit dem Kompilierungspuffer nicht den linken Rand anzeigt.

Drew
quelle
Das Scrollen des Kompilierungspuffers scheint wie der Rest der Emacs zu funktionieren - wenn 'point' (im Fall des Kompilierungspuffers der aktuelle Fehler) einen bestimmten Punkt überschreitet, scrollt der Bildschirm. Bei einem großen Datenbildschirm ist dies ein schwer zu findender Fehler. Das Verhalten des hl-Zeilenmodus wäre großartig, aber es hebt nur den aktuellen Puffer hervor (kann ich diesen überschreiben?) - daher wird die Codezeile, in der der Fehler auftritt, hervorgehoben, die Fehlerdaten jedoch nicht. Fadenkreuz scheint dasselbe mit Spalte und Zeile zu tun, was ich nicht brauche.
Spacemoose
Zumindest für mich immer noch unklar. next-errorSetzt für mich die aktuelle Fehlerzeile in die oberste Zeile des Fensters für den Puffer *compilation*. Es gibt natürlich global-hl-line-mode, aber Ihre Beschwerde / Frage war angeblich über den *compilation*Puffer. Die Frage wird weniger klar, nicht mehr (IMHO).
Drew
Wenn Sie in Emacs mit Fehlern kompilieren, führen Sie den nächsten Fehler aus. Im Quellpuffer befindet sich Ihr Cursor an der Fehlerquelle, und ein kleines schwarzes Dreieck zeigt die aktuelle Compiler-Fehlermeldung im Kompilierungspuffer an . Der aktuelle Fehler ist im Allgemeinen nicht die oberste Zeile des Puffers (ich habe gerade das Experiment in 24.5.1 durchgeführt). Ich finde es visuell anstrengend, nach dem schwarzen Dreieck zu suchen. Der hl-Zeilenmodus markiert nur die Zeile des aktiven Puffers, der der Quellpuffer ist. Ich möchte nicht zum Kompilierungspuffer springen, nur um die Zeile zu finden.
Spacemoose
Ich dachte, Sie rufen den nächsten Fehler im Puffer auf *compilation*. Wenn nicht, müssen Sie eine Funktion aktivieren next-error-hook, um die Hervorhebung (oder was auch immer) im Puffer durchzuführen*compilation* . Ich habe die Antwort mit einem Beispiel aktualisiert.
Drew
Ihr schnelles und schmutziges Beispiel beantwortet OPs Punkt 2, genau das, wonach ich gesucht habe. Durch das Scrollen des Kompilierungspuffers, sodass die aktive Zeile oben liegt (was nur gültig ist, wenn die linken Streifen die Größe 0 haben), habe ich den Kontext verloren (da die Zeilen über dem Fehler von Bedeutung sind), sodass ich festlegen musste compilation-context-lines. Infolgedessen war der aktuell ausgewählte Fehler schwer zu finden. Ihre Lösung hat mich gerettet.
Gauthier