enfatizar o erro atual na janela * compilação *

12

Ao executar o comando compile e pular para o 'próximo erro', o emacs identifica a linha do erro atual colocando um pequeno triângulo preto, apontando para a direita, na margem esquerda do buffer * compilation * . Isso é legal, mas meus velhos olhos gostariam de um indicador mais ousado. O objetivo fundamental aqui é ser capaz de identificar rapidamente visualmente qual linha o emacs está identificando como o erro atual do compilador. Algumas soluções que vêm à mente:

  1. uma face diferente para o erro atual (maior por exemplo).
  2. uma cor de fundo diferente para o erro atual (algo como modo hl-linha).
  3. um triângulo maior.

mas também estou aberto a outras idéias.

Alguém pode me ajudar?

Spacemoose
fonte

Respostas:

2

Eu queria conseguir a mesma coisa, pois muitas vezes era doloroso encontrar a mensagem de erro atual no buffer de compilação. Esta solução é baseada na sugestão de Drew de usar a next-error-hookpara destacar a mensagem de erro. Atualmente, apenas destaca a primeira linha da mensagem de erro, mas acho que isso é bom o suficiente.

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

Uso:

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

Demo:

demonstração

erjoalgo
fonte
1

Aqui está um exemplo de como modificar a imagem de bitmap que aparece na margem esquerda do *compilation*buffer (por exemplo, o *grep*buffer de resultados):

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

Aqui está um exemplo de como definir as cores dos bitmaps adicionais:

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

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

Aqui está um exemplo de como criar seu próprio bitmap adicional:

;; 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)
lista de leis
fonte
Isso parece muito promissor. Vou tentar amanhã (ficando a hora de dormir aqui).
Spacemoose
1

Não next-errorrola o buffer de erros de compilação, para que o erro atual seja exibido como a primeira linha da janela?

Caso contrário, ele não coloca o cursor na linha de erro atual? Se houver, e se o cursor não estiver visível o suficiente para você, considere usar hl-line-modepara destacar a linha atual. Ou considere usar a biblioteca crosshairspara destacar a linha atual e a coluna atual.


Atualize após o seu comentário

Eu pensei que você estava invocando next-errorno buffer *compilation*. Se você fizer isso, a linha será rolada para o topo, como descrevi.

Mas se você estiver chamando o next-errorbuffer externo *compilation*, precisará usar next-error-hook, no buffer*compilation* , a linha ou a franja atual ou o que for, da maneira que desejar.

Aqui está um exemplo rápido e sujo:

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

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

(Claro, você realmente só precisa de ligar hl-line-modeuma vez em que buffer. Fazê-lo como mostrado acima é um exagero, mas não faz mal. Você pode pensar que você poderia apenas adicionar fooao grep-mode-hookou compilation-mode-hook. Mas quando esses ganchos são invocados existe não next-error-last-buffer.)

Nota:

  1. Existem duas opções de usuário que controlam as maneiras de indicar a ocorrência no buffer de origem (não no buffer de compilação): next-error-highlighte next-error-highlight-no-select. Eles oferecem as mesmas possibilidades, mas são usados ​​por comandos diferentes. As possibilidades incluem usar uma seta de franja ou destacar a partida por um certo tempo.

  2. Mas não existe essa opção controlando a indicação da ocorrência atual no buffer *compilation*. Portanto, o Emacs oferece duas opções (onde provavelmente seria suficiente) para o buffer de origem, mas nenhuma opção para o buffer de compilação.

Você pode considerar a apresentação de uma solicitação de melhoria, para obter uma opção semelhante para a compilação (incluindo grep) buffer: M-x report-emacs-bug. Usar um gancho com sua própria função para realizar o realce é bom, mas não deve ser necessário.


E se você quiser apenas alterar o indicador de franja, você pode fazer isso (use o bitmap de franja desejado, em vez de filled-rectangle- consulte (elisp) Bitmaps de franja para obter uma lista dos predefinidos):

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

Atualização # 2:

Acabei de descobrir que, se você desligar a margem esquerda, verá o comportamento que descrevi no início: a janela é rolada para colocar o erro atual no topo. Então essa é outra possibilidade. (É o comportamento que vejo na minha configuração, pois não mostro margem.)

Há um erro neste comportamento, que acabei de relatar ( # 20829 ). O que conta (atualmente, até que o bug seja corrigido) é se a margem esquerda está aparecendo na janela selecionada quando você faz C-x `( next-error). (Atualmente) não é suficiente que a janela que mostra o buffer de compilação não mostre a margem esquerda.

Desenhou
fonte
A rolagem do buffer de compilação parece funcionar como o resto do emacs - quando 'point' (no caso de buffer de compilação, o erro atual) ultrapassa um determinado ponto, a tela rola. para uma grande tela de dados, isso torna um erro difícil de encontrar. O comportamento do modo hl-line-seria ótimo, mas destaca apenas o buffer atual (posso substituir isso?) - portanto, a linha de código onde o erro ocorre é realçada, mas não existem dados de erro. mira parece fazer a mesma coisa com colunas e linhas, das quais não preciso.
Spacemoose
Ainda não está claro, pelo menos para mim. Para mim, next-errorcoloca a linha de erro atual na linha superior da janela do buffer *compilation*. Claro que existe global-hl-line-mode, mas sua reclamação / pergunta era supostamente sobre o *compilation*buffer. A questão está ficando menos clara, não mais (IMHO).
Tirou
Quando você compila no emacs com erros, execute o próximo erro. No buffer de origem, seu cursor estará na origem do erro e há um pequeno triângulo preto indicando a mensagem de erro atual do compilador no buffer de compilação . O erro atual geralmente não é a linha superior do buffer (acabei de fazer o experimento em 24.5.1). Acho visualmente complicado procurar o triângulo preto. O modo hl-line destaca apenas a linha do buffer ativo , que é o buffer de origem. Não quero pular para o buffer de compilação apenas para encontrar a linha.
Spacemoose
Eu pensei que você estava invocando próximo erro no buffer *compilation*. Caso contrário, é necessário ativar uma função next-error-hookpara realçar (ou o que seja) no buffer*compilation* . Eu atualizei a resposta com um exemplo.
Tirou
Seu exemplo rápido e sujo responde ao ponto 2 do OP, que é exatamente o que eu estava procurando. A rolagem do buffer de compilação para que a linha ativa fique no topo (que só é válida se as bordas esquerdas forem do tamanho 0) me fez perder o contexto (já que as linhas acima do erro são significativas), então tive que definir compilation-context-lines. Como resultado, foi difícil encontrar o erro selecionado no momento. Sua solução me salvou.
Gauthier