フォントロックが怠惰にならないようにするには?

この質問に関連しています。

以下は、現在の python-mode のフォントロックの設定です:

(require 'org)
(defconst lpy-font-lock-keywords
  '(("^#\\(\\* .*\\)$" 1 'org-level-1 prepend)
    ("^#\\(\\*\\* .*\\)$" 1 'org-level-2 prepend)
    ("^#\\(\\*\\*\\* .*\\)$" 1 'org-level-3 prepend)
    ("^#\\(\\*\\*\\*\\* .*\\)$" 1 'org-level-4 prepend)
    ("^#\\(\\*\\*\\*\\*\\* .*\\)$" 1 'org-level-5 prepend)
    (lpy-outline-comment-highlight 1 'default prepend)
    ("`\\([^\n']+\\)'" 1 font-lock-constant-face prepend)))

(font-lock-add-keywords 'python-mode lpy-font-lock-keywords)
(defun lpy-outline-comment-highlight (limit)
  (when (re-search-forward "^#\\(?:[^*]\\|$\\)" limit t)
    (let* ((pt (point))
           (success (save-excursion
                      (and (re-search-backward "^#\\*" nil t)
                           (null (re-search-forward "^[^#]" pt t))))))
      (when success
        (set-match-data (list (line-beginning-position) (line-end-position)
                              (point) (line-end-position)))
        (end-of-line)
        t))))

The code appears to do what I want (have comment bodies, but not starters, in default face for comments that belong to outlines), but only for small buffers, or places that I modify.

より大きいバッファ(1画面以上)の場合、 font-lock は遅延します 必要な面は適用しません。ただし、テキストを変更した場合 その地域を中心に正しく強調表示されます。

font-lock-lazy

上の画像では、 font-lock は "多次元索引付けの概要"で怠惰です。 だから私はそこにポイントを移動し、スペースを入力 - ハイライトは正しいとなった。

font-lock に画面上のすべての行を強調表示させるにはどうすればよいですか?

1
はい、しかし、これらのルールは私には一線に見えます。
追加された 著者 Bert Huijben,
あなたはマニュアルの(elisp)Font Lock Multiline ノードを見ましたか?
追加された 著者 sds,

2 答え

[あなたのルールは "一行"なので、(elisp)Font Lock Multiline に記載されている問題の中にはありません。それは本当に「怠惰」とは関係がありません。 ]

問題は非常に単純です:あなたの lpy-outline-comment-highlight 関数では、一致が見つかっても success がnilならば、nilを返します。 font-lockにそれ以上見えることを止めるように指示します。

IOWでは をループに置き換える必要があります。

溶液:

(defun lpy-outline-comment-highlight (limit)
  (catch 'done
    (while (re-search-forward "^#\\(?:[^*\n]\\)" limit t)
      (let* ((pt (point))
             (success (save-excursion
                        (and (re-search-backward "^#\\*" nil t)
                             (null (re-search-forward "^[^#]" pt t))))))
        (when success
          (set-match-data (list (line-beginning-position) (line-end-position)
                                (point) (line-end-position)))
          (end-of-line)
          (throw 'done t))))))
3
追加された

font-lock-extend-region-functions を使用できます。再ハイライトされた領域を拡張する関数のリストが含まれています。地域を拡張して完全なコメントを含める独自の関数を追加して、キーワードを正しく適用させることができます。

2
追加された
私はなぜ何か他のものを使うべきではない。私の印象は、画面全体が処理されるまで、 font-locklpy-outline-comment-highlight を何度も呼び出す必要があるということでした。
追加された 著者 Bert Huijben,
してください。私は複雑な font-lock に関する実用的な情報を見つけることはできませんでした。情報ページには例はなく、wikiの例は簡単なものです。
追加された 著者 Bert Huijben,
まあ、そうではありません。もしそれが適切であると考える地域を決定し、それを強調する。特定のコメントの途中でその領域が開始されると、関数は機能しません。それを画面に接続することはあなたが望むものではありません - あなたのコメントの途中で画面が始まっても、それはまだ動作しません。 (もしあなたが好きなのであれば、私はあなたに再改造エリアを視覚化する未発表のツールを送ることができます。私はそれを似たような状況で使っています。)
追加された 著者 Daniel McPherson,
@ abo-abo、私はちょうどあなたに電子メールを送った。フォントロック情報の最良のソースは、他のパッケージと、フォントロック変数の変数ドキュメントです。それは非常に凝縮されていますが、通常は正しい形成を含んでいます。それが必要なのは、ツールが利用可能で、正しい方法を選択する方法のクックブックです。
追加された 著者 Daniel McPherson,