Sử dụng chế độ khóa phông chữ chỉ trên một phần của bộ đệm


7

Tôi đang cố gắng thêm một tính năng bình luận vào tài liệu Pod cho các tập lệnh Perl và tôi muốn đánh giá cao các bình luận Pod với một khuôn mặt đặc biệt. Một kịch bản Perl nguyên mẫu đơn giản có thể là:

#! /usr/bin/env perl

use strict;
use warnings;

print "Hello\n"; # a Perl comment /* hello */

__END__

=head1 SYNOPSIS

my_program <arg1> [OPTIONS]

/* this is a Pod comment */

Như chúng ta thấy, một nhận xét Pod bị bỏ qua /* */như trong ngôn ngữ lập trình C. Tuy nhiên, chỉ có phần bên dưới dòng __END__là tài liệu Pod. Phần trên dòng đó là mã Perl thông thường. Bây giờ, nếu tôi cố gắng thêm đánh dấu cú pháp vào nhận xét Pod bằng ví dụ (được gọi từ cperl-mode-hook):

(font-lock-add-keywords nil '(("\\(/\\*.*?\\*/\\)" 1 'font-lock-warning-face t)))

Tôi nhận được sau đây bằng cách sử dụng cperl-modenhư chế độ chính:

nhập mô tả hình ảnh ở đây

Vì vậy, các bình luận Pod cũng được tô sáng trong một bình luận Perl thông thường (một bình luận Perl bắt đầu bằng một #ký tự), điều này không mong muốn (các bình luận Pod chỉ nên được tô sáng trong các phần Pod, không phải trong mã Perl thông thường).

Để đơn giản, đối với câu hỏi này, chúng tôi có thể giả sử rằng tài liệu Pod được giới hạn ở cuối tài liệu, bắt đầu bằng các dòng sau __END__thẻ. Có thể kiểm tra vị trí của nhận xét hiện tại và liên kết vị trí đó với vị trí của __END__dòng và từ thông tin đó xác định xem chúng ta có ở trong khối Pod hay không (và sau đó thêm tô sáng cú pháp chỉ khi chúng ta ở trong khối Pod) Khi chạy mã khóa phông chữ?


Tôi chưa sử dụng mmm-modenhưng tôi nghĩ đây có thể là giải pháp cho bạn.
Kaushal Modi

Nếu có một pod-modechế độ chính phù hợp với các vùng nhận xét Pod, thì mmm-modecó thể áp dụng. Tôi không chắc đó là trường hợp. Có lẽ những gì bạn cần ở đây chỉ là cấu hình khóa chữ bổ sung.
sanityinc

Câu trả lời:


8

Giải pháp cập nhật

Có một cách được xây dựng để làm điều này với khóa chữ (cảm ơn bạn sanityinc)

Câu trả lời này có tất cả các chi tiết về cách thức hoạt động của kiểu khóa từ khóa này: https://stackoverflow.com/a/14675550

(defun pod-comment-highlighter (limit)
  "If looking after __END__ or __END__ is before LIMIT, set match-data to a the location of the pod comment."
  (when (or (save-excursion (search-backward "__END__" (point-min) t 1))
            (search-forward "__END__" limit t 1))
    (re-search-forward "\\(/\\*.*?\\*/\\)" limit t 1)))

(font-lock-add-keywords
 'perl-mode
 '((pod-comment-highlighter 0 font-lock-warning-face t)))

Kết quả giống như giải pháp ban đầu.

Đây là hành động:

nhập mô tả hình ảnh ở đây

Giải pháp ban đầu sử dụng chức năng khóa jit (không lý tưởng)

Tôi tin rằng bạn sẽ cần thực hiện việc chỉnh sửa thủ công trong một chức năng được thêm vào jit-lock-functions.

jit-lock-functions là các hàm thực sự thực hiện phông chữ và vùng được gọi với các tham số BEG và END để biểu thị vùng mà chúng được cho là áp dụng các thuộc tính văn bản cho.

Đối với kịch bản này, trước tiên, chức năng của bạn sẽ xem vùng màu sẽ nằm sau __END__vùng đệm của bạn và nếu vậy, hãy tìm kiếm thủ công / * nhận xét * / và áp dụng các thuộc tính văn bản cho chúng.

Đây là một thực hiện:

(defun pod-comment-highlighter (beg end)
  "Highlight /* this style */ of comments but only if they appear after __END__ in the buffer."
  (save-excursion
    (save-match-data
      (goto-char beg)
      ;; only fontify if __END__ appears before the given region, or, if
      ;; __END__ is inside the region, then start fontifiying after __END__
      (when (or (save-excursion (search-backward "__END__" (point-min) t 1))
                (search-forward "__END__" end t 1))
        (while (re-search-forward "\\(/\\*.*?\\*/\\)" end t 1)
          (add-text-properties (match-beginning 0) (match-end 0) '(face font-lock-warning-face)))))))


;; `jit-lock-register' is normally used to add a jit-lock-function, 
;; but I want to make sure this function is the last function to run and
;; color the buffer so font-lock doesn't undo my applied properties.
;; So add-hook works nicely by passing t in the APPEND parameter
(add-hook 'jit-lock-functions 'pod-comment-highlighter t)

Đối với kịch bản của bạn, bạn có thể muốn thêm chức năng khóa jit bên trong hook-mode-hook

Cũng lưu ý rằng chức năng này không "thông minh", nó chỉ tìm kiếm END ở bất kỳ vị trí nào trong bộ đệm, vì vậy nếu nó xuất hiện trong một chuỗi hoặc một nhận xét perl nơi nó không có hiệu lực, thì nó thực sự sẽ có hiệu lực. Bạn có thể mở rộng chức năng để xem xét bối cảnh nơi END xảy ra nếu bạn cần.


1
Nó thường sẽ không tốt để sửa đổi jit-lock-function. Đó là một chi tiết thực hiện nội bộ của font-lock. Cần có một font-lockcách đơn giản để đạt được điều này.
sanityinc

1
Bạn nói đúng @sanityinc, tôi đã tìm thấy cách chuẩn hơn để làm điều đó trong khóa phông chữ, cảm ơn bạn. Tôi đã sử dụng các chức năng khóa jit trong quá khứ, vì vậy điều này rất tốt để biết!
Jordon Biondo

À đúng rồi, có vẻ tốt hơn!
sanityinc

Cảm ơn @JordonBiondo! Đây là một câu trả lời rất hướng dẫn. Nó hoạt động hoàn hảo!
Håkon Hægland
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.