Làm thế nào để bạn cập nhật một định nghĩa chế độ nhỏ khi bạn phát triển nó?


13

Tôi bắt đầu mã hóa một chế độ nhỏ để cung cấp một số keybindings. Nỗ lực ban đầu của tôi có một lỗi đánh máy:

(define-minor-mode borked-mode
  "A mode defined with a broken key binding"
  nil nil
  '(([b] . 'previous-line)))

Tôi đã có ý định sử dụng bchìa khóa, và ngay lập tức nhận ra rằng tôi nên sử dụng "b"thay vì [b]. Vì vậy, tôi xác định lại chế độ nhỏ:

(define-minor-mode borked-mode
  "A mode defined with a broken key binding"
  nil nil
  '(("b" . 'previous-line)))

Tuy nhiên, điều này đã không làm việc. Điều này đặt ra cho tôi một con ngỗng hoang dã đuổi theo tất cả các cách khác nhau của các khóa ràng buộc (ví dụ: (kbd ...), [...], v.v.). Cuối cùng tôi nhận ra rằng chỉ cần đánh giá lại (define-minor-mode ...)biểu mẫu không thay đổi gì cả, tôi đã bị mắc kẹt với bản đồ khóa bị hỏng ban đầu. Sau đó, tôi đã thử thay đổi sơ đồ bàn phím trực tiếp thông qua (define-key borked-mode-map ...)và vẫn không thể tải sơ đồ bàn phím đã sửa. Cuối cùng tôi khởi động lại Emacs và chế độ nhỏ của tôi đã được tải chính xác.

Câu hỏi của tôi là: làm thế nào để bạn cập nhật một định nghĩa chế độ nhỏ khi bạn phát triển nó? Có cách nào để xóa một định nghĩa bị hỏng, hoặc bạn phải khởi động lại emacs để xóa các bit bị hỏng?

Câu trả lời:


11

Lần đầu tiên bạn đánh giá define-minor-modenó sẽ xác định một biến borked-mode-mapvới các ràng buộc chính mà bạn đã chỉ định. Tuy nhiên, khi biểu tượng đó đã được xác định, tuy nhiên, đánh giá lại bạn define-minor-modesẽ không thay đổi nó.

Bạn có thể xóa các borked-mode-xxxbiểu tượng khác nhau bằng cách sử dụng uninternvà sau đó đánh giá lại mã của bạn. Thử:

(unintern 'borked-mode-map)

Bạn có thể quan tâm đến việc mở rộng define-minor-modemacro để xem những gì nó thực sự đang làm. Đặt điểm ở cuối và gọi M-x pp-macroexpand-last-sexp. Điều này sẽ mở một bộ đệm mới hiển thị macro mở rộng. Ở đó bạn sẽ thấy các defvarcuộc gọi được sử dụng để thiết lập các biến chế độ của bạn. Nếu bạn đọc trợ giúp, defvarbạn sẽ thấy rằng giá trị ban đầu chỉ được sử dụng nếu biểu tượng được xác định là không có giá trị - một khi nó tồn tại, các defvarcuộc gọi tiếp theo sẽ không thay đổi giá trị của nó.


13

Tôi nghĩ rằng câu trả lời tốt nhất tôi có thể cung cấp cho bạn là tránh xa "tính năng gõ phím nội tuyến" của define-minor-mode. Sử dụng

(defvar borked-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [b] 'previous-line)
    ...
    map))

(define-minor-mode borked-mode
  "A mode defined with a broken key binding"
  :global nil
  ...)

Thay thế. Sau đó, bạn có thể sử dụng C-M-xđể đánh giá lại các định nghĩa đó.


1
defvarsẽ không đánh giá lại giá trị của nó sau C-M-x:) Bạn cần defparameterhoặc riêng biệt setf.
wvxvw

Như @wvxvw chỉ ra, điều này thực sự không giải quyết được vấn đề. Mã ví dụ của bạn đang làm giống như define-minor-modemacro thực hiện: gọi defvarđể xác định bản đồ. Đánh giá rằng defvar lần thứ hai không có hiệu lực.
glucas

7
@wvxvw Nếu bạn sử dụng C-M-x( eval-defun) để đánh giá lại defvarthì biến được cập nhật. Đây là một trường hợp đặc biệt trong eval-defun; nếu bạn gọi eval-bufferhoặc eval-regionsau đó giá trị hiện tại không thay đổi.
Gilles 'SO- ngừng trở thành ác quỷ'

Ah - đó có vẻ như là điểm chính.
glucas

1
Lưu ý rằng C-M-xtrên defvarbiểu mẫu chỉ cập nhật biến bản đồ chế độ. Bạn cũng phải C-M-xvào define-minor-modebiểu mẫu để đưa bản đồ đã thay đổi 'được cài đặt' vào chế độ nhỏ. Tôi đã cố gắng tìm hiểu tại sao bằng cách mở rộng các macro, nhưng nó vượt xa tôi.
Tyler
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.