Changer la couleur de surbrillance lorsque la fenêtre n'est pas mise au point?

13

J'utilise le mode hl comme mode mineur pour habile. Comment puis-je changer la couleur de la ligne en surbrillance (par exemple en gris) lorsque la fenêtre habile n'est pas la fenêtre actuelle, puis revenir à la couleur de surbrillance par défaut lorsque la fenêtre habile redevient la fenêtre actuelle?

Shankar
la source
Il s'avère qu'il existe une option pour cela, voir emacs.stackexchange.com/a/15141/780 .
glucas

Réponses:

5

J'ai implémenté cela pour hl-line-modeutiliser le buffer-list-update-hook. Voici le code:

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

Que fait ce code:

  • Définissez un nouveau visage hl-line-inactiveà utiliser dans les fenêtres inactives. Vous pouvez utiliser M-x customize-facepour modifier les attributs de ce visage à votre goût.
  • Définissez une fonction pour remapper temporairement le visage en surbrillance dans les fenêtres inactives. Une fenêtre est considérée comme inactive si elle n'affiche pas le même tampon que la fenêtre actuellement sélectionnée.
  • Ajoutez un crochet à buffer-list-update-hookcela qui appelle hl-line-update-facetoutes les fenêtres visibles.

Ancienne réponse

Le code ci-dessus (que j'utilise dans mon propre initfichier) est beaucoup plus simple que ce que j'ai initialement publié. Merci @Drew pour la suggestion à utiliser walk-windows. J'ai également lu plus sur le remappage de visage (voir Remappage de visage dans le manuel Emacs Lisp) et j'ai réalisé que je pouvais supprimer une grande partie du code.

Pour la postérité, voici ce que j'ai initialement publié:

;; 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
la source
Voir aussi la fonction walk-windows, que vous pouvez utiliser pour parcourir les fenêtres des cadres visibles, etc. (Et +1 pour buffer-list-update-hook, qui est appelé par select-window.)
Drew
+1 pour cela! Pas tellement pour les trucs hl-line en particulier, mais je cherche depuis des années pour trouver un moyen fiable d'ombrer l'arrière-plan des fenêtres inactives dans un cadre. Cela marche! Merci!
Aaron Miller
Merci, c'est génial! Malheureusement, il semble avoir des problèmes lors de l'utilisation global-hl-line-mode. Il semble que global-hl-line-modecela ne se charge pas hl-line-modepour chaque tampon. Il utilise une superposition au lieu d'utiliser le hl-linevisage. Je joue avec ça depuis un moment sans chance. Aucune suggestion? Dois-je ouvrir une question distincte?
Lorem Ipsum