バッファの一部のみでフォントロックモードを使用する


7

Perlスクリプトのポッドドキュメントにコメント機能を追加しようとしています。ポッドのコメントを特別な顔で強調したいと思います。単純なプロトタイプPerlスクリプトは次のようになります。

#! /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 */

ご覧の/* */ように、Cプログラミング言語の場合と同様に、Podコメントの後に続きます。ただし、__END__境界より下の部分のみがポッドのドキュメントです。その行の上の部分は通常のPerlコードです。ここで、たとえば(fromから呼び出されるcperl-mode-hook)を使用して、Podコメントに構文の強調表示を追加しようとすると、次のようになります。

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

私はcperl-modeメジャーモードとして以下を使用しています:

ここに画像の説明を入力してください

そのため、Podコメントは通常のPerlコメント(Perlコメントが#文字で始まる)でも強調表示されますが、これは望ましくありません(Podコメントは、通常のPerlコードではなく、Podセクションでのみ強調表示する必要があります)。

簡単にするために、この質問では、ポッドのドキュメントがドキュメントの最後に限定され、__END__タグの後の行から始まると想定できます。現在のコメントの位置を確認し、それを__END__行の位置に関連付けることができます。その情報から、Podブロック内にあるかどうかを判断します(そして、Podブロック内にある場合のみ構文の強調表示を追加します)フォントロックコードを実行するとき?


私は使用してmmm-modeいませんが、これがあなたのための解決策になると思います。
Kaushal Modi、

pod-modeポッドのコメント領域に適したメジャーモードがある場合は、mmm-mode適用できる可能性があります。それが事実かどうかはわかりません。おそらくここで必要なのは、追加のfont-lock構成だけです。
sanityinc 2015年

回答:


8

更新されたソリューション

font-lockでこれを行うための組み込みの方法があります(sanityincに感謝)

この回答には、このスタイルのfont-lock-keywordsがどのように機能するかについての詳細がすべて記載されています。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)))

結果は元のソリューションと同じです。

ここでそれは動作しています:

ここに画像の説明を入力してください

jit-lock-functionsを使用した元のソリューション(理想的ではない)

に追加された関数で手動でフォント設定を行う必要があると思います jit-lock-functions

jit-lock-functions テキストプロパティを適用することになっている領域を示すために、BEFおよびENDパラメーターで呼び出されるフォント化と領域を実際に行う関数です。

このシナリオでは、関数はまず、色を付ける領域が__END__バッファー内の後にあるかどうかを確認し、そうである場合は、手動で/ *コメント* /を検索して、テキストプロパティを適用します。

ここに実装があります:

(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)

あなたのシナリオでは、perl-mode-hook内にjit lock関数を追加することができます

また、この関数は「スマート」ではないことに注意してください。バッファ内のどこかでENDを探すだけなので、文字列またはperlコメントで発生してはいけない場合でも、実際には機能します。必要に応じて、関数を拡張して、ENDが発生する場所のコンテキストを確認できます。


1
通常、変更することは適切ではありませんjit-lock-function。これはの内部実装の詳細ですfont-lock。これfont-lockを達成する簡単な方法があるはずです。
sanityinc 2015年

1
あなたは正しい@sanityincです。フォントロックでより標準化された方法を見つけました。ありがとうございます。私は過去にjit-lock-functionsを使用したことがあるので、これを知っておくと非常に便利です。
Jordon Biondo

ああ、それは良く見えます!
sanityinc 2015年

@JordonBiondoに感謝!これは非常に有益な答えでした。それは完全に動作します!
ホーコンHægland
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.