2 (eval-when-compile (require 'cl))
4 (defconst company-css-property-alist
5 ;; see http://www.w3.org/TR/CSS21/propidx.html
6 '(("azimuth" angle "left-side" "far-left" "left" "center-left" "center"
7 "center-right" "right" "far-right" "right-side" "behind" "leftwards"
9 ("background" background-color background-image background-repeat
10 background-attachment background-position)
11 ("background-attachment" "scroll" "fixed")
12 ("background-color" color "transparent")
13 ("background-image" uri "none")
14 ("background-position" percentage length "left" "center" "right" percentage
15 length "top" "center" "bottom" "left" "center" "right" "top" "center"
17 ("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat")
18 ("border" border-width border-style border-color)
19 ("border-bottom" border)
20 ("border-bottom-color" border-color)
21 ("border-bottom-style" border-style)
22 ("border-bottom-width" border-width)
23 ("border-collapse" "collapse" "separate")
24 ("border-color" color "transparent")
25 ("border-left" border)
26 ("border-left-color" border-color)
27 ("border-left-style" border-style)
28 ("border-left-width" border-width)
29 ("border-right" border)
30 ("border-right-color" border-color)
31 ("border-right-style" border-style)
32 ("border-right-width" border-width)
33 ("border-spacing" length length)
34 ("border-style" border-style)
36 ("border-top-color" border-color)
37 ("border-top-style" border-style)
38 ("border-top-width" border-width)
39 ("border-width" border-width)
40 ("bottom" length percentage "auto")
41 ("caption-side" "top" "bottom")
42 ("clear" "none" "left" "right" "both")
45 ("content" "normal" "none" string uri counter "attr()" "open-quote"
46 "close-quote" "no-open-quote" "no-close-quote")
47 ("counter-increment" identifier integer "none")
48 ("counter-reset" identifier integer "none")
49 ("cue" cue-before cue-after)
50 ("cue-after" uri "none")
51 ("cue-before" uri "none")
52 ("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize"
53 "ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize"
54 "w-resize" "text" "wait" "help" "progress")
55 ("direction" "ltr" "rtl")
56 ("display" "inline" "block" "list-item" "run-in" "inline-block" "table"
57 "inline-table" "table-row-group" "table-header-group" "table-footer-group"
58 "table-row" "table-column-group" "table-column" "table-cell"
59 "table-caption" "none")
60 ("elevation" angle "below" "level" "above" "higher" "lower")
61 ("empty-cells" "show" "hide")
62 ("float" "left" "right" "none")
63 ("font" font-style font-variant font-weight font-size "/" line-height
64 font-family "caption" "icon" "menu" "message-box" "small-caption"
66 ("font-family" family-name generic-family)
67 ("font-size" absolute-size relative-size length percentage)
68 ("font-style" "normal" "italic" "oblique")
69 ("font-variant" "normal" "small-caps")
70 ("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400"
71 "500" "600" "700" "800" "900")
72 ("height" length percentage "auto")
73 ("left" length percentage "auto")
74 ("letter-spacing" "normal" length)
75 ("line-height" "normal" number length percentage)
76 ("list-style" list-style-type list-style-position list-style-image)
77 ("list-style-image" uri "none")
78 ("list-style-position" "inside" "outside")
79 ("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero"
80 "lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin"
81 "armenian" "georgian" "lower-alpha" "upper-alpha" "none")
82 ("margin" margin-width)
83 ("margin-bottom" margin-width)
84 ("margin-left" margin-width)
85 ("margin-right" margin-width)
86 ("margin-top" margin-width)
87 ("max-height" length percentage "none")
88 ("max-width" length percentage "none")
89 ("min-height" length percentage)
90 ("min-width" length percentage)
92 ("outline" outline-color outline-style outline-width)
93 ("outline-color" color "invert")
94 ("outline-style" border-style)
95 ("outline-width" border-width)
96 ("overflow" "visible" "hidden" "scroll" "auto")
97 ("padding" padding-width)
98 ("padding-bottom" padding-width)
99 ("padding-left" padding-width)
100 ("padding-right" padding-width)
101 ("padding-top" padding-width)
102 ("page-break-after" "auto" "always" "avoid" "left" "right")
103 ("page-break-before" "auto" "always" "avoid" "left" "right")
104 ("page-break-inside" "avoid" "auto")
105 ("pause" time percentage)
106 ("pause-after" time percentage)
107 ("pause-before" time percentage)
108 ("pitch" frequency "x-low" "low" "medium" "high" "x-high")
109 ("pitch-range" number)
110 ("play-during" uri "mix" "repeat" "auto" "none")
111 ("position" "static" "relative" "absolute" "fixed")
112 ("quotes" string string "none")
114 ("right" length percentage "auto")
115 ("speak" "normal" "none" "spell-out")
116 ("speak-header" "once" "always")
117 ("speak-numeral" "digits" "continuous")
118 ("speak-punctuation" "code" "none")
119 ("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster"
122 ("table-layout" "auto" "fixed")
123 ("text-align" "left" "right" "center" "justify")
124 ("text-decoration" "none" "underline" "overline" "line-through" "blink")
125 ("text-indent" length percentage)
126 ("text-transform" "capitalize" "uppercase" "lowercase" "none")
127 ("top" length percentage "auto")
128 ("unicode-bidi" "normal" "embed" "bidi-override")
129 ("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle"
130 "bottom" "text-bottom" percentage length)
131 ("visibility" "visible" "hidden" "collapse")
132 ("voice-family" specific-voice generic-voice "*" specific-voice
134 ("volume" number percentage "silent" "x-soft" "soft" "medium" "loud"
136 ("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line")
138 ("width" length percentage "auto")
139 ("word-spacing" "normal" length)
140 ("z-index" "auto" integer))
141 "A list of CSS properties and their possible values.")
143 (defconst company-css-value-classes
144 '((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large"
146 (border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove"
147 "ridge" "inset" "outset")
148 (color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy"
149 "olive" "orange" "purple" "red" "silver" "teal" "white" "yellow")
150 (counter "counter(,)")
151 (family-name "Courier" "Helvetica" "Times")
152 (generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace")
153 (generic-voice "male" "female" "child")
154 (margin-width "auto") ;; length percentage
155 (relative-size "larger" "smaller")
158 "A list of CSS property value classes and their contents.")
159 ;; missing, because not completable
160 ;; <angle><frequency><identifier><integer><length><number><padding-width>
161 ;; <percentage><specific-voice><string><time><uri>
163 (defconst company-css-html-tags
164 '("a" "abbr" "acronym" "address" "applet" "area" "b" "base" "basefont" "bdo"
165 "big" "blockquote" "body" "br" "button" "caption" "center" "cite" "code"
166 "col" "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em" "fieldset"
167 "font" "form" "frame" "frameset" "h1" "h2" "h3" "h4" "h5" "h6" "head" "hr"
168 "html" "i" "iframe" "img" "input" "ins" "isindex" "kbd" "label" "legend"
169 "li" "link" "map" "menu" "meta" "noframes" "noscript" "object" "ol"
170 "optgroup" "option" "p" "param" "pre" "q" "s" "samp" "script" "select"
171 "small" "span" "strike" "strong" "style" "sub" "sup" "table" "tbody" "td"
172 "textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var")
173 "A list of HTML tags for use in CSS completion.")
175 (defconst company-css-pseudo-classes
176 '("active" "after" "before" "first" "first-child" "first-letter" "first-line"
177 "focus" "hover" "lang" "left" "link" "right" "visited")
178 "Identifiers for CSS pseudo-elements and pseudo-classes.")
180 (defconst company-css-property-cache (make-hash-table :size 115 :test 'equal))
182 (defun company-css-property-values (attribute)
183 "Access the `company-css-property-alist' cached and flattened."
184 (or (gethash attribute company-css-property-cache)
186 (dolist (value (cdr (assoc attribute company-css-property-alist)))
188 (dolist (child (or (cdr (assoc value company-css-value-classes))
189 (company-css-property-values
190 (symbol-name value))))
191 (add-to-list 'results child))
192 (add-to-list 'results value)))
193 (setq results (sort results 'string<))
194 (puthash attribute results company-css-property-cache)
197 ;;; bracket detection
199 (defconst company-css-braces-syntax-table
200 (let ((table (make-syntax-table)))
201 (setf (aref table ?{) '(4 . 125))
202 (setf (aref table ?}) '(5 . 123))
204 "A syntax table giving { and } paren syntax.")
206 (defun company-css-inside-braces-p ()
207 "Return non-nil, if point is within matched { and }."
209 (with-syntax-table company-css-braces-syntax-table
210 (let ((parse-sexp-ignore-comments t))
211 (scan-lists (point) -1 1)))))
214 (defconst company-css-tag-regexp
215 (concat "\\(?:\\`\\|}\\)[[:space:]]*"
219 "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
220 ;; space or selectors
221 "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
223 "\\(\\(?:#\\|\\_<[[:alpha:]]\\)\\(?:[[:alnum:]-#]*\\_>\\)?\\_>\\|\\)"
225 "A regular expression matching CSS tags")
228 (defconst company-css-pseudo-regexp
229 (concat "\\(?:\\`\\|}\\)[[:space:]]*"
233 "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
234 ;; space or delimiters
235 "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
237 "\\(?:\\(?:\\#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\):"
238 "\\([[:alpha:]-]+\\_>\\|\\)\\_>\\=")
239 "A regular expression matching CSS pseudo classes")
243 (defun company-css-grab-property ()
244 "Return the CSS property before point, if any.
245 Returns \"\" if no property found, but feasible at this position."
246 (when (company-css-inside-braces-p)
247 (or (company-grab "\\_<[[:alpha:]-]+\\_>\\=")
248 (company-grab "{\\|[[:space:]]" 1))))
251 (defconst company-css-property-value-regexp
252 "\\_<\\([[:alpha:]-]+\\):\\(?:[^};]*[[:space:]]+\\)?\\([^};]*\\_>\\|\\)\\="
253 "A regular expression matching CSS tags")
255 (defun company-css (command &optional arg &rest ignored)
257 ('prefix (and (eq major-mode 'css-mode)
258 (or (company-grab company-css-tag-regexp 1)
259 (company-grab company-css-pseudo-regexp 1)
260 (company-grab company-css-property-value-regexp 2)
261 (company-css-grab-property))))
264 ((company-grab company-css-tag-regexp 1)
265 (all-completions arg company-css-html-tags))
266 ((company-grab company-css-pseudo-regexp 1)
267 (all-completions arg company-css-pseudo-classes))
268 ((company-grab company-css-property-value-regexp 2)
270 (company-css-property-values
271 (company-grab company-css-property-value-regexp 1))))
272 ((company-css-grab-property)
273 (all-completions arg company-css-property-alist))))
276 (provide 'company-css)
277 ;;; company-css.el ends here