Function: tcl--syntax-of-quote

tcl--syntax-of-quote is a byte-compiled function defined in tcl.el.gz.

Signature

(tcl--syntax-of-quote POS)

Documentation

Decide whether a double quote opens a string or not.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/tcl.el.gz
(defun tcl--syntax-of-quote (pos)
  "Decide whether a double quote opens a string or not."
  ;; This is pretty tricky, because strings can be written as "..."
  ;; or as {...} or without any quoting at all for some simple and not so
  ;; simple cases (e.g. `abc' but also `a"b').  To make things more
  ;; interesting, code is represented as strings, so the content of
  ;; strings can be later re-lexed to find nested strings.
  (save-excursion
    (let ((ppss (syntax-ppss pos)))
      (cond
       ((nth 8 ppss) nil) ;; Within a string or a comment.
       ((not (memq (char-before pos)
                   (cons nil
                         (eval-when-compile
                           (mapcar #'identity tcl--word-delimiters)))))
        ;; The double quote appears within some other lexical entity.
        ;; FIXME: Similar treatment should be used for `{' which can appear
        ;; within non-delimited strings (but only at top-level, so
        ;; maybe it's not worth worrying about).
        (string-to-syntax "."))
       ((zerop (nth 0 ppss))
        ;; Not within a { ... }, so can't be truncated by a }.
        ;; FIXME: The syntax-table also considers () and [] as paren
        ;; delimiters just like {}, even though Tcl treats them differently.
        ;; Tho I'm not sure it's worth worrying about, either.
        nil)
       (t
        ;; A double quote within a {...}: leave it as a normal string
        ;; delimiter only if we don't find a closing } before we
        ;; find a closing ".
        (let ((type nil)
              (depth 0))
          (forward-char 1)
          (while (and (not type)
                      (re-search-forward "[\"{}\\]" nil t))
            (pcase (char-after (match-beginning 0))
              (?\\ (forward-char 1))
              (?\" (setq type 'matched))
              (?\{ (incf depth))
              (?\} (if (zerop depth) (setq type 'unmatched)
                     (incf depth)))))
          (when (> (line-beginning-position) pos)
            ;; The quote is not on the same line as the deciding
            ;; factor, so make sure we revisit this choice later.
            (put-text-property pos (point) 'syntax-multiline t))
          (when (eq type 'unmatched)
            ;; The quote has no matching close because a } closes the
            ;; surrounding string before, so it doesn't really "open a string".
            (string-to-syntax "."))))))))