# Modified from Sublime Text Default CSS Package import sublime, sublime_plugin import re common = { "color": ["transparent"], "border-style": ["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"], "border-width": ["thin", "medium", "thick"], "generic-family": ["serif", "sans-serif", "cursive", "fantasy", "monospace"] } css_data = """ "-webkit-font-smoothing"=none | antialiased | subpixel-antialiased "background"= | | repeat | repeat-x | repeat-y | no-repeat | scroll | fixed | left | center | right | top | bottom | inherit "background-attachment"=scroll | fixed | inherit "background-clip"= "background-color"= | inherit "background-image"= | none | inherit "background-origin"= "background-position"=left | center | right | top | bottom | inherit "background-repeat"=repeat | repeat-x | repeat-y | no-repeat | inherit "background-size"=cover | contain | | inherit "border"= | | | inherit "border-collapse"=collapse | separate | inherit "border-color"= | inherit "border-image"= | | | | | "border-image-outset"= | "border-image-repeat"=stretch | repeat | round | space "border-image-slice"= | "border-image-source"=none | "border-image-width"= | | | auto "border-radius"= | "border-style"= "border-spacing"=inherit "border-style"= | inherit "border-top" "border-right" "border-bottom" "border-left"= | | | inherit "border-top-color" "border-right-color" "border-bottom-color" "border-left-color"= | inherit "border-top-style" "border-right-style" "border-bottom-style" "border-left-style"= | inherit "border-top-width" "border-right-width" "border-bottom-width" "border-left-width"= | inherit "border-top-left-radius" "border-top-right-radius" "border-bottom-right-radius" "border-bottom-left-radius"= | "border-width"= | inherit "bottom"= | | auto | inherit "box-decoration-break"=slice | clone "box-shadow"=none | | none "box-sizing"=content-box | padding-box | border-box | inherit "caption-side"=top | bottom | inherit "clear"=none | left | right | both | inherit "clip"= | auto | inherit "color"= | inherit "content"=normal | none | | open-quote | close-quote | no-open-quote | no-close-quote | inherit "counter-increment"=none | inherit "counter-reset"=none | inherit "cursor"= | auto | crosshair | default | pointer | move | e-resize | ne-resize | nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | text | wait | help | progress | inherit "direction"=ltr | rtl | inherit "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 | inherit "empty-cells"=show | hide | inherit "float"=left | right | none | inherit "font-family"=| inherit "font-size"=inherit "font-style"=normal | italic | oblique | inherit "font-variant"=normal | small-caps | inherit "font-weight"=normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit "font"=normal | italic | oblique | normal | small-caps | normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | normal | | caption | icon | menu | message-box | small-caption | status-bar | inherit "height"= | | auto | inherit "left"= | | auto | inherit "letter-spacing"=normal | | inherit "line-height"=normal | | | | inherit "list-style-image"= | none | inherit "list-style-position"=inside | outside | inherit "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 | inherit "list-style"=disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inside | outside | | inherit "margin-right" "margin-left"= | inherit "margin-top" "margin-bottom"= | inherit "margin"= | inherit "max-height"= | | none | inherit "max-width"= | | none | inherit "min-height"= | | inherit "min-width"= | | inherit "opacity"= | inherit "orphans"= | inherit "outline-color"= | invert | inherit "outline-style"= | inherit "outline-width"= | inherit "outline"= | | | inherit "overflow"=visible | hidden | scroll | auto | inherit "overflow-x"=visible | hidden | scroll | auto | inherit "overflow-y"=visible | hidden | scroll | auto | inherit "padding-top" "padding-right" "padding-bottom" "padding-left"= | inherit "padding"= | inherit "page-break-after"=auto | always | avoid | left | right | inherit "page-break-before"=auto | always | avoid | left | right | inherit "page-break-inside"=avoid | auto | inherit "pointer-events"=auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit "position"=static | relative | absolute | fixed | inherit "quotes"=none | inherit "right"= | | auto | inherit "table-layout"=auto | fixed | inherit "text-align"=left | right | center | justify | inherit "text-decoration"=none | underline | overline | line-through | blink | inherit | none "text-indent"= | | inherit "text-transform"=capitalize | uppercase | lowercase | none | inherit "top"= | | auto | inherit "unicode-bidi"=normal | embed | bidi-override | inherit "vertical-align"=baseline | sub | super | top | text-top | middle | bottom | text-bottom | | | inherit "visibility"=visible | hidden | collapse | inherit "white-space"=normal | pre | nowrap | pre-wrap | pre-line | inherit "width"= | | auto | inherit "word-spacing"=normal | | inherit "z-index"=auto | | inherit """ def parse_css_data(data): props = {} for l in data.splitlines(): if l == "": continue names, values = l.split('=') allowed_values = [] for v in values.split('|'): v = v.strip() if v[0] == '<' and v[-1] == '>': key = v[1:-1] if key in common: allowed_values += common[key] else: allowed_values.append(v) for e in names.split(): if e[0] == '"': props[e[1:-1]] = sorted(allowed_values) else: break return props class LESSCompletions(sublime_plugin.EventListener): props = None rex = None def on_query_completions(self, view, prefix, locations): if not view.match_selector(locations[0], "source.less"): return [] if not self.props: self.props = parse_css_data(css_data) self.rex = re.compile("([a-zA-Z-]+):\s*$") l = [] if (view.match_selector(locations[0], "meta.property-value.css") or # This will catch scenarios like .foo {font-style: |} view.match_selector(locations[0] - 1, "meta.property-value.css")): loc = locations[0] - len(prefix) line = view.substr(sublime.Region(view.line(loc).begin(), loc)) m = re.search(self.rex, line) if m: prop_name = m.group(1) if prop_name in self.props: values = self.props[prop_name] add_semi_colon = view.substr(sublime.Region(locations[0], locations[0] + 1)) != ';' for v in values: desc = v snippet = v if add_semi_colon: snippet += ";" # if snippet.find("$1") != -1: # desc = desc.replace("$1", "") l.append((desc, snippet)) return l return None elif ( # Avoid completions for @variables or @{variables} view.match_selector(locations[0], "variable") or view.match_selector(locations[0] - 1, "variable") or # Avoid completions for #selectors view.match_selector(locations[0], "entity.other.attribute-name.id.css") or view.match_selector(locations[0] - 1, "entity.other.attribute-name.id.css") or # Avoid completions for .selectors view.match_selector(locations[0], "entity.other.attribute-name.class.css") or view.match_selector(locations[0] - 1, "entity.other.attribute-name.class.css")): return None else: add_colon = not view.match_selector(locations[0], "meta.property-name.css") for p in self.props: if add_colon: l.append((p, p + ": ")) else: l.append((p, p)) return l