mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
Support completion of attribute values in CSS mode
* lisp/textmodes/css-mode.el (css-property-alist): New defconst holding CSS identifiers and the values they can have. (css-property-ids): Compute dynamically from `css-property-alist'. (css-value-class-alist): New defconst holding property value classes and their values. (css--property-value-cache): New variable providing a cache for `css--property-values'. (css--value-class-lookup): New function for computing a list of values in a value class. (css--property-values): New function for computing a list of possible values for a CSS property. (css--complete-property-value): New function for completing a property value. (css-completion-at-point): Add support for completing property values. * test/lisp/textmodes/css-mode-tests.el: New file.
This commit is contained in:
parent
500a781bc5
commit
269d5631ab
3 changed files with 534 additions and 76 deletions
6
etc/NEWS
6
etc/NEWS
|
|
@ -133,6 +133,12 @@ different group ID.
|
|||
---
|
||||
** 'auto-revert-use-notify' is set back to t in 'global-auto-revert-mode'.
|
||||
|
||||
** CSS mode
|
||||
|
||||
---
|
||||
*** Support for completing attribute values using the `completion-at-point'
|
||||
command.
|
||||
|
||||
|
||||
* New Modes and Packages in Emacs 25.2
|
||||
|
||||
|
|
|
|||
|
|
@ -29,11 +29,13 @@
|
|||
|
||||
;; - electric ; and }
|
||||
;; - filling code with auto-fill-mode
|
||||
;; - attribute value completion
|
||||
;; - fix font-lock errors with multi-line selectors
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'seq)
|
||||
(require 'smie)
|
||||
|
||||
(defgroup css nil
|
||||
"Cascading Style Sheets (CSS) editing mode."
|
||||
:group 'languages)
|
||||
|
|
@ -74,124 +76,465 @@
|
|||
"visual")
|
||||
"Identifiers for types of media.")
|
||||
|
||||
(defconst css-property-ids
|
||||
'(;; CSS 2.1 properties (http://www.w3.org/TR/CSS21/propidx.html).
|
||||
(defconst css-property-alist
|
||||
;; CSS 2.1 properties (http://www.w3.org/TR/CSS21/propidx.html).
|
||||
;;
|
||||
;; Properties duplicated by any of the CSS3 modules below have
|
||||
;; been removed.
|
||||
"azimuth" "border-collapse" "border-spacing" "bottom"
|
||||
"caption-side" "clear" "clip" "content" "counter-increment"
|
||||
"counter-reset" "cue" "cue-after" "cue-before" "direction" "display"
|
||||
"elevation" "empty-cells" "float" "height" "left" "line-height"
|
||||
"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" "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"
|
||||
"width" "z-index"
|
||||
;; Properties duplicated by any of the CSS3 modules below have been
|
||||
;; removed.
|
||||
'(("azimuth" angle "left-side" "far-left" "left" "center-left"
|
||||
"center" "center-right" "right" "far-right" "right-side" "behind"
|
||||
"leftwards" "rightwards")
|
||||
("border-collapse" "collapse" "separate")
|
||||
("border-spacing" length)
|
||||
("bottom" length percentage "auto")
|
||||
("caption-side" "top" "bottom")
|
||||
("clear" "none" "left" "right" "both")
|
||||
("clip" shape "auto")
|
||||
("content" "normal" "none" string uri counter "attr()"
|
||||
"open-quote" "close-quote" "no-open-quote" "no-close-quote")
|
||||
("counter-increment" identifier integer "none")
|
||||
("counter-reset" identifier integer "none")
|
||||
("cue" cue-before cue-after)
|
||||
("cue-after" uri "none")
|
||||
("cue-before" uri "none")
|
||||
("direction" "ltr" "rtl")
|
||||
("display" "inline" "block" "list-item" "inline-block" "table"
|
||||
"inline-table" "table-row-group" "table-header-group"
|
||||
"table-footer-group" "table-row" "table-column-group"
|
||||
"table-column" "table-cell" "table-caption" "none"
|
||||
;; CSS Flexible Box Layout Module Level 1
|
||||
;; (https://www.w3.org/TR/css3-flexbox/#valdef-display-flex)
|
||||
"flex" "inline-flex")
|
||||
("elevation" angle "below" "level" "above" "higher" "lower")
|
||||
("empty-cells" "show" "hide")
|
||||
("float" "left" "right" "none")
|
||||
("height" length percentage "auto")
|
||||
("left" length percentage "auto")
|
||||
("line-height" "normal" number length percentage)
|
||||
("list-style" list-style-type list-style-position
|
||||
list-style-image)
|
||||
("list-style-image" uri "none")
|
||||
("list-style-position" "inside" "outside")
|
||||
("list-style-type" "disc" "circle" "square" "decimal"
|
||||
"decimal-leading-zero" "lower-roman" "upper-roman" "lower-greek"
|
||||
"lower-latin" "upper-latin" "armenian" "georgian" "lower-alpha"
|
||||
"upper-alpha" "none")
|
||||
("margin" margin-width)
|
||||
("margin-bottom" margin-width)
|
||||
("margin-left" margin-width)
|
||||
("margin-right" margin-width)
|
||||
("margin-top" margin-width)
|
||||
("max-height" length percentage "none")
|
||||
("max-width" length percentage "none")
|
||||
("min-height" length percentage)
|
||||
("min-width" length percentage)
|
||||
("padding" padding-width)
|
||||
("padding-bottom" padding-width)
|
||||
("padding-left" padding-width)
|
||||
("padding-right" padding-width)
|
||||
("padding-top" padding-width)
|
||||
("page-break-after" "auto" "always" "avoid" "left" "right")
|
||||
("page-break-before" "auto" "always" "avoid" "left" "right")
|
||||
("page-break-inside" "avoid" "auto")
|
||||
("pause" time percentage)
|
||||
("pause-after" time percentage)
|
||||
("pause-before" time percentage)
|
||||
("pitch" frequency "x-low" "low" "medium" "high" "x-high")
|
||||
("pitch-range" number)
|
||||
("play-during" uri "mix" "repeat" "auto" "none")
|
||||
("position" "static" "relative" "absolute" "fixed")
|
||||
("quotes" string "none")
|
||||
("richness" number)
|
||||
("right" length percentage "auto")
|
||||
("speak" "normal" "none" "spell-out")
|
||||
("speak-header" "once" "always")
|
||||
("speak-numeral" "digits" "continuous")
|
||||
("speak-punctuation" "code" "none")
|
||||
("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast"
|
||||
"faster" "slower")
|
||||
("stress" number)
|
||||
("table-layout" "auto" "fixed")
|
||||
("top" length percentage "auto")
|
||||
("unicode-bidi" "normal" "embed" "bidi-override")
|
||||
("vertical-align" "baseline" "sub" "super" "top" "text-top"
|
||||
"middle" "bottom" "text-bottom" percentage length)
|
||||
("visibility" "visible" "hidden" "collapse")
|
||||
("voice-family" specific-voice generic-voice specific-voice
|
||||
generic-voice)
|
||||
("volume" number percentage "silent" "x-soft" "soft" "medium"
|
||||
"loud" "x-loud")
|
||||
("width" length percentage "auto")
|
||||
("z-index" "auto" integer)
|
||||
|
||||
;; CSS Animations
|
||||
;; (http://www.w3.org/TR/css3-animations/#property-index)
|
||||
"animation" "animation-delay" "animation-direction"
|
||||
"animation-duration" "animation-fill-mode"
|
||||
"animation-iteration-count" "animation-name"
|
||||
"animation-play-state" "animation-timing-function"
|
||||
("animation" single-animation-name time single-timing-function
|
||||
single-animation-iteration-count single-animation-direction
|
||||
single-animation-fill-mode single-animation-play-state)
|
||||
("animation-delay" time)
|
||||
("animation-direction" single-animation-direction)
|
||||
("animation-duration" time)
|
||||
("animation-fill-mode" single-animation-fill-mode)
|
||||
("animation-iteration-count" single-animation-iteration-count)
|
||||
("animation-name" single-animation-name)
|
||||
("animation-play-state" single-animation-play-state)
|
||||
("animation-timing-function" single-timing-function)
|
||||
|
||||
;; CSS Backgrounds and Borders Module Level 3
|
||||
;; (http://www.w3.org/TR/css3-background/#property-index)
|
||||
"background" "background-attachment" "background-clip"
|
||||
"background-color" "background-image" "background-origin"
|
||||
"background-position" "background-repeat" "background-size"
|
||||
"border" "border-bottom" "border-bottom-color"
|
||||
"border-bottom-left-radius" "border-bottom-right-radius"
|
||||
"border-bottom-style" "border-bottom-width" "border-color"
|
||||
"border-image" "border-image-outset" "border-image-repeat"
|
||||
"border-image-slice" "border-image-source" "border-image-width"
|
||||
"border-left" "border-left-color" "border-left-style"
|
||||
"border-left-width" "border-radius" "border-right"
|
||||
"border-right-color" "border-right-style" "border-right-width"
|
||||
"border-style" "border-top" "border-top-color"
|
||||
"border-top-left-radius" "border-top-right-radius"
|
||||
"border-top-style" "border-top-width" "border-width" "box-shadow"
|
||||
("background" bg-layer final-bg-layer)
|
||||
("background-attachment" attachment)
|
||||
("background-clip" box)
|
||||
("background-color" color)
|
||||
("background-image" bg-image)
|
||||
("background-origin" box)
|
||||
("background-position" position)
|
||||
("background-repeat" repeat-style)
|
||||
("background-size" bg-size)
|
||||
("border" line-width line-style color)
|
||||
("border-bottom" line-width line-style color)
|
||||
("border-bottom-color" color)
|
||||
("border-bottom-left-radius" length percentage)
|
||||
("border-bottom-right-radius" length percentage)
|
||||
("border-bottom-style" line-style)
|
||||
("border-bottom-width" line-width)
|
||||
("border-color" color)
|
||||
("border-image" border-image-source border-image-slice
|
||||
border-image-width border-image-outset border-image-repeat)
|
||||
("border-image-outset" length number)
|
||||
("border-image-repeat" "stretch" "repeat" "round" "space")
|
||||
("border-image-slice" number percentage "fill")
|
||||
("border-image-source" "none" image)
|
||||
("border-image-width" length percentage number "auto")
|
||||
("border-left" line-width line-style color)
|
||||
("border-left-color" color)
|
||||
("border-left-style" line-style)
|
||||
("border-left-width" line-width)
|
||||
("border-radius" length percentage)
|
||||
("border-right" line-width line-style color)
|
||||
("border-right-color" color)
|
||||
("border-right-style" line-style)
|
||||
("border-right-width" line-width)
|
||||
("border-style" line-style)
|
||||
("border-top" line-width line-style color)
|
||||
("border-top-color" color)
|
||||
("border-top-left-radius" length percentage)
|
||||
("border-top-right-radius" length percentage)
|
||||
("border-top-style" line-style)
|
||||
("border-top-width" line-width)
|
||||
("border-width" line-width)
|
||||
("box-shadow" "none" shadow)
|
||||
|
||||
;; CSS Basic User Interface Module Level 3 (CSS3 UI)
|
||||
;; (http://www.w3.org/TR/css3-ui/#property-index)
|
||||
"box-sizing" "caret-color" "cursor" "nav-down" "nav-left"
|
||||
"nav-right" "nav-up" "outline" "outline-color" "outline-offset"
|
||||
"outline-style" "outline-width" "resize" "text-overflow"
|
||||
("box-sizing" "content-box" "border-box")
|
||||
("caret-color" "auto" color)
|
||||
("cursor" uri x y "auto" "default" "none" "context-menu" "help"
|
||||
"pointer" "progress" "wait" "cell" "crosshair" "text"
|
||||
"vertical-text" "alias" "copy" "move" "no-drop" "not-allowed"
|
||||
"grab" "grabbing" "e-resize" "n-resize" "ne-resize" "nw-resize"
|
||||
"s-resize" "se-resize" "sw-resize" "w-resize" "ew-resize"
|
||||
"ns-resize" "nesw-resize" "nwse-resize" "col-resize" "row-resize"
|
||||
"all-scroll" "zoom-in" "zoom-out")
|
||||
("nav-down" "auto" id "current" "root" target-name)
|
||||
("nav-left" "auto" id "current" "root" target-name)
|
||||
("nav-right" "auto" id "current" "root" target-name)
|
||||
("nav-up" "auto" id "current" "root" target-name)
|
||||
("outline" outline-color outline-style outline-width)
|
||||
("outline-color" color "invert")
|
||||
("outline-offset" length)
|
||||
("outline-style" "auto" border-style)
|
||||
("outline-width" border-width)
|
||||
("resize" "none" "both" "horizontal" "vertical")
|
||||
("text-overflow" "clip" "ellipsis" string)
|
||||
|
||||
;; CSS Color Module Level 3
|
||||
;; (http://www.w3.org/TR/css3-color/#property)
|
||||
"color" "opacity"
|
||||
("color" color)
|
||||
("opacity" alphavalue)
|
||||
|
||||
;; CSS Flexible Box Layout Module Level 1
|
||||
;; (http://www.w3.org/TR/css-flexbox-1/#property-index)
|
||||
"align-content" "align-items" "align-self" "flex" "flex-basis"
|
||||
"flex-direction" "flex-flow" "flex-grow" "flex-shrink" "flex-wrap"
|
||||
"justify-content" "order"
|
||||
("align-content" "flex-start" "flex-end" "center" "space-between"
|
||||
"space-around" "stretch")
|
||||
("align-items" "flex-start" "flex-end" "center" "baseline"
|
||||
"stretch")
|
||||
("align-self" "auto" "flex-start" "flex-end" "center" "baseline"
|
||||
"stretch")
|
||||
("flex" "none" flex-grow flex-shrink flex-basis)
|
||||
("flex-basis" "auto" "content" width)
|
||||
("flex-direction" "row" "row-reverse" "column" "column-reverse")
|
||||
("flex-flow" flex-direction flex-wrap)
|
||||
("flex-grow" number)
|
||||
("flex-shrink" number)
|
||||
("flex-wrap" "nowrap" "wrap" "wrap-reverse")
|
||||
("justify-content" "flex-start" "flex-end" "center"
|
||||
"space-between" "space-around")
|
||||
("order" integer)
|
||||
|
||||
;; CSS Fonts Module Level 3
|
||||
;; (http://www.w3.org/TR/css3-fonts/#property-index)
|
||||
"font" "font-family" "font-feature-settings" "font-kerning"
|
||||
"font-language-override" "font-size" "font-size-adjust"
|
||||
"font-stretch" "font-style" "font-synthesis" "font-variant"
|
||||
"font-variant-alternates" "font-variant-caps"
|
||||
"font-variant-east-asian" "font-variant-ligatures"
|
||||
"font-variant-numeric" "font-variant-position" "font-weight"
|
||||
("font" font-style font-variant-css21 font-weight font-stretch
|
||||
font-size line-height font-family "caption" "icon" "menu"
|
||||
"message-box" "small-caption" "status-bar")
|
||||
("font-family" family-name generic-family)
|
||||
("font-feature-settings" "normal" feature-tag-value)
|
||||
("font-kerning" "auto" "normal" "none")
|
||||
("font-language-override" "normal" string)
|
||||
("font-size" absolute-size relative-size length percentage)
|
||||
("font-size-adjust" "none" number)
|
||||
("font-stretch" "normal" "ultra-condensed" "extra-condensed"
|
||||
"condensed" "semi-condensed" "semi-expanded" "expanded"
|
||||
"extra-expanded" "ultra-expanded")
|
||||
("font-style" "normal" "italic" "oblique")
|
||||
("font-synthesis" "none" "weight" "style")
|
||||
("font-variant" "normal" "none" common-lig-values
|
||||
discretionary-lig-values historical-lig-values
|
||||
contextual-alt-values "stylistic()" "historical-forms"
|
||||
"styleset()" "character-variant()" "swash()" "ornaments()"
|
||||
"annotation()" "small-caps" "all-small-caps" "petite-caps"
|
||||
"all-petite-caps" "unicase" "titling-caps" numeric-figure-values
|
||||
numeric-spacing-values numeric-fraction-values "ordinal"
|
||||
"slashed-zero" east-asian-variant-values east-asian-width-values
|
||||
"ruby")
|
||||
("font-variant-alternates" "normal" "stylistic()"
|
||||
"historical-forms" "styleset()" "character-variant()" "swash()"
|
||||
"ornaments()" "annotation()")
|
||||
("font-variant-caps" "normal" "small-caps" "all-small-caps"
|
||||
"petite-caps" "all-petite-caps" "unicase" "titling-caps")
|
||||
("font-variant-east-asian" "normal" east-asian-variant-values
|
||||
east-asian-width-values "ruby")
|
||||
("font-variant-ligatures" "normal" "none" common-lig-values
|
||||
discretionary-lig-values historical-lig-values
|
||||
contextual-alt-values)
|
||||
("font-variant-numeric" "normal" numeric-figure-values
|
||||
numeric-spacing-values numeric-fraction-values "ordinal"
|
||||
"slashed-zero")
|
||||
("font-variant-position" "normal" "sub" "super")
|
||||
("font-weight" "normal" "bold" "bolder" "lighter" "100" "200"
|
||||
"300" "400" "500" "600" "700" "800" "900")
|
||||
|
||||
;; 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"
|
||||
("box-decoration-break" "slice" "clone")
|
||||
("break-after" "auto" "avoid" "avoid-page" "page" "left" "right"
|
||||
"recto" "verso" "avoid-column" "column" "avoid-region" "region")
|
||||
("break-before" "auto" "avoid" "avoid-page" "page" "left" "right"
|
||||
"recto" "verso" "avoid-column" "column" "avoid-region" "region")
|
||||
("break-inside" "auto" "avoid" "avoid-page" "avoid-column"
|
||||
"avoid-region")
|
||||
("orphans" integer)
|
||||
("widows" integer)
|
||||
|
||||
;; 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"
|
||||
("column-count" integer "auto")
|
||||
("column-fill" "auto" "balance")
|
||||
("column-gap" length "normal")
|
||||
("column-rule" column-rule-width column-rule-style
|
||||
column-rule-color "transparent")
|
||||
("column-rule-color" color)
|
||||
("column-rule-style" border-style)
|
||||
("column-rule-width" border-width)
|
||||
("column-span" "none" "all")
|
||||
("column-width" length "auto")
|
||||
("columns" column-width column-count)
|
||||
|
||||
;; CSS Overflow Module Level 3
|
||||
;; (http://www.w3.org/TR/css-overflow-3/#property-index)
|
||||
"max-lines" "overflow" "overflow-x" "overflow-y"
|
||||
("max-lines" "none" integer)
|
||||
("overflow" "visible" "hidden" "scroll" "auto" "paged-x" "paged-y"
|
||||
"paged-x-controls" "paged-y-controls" "fragments")
|
||||
("overflow-x" "visible" "hidden" "scroll" "auto" "paged-x"
|
||||
"paged-y" "paged-x-controls" "paged-y-controls" "fragments")
|
||||
("overflow-y" "visible" "hidden" "scroll" "auto" "paged-x"
|
||||
"paged-y" "paged-x-controls" "paged-y-controls" "fragments")
|
||||
|
||||
;; 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"
|
||||
"text-decoration-skip" "text-decoration-style" "text-emphasis"
|
||||
"text-emphasis-color" "text-emphasis-position" "text-emphasis-style"
|
||||
"text-shadow" "text-underline-position"
|
||||
("text-decoration" text-decoration-line text-decoration-style
|
||||
text-decoration-color)
|
||||
("text-decoration-color" color)
|
||||
("text-decoration-line" "none" "underline" "overline"
|
||||
"line-through" "blink")
|
||||
("text-decoration-skip" "none" "objects" "spaces" "ink" "edges"
|
||||
"box-decoration")
|
||||
("text-decoration-style" "solid" "double" "dotted" "dashed"
|
||||
"wavy")
|
||||
("text-emphasis" text-emphasis-style text-emphasis-color)
|
||||
("text-emphasis-color" color)
|
||||
("text-emphasis-position" "over" "under" "right" "left")
|
||||
("text-emphasis-style" "none" "filled" "open" "dot" "circle"
|
||||
"double-circle" "triangle" "sesame" string)
|
||||
("text-shadow" "none" length color)
|
||||
("text-underline-position" "auto" "under" "left" "right")
|
||||
|
||||
;; CSS Text Module Level 3
|
||||
;; (http://www.w3.org/TR/css3-text/#property-index)
|
||||
"hanging-punctuation" "hyphens" "letter-spacing" "line-break"
|
||||
"overflow-wrap" "tab-size" "text-align" "text-align-last"
|
||||
"text-indent" "text-justify" "text-transform" "white-space"
|
||||
"word-break" "word-spacing" "word-wrap"
|
||||
("hanging-punctuation" "none" "first" "force-end" "allow-end"
|
||||
"last")
|
||||
("hyphens" "none" "manual" "auto")
|
||||
("letter-spacing" "normal" length)
|
||||
("line-break" "auto" "loose" "normal" "strict")
|
||||
("overflow-wrap" "normal" "break-word")
|
||||
("tab-size" integer length)
|
||||
("text-align" "start" "end" "left" "right" "center" "justify"
|
||||
"match-parent")
|
||||
("text-align-last" "auto" "start" "end" "left" "right" "center"
|
||||
"justify")
|
||||
("text-indent" length percentage)
|
||||
("text-justify" "auto" "none" "inter-word" "distribute")
|
||||
("text-transform" "none" "capitalize" "uppercase" "lowercase"
|
||||
"full-width")
|
||||
("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line")
|
||||
("word-break" "normal" "keep-all" "break-all")
|
||||
("word-spacing" "normal" length percentage)
|
||||
("word-wrap" "normal" "break-word")
|
||||
|
||||
;; CSS Transforms Module Level 1
|
||||
;; (http://www.w3.org/TR/css3-2d-transforms/#property-index)
|
||||
"backface-visibility" "perspective" "perspective-origin"
|
||||
"transform" "transform-origin" "transform-style"
|
||||
("backface-visibility" "visible" "hidden")
|
||||
("perspective" "none" length)
|
||||
("perspective-origin" "left" "center" "right" "top" "bottom"
|
||||
percentage length)
|
||||
("transform" "none" transform-list)
|
||||
("transform-origin" "left" "center" "right" "top" "bottom"
|
||||
percentage length)
|
||||
("transform-style" "flat" "preserve-3d")
|
||||
|
||||
;; CSS Transitions
|
||||
;; (http://www.w3.org/TR/css3-transitions/#property-index)
|
||||
"transition" "transition-delay" "transition-duration"
|
||||
"transition-property" "transition-timing-function"
|
||||
("transition" single-transition)
|
||||
("transition-delay" time)
|
||||
("transition-duration" time)
|
||||
("transition-property" "none" single-transition-property "all")
|
||||
("transition-timing-function" single-transition-timing-function)
|
||||
|
||||
;; Filter Effects Module Level 1
|
||||
;; (http://www.w3.org/TR/filter-effects/#property-index)
|
||||
"color-interpolation-filters" "filter" "flood-color"
|
||||
"flood-opacity" "lighting-color")
|
||||
("color-interpolation-filters" "auto" "sRGB" "linearRGB")
|
||||
("filter" "none" filter-function-list)
|
||||
("flood-color" color)
|
||||
("flood-opacity" number percentage)
|
||||
("lighting-color" color))
|
||||
"Identifiers for properties and their possible values.
|
||||
The CAR of each entry is the name of a property, while the CDR is
|
||||
a list of possible values for that property. String values in
|
||||
the CDRs represent literal values, while symbols represent one of
|
||||
the value classes found in `css-value-class-alist'. If a symbol
|
||||
is not found in `css-value-class-alist', it's interpreted as a
|
||||
reference back to one of the properties in this list. Some
|
||||
symbols, such as `number' or `identifier', don't produce any
|
||||
further value candidates, since that list would be infinite.")
|
||||
|
||||
(defconst css-property-ids
|
||||
(mapcar #'car css-property-alist)
|
||||
"Identifiers for properties.")
|
||||
|
||||
(defconst css-value-class-alist
|
||||
'((absolute-size
|
||||
"xx-small" "x-small" "small" "medium" "large" "x-large"
|
||||
"xx-large")
|
||||
(alphavalue number)
|
||||
(attachment "scroll" "fixed" "local")
|
||||
(bg-image image "none")
|
||||
(bg-layer bg-image position repeat-style attachment box)
|
||||
(bg-size length percentage "auto" "cover" "contain")
|
||||
(box "border-box" "padding-box" "content-box")
|
||||
(color
|
||||
"aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon"
|
||||
"navy" "olive" "orange" "purple" "red" "silver" "teal" "white"
|
||||
"yellow" "transparent")
|
||||
(common-lig-values "common-ligatures" "no-common-ligatures")
|
||||
(contextual-alt-values "contextual" "no-contextual")
|
||||
(counter "counter()" "counters()")
|
||||
(discretionary-lig-values
|
||||
"discretionary-ligatures" "no-discretionary-ligatures")
|
||||
(east-asian-variant-values
|
||||
"jis78" "jis83" "jis90" "jis04" "simplified" "traditional")
|
||||
(east-asian-width-values "full-width" "proportional-width")
|
||||
(family-name "Courier" "Helvetica" "Times")
|
||||
(feature-tag-value string integer "on" "off")
|
||||
(filter-function
|
||||
"blur()" "brightness()" "contrast()" "drop-shadow()"
|
||||
"grayscale()" "hue-rotate()" "invert()" "opacity()" "sepia()"
|
||||
"saturate()")
|
||||
(filter-function-list filter-function uri)
|
||||
(final-bg-layer
|
||||
bg-image position repeat-style attachment box color)
|
||||
(font-variant-css21 "normal" "small-caps")
|
||||
(generic-family
|
||||
"serif" "sans-serif" "cursive" "fantasy" "monospace")
|
||||
(generic-voice "male" "female" "child")
|
||||
(gradient
|
||||
linear-gradient radial-gradient repeating-linear-gradient
|
||||
repeating-radial-gradient)
|
||||
(historical-lig-values
|
||||
"historical-ligatures" "no-historical-ligatures")
|
||||
(image uri image-list element-reference gradient)
|
||||
(image-list "image()")
|
||||
(length number)
|
||||
(line-height "normal" number length percentage)
|
||||
(line-style
|
||||
"none" "hidden" "dotted" "dashed" "solid" "double" "groove"
|
||||
"ridge" "inset" "outset")
|
||||
(line-width length "thin" "medium" "thick")
|
||||
(linear-gradient "linear-gradient()")
|
||||
(margin-width "auto" length percentage)
|
||||
(numeric-figure-values "lining-nums" "oldstyle-nums")
|
||||
(numeric-fraction-values "diagonal-fractions" "stacked-fractions")
|
||||
(numeric-spacing-values "proportional-nums" "tabular-nums")
|
||||
(padding-width length percentage)
|
||||
(position
|
||||
"left" "center" "right" "top" "bottom" percentage length)
|
||||
(radial-gradient "radial-gradient()")
|
||||
(relative-size "larger" "smaller")
|
||||
(repeat-style
|
||||
"repeat-x" "repeat-y" "repeat" "space" "round" "no-repeat")
|
||||
(repeating-linear-gradient "repeating-linear-gradient()")
|
||||
(repeating-radial-gradient "repeating-radial-gradient()")
|
||||
(shadow "inset" length color)
|
||||
(shape "rect()")
|
||||
(single-animation-direction
|
||||
"normal" "reverse" "alternate" "alternate-reverse")
|
||||
(single-animation-fill-mode "none" "forwards" "backwards" "both")
|
||||
(single-animation-iteration-count "infinite" number)
|
||||
(single-animation-name "none" identifier)
|
||||
(single-animation-play-state "running" "paused")
|
||||
(single-timing-function single-transition-timing-function)
|
||||
(single-transition
|
||||
"none" single-transition-property time
|
||||
single-transition-timing-function)
|
||||
(single-transition-property "all" identifier)
|
||||
(single-transition-timing-function
|
||||
"ease" "linear" "ease-in" "ease-out" "ease-in-out" "step-start"
|
||||
"step-end" "steps()" "cubic-bezier()")
|
||||
(specific-voice identifier)
|
||||
(target-name string)
|
||||
(transform-list
|
||||
"matrix()" "translate()" "translateX()" "translateY()" "scale()"
|
||||
"scaleX()" "scaleY()" "rotate()" "skew()" "skewX()" "skewY()"
|
||||
"matrix3d()" "translate3d()" "translateZ()" "scale3d()"
|
||||
"scaleZ()" "rotate3d()" "rotateX()" "rotateY()" "rotateZ()"
|
||||
"perspective()")
|
||||
(uri "url()")
|
||||
(width length percentage "auto")
|
||||
(x number)
|
||||
(y number))
|
||||
"Property value classes and their values.
|
||||
The format is similar to that of `css-property-alist', except
|
||||
that the CARs aren't actual CSS properties, but rather a name for
|
||||
a class of values, and that symbols in the CDRs always refer to
|
||||
other entries in this list, not to properties.
|
||||
|
||||
The following classes have been left out above because they
|
||||
cannot be completed sensibly: `angle', `element-reference',
|
||||
`frequency', `id', `identifier', `integer', `number',
|
||||
`percentage', `string', and `time'.")
|
||||
|
||||
(defcustom css-electric-keys '(?\} ?\;) ;; '()
|
||||
"Self inserting keys which should trigger re-indentation."
|
||||
:version "22.2"
|
||||
|
|
@ -335,8 +678,6 @@
|
|||
:type 'integer
|
||||
:safe 'integerp)
|
||||
|
||||
(require 'smie)
|
||||
|
||||
(defconst css-smie-grammar
|
||||
(smie-prec2->grammar
|
||||
(smie-precs->prec2 '((assoc ";") (assoc ",") (left ":")))))
|
||||
|
|
@ -410,11 +751,56 @@
|
|||
(when (eq (char-before) ?\@)
|
||||
(list (point) pos css-at-ids)))))
|
||||
|
||||
(defvar css--property-value-cache
|
||||
(make-hash-table :test 'equal :size (length css-property-alist))
|
||||
"Cache of previously completed property values.")
|
||||
|
||||
(defun css--value-class-lookup (value-class)
|
||||
"Return a list of value completion candidates for VALUE-CLASS.
|
||||
Completion candidates are looked up in `css-value-class-alist' by
|
||||
the symbol VALUE-CLASS."
|
||||
(seq-mapcat
|
||||
(lambda (value)
|
||||
(if (stringp value)
|
||||
(list value)
|
||||
(css--value-class-lookup value)))
|
||||
(cdr (assq value-class css-value-class-alist))))
|
||||
|
||||
(defun css--property-values (property)
|
||||
"Return a list of value completion candidates for PROPERTY.
|
||||
Completion candidates are looked up in `css-property-alist' by
|
||||
the string PROPERTY."
|
||||
(or (gethash property css--property-value-cache)
|
||||
(seq-mapcat
|
||||
(lambda (value)
|
||||
(if (stringp value)
|
||||
(list value)
|
||||
(or (css--value-class-lookup value)
|
||||
(css--property-values (symbol-name value)))))
|
||||
(cdr (assoc property css-property-alist)))))
|
||||
|
||||
(defun css--complete-property-value ()
|
||||
"Complete property value at point."
|
||||
(let ((property
|
||||
(save-excursion
|
||||
(re-search-backward ":[^/]" (line-beginning-position) t)
|
||||
(let ((property-end (point)))
|
||||
(skip-chars-backward "-[:alnum:]")
|
||||
(let ((property (buffer-substring (point) property-end)))
|
||||
(car (member property css-property-ids)))))))
|
||||
(when property
|
||||
(let ((end (point)))
|
||||
(save-excursion
|
||||
(skip-chars-backward "[:graph:]")
|
||||
(list (point) end
|
||||
(cons "inherit" (css--property-values property))))))))
|
||||
|
||||
(defun css-completion-at-point ()
|
||||
"Complete current symbol at point.
|
||||
Currently supports completion of CSS properties, pseudo-elements,
|
||||
pseudo-classes, and at-rules."
|
||||
Currently supports completion of CSS properties, property values,
|
||||
pseudo-elements, pseudo-classes, and at-rules."
|
||||
(or (css--complete-property)
|
||||
(css--complete-property-value)
|
||||
(css--complete-pseudo-element-or-class)
|
||||
(css--complete-at-rule)))
|
||||
|
||||
|
|
|
|||
66
test/lisp/textmodes/css-mode-tests.el
Normal file
66
test/lisp/textmodes/css-mode-tests.el
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
;;; css-mode-tests.el --- Test suite for CSS mode -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Simen Heggestøyl <simenheg@gmail.com>
|
||||
;; Keywords: internal
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ert)
|
||||
(require 'css-mode)
|
||||
|
||||
(ert-deftest css-test-property-values ()
|
||||
;; The `float' property has a flat value list.
|
||||
(should
|
||||
(equal (sort (css--property-values "float") #'string-lessp)
|
||||
'("left" "none" "right")))
|
||||
|
||||
;; The `list-style' property refers to several other properties.
|
||||
(should
|
||||
(equal (sort (css--property-values "list-style") #'string-lessp)
|
||||
(sort (append (css--property-values "list-style-type")
|
||||
(css--property-values "list-style-position")
|
||||
(css--property-values "list-style-image"))
|
||||
#'string-lessp)))
|
||||
|
||||
;; The `position' property is tricky because it's also the name of a
|
||||
;; value class.
|
||||
(should
|
||||
(equal (sort (css--property-values "position") #'string-lessp)
|
||||
'("absolute" "fixed" "relative" "static")))
|
||||
|
||||
;; The `background-position' property should refer to the `position'
|
||||
;; value class, not the property of the same name.
|
||||
(should
|
||||
(equal (css--property-values "background-position")
|
||||
(css--value-class-lookup 'position)))
|
||||
|
||||
;; Check that the `color' property doesn't cause infinite recursion
|
||||
;; because it refers to the value class of the same name.
|
||||
(should (= (length (css--property-values "color")) 18)))
|
||||
|
||||
(ert-deftest css-test-value-class-lookup ()
|
||||
(should
|
||||
(equal (sort (css--value-class-lookup 'position) #'string-lessp)
|
||||
'("bottom" "center" "left" "right" "top"))))
|
||||
|
||||
(provide 'css-mode-tests)
|
||||
;;; css-mode-tests.el ends here
|
||||
Loading…
Add table
Add a link
Reference in a new issue