Tôi sẽ phác thảo chế độ chính đơn giản để làm nổi bật các khối <style>
(CSS) và <script>
(JavaScript, v.v ...). Để có được khóa phông chữ đa phương thức hoạt động tốt, trước tiên bạn cần bật nó bằng cách đặt font-lock-multiline
đến t
và viết hàm để thêm font-lock-extend-region-functions
. Sau đó, bạn cần phải ghi các đối sánh nhiều dòng — một trong hai biểu thức hoặc hàm thông thường — và thêm chúng vào font-lock-defaults
.
Dưới đây là một định nghĩa chế độ chính cơ bản mà tên font khóa danh sách từ khóa (ở đây, test-font-lock-keywords
), cho phép khóa phông chữ multiline và thêm các chức năng mở rộng khu vực test-font-lock-extend-region
.
chức năng mở rộng
(define-derived-mode test-mode html-mode "Test"
"Major mode for highlighting JavaScript and CSS blocks."
;; Basic font lock
(set (make-local-variable 'font-lock-defaults)
'(test-font-lock-keywords))
;; Multiline font lock
(set (make-local-variable 'font-lock-multiline) t)
(add-hook 'font-lock-extend-region-functions
'test-font-lock-extend-region))
Vùng nên tìm một cái gì đó như thế này:
(defun test-font-lock-extend-region()
"Extend the search region to include an entire block of text."
;; Avoid compiler warnings about these global variables from font-lock.el.
;; See the documentation for variable `font-lock-extend-region-functions'.
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
(save-excursion
(goto-char font-lock-beg)
(let ((found (or (re-search-backward "\n\n" nil t) (point-min))))
(goto-char font-lock-end)
(when (re-search-forward "\n\n" nil t)
(beginning-of-line)
(setq font-lock-end (point)))
(setq font-lock-beg found))))
chức năng này xem xét các biến toàn cục font-lock-beg
và font-lock-end
, có chứa thời gian bắt đầu và vị trí kết thúc của khu vực tìm kiếm, và mở rộng vùng chứa toàn bộ khối văn bản (được phân tách bằng các dòng trống hoặc "\n\n"
).
Hiện tại, Emacs sẽ tìm kiếm các kết quả phù hợp ở các khu vực lớn hơn, chúng tôi cần thiết lập danh sách test-font-lock-keywords
. Có hai cách hợp lý để đi về các cấu trúc đa kết hợp: cụm từ thông dụng sẽ khớp với các dòng và hàm phù hợp. Tôi sẽ đưa ra ví dụ về cả hai. danh sách từ khoá này chứa một biểu hiện thường xuyên cho phù hợp với <style>
khối và chức năng cho phù hợp với <script>
khối:
(defvar test-font-lock-keywords
(list
(cons test-style-block-regexp 'font-lock-string-face)
(cons 'test-match-script-blocks '((0 font-lock-keyword-face)))
)
"Font lock keywords for inline JavaScript and CSS blocks.")
Các mục đầu tiên trong danh sách này là đơn giản: một biểu thức chính quy và một khuôn mặt để làm nổi bật các trận đấu đó thường xuyên biểu hiện. Thứ hai có vẻ phức tạp hơn một chút, nhưng có thể được khái quát hóa để chỉ định các khuôn mặt khác nhau cho các nhóm khác nhau được xác định trong dữ liệu đối sánh được chỉ định bởi hàm. Ở đây, chúng tôi chỉ đánh dấu nhóm không (toàn bộ kết quả phù hợp) bằng cách sử dụng font-lock-keyword-face
. (Các tài liệu có liên quan cho những quẹt là trong phần Search-based fontification của hướng dẫn Emacs.)
Một biểu thức chính quy cơ bản cho phù hợp với <style>
khối sẽ là:
(defconst test-style-block-regexp
"<style>\\(.\\|\n\\)*</style>"
"Regular expression for matching inline CSS blocks.")
Lưu ý rằng chúng ta phải đặt \n
trong nhóm bên trong vì .
không khớp với dòng mới.
Các chức năng phù hợp, mặt khác, cần phải tìm kiếm các <script>
khối đầu tiên trong khu vực từ điểm đến duy nhất cho luận, last
:
(defun test-match-script-blocks (last)
"Match JavaScript blocks from the point to LAST."
(cond ((search-forward "<script" last t)
(let ((beg (match-beginning 0)))
(cond ((search-forward-regexp "</script>" last t)
(set-match-data (list beg (point)))
t)
(t nil))))
(t nil)))
Chức năng này đặt ra các dữ liệu phù hợp , là danh sách có dạng begin-0 end-0 begin-1 end-1 ...
cho phần đầu và cuối của nhóm số, nhóm đầu tiên, v.v. Ở đây, chúng tôi chỉ đưa ra giới hạn trên toàn bộ khối đã được đối sánh, nhưng bạn có thể làm điều gì đó hơn phức tạp, chẳng hạn như đặt các khuôn mặt khác nhau cho thẻ và nội dung .
Nếu bạn kết hợp tất cả mã này vào một tệp và chạy M-x test-mode
, nó sẽ hoạt động để làm nổi bật hai loại này khối. Trong khi tôi tin rằng điều này thực hiện công việc, nếu có thêm cách hiệu quả hoặc thích hợp để thực hiện việc đó, tôi cũng tò mò muốn biết cũng biết.
Trong [thread] này (http://lists.gnu.org/archive/html/help-gnu-emacs/2004-09/msg00534.html), Stefan Monnier nói rằng phông chữ-khóa-nhiều dòng là thích hợp cho những thứ thường là một dòng, nhưng đôi khi nhiều dòng. Bình luận? –
Vâng, Stefan Monnier là tài liệu tham khảo dứt khoát khi nói đến bất cứ điều gì liên quan đến font-lock, do đó, bất kỳ lời khuyên nào từ anh ta cũng đáng được theo dõi. Sử dụng hệ thống cú pháp, như ông gợi ý, là một cách để làm điều đó. Cách khác là sử dụng "hàm so khớp" thay vì hàm regexp, có thể khớp với toàn bộ khối. Bạn sẽ thấy câu trả lời của tôi như là một câu trả lời trực tiếp cho câu hỏi (cung cấp một ví dụ về tính năng khóa nhiều dòng) và có thể không phải là câu trả lời về cách tốt nhất để hoàn thành bất kỳ poster ban đầu nào được hỏi. – Lindydancer