Змінити колір виділення, коли вікно не в фокусі?


13

Я використовую hl-режим як другорядний режим для спритного. Як зробити так, щоб виділена лінія змінила колір (наприклад, на сірий), коли вільне поле не є поточним вікном, а потім повернутись до кольору підсвічування за замовчуванням, коли схиле вікно знову стане поточним вікном?


Виявляється, для цього є варіант, див. Emacs.stackexchange.com/a/15141/780 .
glucas

Відповіді:


5

Я реалізував це для hl-line-modeвикористання buffer-list-update-hook. Ось код:

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

Що робить цей код:

  • Визначте нове обличчя, hl-line-inactiveяке використовуватиметься в неактивних вікнах. Ви можете використовувати M-x customize-faceдля зміни атрибутів цього обличчя на свій смак.
  • Визначте функцію тимчасового перестановки підсвічування обличчя в неактивних вікнах. Вікно вважається неактивним, якщо воно не відображає той самий буфер, як і поточне обране вікно.
  • Додайте гачок, buffer-list-update-hookщо вимагає hl-line-update-faceвсіх видимих ​​вікон.

Стара відповідь

Код вище (який я використовую у власному initфайлі) набагато простіше, ніж те, що я розмістив спочатку. Дякую @Drew за пропозицію використовувати walk-windows. Я також прочитав більше про перепланування обличчя (див. « Переробка обличчя» у посібнику Emacs Lisp) і зрозумів, що я можу видалити багато коду.

Щодо нащадків, ось що я спочатку розмістив:

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

Дивіться також функцію walk-windows, яку ви можете використовувати для ітерації над вікнами видимих ​​кадрів тощо (і +1 для buffer-list-update-hook, на яку телефонує select-window.)
Дрю

+1 для цього! Не стільки для специфіки hl-line конкретного, але я вже не дивлюся і намагаюся роками шукати надійний спосіб затінення фонів неактивних вікон у кадрі. Це працює! Спасибі!
Аарон Міллер

Дякую, це приголомшливо! На жаль, схоже, що проблеми користуються global-hl-line-mode. Здається, що global-hl-line-modeне завантажується hl-line-modeдля кожного буфера. Він використовує накладку замість використання hl-lineобличчя. Я певний час поспілкувався з нею. Будь-які пропозиції? Чи варто відкрити окреме запитання?
Lorem Ipsum
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.