jak wykryć, czy w dopasowanej parze?

16

P: Czy istnieje ogólny sposób na wykrycie, czy punkt znajduje się w dopasowanej parze znaków?

To znaczy: czy istnieje ogólna funkcja predykatu (lub coś w tym rodzaju), która może określić, czy punkt znajduje się pomiędzy dopasowaną parą, czy niektórymi dowolnie wybranymi znakami? Myślę o jednym, który oceniałby t, powiedzmy, w następujących scenariuszach w !odniesieniu do punktu:

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

Edycja : syntax-ppsswydaje się być dobrym punktem wyjścia, ale nie jest dla mnie jasne, w jaki sposób można go dostosować do par dopasowanych do wielu znaków (np. `` Cytaty LaTeX '', a nawet dopasowane <b>html tags</b>). Zastanawiam się, czy istnieje ogólne rozwiązanie, czy też wymagałoby to specjalnie skonstruowanego analizatora składni.

Dan
źródło

Odpowiedzi:

16

syntax-ppssmoże tu pomóc. To zwraca listę , która ma również następujące elementy:

  • element 0: głębokość w parens
  • element 3: inny niż zero, jeśli znajduje się w ciągu

Możesz użyć tego w następujący sposób:

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

Przy poprawnie skonfigurowanej tabeli składni w buforze (dla ciągów i pasujących parens) funkcja powinna robić to, czego oczekujesz. Jeśli korzystanie z tabeli składni tego trybu nie jest możliwe, możesz skorzystać z niej with-syntax-table.

papryka
źródło
Powinienem zaznaczyć, że dokumentacja parse-partial-sexpwyjaśnia strukturę danych zwróconą syntax-ppssbardziej szczegółowo niż sekcja instrukcji Elisp, do której linkowałem.
papryka
2

Jeśli chcesz na przykład sprawdzić, czy między nawiasami klamrowymi, użyj tego:

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

Jasne, możesz zastąpić nawiasy klamrowe czymkolwiek chcesz.

EDYTOWAĆ:

Bardziej użyteczną funkcją będzie coś podobnego:

(defun test-inside-curly-braces ()
 (interactive)
 (when (and (looking-back "{\\(.*?\\)") (looking-at "\\(.*?\\)}"))
  (message "inside curly braces")))
Nsukami _
źródło
2
Działa to tylko wtedy, gdy punkt jest na zamknięciu }, i nie ma nic pomiędzy {}. Prawidłowe sparowanie ograniczników z wyrażeniami regularnymi może być trudne. Lepiej używać syntax-ppszgodnie z sugestią @paprika.
Tyler
@Tyler działa tylko wtedy, gdy punktem zamknięcia }nie jest zachowanie, które widziałem: \ ale tak, uzyskanie par za pomocą
wyrażeń
looking-atsprawdza tekst zaczynając od punktu. chyba że punkt na }pierwszym stwierdzeniu powyżej nie powinien działać? Może różnica między wersjami Emacsa. : /
Tyler,