Zmienić kolor podświetlenia, gdy okno nie jest ostre?

13

Używam trybu hl jako mniejszego trybu dla zręczności. Jak zmienić kolor podświetlonej linii (np. Na szary), gdy okno deft nie jest bieżącym oknem, a następnie powrócić do domyślnego koloru podświetlenia, gdy okno deft ponownie staje się bieżącym oknem?

Shankar
źródło
Okazuje się, że jest na to opcja, patrz emacs.stackexchange.com/a/15141/780 .
glucas

Odpowiedzi:

5

Zaimplementowałem to do hl-line-modeużywania buffer-list-update-hook. Oto kod:

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

Co robi ten kod:

  • Zdefiniuj nową twarz hl-line-inactivedo użycia w nieaktywnych oknach. Możesz użyć M-x customize-facedo zmodyfikowania atrybutów tej twarzy według własnego gustu.
  • Zdefiniuj funkcję tymczasowego mapowania podświetlonej twarzy w nieaktywnych oknach. Okno jest uważane za nieaktywne, jeśli nie wyświetla tego samego bufora co aktualnie wybrane okno.
  • Dodaj hak do buffer-list-update-hooktych połączeń hl-line-update-facedla wszystkich widocznych okien.

Stara odpowiedź

Powyższy kod (którego używam we własnym initpliku) jest znacznie prostszy niż ten, który pierwotnie opublikowałem. Dzięki @Drew za sugestię użycia walk-windows. Przeczytałem również więcej o remapowaniu twarzy (zobacz Remapowanie twarzy w Podręczniku Emacs Lisp) i zdałem sobie sprawę, że mogę usunąć dużo kodu.

Dla potomnych oto, co pierwotnie opublikowałem:

;; 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
źródło
Zobacz także funkcję walk-windows, której można użyć do iteracji po oknach widocznych ram itp. (I +1 dla buffer-list-update-hook, który zostaje wywołany select-window).
Drew
+1 za to! Nie tyle w kwestii hl-line w konkretnym przypadku, ale od lat szukałem niezawodnego sposobu cieniowania tła nieaktywnych okien w ramce. To działa! Dzięki!
Aaron Miller
Dziękuję, to jest niesamowite! Niestety wydaje się, że występują problemy podczas korzystania global-hl-line-mode. Wygląda na to, że global-hl-line-modenie ładuje się hl-line-modedla każdego bufora. Używa nakładki zamiast hl-linetwarzy. Przez jakiś czas majstrowałem przy tym bez powodzenia. Jakieś sugestie? Czy powinienem otworzyć osobne pytanie?
Lorem Ipsum