X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/59db4308b546cbe32d3bfe6e23dbc1899d511975..ea626c72e590aa7a45fd26df42240854e4225cef:/lisp/textmodes/css-mode.el diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 424cdb7f83..93a8dceec1 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1,6 +1,6 @@ ;;; css-mode.el --- Major mode to edit CSS files -*- lexical-binding: t -*- -;; Copyright (C) 2006-2015 Free Software Foundation, Inc. +;; Copyright (C) 2006-2016 Free Software Foundation, Inc. ;; Author: Stefan Monnier ;; Maintainer: Simen Heggestøyl @@ -54,6 +54,14 @@ '("charset" "font-face" "import" "media" "namespace" "page") "Identifiers that appear in the form @foo.") +(defconst css-bang-ids + '("important") + "Identifiers that appear in the form !foo.") + +(defconst scss-bang-ids + '("default" "global" "optional") + "Additional identifiers that appear in the form !foo in SCSS.") + (defconst css-descriptor-ids '("ascent" "baseline" "bbox" "cap-height" "centerline" "definition-src" "descent" "font-family" "font-size" "font-stretch" "font-style" @@ -78,14 +86,14 @@ "list-style" "list-style-image" "list-style-position" "list-style-type" "margin" "margin-bottom" "margin-left" "margin-right" "margin-top" "max-height" "max-width" "min-height" - "min-width" "orphans" "overflow" "padding" "padding-bottom" - "padding-left" "padding-right" "padding-top" "page-break-after" + "min-width" "padding" "padding-bottom" "padding-left" + "padding-right" "padding-top" "page-break-after" "page-break-before" "page-break-inside" "pause" "pause-after" "pause-before" "pitch" "pitch-range" "play-during" "position" "quotes" "richness" "right" "speak" "speak-header" "speak-numeral" "speak-punctuation" "speech-rate" "stress" "table-layout" "top" "unicode-bidi" "vertical-align" "visibility" "voice-family" "volume" - "widows" "width" "z-index" + "width" "z-index" ;; CSS Animations ;; (http://www.w3.org/TR/css3-animations/#property-index) @@ -136,6 +144,24 @@ "font-variant-east-asian" "font-variant-ligatures" "font-variant-numeric" "font-variant-position" "font-weight" + ;; CSS Fragmentation Module Level 3 + ;; (https://www.w3.org/TR/css-break-3/#property-index) + "box-decoration-break" "break-after" "break-before" "break-inside" + "orphans" "widows" + + ;; CSS Multi-column Layout Module + ;; (https://www.w3.org/TR/css3-multicol/#property-index) + ;; "break-after", "break-before", and "break-inside" are left out + ;; below, because they're already included in CSS Fragmentation + ;; Module Level 3. + "column-count" "column-fill" "column-gap" "column-rule" + "column-rule-color" "column-rule-style" "column-rule-width" + "column-span" "column-width" "columns" + + ;; CSS Overflow Module Level 3 + ;; (http://www.w3.org/TR/css-overflow-3/#property-index) + "max-lines" "overflow" "overflow-x" "overflow-y" + ;; CSS Text Decoration Module Level 3 ;; (http://dev.w3.org/csswg/css-text-decor-3/#property-index) "text-decoration" "text-decoration-color" "text-decoration-line" @@ -198,6 +224,16 @@ (modify-syntax-entry ?- "_" st) st)) +(eval-and-compile + (defconst css--uri-re + (concat + "url\\((\\)[[:space:]]*\\(?:\\\\.\\|[^()[:space:]\n'\"]\\)+" + "[[:space:]]*\\()\\)"))) + +(defconst css-syntax-propertize-function + (syntax-propertize-rules + (css--uri-re (1 "|") (2 "|")))) + (defconst css-escapes-re "\\\\\\(?:[^\000-\037\177]\\|[0-9a-fA-F]+[ \n\t\r\f]?\\)") (defconst css-nmchar-re (concat "\\(?:[-[:alnum:]]\\|" css-escapes-re "\\)")) @@ -222,8 +258,8 @@ (defun css--font-lock-keywords (&optional sassy) `((,(concat "!\\s-*" - (regexp-opt (append (if sassy '("global")) - '("important")))) + (regexp-opt (append (if sassy scss-bang-ids) + css-bang-ids))) (0 font-lock-builtin-face)) ;; Atrules keywords. IDs not in css-at-ids are valid (ignored). ;; In fact the regexp should probably be @@ -232,6 +268,8 @@ ;; Since "An at-rule consists of everything up to and including the next ;; semicolon (;) or the next block, whichever comes first." (,(concat "@" css-ident-re) (0 font-lock-builtin-face)) + ;; Variables. + (,(concat "--" css-ident-re) (0 font-lock-variable-name-face)) ;; Selectors. ;; FIXME: attribute selectors don't work well because they may contain ;; strings which have already been highlighted as f-l-string-face and @@ -243,22 +281,22 @@ (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 css-pseudo-element-ids) t) "\\|\\::" (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)) @@ -278,7 +316,13 @@ "\\(?:\\(" css-proprietary-nmstart-re "\\)\\|" css-nmstart-re "\\)" css-nmchar-re "*" "\\)\\s-*:") - (1 (if (match-end 2) 'css-proprietary-property 'css-property))))) + (1 (if (match-end 2) 'css-proprietary-property 'css-property))) + ;; Make sure the parens in a url(...) expression receive the + ;; default face. This is done because the parens may sometimes + ;; receive generic string delimiter syntax (see + ;; `css-syntax-propertize-function'). + (,css--uri-re + (1 'default t) (2 'default t)))) (defvar css-font-lock-keywords (css--font-lock-keywords)) @@ -288,7 +332,8 @@ (defcustom css-indent-offset 4 "Basic size of one indentation step." :version "22.2" - :type 'integer) + :type 'integer + :safe 'integerp) (require 'smie) @@ -328,7 +373,7 @@ (`(:elem . arg) 0) (`(:list-intro . ,(or `";" `"")) t) ;"" stands for BOB (bug#15467). (`(:before . "{") - (when (smie-rule-hanging-p) + (when (or (smie-rule-hanging-p) (smie-rule-bolp)) (smie-backward-sexp ";") (smie-indent-virtual))) (`(:before . ,(or "{" "(")) @@ -381,6 +426,8 @@ pseudo-classes, and at-rules." (setq-local comment-start-skip "/\\*+[ \t]*") (setq-local comment-end "*/") (setq-local comment-end-skip "[ \t]*\\*+/") + (setq-local syntax-propertize-function + css-syntax-propertize-function) (setq-local fill-paragraph-function #'css-fill-paragraph) (setq-local adaptive-fill-function #'css-adaptive-fill) (setq-local add-log-current-defun-function #'css-current-defun-name) @@ -500,6 +547,8 @@ pseudo-classes, and at-rules." (let ((st (make-syntax-table css-mode-syntax-table))) (modify-syntax-entry ?/ ". 124" st) (modify-syntax-entry ?\n ">" st) + ;; Variable names are prefixed by $. + (modify-syntax-entry ?$ "'" st) st)) (defvar scss-font-lock-keywords