comment détecter si à l'intérieur d'une paire assortie?

16

Q: Existe -t-il un moyen général de détecter si le point se trouve ou non à l'intérieur d'une paire de caractères correspondante?

C'est-à-dire: y a-t-il une fonction de prédicat générale (ou quelque chose) qui peut déterminer si le point est entre une paire appariée ou certains caractères choisis arbitrairement? Je pense à un qui évaluerait tdans, disons, les scénarios suivants, en se !référant au point:

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

Edit : syntax-ppsssemble être un bon point de départ, mais je ne sais pas comment on pourrait l'adapter à des paires appariées à plusieurs caractères (par exemple, les `` guillemets LaTeX '', ou même appariés <b>html tags</b>). Je me demande s'il existe une solution générale ou si elle nécessiterait un analyseur spécialement conçu.

Dan
la source

Réponses:

16

syntax-ppsspourrait être utile ici. Il renvoie une liste qui contient également ces éléments:

  • élément 0: profondeur en parens
  • élément 3: non nul si à l'intérieur d'une chaîne

Vous pouvez l'utiliser comme ceci:

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

Avec une table de syntaxe correctement configurée dans le tampon (pour les chaînes et les parens correspondants), la fonction devrait faire ce que vous attendez. Si l'utilisation de la table de syntaxe du mode n'est pas possible, vous pouvez recourir à l'utilisation with-syntax-table.

paprika
la source
Je dois souligner que la docstring de parse-partial-sexpexplique la structure de données retournée par syntax-ppssplus en détail que la section du manuel Elisp à laquelle j'ai lié.
paprika
2

Si vous voulez par exemple vérifier si entre accolades, utilisez ceci:

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

Bien sûr, vous pouvez remplacer les accolades par ce que vous voulez.

ÉDITER:

Une fonction plus utile sera proche de cela:

(defun test-inside-curly-braces ()
 (interactive)
 (when (and (looking-back "{\\(.*?\\)") (looking-at "\\(.*?\\)}"))
  (message "inside curly braces")))
Nsukami _
la source
2
Cela ne fonctionne que si le point est sur la fermeture }, et il n'y a rien entre les {}. Il peut être difficile d'obtenir des délimiteurs appariés avec des expressions rationnelles. Mieux vaut l'utiliser syntax-ppscomme l'a suggéré @paprika.
Tyler
@Tyler ne fonctionne que si le point de fermeture }n'est pas le comportement que j'ai vu: \ mais oui, obtenir les paires en utilisant des expressions rationnelles est difficile, en effet
Nsukami _
looking-atexamine le texte à partir du point. sauf si le point est sur }votre première déclaration ci-dessus ne devrait pas fonctionner? Peut-être une différence entre les versions d'Emacs. : /
Tyler