Ubah warna sorotan saat jendela tidak fokus?

13

Saya menggunakan mode-hl sebagai mode minor untuk cekatan. Bagaimana cara membuat garis yang disorot berubah warna (misalnya menjadi abu-abu) ketika jendela cekatan bukan jendela saat ini, dan kemudian kembali ke warna sorot default ketika jendela cekatan menjadi jendela saat ini lagi?

Shankar
sumber
Ternyata ada opsi untuk ini, lihat emacs.stackexchange.com/a/15141/780 .
glucas

Jawaban:

5

Saya sudah menerapkan ini untuk hl-line-modemenggunakan buffer-list-update-hook. Berikut kodenya:

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

Apa yang dilakukan kode ini:

  • Tentukan wajah baru hl-line-inactiveuntuk digunakan di windows tidak aktif. Anda dapat menggunakannya M-x customize-faceuntuk memodifikasi atribut wajah ini sesuai selera Anda.
  • Tetapkan fungsi untuk memetakan sementara wajah sorotan di jendela yang tidak aktif. Sebuah jendela dianggap tidak aktif jika tidak menampilkan buffer yang sama dengan jendela yang saat ini dipilih.
  • Tambahkan hook ke buffer-list-update-hookpanggilan itu hl-line-update-faceuntuk semua jendela yang terlihat.

Jawaban lama

Kode di atas (yang saya gunakan dalam initfile saya sendiri ) jauh lebih sederhana daripada apa yang saya posting sebelumnya. Terima kasih @Drew atas saran untuk digunakan walk-windows. Saya juga membaca lebih lanjut tentang remapping wajah (lihat Face Remapping dalam Manual Emacs Lisp) dan menyadari bahwa saya dapat menghapus banyak kode.

Untuk anak cucu, inilah yang awalnya saya posting:

;; 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)
glukas
sumber
Lihat juga fungsi walk-windows, yang dapat Anda gunakan untuk beralih ke jendela-jendela bingkai yang terlihat, dll. (Dan +1 untuk buffer-list-update-hook, yang dipanggil oleh select-window.)
Drew
+1 untuk ini! Tidak terlalu banyak untuk hal-hal hl-line secara spesifik, tetapi saya telah mencari selama bertahun-tahun untuk menemukan cara yang dapat diandalkan untuk menaungi latar belakang jendela tidak aktif dalam bingkai. Ini bekerja! Terima kasih!
Aaron Miller
Terima kasih, ini luar biasa! Sayangnya, sepertinya ada masalah saat menggunakan global-hl-line-mode. Tampaknya global-hl-line-modetidak memuat hl-line-modeuntuk setiap buffer. Ia menggunakan overlay alih-alih menggunakan hl-linewajah. Saya sudah mengotak-atiknya untuk sementara waktu tanpa hasil. Ada saran? Haruskah saya membuka pertanyaan terpisah?
Lorem Ipsum