文字列/引用符内の特定のキーワードを強調表示する方法は?


7

VIMの文字列内(引用符内)のSQLキーワードを強調する別の構文があります。次のようになります。

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

次に、PHPモードのEmacsでは、引用符(')の間のすべてがフォントロックによって文字列と見なされます。

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

ご覧のとおり、別のフォントフェイスプロパティ(筆記体キーワードなし)を使用した最初の例はより明確です。キーワードは区別がはるかに簡単です。

font faceプロパティを調べているとき:

 (font-lock-string-face ((t (:foreground "#536991" :slant italic)))) 

次に、特定のキーワードに一致する場合、のに別の顔font-lock-string-face適用する必要があるとどうしてわかるのかと思います。

任意の提案をいただければ幸いです。


ここでも、emacs.stackexchange.com / questions / 19002 /…のようなPHPモードです。そして、あなたはその答えからのハックを実行していますか?質問には、現在のメジャーモードに関するメモを追加してください。
Tobias

@Tobias StackExchangeは私があなたから返信を受け取ったことを私に通知しませんでした!私の遅れた応答を非常に申し訳ありませんが、私の返信のリンクを参照してください。そして、あなたは正しい、私はPHPモードを追加しました。しかし、フォントフェイスのみを対象としているため、ソリューションはメジャーモードに関連していない可能性があると思います。
ReneFroger

回答:


11

次のelispスニペットで実行できます。重要な詳細は次のとおりです。

  • 文字列は構文の強調表示によって処理され、パターンマッチング(つまり、キーワードの強調表示)では処理されません。これは非常に優先度が高いです。したがってt、MATCHERフラグOVERRIDEの値で明示的にオーバーライドする必要があります(のドキュメントを参照font-lock-keywords)。
  • 文字列内のSQLキーワードのみをチェックする必要があるため、正規表現をキーワードMATCHERとして使用することはできません。以下のコードはphp-sql-keyword-matcher、その目的のために提供されています。文字列のテストは経由で行われますsyntax-ppss(この関数についてはドキュメントを参照してください)。

クラスの表示しか持っていないことに注意してくださいcolor。他のクラスはテストできませんでした。例では文字列が斜体で表示されているため、他の表示クラスがあると思います。期待どおりの結果が得られない場合は、顔をカスタマイズしてくださいphp-sql-keyword-face

(require 'sql) ;; for sql-keywords
(require 'php-mode) ;; for php-mode-hook

(defvar php-sql-keywords (concat "\\<" (mapconcat 'car sql-mode-ansi-font-lock-keywords "\\|") "\\>")
  "SQL keywords for php-mode stolen from `sql-mode-ansi-font-lock-keywords'.")

(defun php-sql-keyword-matcher (end)
  "Search for SQl keywords within PHP strings."
  (let (pos (case-fold-search t))
    (while (and (setq pos (re-search-forward php-sql-keywords end t))
                (null (nth 3 (syntax-ppss pos)))))
    (when pos (message "Found keyword at %s" pos))
    pos))

(defface php-sql-keyword-face
  '((((class grayscale))  :slant nil :inherit font-lock-string-face)
    (((class color)) :slant italic :inherit font-lock-string-face)
    (t :slant nil :inherit font-lock-string-face))
  "Face to highlight SQL keywords within PHP strings."
  :group 'php-sql)

(defcustom php-sql-keyword-face 'php-sql-keyword-face
  "Face to highlight SQL keywords within PHP strings."
  :type 'face
  :group 'php-sql)

(defun php-add-sql-keyword-matcher ()
  "Hook to add fontification of sql-keywords in strings."
  (font-lock-add-keywords
   nil
   '((php-sql-keyword-matcher 0 php-sql-keyword-face t))
   'append))

(add-hook 'php-mode-hook 'php-add-sql-keyword-matcher)

注:問題の再現に必要なテキストの画像だけを挿入しないでください。アスキーテキストは、問題の再構築の潜在的なヘルパーを緩和できます。他の誰かがより良い解決策を持っている場合のために、私はテキストのASCIIバージョンをここに挿入します:

$sSql = 'SELECT T05.foo
             T07.bar

         FROM db_pgm_intranet.inttbl_keyuser_proces_keyuser T05

             INNER JOIN db_pgm_intranet.inttbl_keyuser_keyuser T07
             ON    T07.nKkuID = T01.nKpkKeyuserID

             LEFT JOIN db_pgm_intranet.inttbl_keyuser_applicate T07
             ON   T06.nKpaProcesID = T07.nKapID';

そして、ここに私がPHPモードでemacsにそれをロードしたときのように見えるテキストの写真:

SQL文字列内のイタリックキーワードを含むphpファイルの画像

表示クラスでは、color文字列は斜体ではありませんが、色が異なります。したがって、私は文字列内のSQLキーワードにイタリック体を選択しました。

コメントは、この回答のいくつかの困難を示しています。デフォルトのフォントがに設定されていると、ソリューションが機能しないことが示されていますConsolas。私はそれをテストしましたが、私のシステムではデフォルトでConsolaフォントでも動作します:

デフォルトでConsolasフォントを使用したphp文字列のSQLキーワードの強調表示。

ヘルプfont-lock-add-keywordsの次のテキストを見つけました:

例えば:

(font-lock-add-keywords 'c-mode
  '(("\\<\\(FIXME\\):" 1 'font-lock-warning-face prepend)
    ("\\<\\(and\\|or\\|not\\)\\>" . 'font-lock-keyword-face)))

Cモードの2つのフォント化パターンを追加して、「FIXME:」の単語をコメント化し、フォント化しand、単語をキーワードとしてフォント化ornotます。

最初のケース「FIXME」は興味深いものです。ここではprepend、オーバーライドフラグとして使用します。


1
トビアス、あなたはまた私を助けようとした。あなたには感謝してもしきれません。可変font-lock-keywordsの文書化を調査しました(22.6.2検索ベースのフォント化)。subexp-highlighterオーバーライドフラグをtrue に設定する必要があるようです。しかし、あなたはすでにでやったと思います(php-sql-keyword-matcher 0 php-sql-keyword-face t)。そして、あなたがいることをASCIIテキストで新しいバッファを作成したバッファを、評価ボード上の唯一のPHPモードで空のEmacsの設定、であなたのコードをコピーし、私はそうであっても再構築!あなたの詳細な優れた説明にもかかわらず、残念ながら筆記体のテキストや別のテキストはありません。
ReneFroger 2016年

さらに、カーソルを文字列に置いて呼び出しphp-sql-keyword-matcher(追加(interactive)した)と、エラーが発生するため、インタラクティブな呼び出しを意図していません。コードを評価し、ASCIIテキストをPHPモードを有効にしてスクラッチバッファーに貼り付けた後、SQLキーワードと残りの文字列の間に違いはありません。デバッグ情報のスクリーンショットが必要な場合は、Elispの知識がまだ十分ではないため、さらに情報を追加したいと思います。私の場合、あなたの助けに本当に感謝しています。
ところで

1
問題の原因として最も可能性が高いのは、jit-ockいくつかのエラーをあきらめることです。jit-lockエラーが発生しても救済されませんが、エラーの原因となったハンドラーが非アクティブになり、ジョブが続行されます。それでも、メッセージバッファにエラーメッセージが残ります。そのため、新しいemacsを起動して自分のものを試し、メッセージバッファーを非常に注意深く観察してください。私の知る限り、デバッガを介してこれらの種類のエラーをキャッチすることはできません。jit-lockエラーで停止すると、デッドロックなどの有線の結果が生じる可能性があります。私はそれが再びいくつかの欠けている機能であると思います。で再試行し-Qます。ちなみに、よろしくお願いします。
トビアス

1
私のコードスニペットはemacs -Q、X11インターフェイスを使用して私の場所で正常に動作することを確認できます。コンソールモードでもう一度試します...
Tobias

Emacsのどのバージョンを使用していますか?私はUbuntuでEmacs 25.50を使用していますM-x php-modeが、空のEmacs構成にはPHPモードがありません。それが私がさらに空の設定でPHPモードに乗り込んだ理由です。
ReneFroger 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.