Изменить цвет подсветки, когда окно не в фокусе?

13

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

Шанкар
источник
Оказывается, есть вариант для этого, см. 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. Я также прочитал больше о перераспределении лиц (см. Face Remapping в Руководстве по 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)
glucas
источник
См. Также функцию 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