¿Cómo resaltar palabras clave específicas dentro de cadenas / citas?


7

Tengo otro resaltado de sintaxis para palabras clave SQL dentro de cadenas (entre comillas) en VIM. Se parece a esto:

ingrese la descripción de la imagen aquí

Luego, en Emacs con modo PHP, 'el bloqueo de fuente considerará todo entre comillas ( ):

ingrese la descripción de la imagen aquí

Como puede ver, el primer ejemplo con otras propiedades de fuente (sin palabras clave cursivas) es más claro. Las palabras clave son mucho más fáciles de distinguir.

Cuando estoy mirando mis font facepropiedades:

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

Entonces me pregunto cómo podría decir que debería aplicarse otra cara dentro de una font-lock-string-face, si coincide con las palabras clave específicas.

Cualquier sugerencia sería apreciada.


¿Otra vez el modo PHP como en emacs.stackexchange.com/questions/19002/… ? ¿Y tienes el truco de esa respuesta corriendo? Debe agregar una nota sobre el modo principal actual en la pregunta.
Tobias

¡@Tobias the StackExchange no me notificó que recibí una respuesta tuya! Lo siento mucho por mi tardía respuesta, vea el enlace para mi respuesta. Y tienes razón, agregué el modo PHP. Pero creo que la solución podría no estar relacionada con el modo principal, ya que está dirigida solo a las fuentes.
ReneFroger

Respuestas:


11

El siguiente fragmento de código elisp debería hacer. Los detalles importantes son:

  • Las cadenas se manejan mediante el resaltado de sintaxis y no mediante la coincidencia de patrones (es decir, el resaltado de palabras clave). Esto tiene una prioridad muy alta. Por lo tanto, es necesario anularlo explícitamente por el valor tde la anulación del indicador MATCHER (ver documento de font-lock-keywords).
  • No se puede usar una expresión regular como palabra clave MATCHER ya que solo se deben verificar las palabras clave SQL dentro de las cadenas. El código siguiente proporciona php-sql-keyword-matcherpara ese propósito. La prueba de cadenas se realiza a través de syntax-ppss(consulte el documento para esta función).

Tenga en cuenta que solo tengo una pantalla de clase color. Entonces no pude probar las otras clases. Supongo que tiene otra clase de visualización ya que las cadenas se muestran en cursiva en su ejemplo. Si no obtiene el resultado esperado, personalice la cara 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: No inserte solo imágenes de textos necesarios para la reconstrucción del problema. El texto ASCII puede facilitar a los posibles ayudantes la reconstrucción del problema. Para el caso de que otra persona tenga una mejor solución, inserto la versión ASCII del texto aquí:

$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';

Y aquí una imagen del texto como se ve cuando lo cargo en emacs con modo PHP:

Imagen del archivo php con palabras clave en cursiva en cadenas sql

Con la clase de visualización, las colorcadenas no están en cursiva pero tienen un color diferente. Por lo tanto, he elegido la fuente en cursiva para las palabras clave SQL dentro de las cadenas.

Los comentarios indican algunas dificultades con esta respuesta. Se ha indicado que la solución no funcionaría con la fuente predeterminada establecida en Consolas. Lo acabo de probar y en mi sistema también funciona con la fuente Consola por defecto:

Resaltado de palabras clave SQL en cadenas php con fuentes Consolas como predeterminadas.

En la ayuda para font-lock-add-keywordsencontré el siguiente texto:

Por ejemplo:

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

agrega dos patrones de fuente para el modo C, para fontify 'FIXME:' palabras, incluso en los comentarios, y para fontify and, ory notpalabras como palabras clave.

El primer caso " FIXME" es el interesante. Aquí se usan prependcomo bandera de anulación.


1
Tobias, intentaste ayudarme de nuevo. No puedo agradecerte lo suficiente. Estudié la documentación de palabras clave variables de bloqueo de fuente (fontización basada en la búsqueda 22.6.2). Parece que necesito establecer el subexp-highlighterindicador de anulación en verdadero. Pero veo que ya lo hiciste (php-sql-keyword-matcher 0 php-sql-keyword-face t). ¡Copié su código en una configuración vacía de Emacs con solo modo PHP integrado, evalué el búfer y luego creé un nuevo búfer con el texto ASCII que incluso reconstruyó! A pesar de su excelente explicación detallada, desafortunadamente no veo texto cursivo o texto diferente.
ReneFroger

Además, cuando pongo el cursor en la cadena y llamo php-sql-keyword-matcher(lo he agregado (interactive)), recibo un error, por lo que asumo que no está destinado a llamadas interactivas. Después de evaluar su código y pegar el texto ASCII en el búfer de memoria virtual con el modo PHP habilitado, no veo diferencia entre las palabras clave SQL y el resto de las cadenas. Si necesita una captura de pantalla, de información de depuración, me encantaría agregar más información ya que mi conocimiento de Elisp aún no es suficiente. Realmente aprecio su ayuda en mis casos, y por cierto, mis mejores deseos para 2016.
ReneFroger

1
El origen más probable del problema es que jit-ockrenuncia a algún error. jit-lockno rescata los errores, pero desactiva el controlador que causa el error y continúa con su trabajo. Sin embargo, deja un mensaje de error en el búfer de mensajes. Entonces, comience un nuevo emacs, pruebe sus cosas y observe con mucho cuidado el buffer de mensajes. AFAIK no puede atrapar este tipo de errores a través del depurador. Detener jit-lockel error podría tener consecuencias cableadas, como un bloqueo muerto. Supongo que nuevamente es una función faltante. Lo intentaré de nuevo con -Q. Por cierto, mis mejores deseos para ti también.
Tobias

1
Puedo confirmar que el fragmento de código funciona bien emacs -Qaquí en mi lugar con la interfaz X11. Intentaré nuevamente en modo consola ...
Tobias

¿Qué versión de Emacs usas entonces? Uso Emacs 25.50 en Ubuntu, y no hay modo PHP con M-x php-modela configuración vacía de Emacs. Es por eso que abordé el modo PHP con una configuración vacía más.
ReneFroger
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.