unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#22923: [PATCH] Support completion of attribute values in CSS mode
@ 2016-03-06 13:53 Simen Heggestøyl
  2016-03-06 19:10 ` Dmitry Gutov
  0 siblings, 1 reply; 10+ messages in thread
From: Simen Heggestøyl @ 2016-03-06 13:53 UTC (permalink / raw)
  To: 22923; +Cc: Stefan Monnier, Dmitry Gutov


[-- Attachment #1.1: Type: text/plain, Size: 1749 bytes --]

Hello!

I've finally gotten around to implement property value completion in
CSS mode. I've been using the attached patch privately for some weeks
now, and it seems to me that it works well.

The code has taken much inspiration from company-css.el, but there are
some differences:

- Completion lists for many new properties have been added, and a few
  have been removed (most of them from the obsoleted marquee
  module [1]).

- I've manually updated all completion lists according to the CSS spec
  and fixed some bugs in the existing lists along the way. In general
  I've tried to stay as close as possible to the grammar described in
  the CSS spec wrt. names and order of the values and classes.

- The new `css--property-values' function is very similar to
  `company-css-property-values', but it has been updated to support
  following completion candidates further from the value class
  completion lists.

- Completion a function name will no longer put commas between the
  parenthesis. My reason for this is that many CSS functions take a
  variable number of arguments. For instance, the `translate' function
  is completed by company-css to `translate(,)', but `translate' can
  take only one argument too, so the completion is misleading. Also,
  there are functions that support an arbitrary number of
  arguments. Instead of trying to support this, I've made every
  function name complete to just `function()'. I think having ElDoc
  support for CSS functions would be good for making it easier to
  remember which arguments functions take.

- `inherit' has been added as a completion candidate for every
  property.

Please have a look at the patch and tell me what you think!

-- Simen


[1] https://www.w3.org/TR/css3-marquee/

[-- Attachment #1.2: Type: text/html, Size: 2363 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Support-completion-of-attribute-values-in-CSS-mode.patch --]
[-- Type: text/x-patch, Size: 28612 bytes --]

From cff60501026539692491a5f422b7dcb415402b70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Simen=20Heggest=C3=B8yl?= <simenheg@gmail.com>
Date: Sat, 13 Feb 2016 22:18:42 +0100
Subject: [PATCH] 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--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.
---
 etc/NEWS                   |   6 +
 lisp/textmodes/css-mode.el | 513 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 445 insertions(+), 74 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 92d69d2..d2486da 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -127,6 +127,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.
+
 \f
 * New Modes and Packages in Emacs 25.2
 
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 93a8dce..2bb3dd8 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -29,7 +29,6 @@
 
 ;; - electric ; and }
 ;; - filling code with auto-fill-mode
-;; - attribute value completion
 ;; - fix font-lock errors with multi-line selectors
 
 ;;; Code:
@@ -74,124 +73,455 @@ css-media-ids
     "visual")
   "Identifiers for types of media.")
 
-(defconst css-property-ids
-  '(;; 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"
+(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" 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)
+    ("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. A string value
+represents a literal value, while a symbol must be looked up in
+`css-property-alist' and `css-value-class-alist' to find further
+possible values. 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
+     background-color)
+    ("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)
+    ("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)
+    ("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 equal to that of `css-property-alist', except that
+the CARs aren't actual CSS properties, but rather a name for a
+class of values.
+
+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"
@@ -410,11 +740,46 @@ css--complete-at-rule
       (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)
+                                         (length css-value-class-alist)))
+  "Cache of previously completed property values.")
+
+(defun css--property-values (property)
+  "Return value completion candidates for PROPERTY."
+  (or (gethash property css--property-value-cache)
+      (let (values)
+        (dolist (value (or (cdr (assoc property css-value-class-alist))
+                           (cdr (assoc property css-property-alist))))
+          (if (stringp value)
+              (push value values)
+            (let ((new-values (css--property-values (symbol-name value))))
+              (setq values (append values new-values))))
+          (puthash property values css--property-value-cache))
+        values)))
+
+(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 (assoc property css-property-alist)))))))
+    (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)))
 
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-06 13:53 bug#22923: [PATCH] Support completion of attribute values in CSS mode Simen Heggestøyl
@ 2016-03-06 19:10 ` Dmitry Gutov
  2016-03-09 19:01   ` Simen Heggestøyl
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Gutov @ 2016-03-06 19:10 UTC (permalink / raw)
  To: Simen Heggestøyl, 22923; +Cc: Stefan Monnier

