O seguinte snippet elisp deve funcionar. Os detalhes importantes são:
- As strings são tratadas pelo realce da sintaxe e não pela correspondência de padrões (ou seja, realce da palavra-chave). Isso tem uma prioridade muito alta. Portanto, é necessário substituí-lo explicitamente pelo valor
t
do sinalizador MATCHER OVERRIDE (consulte o documento de font-lock-keywords
).
- Não se pode usar um regexp como palavra-chave MATCHER, pois é necessário verificar apenas as palavras-chave SQL nas cadeias. O código abaixo fornece
php-sql-keyword-matcher
para esse fim. O teste para seqüências de caracteres é feito via syntax-ppss
(consulte o documento para esta função).
Observe que eu só tenho uma exibição de classe color
. Então eu não pude testar as outras classes. Suponho que você tenha uma outra classe de exibição, pois as strings são exibidas em itálico no seu exemplo. Se você não obtiver o resultado esperado, personalize o rosto 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)
Nota: Não insira apenas imagens de textos necessários para a reconstrução do problema. O texto ascii pode facilitar possíveis auxiliares na reconstrução do problema. No caso de alguém ter uma solução melhor, insiro a versão ASCII do texto aqui:
$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';
E aqui uma imagem do texto como parece quando eu o carrego no emacs com o modo PHP:
Na classe de exibição, as color
strings não estão em itálico, mas têm uma cor diferente. Portanto, escolhi a fonte em itálico para as palavras-chave SQL nas cadeias.
Os comentários indicam algumas dificuldades com esta resposta. Foi indicado que a solução não funcionaria com a fonte padrão definida como Consolas
. Acabei de o testar e no meu sistema também funciona com a fonte Consola como padrão:
Na ajuda para font-lock-add-keywords
encontrei o seguinte texto:
Por exemplo:
(font-lock-add-keywords 'c-mode
'(("\\<\\(FIXME\\):" 1 'font-lock-warning-face prepend)
("\\<\\(and\\|or\\|not\\)\\>" . 'font-lock-keyword-face)))
adiciona dois fontification padrões para o modo C, para fontify 'FIXME:' palavras, mesmo em comentários, e para fontify and
, or
e not
palavras como palavras-chave.
O primeiro caso " FIXME
" é o interessante. Aqui eles usam prepend
como sinalizador de substituição.