Câu trả lời:
Danh sách tất cả các lệnh chế độ nhỏ được lưu trữ trong biến minor-mode-list
. Việc tìm hiểu xem chúng có đang hoạt động hay không thường được thực hiện bằng cách kiểm tra biến cùng tên. Vì vậy, bạn có thể làm điều gì đó như sau:
(defun which-active-modes ()
"Give a message of which minor modes are enabled in the current buffer."
(interactive)
(let ((active-modes))
(mapc (lambda (mode) (condition-case nil
(if (and (symbolp mode) (symbol-value mode))
(add-to-list 'active-modes mode))
(error nil) ))
minor-mode-list)
(message "Active modes are %s" active-modes)))
Lưu ý: điều này chỉ hoạt động đối với bộ đệm hiện tại (vì các chế độ phụ có thể chỉ được bật trong một số bộ đệm nhất định).
boundp
thay vì symbolp
bạn có thể loại bỏ condition-case
.
describe-mode
bằng cách nào đó có thể đưa ra danh sách các chế độ nhỏ được bật, tại sao tôi không thể? Vì vậy, sau khi đọc mã nguồn của nó, tôi nhận ra rằng nó nhận được danh sách các chế độ nhỏ đang hoạt động từ cả hai minor-mode-list
và minor-mode-alist
. Sử dụng dash.el
thư viện thao tác danh sách của bên thứ ba, tôi đã đi kèm với mã này:
(--filter (and (boundp it) (symbol-value it)) minor-mode-list)
Vì vậy, ví dụ, để tắt tất cả các chế độ nhỏ, hãy sử dụng -each
:
(--each (--filter (and (boundp it) (symbol-value it)) minor-mode-list)
(funcall it -1))
Đừng quên lưu danh sách các chế độ nhỏ trong một biến, nếu không bạn sẽ phải khởi động lại Emacs hoặc kích hoạt chúng bằng bộ nhớ.
Nếu bạn muốn lập trình làm điều gì đó với tất cả các bộ đệm có một chế độ nhất định đang hoạt động, thì giải pháp tích hợp tốt nhất, tối giản nhất, sạch sẽ nhất là như sau:
(dolist ($buf (buffer-list (current-buffer)))
(with-current-buffer $buf
(when some-buffer-local-minor-or-major-mode-variable-you-want-to-find
(message "x %s" $buf))))
Nó làm như sau:
buffer-list
, với bộ đệm hiện đang hoạt động ở đầu danh sách (vì vậy, nó được xử lý đầu tiên, thường là những gì bạn muốn, nhưng bỏ qua current-buffer
tham số nếu bạn không quan tâm).$buf
.with-current-buffer $buf
để nói với Emacs rằng tất cả mã bên trong phần thân sẽ chạy như thể nó đang chạy bên trong bộ đệm $buf
thay vì bất kỳ bộ đệm nào bạn đang thực sự hiển thị trên màn hình.when <some mode variable>
là cách chính xác để kiểm tra xem một chế độ đã được bật chưa; bạn cũng có thể sử dụng if
và các phương pháp khác như vậy. Dù bằng cách nào, mục tiêu là kiểm tra xem biến chế độ chính của chế độ phụ hoặc chế độ chính có được đặt trong bộ đệm hay không. Hầu hết tất cả các chế độ xác định một biến thông qua "định nghĩa" một chế độ, chế độ này sẽ tự động tạo ra một biến cục bộ đệm được đặt tên theo chế độ, đó là cách hoạt động của nó. Và nếu họ không có biến tiêu chuẩn, hãy xem mã nguồn của chính họ để xem cách mã "chuyển đổi" của họ xác định cách bật và tắt chúng. 99% trong số họ sử dụng sự tồn tại của biến modename của họ (và nếu không, tôi khuyên bạn nên báo cáo đó là lỗi cho tác giả của mode). Ví dụ, để kiểm tra xem một bộ đệm có hoạt động ở chế độ khoảng trắng hay không, bạn sẽ nói when whitespace-mode
.Thưởng thức! Chuyển sang mã lisp lớn hơn và sạch hơn!
Đây là một đoạn mã thay thế đơn giản tương tự như một số phương pháp đã được đề cập trong các câu trả lời khác:
(delq nil
(mapcar
(lambda (x)
(let ((car-x (car x)))
(when (and (symbolp car-x) (symbol-value car-x))
x)))
minor-mode-alist))