¿Cómo detectar si dentro de un par coincidente?

16

P: ¿hay alguna forma general de detectar si el punto está dentro de un par de caracteres coincidentes?

Es decir: ¿hay una función de predicado general (o algo) que pueda determinar si el punto está entre un par coincidente o algunos caracteres elegidos arbitrariamente? Estoy pensando en uno que evaluaría ten, por ejemplo, los siguientes escenarios, con !referencia al punto:

"!"   (quotes in general)
``!'' (LaTeX quotes)
$!$   (LaTeX math)
(!)   (lisp parens)
*!*   (org emphasis)

Editar : syntax-ppssparece ser un buen punto de partida, pero no está claro para mí cómo uno lo adaptaría a pares coincidentes de varios caracteres (por ejemplo, las `` citas de LaTeX '', o incluso las coincide <b>html tags</b>). Me pregunto si hay una solución general, o si requeriría un analizador especialmente diseñado.

Dan
fuente

Respuestas:

16

syntax-ppsspodría ser de ayuda aquí. Se devuelve una lista que también tiene los siguientes elementos:

  • elemento 0: profundidad en parens
  • elemento 3: no nulo si está dentro de una cadena

Podrías usarlo así:

(or (> (nth 0 (syntax-ppss)) 0)
    (nth 3 (syntax-ppss)))

Con una tabla de sintaxis configurada correctamente en el búfer (para cadenas y parens coincidentes), la función debe hacer lo que espera. Si no es posible usar la tabla de sintaxis del modo, entonces podría recurrir al uso with-syntax-table.

pimenton
fuente
Debo señalar que la cadena de documentación de parse-partial-sexpexplica la estructura de datos devuelta con syntax-ppssmás detalle que la sección del manual de Elisp a la que me vinculé.
pimentón
2

Si desea, por ejemplo, verificar si está entre llaves, use esto:

(and (looking-back "{") (looking-at "}"))

Claro, puedes reemplazar las llaves por lo que quieras.

EDITAR:

Una función más útil será algo parecido a esto:

(defun test-inside-curly-braces ()
 (interactive)
 (when (and (looking-back "{\\(.*?\\)") (looking-at "\\(.*?\\)}"))
  (message "inside curly braces")))
Nsukami _
fuente
2
Eso solo funciona si el punto está en el cierre }, y no hay nada entre {}. Obtener delimitadores emparejados correctamente con expresiones regulares puede ser complicado. Mejor usar syntax-ppscomo sugirió @paprika.
Tyler
@Tyler solo funciona si el punto de cierre }no es el comportamiento que he visto: \ pero sí, obtener pares usando expresiones regulares es complicado, de hecho
Nsukami _
looking-atexamina el texto comenzando en el punto. a menos que el punto esté en }su primera declaración anterior, ¿no debería funcionar? Tal vez una diferencia entre las versiones de Emacs. : /
Tyler