Elisp là một ngôn ngữ được giải thích. Bạn có thể đặt mã dành riêng cho phiên bản .emacs
, nhưng bảo vệ mã bằng cách kiểm tra tại thời điểm tải mà nó hoạt động trên phiên bản chính xác.
(if (is-new-feature-available)
(shiny-new-feature)
(old-less-nifty-feature))
Mã này sẽ hoạt động trong tất cả các phiên bản vì (shiny-new-feature)
chỉ được đánh giá khi (is-new-feature-available)
trả về true. Phần lớn câu trả lời này được dành cho cách thực hiện (is-new-feature-available)
.
Đối phó với các bộ tính năng khác nhau
Tốt hơn hết là kiểm tra xem một tính năng có khả dụng hay không hơn là kiểm tra phiên bản Emacs. Đôi khi tính năng có thể có sẵn như là một gói tùy chọn. Nếu bạn muốn chạy mã trong XEmac hoặc biến thể Emacs khác, nó có thể đã có được các tính năng tương tự trong các phiên bản khác nhau. Sử dụng chức năng boundp
để kiểm tra nếu một biến có sẵn và fboundp
để kiểm tra nếu một chức năng có sẵn.
Ví dụ: đoạn mã sau liên kết một phím để chuyển đổi visual-line-mode
nếu có, và longlines-mode
nếu không.
(global-set-key "\eml" (if (fboundp 'visual-line-mode)
'visual-line-mode
'longlines-mode))
Đôi khi, thay vì kiểm tra tính năng, việc chạy một đoạn mã nhỏ sẽ dễ dàng hơn và bỏ qua mọi lỗi do các hàm không xác định, đối số không hợp lệ, v.v. Đừng làm điều này với số lượng lớn mã, vì điều này sẽ làm cho mã của bạn rất khó gỡ lỗi.
Ví dụ: tôi không muốn xem thanh công cụ. Các phiên bản cũ hơn của Emacs hoàn toàn không có chúng. GNU Emacs và XEmac đã thêm tính năng đó theo nhiều cách khác nhau và biến nó thành mặc định. Đây là cách tôi tắt chúng đi. Các set-specifier
chức năng cụ thể để XEmacs, và default-toolbar-visible-p
là cụ thể cho các phiên bản gần đây của đủ Emacs; sử dụng condition-case
chăm sóc cả hai yêu cầu. GNU Emacs cung cấp một chức năng chuyên dụng vì vậy tôi chỉ kiểm tra xem chức năng đó có khả dụng không.
;; For XEmacs
(condition-case nil
(set-specifier default-toolbar-visible-p nil)
(error nil))
;; For GNU Emacs
(if (fboundp 'tool-bar-mode)
(tool-bar-mode 0))
Một số tên khuôn mặt thay đổi qua các phiên bản. Sử dụng facep
để kiểm tra tính khả dụng của một tên khuôn mặt.
(let ((face (if (facep 'mode-line) 'mode-line 'modeline)))
(set-face-background face …))
Đôi khi bạn có thể muốn tải một gói đẹp nếu có, và không làm gì nếu gói đó không có sẵn. require
có một đối số tùy chọn cho điều đó.
(require 'tex-site nil t) ;; Load AUCTeX if available
Đối số này đã được giới thiệu trong GNU Emacs 20.4 và không có sẵn trong XEmac, vì vậy nếu bạn muốn quay lại đó, bạn sẽ phải bọc nó lại condition-case
hoặc sử dụng load
thay thế (không kiểm tra các thư viện đã được tải) .
Giới hạn các phụ thuộc phiên bản cho các tính năng cấp người dùng. Không sử dụng các tính năng lập trình mới hơn không có sẵn trong tất cả các phiên bản bạn muốn hỗ trợ: bạn sẽ phải cung cấp phiên bản tương thích cho các phiên bản cũ hơn và việc duy trì một phiên bản duy nhất sẽ dễ dàng hơn.
Đôi khi bạn cần một tính năng ở nhiều nơi và nó có sẵn trên tất cả các triển khai bạn quan tâm, nhưng theo một cách khác. Đây chủ yếu là trường hợp nếu bạn muốn hỗ trợ cả XEmac và GNU Emacs: chúng có xu hướng bực bội khi sao chép các tính năng của nhau nhưng không phải giao diện của chúng. Trong trường hợp này, việc xác định chức năng tương thích sẽ thuận tiện hơn so với thử nghiệm tại điểm sử dụng.
Ví dụ, đoạn mã sau định nghĩa một hàm trả về hệ thống cửa sổ của khung hiện tại, cách GNU hiện đại, cách XEmac hiện đại và cách kiểu cũ khi bạn không thể kết hợp các khung đầu cuối và GUI trong cùng một ví dụ.
(defalias 'compat-window-system
(cond
((fboundp 'window-system) #'window-system)
((fboundp 'device-type)
(lambda (&optional frame)
(device-type (frame-device frame))))
(t
(lambda (&optional frame) window-system))))
Phụ thuộc môi trường
Không có nhiều mã cần phải phụ thuộc vào nền tảng. Biến system-type
chỉ ra hệ điều hành. Tôi sử dụng nó để kích hoạt một vài bản hack cho ms-dos
(vâng, các tệp của tôi đã cũ) và windows-nt
.
Bạn có thể muốn thêm các thư mục vào đường dẫn tìm kiếm thực thi của mình ( PATH
), nhưng điều đó thường được thực hiện tốt nhất bên ngoài Emacs, trong .profile
hệ thống giống như Unix của bạn và thông qua bảng điều khiển trong Windows. Để kiểm tra xem một chương trình bên ngoài có sẵn hay không, hãy gọi executable-find
.
Đối với mã cần hành động khác nhau tùy thuộc vào loại GUI nếu có, hãy kiểm tra window-type
hoặc người kế thừa của nó (xem bên trên).
Tập tin khởi tạo
Để tương thích tối đa, đặt mã của bạn vào ~/.emacs
. GNU Emac bắt đầu tìm kiếm trong ~/emacs.d
phiên bản 22. XEmac bắt đầu tìm kiếm ~/.xemacs
trong phiên bản 21.4. Một cách tiếp cận khác là đưa mã tương thích vào ~/.emacs
và kết thúc bằng cách tải tệp chính của bạn. Đặt (setq load-home-init-file t)
một nơi nào đó để tránh có các phiên bản gần đây của XEmacs hỏi bạn có muốn di chuyển .emacs
đến vị trí chỉ XEmacs không.
Các phiên bản khác nhau của Emacs có thể có sự mở rộng khác nhau và không tương thích đối với một số macro. Vì vậy, đừng chia sẻ các tệp được biên dịch byte của bạn giữa các phiên bản, biên dịch các tệp trên mỗi máy.
Đôi khi một tính năng không được dùng nữa, nhưng bạn vẫn muốn sử dụng nó vì đó là tất cả những gì có trong một phiên bản khác mà bạn muốn hỗ trợ. Các cảnh báo trình biên dịch byte đến từ byte-obsolete-variable
tài sản.
(cond
((not (boundp 'desktop-enable))
(defvaralias 'desktop-enable 'desktop-save-mode))
((get 'desktop-enable 'byte-obsolete-variable)
(put 'desktop-enable 'byte-obsolete-variable nil)))
¹ Tương đối nói, so với XEmacs cũ.
window-system
, vv có thể được trả lời hợp lý ở đây.