Hi Simen,

On 03/06/2016 03:53 PM, Simen Heggestøyl wrote:

> I've finally gotten around to implement property value completion in
> CSS mode. I've been using the attached patch privately for some weeks
> now, and it seems to me that it works well.

I haven't tried it, but it looks good overall.

> - The new `css--property-values' function is very similar to
>   `company-css-property-values', but it has been updated to support
>   following completion candidates further from the value class
>   completion lists.

Doesn't the latter allow for several indirections? It seems to me the 
two functions are equivalent.

One question: is there a reason to do the (symbol-name value) conversion 
before doing the css--property-values lookup?

Maybe the css-value-class-alist should have symbol keys, not strings.

> - Completion a function name will no longer put commas between the
>   parenthesis. My reason for this is that many CSS functions take a
>   variable number of arguments. For instance, the `translate' function
>   is completed by company-css to `translate(,)', but `translate' can
>   take only one argument too, so the completion is misleading. Also,
>   there are functions that support an arbitrary number of
>   arguments. Instead of trying to support this, I've made every
>   function name complete to just `function()'. I think having ElDoc
>   support for CSS functions would be good for making it easier to
>   remember which arguments functions take.

Sounds good.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-06 19:10 ` Dmitry Gutov
@ 2016-03-09 19:01   ` Simen Heggestøyl
  2016-03-11  1:25     ` Dmitry Gutov
  0 siblings, 1 reply; 10+ messages in thread
From: Simen Heggestøyl @ 2016-03-09 19:01 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 22923, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1359 bytes --]

Hi Dmitry, thanks for your review.

On Sun, Mar 6, 2016 at 8:10 PM, Dmitry Gutov <dgutov@yandex.ru> wrote:
> Doesn't the latter allow for several indirections? It seems to me the 
> two functions are equivalent.

It does, sorry for being unclear. I'll try to reformulate it:

There are two lists that must be traversed to find completion
candidates: the property alist and the value class alist. company-css.el
supports indirections from the property alist into itself, and into the
value class alist. With this patch, indirection can happen from the
property alist into itself and into the value class alist, but also from
the value class alist into itself and back into the property alist.

> One question: is there a reason to do the (symbol-name value) 
> conversion before doing the css--property-values lookup?
> 
> Maybe the css-value-class-alist should have symbol keys, not strings.

With the change mentioned above, the property alist and the value class
alist are now treated like the same kind of data structure by
`css--property-values'. The only difference is that the CARs of the
entries in the property alist are also valid property names. So I
thought it simpler if the keys were of the same data type. I don't have
an opinion on whether that should be string or symbol, just that they
are the same.

Did this answer your question?

-- Simen

[-- Attachment #2: Type: text/html, Size: 1824 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-09 19:01   ` Simen Heggestøyl
@ 2016-03-11  1:25     ` Dmitry Gutov
  2016-03-19 12:42       ` Simen Heggestøyl
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Gutov @ 2016-03-11  1:25 UTC (permalink / raw)
  To: Simen Heggestøyl; +Cc: 22923, Stefan Monnier

On 03/09/2016 09:01 PM, Simen Heggestøyl wrote:

> There are two lists that must be traversed to find completion
> candidates: the property alist and the value class alist. company-css.el
> supports indirections from the property alist into itself, and into the
> value class alist. With this patch, indirection can happen from the
> property alist into itself and into the value class alist, but also from
> the value class alist into itself and back into the property alist.

I see. Is there anything in particular this approach is buying us? Any 
properties that company-css doesn't support now, and would be suboptimal 
using its current approach?

IMHO, having the indirection go only one way is better organization, and 
it's easier to understand when reading the code.

> With the change mentioned above, the property alist and the value class
> alist are now treated like the same kind of data structure by
> `css--property-values'. The only difference is that the CARs of the
> entries in the property alist are also valid property names. So I
> thought it simpler if the keys were of the same data type. I don't have
> an opinion on whether that should be string or symbol, just that they
> are the same.
>
> Did this answer your question?

Yes, thanks.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-11  1:25     ` Dmitry Gutov
@ 2016-03-19 12:42       ` Simen Heggestøyl
  2016-03-20  1:17         ` Dmitry Gutov
  0 siblings, 1 reply; 10+ messages in thread
From: Simen Heggestøyl @ 2016-03-19 12:42 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 22923, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1268 bytes --]

Hello again, Dmitry, and sorry for the late response.

