1

font-lockとelispの正規表現を使用して、次のようなものを強調表示しようとしています。

class Foo implements A, B, C, D { }

問題は、。の後のコンマ区切りリストの長さが不明であるということですimplements。リスト上のすべての単語を強調表示する正規表現をすでに実行しました(re-buiderを使用して、A、B、C、およびDが強調表示されます):

"implements\\s-+\\(?:\\(\\sw+\\)\\s-*,\\s-*\\)*\\(\\sw+\\)"

しかし、これをfont-lockと組み合わせることができません。

明らかに

'("implements\\s-+\\(?:\\(\\sw+\\)\\s-*,\\s-*\\)*\\(\\sw+\\)"
  (1 font-lock-type-face) (2 font-lock-type-face))

*最初の後方参照後の星()を無視して、最後の出現(CおよびD)のみを強調表示するため、機能しません。

一致したすべての単語のリストをキャプチャする方法、またはこの問題を解決するためのまったく異なる方法はありますか?

4

2 に答える 2

2

カンマも強調表示したくない場合は、アプローチを機能させることはできません。フォームのsubexp-highlighterを使用する場合

(subexp facespec)

subexp、正規表現のサブグループを参照し、指定されたで強調表示されますfacespec。現在、正規表現一致のサブグループは、開始と終了のあるテキストの連続スパンです。実際、正規表現検索を実行するときはいつでも、関数(match-beginning subexp)とを使用してこれらの値を照会できます(match-end subexp)

ただし、これは、コンマを除く可変数のクラス名を単一の部分式と一致させることができないことを意味します。これは、その部分式が連続したスパンである必要があるためです。また、可変数のクラス名をカバーする連続スパンには、常にコンマが含まれている必要があります。これを回避する方法はありません。

あなたのアプローチがそれほど良い考えではないもう一つの理由はここにあります:あなたの正規表現は明示的に空白を使用します。空白が強調表示から除外されているかどうかは関係ありませんが、正規表現で使用することはあまり良い考えではありません。空白が許可されている場合は常にコメントも表示される可能性があるためです。

次のコード行を検討してください。

class Foo implements A, /*B, C,*/ D { }

その場合、スパン内の文字と、内の周囲のクラスを/*B, C,*/使用して強調表示する必要があります。他のすべてがすでに強調表示された後でのみコメントを強調表示し、コメントが他のフォントロックの一致を上書きできるようにすると、この効果を引き続き達成できます。ただし、これはかなり非効率的なマッチングにつながります。これは、すべてのコメントが最初にコードであるかのように強調表示され、次に2回目のパスでコメントとして強調表示されるためです。font-lock-comment-facefont-lock-type-face

両方の問題の解決策は、おそらくキーワード(「実装」)とクラスのマッチングを2つの異なるマッチングルールに分割することです。おそらく、次の行に沿って何かを開始点として使用できます。

'(("\\bimplements\\b" . font-lock-keyword-face)
  ("\\b[A-Z]\\w*\\b" . font-lock-type-face))
于 2011-05-29T22:06:21.953 に答える
1

このようなものはここで機能するようです:

'("\\(implements\\)\\s-+\\(\\(\\sw+\\s-*,\\s-*\\)*\\sw+\\)"
   (1 font-lock-warning-face)
   (2 font-lock-keyword-face))

(そして明らかにあなたはおそらく別の顔が欲しいでしょう...)

于 2011-05-26T09:20:08.827 に答える