Alterar a cor de destaque quando a janela não está em foco?

13

Estou usando o hl-mode como um modo menor para habilidoso. Como faço para que a linha destacada mude de cor (por exemplo, para cinza) quando a janela hábil não é a janela atual e depois para a cor de destaque padrão quando a janela hábil se torna a janela atual novamente?

Shankar
fonte
Acontece que há uma opção para isso, consulte emacs.stackexchange.com/a/15141/780 .
glucas

Respostas:

5

Eu implementei isso hl-line-modeusando o buffer-list-update-hook. Aqui está o código:

(defface hl-line-inactive
  '((t nil))
  "Inactive variant of `hl-line'."
  :group 'hl-line)

(defun hl-line-update-face (window)
  "Update the `hl-line' face in WINDOW to indicate whether the window is selected."
  (with-current-buffer (window-buffer window)
    (when hl-line-mode
      (if (eq (current-buffer) (window-buffer (selected-window)))
          (face-remap-reset-base 'hl-line)
        (face-remap-set-base 'hl-line (face-all-attributes 'hl-line-inactive))))))

(add-hook 'buffer-list-update-hook (lambda () (walk-windows #'hl-line-update-face nil t)))

O que esse código está fazendo:

  • Defina uma nova face hl-line-inactivea ser usada em janelas inativas. Você pode usar M-x customize-facepara modificar os atributos dessa face ao seu gosto.
  • Defina uma função para remapear temporariamente a face de destaque em janelas inativas. Uma janela é considerada inativa se não estiver exibindo o mesmo buffer que a janela atualmente selecionada.
  • Adicione um gancho a buffer-list-update-hookisso chama hl-line-update-facetodas as janelas visíveis.

Resposta antiga

O código acima (que eu estou usando no meu próprio initarquivo) é muito mais simples do que o que eu originalmente publiquei. Obrigado @Drew pela sugestão de uso walk-windows. Também li mais sobre o remapeamento de rosto (consulte Remapeamento de rosto no Emacs Lisp Manual) e percebi que poderia remover muito do código.

Para a posteridade, aqui está o que eu postei originalmente:

;; Define a face for the inactive highlight line.
(defface hl-line-inactive
  '((t nil))
  "Inactive variant of `hl-line'."
  :group 'local)

(defun toggle-active-window-highlighting ()
  "Update the `hl-line' face in any visible buffers to indicate which window is active."
  (let ((dups))
    (mapc
     (lambda (frame)
       (mapc
        (lambda (window)
          (with-current-buffer (window-buffer window)
            (when hl-line-mode
              (make-local-variable 'face-remapping-alist)
              (let ((inactive (rassoc '(hl-line-inactive) face-remapping-alist)))
                (if (eq window (selected-window))
                    (progn
                      (setq dups (get-buffer-window-list nil nil 'visible))
                      (setq face-remapping-alist (delq inactive face-remapping-alist)))
                  (unless (or inactive (memq window dups))
                    (add-to-list 'face-remapping-alist '(hl-line hl-line-inactive))))))))
        (window-list frame)))
     (visible-frame-list))))

(add-hook 'buffer-list-update-hook #'toggle-active-window-highlighting)
glucas
fonte
Veja também a função walk-windows, que você pode usar para iterar sobre as janelas de quadros visíveis etc. (E +1 para buffer-list-update-hook, o que é chamado por select-window).
Drew
+1 para isso! Não é muito específico para as coisas da linha hl, mas tenho procurado anos e anos para encontrar uma maneira confiável de proteger os fundos das janelas inativas em um quadro. Isso funciona! Obrigado!
Aaron Miller
Obrigado, isso é incrível! Infelizmente, parece ter problemas ao usar global-hl-line-mode. Parece que global-hl-line-modenão carrega hl-line-modepara cada buffer. Ele usa uma sobreposição em vez de usar a hl-lineface. Estou brincando com isso há um tempo, sem sorte. Alguma sugestão? Devo abrir uma pergunta separada?
Lorem Ipsum