Bagaimana cara "mengelompokkan" kait?

14

Ada hal-hal tertentu seperti tampilan spasi spasi, tampilan batas buffer, pembatas berwarna pelangi, dan banyak lagi yang ingin saya aktifkan di sebagian besar mode atau lebih tepatnya, semua pemrograman dan yang terkait dengan teks (karena menampilkan spasi tambahan di, katakanlah ediff-mode, akan berbenturan dengan mode utama) daripada menggunakan mode minor global dengan aturan pengecualian. Karena sebagian besar mode berasal dari salah satu prog-modeatau text-mode, menambahkan fungsi yang dipermasalahkan ke keduanya prog-mode-hookdan text-mode-hookberfungsi, namun ada cukup mode yang tidak mengikuti spesifikasi ini, seperti css-modeatau LaTeX-mode.

Saya ingin mendefinisikan sebuah hook yang mencakup semua mode ini untuk saat ini hanya menambahkan fungsi ke satu hook. Sebut saja non-special-mode-hook(untuk membedakannya dari special-mode-hook). Bagaimana saya bisa membuat pengait yang dijalankan untuk semua mode utama yang dibuatnya?

wasamasa
sumber

Jawaban:

19

Cukup kelompok pengaturan itu bersama-sama ke dalam suatu fungsi, dan tambahkan fungsi itu ke semua fungsi kait yang relevan:

(defun my-non-special-mode-setup ()
  (setq show-trailing-whitespace t)
  ...)
(dolist (hook '(prog-mode-hook text-mode-hook css-mode-hook ...))
  (add-hook hook 'my-non-special-mode-setup))

Tidak ada cara lain untuk melakukan ini yang lebih ringkas: apa pun yang terjadi, di suatu tempat Anda akan memiliki daftar putih atau daftar hitam mode. Dalam praktiknya, Anda hanya akan menemukan beberapa mode yang perlu ditambahkan ke daftar, jadi saya sarankan agar semuanya tetap sederhana.

Dalam konfigurasi saya sendiri, saya menggunakan trik ini untuk menyatukan konfigurasi beberapa mode berorientasi lisp.

sanityinc
sumber
Terima kasih, saya pikir saya akan mengadaptasi solusi ini untuk kelompok berguna lainnya (seperti yang lispy) juga.
wasamasa
1
Itulah yang saya lakukan sendiri: github.com/purcell/emacs.d/blob/…
sanityinc
1
Luar biasa, bisakah Anda menambahkan URL ke jawaban Anda? Saya percaya cuplikan yang disorot tidak hanya menjelaskan penggunaan sebenarnya dengan sangat baik, tetapi juga menunjukkan penggunaan lebih lanjut, seperti menggunakan "kait" yang terkait dengan Emacs Lisp sebagai bagian dari "kait" yang lebih besar dan bagaimana seseorang secara otomatis membuat nama kait dari mode utama yang ada dengan derived-mode-hook-name.
wasamasa
Aku seperti ini lebih dari saya, hanya untuk (dolist ...)vs (add-hook ...)<ulangi>. Saya hanya akan tetap dengan milik saya ketika menjaga perubahan spesifik mode (file per mode use-package,, el-get). Keduanya merupakan solusi all-in-one-place, tetapi dari sudut pandang yang berbeda.
Jonathan Leech-Pepin
Perlu diketahui bahwa jika Anda tidak memberikan APPENDargumen nihil ke add-hooksini, maka kait akan dipanggil dalam urutan terbalik dari urutan daftar yang Anda berikan. Tidak ada yang salah dengan itu; hanya sadar akan hal itu, jika urutan masalah.
Drew
5

Anda dapat menambahkan fungsi ke after-change-major-mode-hook, yang memeriksa apakah mode baru itu menarik (mungkin melalui (not (derived-mode-p 'special-mode))), dan jika demikian berjalan non-special-mode-hook.

legoscia
sumber
Ini kedengarannya cukup bagus (begitu seseorang telah menemukan semua mode "tidak khusus" karena ada beberapa yang hanya digunakan fundamental-mode, tetapi melakukan lebih dari sekedar menampilkan teks), tetapi agak terlalu ajaib untuk seleraku. Karena itu upvote.
wasamasa
4

Saya menemukan diri saya sering melakukan pola @ sanityinc untuk membungkus pengaturan saya dan aktivasi mode minor dalam defun dan mengulang melalui kait untuk menyebutnya, tapi saya ingin pendekatan yang lebih bersih jadi saya menulis makro ini:

(defmacro hook-modes (modes &rest body)
  (declare (indent 1))
  `(--each ,modes
     (add-hook (intern (format "%s-hook" it))
               (lambda () ,@body))))

Catatan: Saya dash.elkebersihan, tetapi mudah disesuaikan untuk digunakan (dolist).

Kemudian Anda dapat mendefinisikan mode yang dikelompokkan sebagai variabel daftar dan menggunakannya seperti:

(defvar progish-modes
  '(prog-mode css-mode sgml-mode))

(hook-modes progish-modes
  (highlight-symbol-mode)
  (highlight-symbol-nav-mode))
waymondo
sumber
1
Perhatikan bahwa di sini Anda dapat menggunakan derived-mode-hook-nameuntuk mendapatkan nama variabel kait mode, sehingga menghindari interntriknya.
sanityinc
@sanityinc TIL derived-mode-hook-name. tip yang bagus!
waymondo
1

Daripada menetapkan hook baru yang berfungsi untuk semua mode non-diturunkan ini Anda dapat melakukan hal berikut.

(defun run-my-hooks ()
  "Run all the following functions in the hook"
  (smartparens-mode 1)
  (whitespace-mode 1)
  (my-needed-mode 1)
  ...)

(add-hook 'specific-mode-hook 'run-my-hooks)
(add-hook 'another-mode-hook 'run-my-hooks)

Anda masih harus menambahkannya ke semua mode, tetapi dengan mendefinisikan fungsi Anda untuk memasukkan semua mode, Anda hanya perlu mengubah satu definisi saat menambahkan / menghapus fitur tambahan.

Jonathan Leech-Pepin
sumber
-2

Mungkin Anda bisa mencoba ini:

(setq lisp-dialects-mode-hook '(lisp-mode-hook
                            lisp-interaction-mode-hook
                            emacs-lisp-mode-hook
                            ;; common-lisp-mode-hook
                            scheme-mode-hook
                            clojure-mode-hook
                            cider-repl-mode-hook
                            ))

(add-hook 'lisp-dialects-mode-hook 'func)
stardiviner
sumber