マイナーモードで複雑な構文ハイライトを追加するには?

マイナーモードでさまざまな顔のコードを強調したいと思います。

ここに私が望むものに近いスクリーンショットがあります:

python-syntax-highlight

私が欠けていることの1つは、コメントfont-lock-comment-face 。アイデアは、「所属する」というコメントを持つことです。 プレーンテキストとしてハイライトされたアウトラインに変換するので、読みやすくなります。中 彼らの通常より少なく目立つ顔との定期的なコメントを持っています。

私が使用したコードは次のとおりです。

(setq-local font-lock-defaults
            '(python-font-lock-keywords
              nil nil nil nil
              (font-lock-syntactic-face-function
               . lpy-font-lock-syntactic-face-function)))

(defun lpy-font-lock-syntactic-face-function (state)
  "Return syntactic face given STATE.
Returns 'defalt face for comments that belong to an outline."
  (cond ((nth 3 state)
         (if (python-info-docstring-p state)
             font-lock-doc-face
           font-lock-string-face))
        ((save-excursion
           (while (and (> (point) (point-min))
                       (progn (move-beginning-of-line 0)
                              (eq (char-after) ?\#))))
           (forward-line 1)
           (looking-at "#\\*+ "))
         'default)
        (t
         font-lock-comment-face)))

問題は、私にはインタフェースについての手掛かりはありません font-lock-syntactic-face-function が動作します。 複雑なデータ構造 state は、異なるポイント状態を持ち、 顔。

誰かがこのインターフェースを説明できますか?おそらくもっと良いものはありますか?

9

2 答え

font-lock-syntactic-face-function is a regular variable from Font Lock, more specifically from the Syntactic Font Lock phase (emphasis mine):

この変数がnil以外の場合は、指定された構文要素(文字列またはコメント)にどの面を使用するかを決定する関数でなければなりません。この値は通常、font-lock-defaultsのother-vars要素によって設定されます。

     

この関数は1つの引数、つまり parse-partial-sexp によって返された点の解析状態で呼び出され、面を返す必要があります。デフォルト値は、コメントの場合はfont-lock-comment-faceを返し、文字列の場合はfont-lock-string-faceを返します(フォントロックについてはFacesを参照してください)。

parse-partial-sexp in turn returns a list which describes Emacs' current syntactic state, which is essentially the result of the application of the syntax table to the current buffer. The list is rather complex, hence I'll spare it here; you can see the complete reference in the docstring of parse-partial-sexp. The purpose of this function is to change the face applied to a syntactic element under certain rules. The beginning of your function demonstrates this: If the current string is a docstring, use a different face for it.

しかし、顔は常に全体の構文要素、つまり文字列全体またはコメント全体に適用されます。この関数を使用して個々の部分をハイライトすることはできません。この目的のために、(python-info-docstring-p state)のような特定の state あなたのコードで。この場所でポイントを使用しない フォントロックのこの段階で point の値が適切に定義されているかどうかはわかりません。


作品をまとめると、あなたの目的に間違った機能が使用されているので、それを動作させることができません。

私はあなたの目的のハイライトを実装しようとはしていませんが、私はあなたの目的のために深すぎる方法を掘ったと思う。正直なことを理解していれば、コメントの輪郭をハイライトしたいだけです。

私が正しいとすれば、特殊な方法で font-lock-keywords だけが必要です。

(my/find-outline-in-comment-p 0 'outline-face t)

outline-face は見出しに適用したい面、 t はこの場所の以前のフォントロックを上書きすることを意味し、 my/find-outline-in-commentは、 font-lock-defaults のコメント内の最初のアウトラインを検索するマッチャー関数です( font-lock-defaults のdocstringを参照) (ポイント)とその位置に移動し、マッチデータで強調表示されるアウトラインの範囲を返します。

アウトラインを見つけるには、( font-lock-comment-face や構文の状態を使って)コメントをスキャンしてから look-at を使ってコメントには概要があります。

6
追加された

次のような font-lock-syntax-face-function を定義することを検討してください。

(setq font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state))
            MY-COMMENT-FACE
          (t  font-lock-comment-face))))

これはpython-mode.elでテストされ、comment-faceのない "#*"で始まるセクションが残っています:

(setq py--font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state)
            (progn (save-excursion
                 (goto-char (nth 8 state))
                 (looking-at (concat comment-start (regexp-quote "*"))))))
           nil)
          (t font-lock-comment-face))))

それはモードで管理されている間:

(font-lock-syntactic-face-function
                    . py--font-lock-syntactic-face-function)

nil の代わりに、有効な顔があればいいはずです。

0
追加された