Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

446 line
19 KiB

4 年之前
  1. ;;; company-css.el --- company-mode completion backend for css-mode -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2009, 2011, 2014, 2018 Free Software Foundation, Inc.
  3. ;; Author: Nikolaj Schumacher
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is free software: you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;;
  17. ;; In Emacs >= 26, company-capf is used instead.
  18. ;;; Code:
  19. (require 'company)
  20. (require 'cl-lib)
  21. (declare-function web-mode-language-at-pos "web-mode" (&optional pos))
  22. (defconst company-css-property-alist
  23. ;; see http://www.w3.org/TR/CSS21/propidx.html
  24. '(("azimuth" angle "left-side" "far-left" "left" "center-left" "center"
  25. "center-right" "right" "far-right" "right-side" "behind" "leftwards"
  26. "rightwards")
  27. ("background" background-color background-image background-repeat
  28. background-attachment background-position
  29. background-clip background-origin background-size)
  30. ("background-attachment" "scroll" "fixed")
  31. ("background-color" color "transparent")
  32. ("background-image" uri "none")
  33. ("background-position" percentage length "left" "center" "right" percentage
  34. length "top" "center" "bottom" "left" "center" "right" "top" "center"
  35. "bottom")
  36. ("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat")
  37. ("border" border-width border-style border-color)
  38. ("border-bottom" border)
  39. ("border-bottom-color" border-color)
  40. ("border-bottom-style" border-style)
  41. ("border-bottom-width" border-width)
  42. ("border-collapse" "collapse" "separate")
  43. ("border-color" color "transparent")
  44. ("border-left" border)
  45. ("border-left-color" border-color)
  46. ("border-left-style" border-style)
  47. ("border-left-width" border-width)
  48. ("border-right" border)
  49. ("border-right-color" border-color)
  50. ("border-right-style" border-style)
  51. ("border-right-width" border-width)
  52. ("border-spacing" length length)
  53. ("border-style" border-style)
  54. ("border-top" border)
  55. ("border-top-color" border-color)
  56. ("border-top-style" border-style)
  57. ("border-top-width" border-width)
  58. ("border-width" border-width)
  59. ("bottom" length percentage "auto")
  60. ("caption-side" "top" "bottom")
  61. ("clear" "none" "left" "right" "both")
  62. ("clip" shape "auto")
  63. ("color" color)
  64. ("content" "normal" "none" string uri counter "attr()" "open-quote"
  65. "close-quote" "no-open-quote" "no-close-quote")
  66. ("counter-increment" identifier integer "none")
  67. ("counter-reset" identifier integer "none")
  68. ("cue" cue-before cue-after)
  69. ("cue-after" uri "none")
  70. ("cue-before" uri "none")
  71. ("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize"
  72. "ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize"
  73. "w-resize" "text" "wait" "help" "progress")
  74. ("direction" "ltr" "rtl")
  75. ("display" "inline" "block" "list-item" "run-in" "inline-block" "table"
  76. "inline-table" "table-row-group" "table-header-group" "table-footer-group"
  77. "table-row" "table-column-group" "table-column" "table-cell"
  78. "table-caption" "none")
  79. ("elevation" angle "below" "level" "above" "higher" "lower")
  80. ("empty-cells" "show" "hide")
  81. ("float" "left" "right" "none")
  82. ("font" font-style font-weight font-size "/" line-height
  83. font-family "caption" "icon" "menu" "message-box" "small-caption"
  84. "status-bar" "normal" "small-caps"
  85. ;; CSS3
  86. font-stretch)
  87. ("font-family" family-name generic-family)
  88. ("font-size" absolute-size relative-size length percentage)
  89. ("font-style" "normal" "italic" "oblique")
  90. ("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400"
  91. "500" "600" "700" "800" "900")
  92. ("height" length percentage "auto")
  93. ("left" length percentage "auto")
  94. ("letter-spacing" "normal" length)
  95. ("line-height" "normal" number length percentage)
  96. ("list-style" list-style-type list-style-position list-style-image)
  97. ("list-style-image" uri "none")
  98. ("list-style-position" "inside" "outside")
  99. ("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero"
  100. "lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin"
  101. "armenian" "georgian" "lower-alpha" "upper-alpha" "none")
  102. ("margin" margin-width)
  103. ("margin-bottom" margin-width)
  104. ("margin-left" margin-width)
  105. ("margin-right" margin-width)
  106. ("margin-top" margin-width)
  107. ("max-height" length percentage "none")
  108. ("max-width" length percentage "none")
  109. ("min-height" length percentage)
  110. ("min-width" length percentage)
  111. ("orphans" integer)
  112. ("outline" outline-color outline-style outline-width)
  113. ("outline-color" color "invert")
  114. ("outline-style" border-style)
  115. ("outline-width" border-width)
  116. ("overflow" "visible" "hidden" "scroll" "auto"
  117. ;; CSS3:
  118. "no-display" "no-content")
  119. ("padding" padding-width)
  120. ("padding-bottom" padding-width)
  121. ("padding-left" padding-width)
  122. ("padding-right" padding-width)
  123. ("padding-top" padding-width)
  124. ("page-break-after" "auto" "always" "avoid" "left" "right")
  125. ("page-break-before" "auto" "always" "avoid" "left" "right")
  126. ("page-break-inside" "avoid" "auto")
  127. ("pause" time percentage)
  128. ("pause-after" time percentage)
  129. ("pause-before" time percentage)
  130. ("pitch" frequency "x-low" "low" "medium" "high" "x-high")
  131. ("pitch-range" number)
  132. ("play-during" uri "mix" "repeat" "auto" "none")
  133. ("position" "static" "relative" "absolute" "fixed")
  134. ("quotes" string string "none")
  135. ("richness" number)
  136. ("right" length percentage "auto")
  137. ("speak" "normal" "none" "spell-out")
  138. ("speak-header" "once" "always")
  139. ("speak-numeral" "digits" "continuous")
  140. ("speak-punctuation" "code" "none")
  141. ("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster"
  142. "slower")
  143. ("stress" number)
  144. ("table-layout" "auto" "fixed")
  145. ("text-align" "left" "right" "center" "justify")
  146. ("text-indent" length percentage)
  147. ("text-transform" "capitalize" "uppercase" "lowercase" "none")
  148. ("top" length percentage "auto")
  149. ("unicode-bidi" "normal" "embed" "bidi-override")
  150. ("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle"
  151. "bottom" "text-bottom" percentage length)
  152. ("visibility" "visible" "hidden" "collapse")
  153. ("voice-family" specific-voice generic-voice "*" specific-voice
  154. generic-voice)
  155. ("volume" number percentage "silent" "x-soft" "soft" "medium" "loud"
  156. "x-loud")
  157. ("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line")
  158. ("widows" integer)
  159. ("width" length percentage "auto")
  160. ("word-spacing" "normal" length)
  161. ("z-index" "auto" integer)
  162. ;; CSS3
  163. ("align-content" align-stretch "space-between" "space-around")
  164. ("align-items" align-stretch "baseline")
  165. ("align-self" align-items "auto")
  166. ("animation" animation-name animation-duration animation-timing-function
  167. animation-delay animation-iteration-count animation-direction
  168. animation-fill-mode)
  169. ("animation-delay" time)
  170. ("animation-direction" "normal" "reverse" "alternate" "alternate-reverse")
  171. ("animation-duration" time)
  172. ("animation-fill-mode" "none" "forwards" "backwards" "both")
  173. ("animation-iteration-count" integer "infinite")
  174. ("animation-name" "none")
  175. ("animation-play-state" "paused" "running")
  176. ("animation-timing-function" transition-timing-function
  177. "step-start" "step-end" "steps(,)")
  178. ("backface-visibility" "visible" "hidden")
  179. ("background-clip" background-origin)
  180. ("background-origin" "border-box" "padding-box" "content-box")
  181. ("background-size" length percentage "auto" "cover" "contain")
  182. ("border-image" border-image-outset border-image-repeat border-image-source
  183. border-image-slice border-image-width)
  184. ("border-image-outset" length)
  185. ("border-image-repeat" "stretch" "repeat" "round" "space")
  186. ("border-image-source" uri "none")
  187. ("border-image-slice" length)
  188. ("border-image-width" length percentage)
  189. ("border-radius" length)
  190. ("border-top-left-radius" length)
  191. ("border-top-right-radius" length)
  192. ("border-bottom-left-radius" length)
  193. ("border-bottom-right-radius" length)
  194. ("box-decoration-break" "slice" "clone")
  195. ("box-shadow" length color)
  196. ("box-sizing" "content-box" "border-box")
  197. ("break-after" "auto" "always" "avoid" "left" "right" "page" "column"
  198. "avoid-page" "avoid-column")
  199. ("break-before" break-after)
  200. ("break-inside" "avoid" "auto")
  201. ("columns" column-width column-count)
  202. ("column-count" integer)
  203. ("column-fill" "auto" "balance")
  204. ("column-gap" length "normal")
  205. ("column-rule" column-rule-width column-rule-style column-rule-color)
  206. ("column-rule-color" color)
  207. ("column-rule-style" border-style)
  208. ("column-rule-width" border-width)
  209. ("column-span" "all" "none")
  210. ("column-width" length "auto")
  211. ("filter" url "blur()" "brightness()" "contrast()" "drop-shadow()"
  212. "grayscale()" "hue-rotate()" "invert()" "opacity()" "saturate()" "sepia()")
  213. ("flex" flex-grow flex-shrink flex-basis)
  214. ("flex-basis" percentage length "auto")
  215. ("flex-direction" "row" "row-reverse" "column" "column-reverse")
  216. ("flex-flow" flex-direction flex-wrap)
  217. ("flex-grow" number)
  218. ("flex-shrink" number)
  219. ("flex-wrap" "nowrap" "wrap" "wrap-reverse")
  220. ("font-feature-setting" normal string number)
  221. ("font-kerning" "auto" "normal" "none")
  222. ("font-language-override" "normal" string)
  223. ("font-size-adjust" "none" number)
  224. ("font-stretch" "normal" "ultra-condensed" "extra-condensed" "condensed"
  225. "semi-condensed" "semi-expanded" "expanded" "extra-expanded" "ultra-expanded")
  226. ("font-synthesis" "none" "weight" "style")
  227. ("font-variant" font-variant-alternates font-variant-caps
  228. font-variant-east-asian font-variant-ligatures font-variant-numeric
  229. font-variant-position)
  230. ("font-variant-alternates" "normal" "historical-forms" "stylistic()"
  231. "styleset()" "character-variant()" "swash()" "ornaments()" "annotation()")
  232. ("font-variant-caps" "normal" "small-caps" "all-small-caps" "petite-caps"
  233. "all-petite-caps" "unicase" "titling-caps")
  234. ("font-variant-east-asian" "jis78" "jis83" "jis90" "jis04" "simplified"
  235. "traditional" "full-width" "proportional-width" "ruby")
  236. ("font-variant-ligatures" "normal" "none" "common-ligatures"
  237. "no-common-ligatures" "discretionary-ligatures" "no-discretionary-ligatures"
  238. "historical-ligatures" "no-historical-ligatures" "contextual" "no-contextual")
  239. ("font-variant-numeric" "normal" "ordinal" "slashed-zero"
  240. "lining-nums" "oldstyle-nums" "proportional-nums" "tabular-nums"
  241. "diagonal-fractions" "stacked-fractions")
  242. ("font-variant-position" "normal" "sub" "super")
  243. ("hyphens" "none" "manual" "auto")
  244. ("justify-content" align-common "space-between" "space-around")
  245. ("line-break" "auto" "loose" "normal" "strict")
  246. ("marquee-direction" "forward" "reverse")
  247. ("marquee-play-count" integer "infinite")
  248. ("marquee-speed" "slow" "normal" "fast")
  249. ("marquee-style" "scroll" "slide" "alternate")
  250. ("opacity" number)
  251. ("order" number)
  252. ("outline-offset" length)
  253. ("overflow-x" overflow)
  254. ("overflow-y" overflow)
  255. ("overflow-style" "auto" "marquee-line" "marquee-block")
  256. ("overflow-wrap" "normal" "break-word")
  257. ("perspective" "none" length)
  258. ("perspective-origin" percentage length "left" "center" "right" "top" "bottom")
  259. ("resize" "none" "both" "horizontal" "vertical")
  260. ("tab-size" integer length)
  261. ("text-align-last" "auto" "start" "end" "left" "right" "center" "justify")
  262. ("text-decoration" text-decoration-color text-decoration-line text-decoration-style)
  263. ("text-decoration-color" color)
  264. ("text-decoration-line" "none" "underline" "overline" "line-through" "blink")
  265. ("text-decoration-style" "solid" "double" "dotted" "dashed" "wavy")
  266. ("text-overflow" "clip" "ellipsis")
  267. ("text-shadow" color length)
  268. ("text-underline-position" "auto" "under" "left" "right")
  269. ("transform" "matrix(,,,,,)" "translate(,)" "translateX()" "translateY()"
  270. "scale()" "scaleX()" "scaleY()" "rotate()" "skewX()" "skewY()" "none")
  271. ("transform-origin" perspective-origin)
  272. ("transform-style" "flat" "preserve-3d")
  273. ("transition" transition-property transition-duration
  274. transition-timing-function transition-delay)
  275. ("transition-delay" time)
  276. ("transition-duration" time)
  277. ("transition-timing-function"
  278. "ease" "linear" "ease-in" "ease-out" "ease-in-out" "cubic-bezier(,,,)")
  279. ("transition-property" "none" "all" identifier)
  280. ("word-wrap" overflow-wrap)
  281. ("word-break" "normal" "break-all" "keep-all"))
  282. "A list of CSS properties and their possible values.")
  283. (defconst company-css-value-classes
  284. '((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large"
  285. "xx-large")
  286. (align-common "flex-start" "flex-end" "center")
  287. (align-stretch align-common "stretch")
  288. (border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove"
  289. "ridge" "inset" "outset")
  290. (border-width "thick" "medium" "thin")
  291. (color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy"
  292. "olive" "orange" "purple" "red" "silver" "teal" "white" "yellow")
  293. (counter "counter(,)")
  294. (family-name "Courier" "Helvetica" "Times")
  295. (generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace")
  296. (generic-voice "male" "female" "child")
  297. (margin-width "auto") ;; length percentage
  298. (relative-size "larger" "smaller")
  299. (shape "rect(,,,)")
  300. (uri "url()"))
  301. "A list of CSS property value classes and their contents.")
  302. ;; missing, because not completable
  303. ;; <angle><frequency><identifier><integer><length><number><padding-width>
  304. ;; <percentage><specific-voice><string><time><uri>
  305. (defconst company-css-html-tags
  306. '("a" "abbr" "acronym" "address" "applet" "area" "b" "base" "basefont" "bdo"
  307. "big" "blockquote" "body" "br" "button" "caption" "center" "cite" "code"
  308. "col" "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em" "fieldset"
  309. "font" "form" "frame" "frameset" "h1" "h2" "h3" "h4" "h5" "h6" "head" "hr"
  310. "html" "i" "iframe" "img" "input" "ins" "isindex" "kbd" "label" "legend"
  311. "li" "link" "map" "menu" "meta" "noframes" "noscript" "object" "ol"
  312. "optgroup" "option" "p" "param" "pre" "q" "s" "samp" "script" "select"
  313. "small" "span" "strike" "strong" "style" "sub" "sup" "table" "tbody" "td"
  314. "textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var"
  315. ;; HTML5
  316. "section" "article" "aside" "header" "footer" "nav" "figure" "figcaption"
  317. "time" "mark" "main")
  318. "A list of HTML tags for use in CSS completion.")
  319. (defconst company-css-pseudo-classes
  320. '("active" "after" "before" "first" "first-child" "first-letter" "first-line"
  321. "focus" "hover" "lang" "left" "link" "right" "visited")
  322. "Identifiers for CSS pseudo-elements and pseudo-classes.")
  323. (defconst company-css-property-cache (make-hash-table :size 115 :test 'equal))
  324. (defun company-css-property-values (attribute)
  325. "Access the `company-css-property-alist' cached and flattened."
  326. (or (gethash attribute company-css-property-cache)
  327. (let (results)
  328. (dolist (value (cdr (assoc attribute company-css-property-alist)))
  329. (if (symbolp value)
  330. (dolist (child (or (cdr (assoc value company-css-value-classes))
  331. (company-css-property-values
  332. (symbol-name value))))
  333. (push child results))
  334. (push value results)))
  335. (setq results (sort results 'string<))
  336. (puthash attribute
  337. (if (fboundp 'delete-consecutive-dups)
  338. (delete-consecutive-dups results)
  339. (delete-dups results))
  340. company-css-property-cache)
  341. results)))
  342. ;;; bracket detection
  343. (defconst company-css-braces-syntax-table
  344. (let ((table (make-syntax-table)))
  345. (setf (aref table ?{) '(4 . 125))
  346. (setf (aref table ?}) '(5 . 123))
  347. table)
  348. "A syntax table giving { and } paren syntax.")
  349. (defun company-css-inside-braces-p ()
  350. "Return non-nil, if point is within matched { and }."
  351. (ignore-errors
  352. (with-syntax-table company-css-braces-syntax-table
  353. (let ((parse-sexp-ignore-comments t))
  354. (scan-lists (point) -1 1)))))
  355. ;;; tags
  356. (defconst company-css-tag-regexp
  357. (concat "\\(?:\\`\\|}\\)[[:space:]]*"
  358. ;; multiple
  359. "\\(?:"
  360. ;; previous tags:
  361. "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
  362. ;; space or selectors
  363. "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
  364. "\\)*"
  365. "\\(\\(?:#\\|\\_<[[:alpha:]]\\)\\(?:[[:alnum:]-#]*\\_>\\)?\\_>\\|\\)"
  366. "\\=")
  367. "A regular expression matching CSS tags.")
  368. ;;; pseudo id
  369. (defconst company-css-pseudo-regexp
  370. (concat "\\(?:\\`\\|}\\)[[:space:]]*"
  371. ;; multiple
  372. "\\(?:"
  373. ;; previous tags:
  374. "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
  375. ;; space or delimiters
  376. "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
  377. "\\)*"
  378. "\\(?:\\(?:\\#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\):"
  379. "\\([[:alpha:]-]+\\_>\\|\\)\\_>\\=")
  380. "A regular expression matching CSS pseudo classes.")
  381. ;;; properties
  382. (defun company-css-grab-property ()
  383. "Return the CSS property before point, if any.
  384. Returns \"\" if no property found, but feasible at this position."
  385. (when (company-css-inside-braces-p)
  386. (company-grab-symbol)))
  387. ;;; values
  388. (defconst company-css-property-value-regexp
  389. "\\_<\\([[:alpha:]-]+\\):\\(?:[^{};]*[[:space:]]+\\)?\\([^{};]*\\_>\\|\\)\\="
  390. "A regular expression matching CSS tags.")
  391. ;;;###autoload
  392. (defun company-css (command &optional arg &rest ignored)
  393. "`company-mode' completion backend for `css-mode'."
  394. (interactive (list 'interactive))
  395. (cl-case command
  396. (interactive (company-begin-backend 'company-css))
  397. (prefix (and (or (derived-mode-p 'css-mode)
  398. (and (derived-mode-p 'web-mode)
  399. (string= (web-mode-language-at-pos) "css")))
  400. (or (company-grab company-css-tag-regexp 1)
  401. (company-grab company-css-pseudo-regexp 1)
  402. (company-grab company-css-property-value-regexp 2
  403. (line-beginning-position))
  404. (company-css-grab-property))))
  405. (candidates
  406. (cond
  407. ((company-grab company-css-tag-regexp 1)
  408. (all-completions arg company-css-html-tags))
  409. ((company-grab company-css-pseudo-regexp 1)
  410. (all-completions arg company-css-pseudo-classes))
  411. ((company-grab company-css-property-value-regexp 2
  412. (line-beginning-position))
  413. (all-completions arg
  414. (company-css-property-values
  415. (company-grab company-css-property-value-regexp 1))))
  416. ((company-css-grab-property)
  417. (all-completions arg company-css-property-alist))))
  418. (sorted t)))
  419. (provide 'company-css)
  420. ;;; company-css.el ends here