Subject: Re: bug#21230: 25.0.50; scss-mode: Font Lock hangs on Sass lists

From: Simen Heggestøyl <[email-masked]>
Date: Sat, 09 Jan 2016 13:55:10 +0100

It seems that this happens because scss-mode thinks that the list
elements are selectors. The attached patch attempts to fix this by
disallowing parenthesis in selectors, except for in the function
notation that might appear right after pseudo-classes.

-- Simen
>From f4ff7b89348142f103412e9aa6b3e2352dbfa567 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simen=20Heggest=C3=B8yl?= <[email-masked]>
Date: Sat, 2 Jan 2016 23:44:58 +0100
Subject: [PATCH] Disallow parenthesis in non-pseudo CSS selectors

* lisp/textmodes/css-mode.el (css--font-lock-keywords): Disallow
parenthesis in selectors except for in the function notation that
might appear right after a pseudo-class.
---
 lisp/textmodes/css-mode.el | 10 +++++-----
 test/indent/scss-mode.scss | 10 ++++++++++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 48c2484..d402fb1 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -257,13 +257,13 @@ css--font-lock-keywords
        (if (not sassy)
            ;; We don't allow / as first char, so as not to
            ;; take a comment as the beginning of a selector.
-           "[^@/:{} \t\n][^:{}]+"
+           "[^@/:{}() \t\n][^:{}()]+"
          ;; Same as for non-sassy except we do want to allow { and }
          ;; chars in selectors in the case of #{$foo}
          ;; variable interpolation!
          (concat "\\(?:" scss--hash-re
-                 "\\|[^@/:{} \t\n#]\\)"
-                 "[^:{}#]*\\(?:" scss--hash-re "[^:{}#]*\\)*"))
+                 "\\|[^@/:{}() \t\n#]\\)"
+                 "[^:{}()#]*\\(?:" scss--hash-re "[^:{}()#]*\\)*"))
        ;; Even though pseudo-elements should be prefixed by ::, a
        ;; single colon is accepted for backward compatibility.
        "\\(?:\\(:" (regexp-opt (append css-pseudo-class-ids
@@ -271,8 +271,8 @@ css--font-lock-keywords
        "\\|\\::" (regexp-opt css-pseudo-element-ids t) "\\)"
        "\\(?:([^)]+)\\)?"
        (if (not sassy)
-           "[^:{}\n]*"
-         (concat "[^:{}\n#]*\\(?:" scss--hash-re "[^:{}\n#]*\\)*"))
+           "[^:{}()\n]*"
+         (concat "[^:{}()\n#]*\\(?:" scss--hash-re "[^:{}()\n#]*\\)*"))
        "\\)*"
        "\\)\\(?:\n[ \t]*\\)*{")
      (1 'css-selector keep))
diff --git a/test/indent/scss-mode.scss b/test/indent/scss-mode.scss
index 7a29929..02a4a98 100644
--- a/test/indent/scss-mode.scss
+++ b/test/indent/scss-mode.scss
@@ -55,3 +55,13 @@ article[role="main"] {
 }
 
 .box { @include border-radius(10px); }
+
+// bug:21230
+$list: (
+   ('a', #000000, #fff)
+   ('b', #000000, #fff)
+   ('c', #000000, #fff)
+   ('d', #000000, #fff)
+   ('e', #000000, #fff)
+   ('f', #000000, #fff)
+);
-- 
2.6.4