On Fri, Mar 11, 2016 at 2:25 AM, Dmitry Gutov <dgutov@yandex.ru> wrote:
> I see. Is there anything in particular this approach is buying us? 
> Any properties that company-css doesn't support now, and would be 
> suboptimal using its current approach?

Yes, it allows us to stay close to the CSS spec, which is my view is
very valuable when maintaining these lists.

Here is a concrete example: the value class `image' is defined as
follows in the CSS Image Values spec [1]:

  <image> = <url> | <image-list> | <element-reference> | <gradient>

Which translates naturally to:

  ("image" uri image-list element-reference gradient)

It is not a CSS property, so it should go into the value class alist. It
is referenced by the `border-image-source' property as well as the
`bg-image' value class (which in turn is referenced by the
`background-image' property and `bg-layer' value class).

My point is that even though it would be possible to eliminate the need
for this value class by expanding it where it is referenced, I think
that by keeping it, it'll be much easier to make updates to it when the
CSS spec changes. I think it is worth the added complexity.

-- Simen


[1] https://www.w3.org/TR/css3-images/

[-- Attachment #2: Type: text/html, Size: 1785 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-19 12:42       ` Simen Heggestøyl
@ 2016-03-20  1:17         ` Dmitry Gutov
  2016-03-21  9:14           ` Simen Heggestøyl
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Gutov @ 2016-03-20  1:17 UTC (permalink / raw)
  To: Simen Heggestøyl; +Cc: 22923, Stefan Monnier

Hi again, Simen,

On 03/19/2016 02:42 PM, Simen Heggestøyl wrote:

> Yes, it allows us to stay close to the CSS spec, which is my view is
> very valuable when maintaining these lists.

Sure, but by "current approach" I meant what Company does. Please clarify:

> Here is a concrete example: the value class `image' is defined as
> follows in the CSS Image Values spec [1]:
>
>   <image> = <url> | <image-list> | <element-reference> | <gradient>
>
> Which translates naturally to:
>
>   ("image" uri image-list element-reference gradient)
>
> It is not a CSS property, so it should go into the value class alist. It
> is referenced by the `border-image-source' property as well as the
> `bg-image' value class (which in turn is referenced by the
> `background-image' property and `bg-layer' value class).

If you were adding it to company-css, wouldn't you just add it to 
company-css-value-classes? And then refer to it in background-image 
value inside company-css-property-alist?

What the limitation of that approach? Do value classes in the spec refer 
back to the actual properties sometimes?

> My point is that even though it would be possible to eliminate the need
> for this value class by expanding it where it is referenced, I think
> that by keeping it, it'll be much easier to make updates to it when the
> CSS spec changes. I think it is worth the added complexity.

I'm not sure I follow. Expanding it in company-css-property-alist?





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-20  1:17         ` Dmitry Gutov
@ 2016-03-21  9:14           ` Simen Heggestøyl
  2016-03-21 11:02             ` Dmitry Gutov
  0 siblings, 1 reply; 10+ messages in thread
From: Simen Heggestøyl @ 2016-03-21  9:14 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 22923, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1367 bytes --]

On Sun, Mar 20, 2016 at 2:17 AM, Dmitry Gutov <dgutov@yandex.ru> wrote:
> If you were adding it to company-css, wouldn't you just add it to 
> company-css-value-classes? And then refer to it in background-image 
> value inside company-css-property-alist?
> 
> What the limitation of that approach? Do value classes in the spec 
> refer back to the actual properties sometimes?

Yes, though on closer inspection, I see that it only happens in one case
so far (the value class `bg-layer' referring to the property
`background-color').

But more importantly, in the example above, the `image' value class
refers to four other value classes, one of which has further references.
This case is not handled by the current company-css, since it only
recurses on values from the property alist.

This is the main difference between `company-css-property-values' and
`css--property-values': the former doesn't support referencing from the
value class alist.

