Permalink
Browse files

fixing triple quoted strings issue with code from python-mode

  • Loading branch information...
1 parent 244d4b3 commit 168b32deb6e0fff9c3f4ab1e09515a03f7ad77af @disnet disnet committed Feb 28, 2012
Showing with 54 additions and 0 deletions.
  1. +54 −0 coffee-mode.el
View
@@ -656,6 +656,50 @@ line? Returns `t' or `nil'. See the README for more details."
(backward-to-indentation 0)
(= (char-after) (string-to-char "#"))))
+
+(defun coffee-quote-syntax (n)
+ "Put `syntax-table' property correctly on triple quote.
+Used for syntactic keywords. N is the match number (1, 2 or 3)."
+ ;; From python-mode...
+ ;;
+ ;; Given a triple quote, we have to check the context to know
+ ;; whether this is an opening or closing triple or whether it's
+ ;; quoted anyhow, and should be ignored. (For that we need to do
+ ;; the same job as `syntax-ppss' to be correct and it seems to be OK
+ ;; to use it here despite initial worries.) We also have to sort
+ ;; out a possible prefix -- well, we don't _have_ to, but I think it
+ ;; should be treated as part of the string.
+
+ ;; Test cases:
+ ;; ur"""ar""" x='"' # """
+ ;; x = ''' """ ' a
+ ;; '''
+ ;; x '"""' x """ \"""" x
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (cond
+ ;; Consider property for the last char if in a fenced string.
+ ((= n 3)
+ (let* ((font-lock-syntactic-keywords nil)
+ (syntax (syntax-ppss)))
+ (when (eq t (nth 3 syntax)) ; after unclosed fence
+ (goto-char (nth 8 syntax)) ; fence position
+ ;; (skip-chars-forward "uUrR") ; skip any prefix
+ ;; Is it a matching sequence?
+ (if (eq (char-after) (char-after (match-beginning 2)))
+ (eval-when-compile (string-to-syntax "|"))))))
+ ;; Consider property for initial char, accounting for prefixes.
+ ((or (and (= n 2) ; leading quote (not prefix)
+ (not (match-end 1))) ; prefix is null
+ (and (= n 1) ; prefix
+ (match-end 1))) ; non-empty
+ (let ((font-lock-syntactic-keywords nil))
+ (unless (eq 'string (syntax-ppss-context (syntax-ppss)))
+ (eval-when-compile (string-to-syntax "|")))))
+ ;; Otherwise (we're in a non-matching string) the property is
+ ;; nil, which is OK.
+ )))
+
;;
;; Define Major Mode
;;
@@ -685,6 +729,16 @@ line? Returns `t' or `nil'. See the README for more details."
;; single quote strings
(modify-syntax-entry ?' "\"" coffee-mode-syntax-table)
+ (setq font-lock-syntactic-keywords
+ ;; Make outer chars of matching triple-quote sequences into generic
+ ;; string delimiters.
+ ;; First avoid a sequence preceded by an odd number of backslashes.
+ `((,(concat "\\(?:^\\|[^\\]\\(?:\\\\.\\)*\\)" ;Prefix.
+ "\\(?:\\('\\)\\('\\)\\('\\)\\|\\(?1:\"\\)\\(?2:\"\\)\\(?3:\"\\)\\)")
+ (1 (coffee-quote-syntax 1) nil lax)
+ (2 (coffee-quote-syntax 2))
+ (3 (coffee-quote-syntax 3)))))
+
;; indentation
(make-local-variable 'indent-line-function)
(setq indent-line-function 'coffee-indent-line)

0 comments on commit 168b32d

Please sign in to comment.