dryman / toml-mode.el

Emacs Mojor mode for editing TOML files
49 stars 15 forks source link

triple quoted strings not treated correctly #12

Open vitiral opened 7 years ago

vitiral commented 7 years ago

The following leads to odd highlighting:

[foo]
text = '''
foo bar 'baz
'''

[bar]
text = '''
foo bar 'baz
'''

Namely, the syntax highlighter doesn't recognize that ''' is a special "block string". It thinks that the string ends at the next ' when in fact it should only end at the next '''

vmfhrmfoaj commented 3 years ago

Hi @vitiral

To fix the problem, I copied code related to multi-line string from python-mode:

(defconst toml-syntax-propertize-function
  (syntax-propertize-rules
   ("\"\"\"\\|'''"
    (0 (ignore (toml-syntax-stringify))))))

(defun toml-syntax-stringify ()
  "Put `syntax-table' property correctly on single/triple quotes."
  (let* ((ppss (save-excursion (backward-char 3) (syntax-ppss)))
         (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss)))
         (quote-starting-pos (- (point) 3))
         (quote-ending-pos (point)))
    (cond
     ((or (nth 4 ppss)                ; Inside a comment
          (and string-start
               ;; Inside of a string quoted with different triple quotes.
               (not (eql (char-after string-start)
                         (char-after quote-starting-pos)))))
      ;; Do nothing.
      nil)
     ((nth 5 ppss)
      ;; The first quote is escaped, so it's not part of a triple quote!
      (goto-char (1+ quote-starting-pos)))
     ((null string-start)
      ;; This set of quotes delimit the start of a string.
      (put-text-property quote-starting-pos (1+ quote-starting-pos)
                         'syntax-table (string-to-syntax "|")))
     (t
      ;; This set of quotes delimit the end of a string.
      (put-text-property (1- quote-ending-pos) quote-ending-pos
                         'syntax-table (string-to-syntax "|"))))))

(add-hook 'toml-mode-hook
          (lambda ()
            (setq-local parse-sexp-lookup-properties t)
            (setq-local syntax-propertize-function toml-syntax-propertize-function)))