(Indeed, there seems to be a bug in `company-css-value-classes' where
`align-stretch' tries to refer to `align-common', but that won't work.)

> I'm not sure I follow. Expanding it in company-css-property-alist?

I meant that if we wanted to keep the value class alist flat, i.e. don't
put references in it, we could replace every entry with the result of
`(company-css-property-values "value-class-name")'.

-- Simen

[-- Attachment #2: Type: text/html, Size: 1800 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-21  9:14           ` Simen Heggestøyl
@ 2016-03-21 11:02             ` Dmitry Gutov
  2016-03-23 18:17               ` Simen Heggestøyl
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Gutov @ 2016-03-21 11:02 UTC (permalink / raw)
  To: Simen Heggestøyl; +Cc: 22923, Stefan Monnier

On 03/21/2016 11:14 AM, Simen Heggestøyl wrote:

> Yes, though on closer inspection, I see that it only happens in one case
> so far (the value class `bg-layer' referring to the property
> `background-color').

It seems like you could replace that reference with `color'.

> But more importantly, in the example above, the `image' value class
> refers to four other value classes, one of which has further references.
> This case is not handled by the current company-css, since it only
> recurses on values from the property alist.
 >
> This is the main difference between `company-css-property-values' and
> `css--property-values': the former doesn't support referencing from the
> value class alist.
>
> (Indeed, there seems to be a bug in `company-css-value-classes' where
> `align-stretch' tries to refer to `align-common', but that won't work.)

You're right, it's a bug. I'd fix that with only making 
company-css-value-classes recursive (but not refer back to 
company-css-property-alist there).

To put it differently, I don't like that there's conflation of property 
values and property names: if there appears a value sometimes that is 
the same as some property's name (unlikely, I know), it would be hard to 
represent in the proposed structure.

Anyway, I've taken more than enough of your time. Please go ahead with 
whichever version you prefer.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-21 11:02             ` Dmitry Gutov
@ 2016-03-23 18:17               ` Simen Heggestøyl
  2016-03-23 23:08                 ` Dmitry Gutov
  0 siblings, 1 reply; 10+ messages in thread
From: Simen Heggestøyl @ 2016-03-23 18:17 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 22923-done, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1376 bytes --]

On Mon, Mar 21, 2016 at 12:02 PM, Dmitry Gutov <dgutov@yandex.ru> wrote:
> You're right, it's a bug. I'd fix that with only making 
> company-css-value-classes recursive (but not refer back to 
> company-css-property-alist there).
> 
> To put it differently, I don't like that there's conflation of 
> property values and property names: if there appears a value 
> sometimes that is the same as some property's name (unlikely, I 
> know), it would be hard to represent in the proposed structure.
> 
> Anyway, I've taken more than enough of your time. Please go ahead 
> with whichever version you prefer.

Don't worry Dmitry, I very much appreciate your through reviews.

You are right that there are some cases where property names and value
class names are the same (there are currently four), and I found a bug
in my handling of one of those. I remedied that by going with your
suggestion of making value classes symbols again, and only referring to
other value classes from those.

For properties, I made them also refer to value classes by default, but
made it possible to refer back to other properties in the cases where
the reference isn't found in the value class alist.

I attempted to document this thoroughly in the code and added some tests
that should cover the tricky cases.

I've installed the patch with the changes mentioned above.

Thanks again!

-- Simen

[-- Attachment #2: Type: text/html, Size: 1706 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* bug#22923: [PATCH] Support completion of attribute values in CSS mode
  2016-03-23 18:17               ` Simen Heggestøyl
@ 2016-03-23 23:08                 ` Dmitry Gutov
  0 siblings, 0 replies; 10+ messages in thread
From: Dmitry Gutov @ 2016-03-23 23:08 UTC (permalink / raw)
  To: 22923, simenheg

On 03/23/2016 08:17 PM, Simen Heggestøyl wrote:

> You are right that there are some cases where property names and value
> class names are the same (there are currently four), and I found a bug
> in my handling of one of those. I remedied that by going with your
> suggestion of making value classes symbols again, and only referring to
> other value classes from those.
>
> For properties, I made them also refer to value classes by default, but
> made it possible to refer back to other properties in the cases where
> the reference isn't found in the value class alist.
>
> I attempted to document this thoroughly in the code and added some tests
> that should cover the tricky cases.
>
> I've installed the patch with the changes mentioned above.

Great! Thanks, Simen.





^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-03-23 23:08 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-06 13:53 bug#22923: [PATCH] Support completion of attribute values in CSS mode Simen Heggestøyl
2016-03-06 19:10 ` Dmitry Gutov
2016-03-09 19:01   ` Simen Heggestøyl
2016-03-11  1:25     ` Dmitry Gutov
2016-03-19 12:42       ` Simen Heggestøyl
2016-03-20  1:17         ` Dmitry Gutov
2016-03-21  9:14           ` Simen Heggestøyl
2016-03-21 11:02             ` Dmitry Gutov
2016-03-23 18:17               ` Simen Heggestøyl
2016-03-23 23:08                 ` Dmitry Gutov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).