16

Q: is there a general way to detect whether or not point is inside a matched pair of characters?

That is: is there a general predicate function (or something) that can determine if point is in-between a matched pair or some arbitrarily-chosen characters? I'm thinking about one that would evaluate to t in, say, the following scenarios, with ! referring to point:

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

Edit: syntax-ppss seems to be a good starting point, but it's not clear to me how one would adapt it to multi-character matched pairs (eg, the ``LaTeX quotes'', or even matched <b>html tags</b>). I'm wondering if there's a general solution, or if it would require a purpose-built parser.

Dan
  • 32,584
  • 6
  • 98
  • 168

2 Answers2

16

syntax-ppss might be of help here. It returns a list that also has these elements:

  • element 0: depth in parens
  • element 3: non-nil if inside a string

You could use it like this:

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

With a properly set up syntax-table in the buffer (for strings and matching parens) the function should do what you expect. If using the mode's syntax-table is not possible than you could resort to using with-syntax-table.

paprika
  • 1,944
  • 19
  • 26
  • I should point out that the docstring of `parse-partial-sexp` explains the data structure returned by `syntax-ppss` in more detail than the Elisp manual section I linked to. – paprika Oct 08 '14 at 09:32
2

If you want for example to check if between curly braces, use this:

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

Sure, you can replace the curly braces by whatever you want.

EDIT:

A more useful function will be something close to this:

(defun test-inside-curly-braces ()
 (interactive)
 (when (and (looking-back "{\\(.*?\\)") (looking-at "\\(.*?\\)}"))
  (message "inside curly braces")))
Nsukami _
  • 6,341
  • 2
  • 22
  • 35
  • 2
    That only works if point is on the closing `}`, and there's nothing between the `{}`. Getting paired delimiters right with regexps can be tricky. Better to use `syntax-pps` as @paprika suggested. – Tyler Oct 07 '14 at 16:56
  • @Tyler works only if point on closing `}` is not the behaviour I've seen :\ but yeah, get the pairs using regexps is tricky, indeed – Nsukami _ Oct 07 '14 at 17:34
  • `looking-at` examines the text starting at point. unless point is on the `}` your first statement above shouldn't work? Maybe a difference between Emacs versions. :/ – Tyler Oct 07 '14 at 17:51