├── Commands └── Save to CSS.tmCommand ├── README.md ├── Syntaxes └── LESS.tmLanguage ├── info.plist ├── sample.less └── sample.png /Commands/Save to CSS.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | saveActiveFile 7 | command 8 | #!/usr/bin/env ruby 9 | file = STDIN.read[/lessc: ([^*]+\.less)/, 1] || ENV["TM_FILEPATH"] 10 | system("lessc --verbose \"#{file}\"") 11 | input 12 | document 13 | keyEquivalent 14 | @s 15 | name 16 | Save to CSS 17 | output 18 | showAsTooltip 19 | scope 20 | source.css.less 21 | uuid 22 | 78788223-5E5E-434E-98BE-17BCDF600611 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LESS TextMate bundle 2 | 3 | Syntax highlighting for `.less` files. To learn more about [LESS][], see . 4 | 5 | This bundle was forked from `appden/less.tmbundle` but has since been rewritten from scratch (the language syntax). 6 | 7 | [`sample.less`](http://github.com/rsms/less.tmbundle/blob/master/sample.less): 8 | 9 | 10 | 11 | Rendered in the ["Hunch Dark dimmed" theme](http://github.com/rsms/workenv/blob/master/textmate/Hunch-Dark-dimmed.tmTheme) 12 | 13 | ## Compiling to CSS (⌘B) 14 | 15 | Runs `lessc` on the current file, saving to the same file name with a .css extension (e.g. style.less => style.css). When there is `lessc: somefile.less` somewhere in the current file, that file is compiled instead. 16 | 17 | Compiling requires some version of `lessc` to be in your `PATH`. 18 | 19 | ## Authors 20 | 21 | * Rasmus Andersson rsms@github 22 | * Scott Kyle appden@github 23 | 24 | ## License (MIT) 25 | 26 | Copyright (c) 2010 Scott Kyle and Rasmus Andersson 27 | 28 | Permission is hereby granted, free of charge, to any person obtaining a copy 29 | of this software and associated documentation files (the "Software"), to deal 30 | in the Software without restriction, including without limitation the rights 31 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 32 | copies of the Software, and to permit persons to whom the Software is 33 | furnished to do so, subject to the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be included in 36 | all copies or substantial portions of the Software. 37 | 38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 40 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 41 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 43 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 44 | THE SOFTWARE. 45 | 46 | 47 | [LESS]: http://lesscss.org 48 | -------------------------------------------------------------------------------- /Syntaxes/LESS.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | comment 6 | LeSS 7 | fileTypes 8 | 9 | less 10 | 11 | foldingStartMarker 12 | /\*\*(?!\*)|\{\s*($|/\*(?!.*?\*/.*\S)) 13 | foldingStopMarker 14 | (?<!\*)\*\*/|^\s*\} 15 | keyEquivalent 16 | ^~L 17 | name 18 | LESS 19 | patterns 20 | 21 | 22 | match 23 | \b(a|abbr|acronym|address|area|b|base|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|dt|em|fieldset|figure|form|frame|frameset|(h[1-6])|head|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|meta|noframes|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var|header|section|footer|article|nav|aside|hgroup|time|mark)\b 24 | name 25 | keyword.control.html.elements 26 | 27 | 28 | begin 29 | " 30 | end 31 | " 32 | name 33 | string.quoted.double.css 34 | patterns 35 | 36 | 37 | match 38 | \\. 39 | name 40 | constant.character.escaped.css 41 | 42 | 43 | 44 | 45 | begin 46 | ' 47 | end 48 | ' 49 | name 50 | string.quoted.single.css 51 | patterns 52 | 53 | 54 | match 55 | \\. 56 | name 57 | constant.character.escaped.css 58 | 59 | 60 | 61 | 62 | captures 63 | 64 | 1 65 | 66 | name 67 | entity.other.attribute-name.class.css 68 | 69 | 70 | match 71 | (\.[a-zA-Z0-9_-]+)[\s,{;] 72 | 73 | 74 | begin 75 | url\( 76 | contentName 77 | variable.parameter.url 78 | end 79 | \) 80 | name 81 | support.function.any-method.builtin.css 82 | 83 | 84 | match 85 | (#)([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b 86 | name 87 | constant.other.rgb-value.css 88 | 89 | 90 | captures 91 | 92 | 0 93 | 94 | name 95 | entity.other.attribute-name.id 96 | 97 | 98 | match 99 | #[a-zA-Z0-9_-]+ 100 | name 101 | meta.selector.css 102 | 103 | 104 | begin 105 | /\* 106 | end 107 | \*/ 108 | name 109 | comment.block.css 110 | 111 | 112 | match 113 | (-|\+)?\s*[0-9]+(\.[0-9]+)? 114 | name 115 | constant.numeric.css 116 | 117 | 118 | match 119 | (?<=[\d])(px|pt|cm|mm|in|em|ex|pc)\b|% 120 | name 121 | keyword.unit.css 122 | 123 | 124 | captures 125 | 126 | 1 127 | 128 | name 129 | punctuation.definition.entity.css 130 | 131 | 132 | match 133 | (:+)\b(after|before|first-child|first-letter|first-line|selection)\b 134 | name 135 | entity.other.attribute-name.pseudo-element.css 136 | 137 | 138 | captures 139 | 140 | 1 141 | 142 | name 143 | punctuation.definition.entity.css 144 | 145 | 146 | match 147 | (:)\b(active|hover|link|visited|focus)\b 148 | name 149 | entity.other.attribute-name.pseudo-class.css 150 | 151 | 152 | captures 153 | 154 | 1 155 | 156 | name 157 | punctuation.definition.entity.css 158 | 159 | 2 160 | 161 | name 162 | entity.other.attribute-name.attribute.css 163 | 164 | 3 165 | 166 | name 167 | punctuation.separator.operator.css 168 | 169 | 4 170 | 171 | name 172 | string.unquoted.attribute-value.css 173 | 174 | 5 175 | 176 | name 177 | string.quoted.double.attribute-value.css 178 | 179 | 6 180 | 181 | name 182 | punctuation.definition.string.begin.css 183 | 184 | 7 185 | 186 | name 187 | punctuation.definition.string.end.css 188 | 189 | 190 | match 191 | (?i)(\[)\s*(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)(?:\s*([~|^$*]?=)\s*(?:(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)|((?>(['"])(?:[^\\]|\\.)*?(\6)))))?\s*(\]) 192 | name 193 | meta.attribute-selector.css 194 | 195 | 196 | captures 197 | 198 | 1 199 | 200 | name 201 | keyword.control.at-rule.import.css 202 | 203 | 2 204 | 205 | name 206 | punctuation.definition.keyword.css 207 | 208 | 209 | match 210 | ^\s*((@)import\b) 211 | name 212 | meta.at-rule.import.css 213 | 214 | 215 | captures 216 | 217 | 1 218 | 219 | name 220 | support.type.property-name.css.vendor 221 | 222 | 223 | match 224 | (-(?:webkit|moz|khtml|o|icab)-(?:background-size|border-radius|box-shadow|opacity|border-image))\s*: 225 | 226 | 227 | captures 228 | 229 | 1 230 | 231 | name 232 | support.type.property-name.css 233 | 234 | 235 | match 236 | \b(azimuth|background-attachment|background-color|background-clip|background-image|background-position|background-repeat|background-size|background|behavior|border-bottom-color|border-bottom-style|border-bottom-width|border-bottom|border-collapse|border-color|border-left-color|border-left-style|border-left-width|border-left|border-right-color|border-right-style|border-right-width|border-right|border-spacing|border-style|border-top-color|border-top-style|border-top-width|border-top|border-width|border-radius|border|box-shadow|bottom|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|float|font-family|font-size-adjust|font-size|font-stretch|font-style|font-variant|font-weight|font|height|left|letter-spacing|line-height|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|marker-offset|margin|marks|max-height|max-width|min-height|min-width|opacity|orphans|outline-color|outline-style|outline-width|outline|overflow(-[xy])?|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page|pause-after|pause-before|pause|pitch-range|pitch|play-during|position|quotes|richness|right|size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|stress|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|white-space|widows|width|word-spacing|z-index)\s*: 237 | 238 | 239 | match 240 | \b(absolute|all-scroll|always|auto|baseline|below|bidi-override|block|bold|bolder|both|bottom|break-all|break-word|capitalize|center|char|circle|col-resize|collapse|crosshair|dashed|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|groove|hand|help|hidden|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|keep-all|left|lighter|line-edge|line-through|line|linear|list-item|loose|lower-alpha|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-roman|uppercase|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|padding-box)\b 241 | name 242 | support.constant.property-value.css 243 | 244 | 245 | match 246 | (\b(?i:arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace)\b) 247 | name 248 | support.constant.font-name.css 249 | 250 | 251 | comment 252 | http://www.w3.org/TR/CSS21/syndata.html#value-def-color 253 | match 254 | \b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)\b 255 | name 256 | support.constant.color.w3c-standard-color-name.css 257 | 258 | 259 | match 260 | \b(saturate|desaturate|lighten|darken|grayscale)\b 261 | name 262 | support.function.any-method.builtin.less 263 | 264 | 265 | match 266 | \b(rgb|rgba|hsl|hsla|url)\b 267 | name 268 | support.function.any-method.builtin.css 269 | 270 | 271 | captures 272 | 273 | 1 274 | 275 | name 276 | support.function.any-method.vendor.css 277 | 278 | 279 | match 280 | (-(?:webkit|moz|khtml|o|icab)-(?:gradient|linear-gradient)) 281 | 282 | 283 | match 284 | \b(color-stop|from|to)\b 285 | name 286 | support.function.any-method.webkit.gradient.css 287 | 288 | 289 | captures 290 | 291 | 1 292 | 293 | name 294 | support.function.less 295 | 296 | 297 | match 298 | (\.[a-zA-Z0-9_-]+)\s*(;|\() 299 | 300 | 301 | begin 302 | // 303 | end 304 | $\n? 305 | name 306 | comment.line.double-slash.less 307 | 308 | 309 | match 310 | @[a-zA-Z0-9_-][\w-]* 311 | name 312 | variable.other.less 313 | 314 | 315 | match 316 | \$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|(?<!\()/=|%=|\+=|\-=|&=|\^=|\/\b 317 | name 318 | keyword.operator.less 319 | 320 | 321 | match 322 | \{|\} 323 | name 324 | meta.brace.curly.js 325 | 326 | 327 | match 328 | \(|\) 329 | name 330 | meta.brace.round.js 331 | 332 | 333 | match 334 | \[|\] 335 | name 336 | meta.brace.square.js 337 | 338 | 339 | scopeName 340 | source.css.less 341 | uuid 342 | 9343D324-75A1-4733-A5C0-5D1D4B6182D0 343 | 344 | 345 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | LESS 7 | uuid 8 | D1D51EE5-E89F-4B14-8AE4-FC364E540B47 9 | ordering 10 | 11 | 78788223-5E5E-434E-98BE-17BCDF600611 12 | 9343D324-75A1-4733-A5C0-5D1D4B6182D0 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /sample.less: -------------------------------------------------------------------------------- 1 | // Importing 2 | @import "_base.less" 3 | 4 | // Variables 5 | @nice-blue: #5B83AD; 6 | @light-blue: @nice-blue + #111; 7 | #header { color: @light-blue; } 8 | 9 | // Mixins 10 | .bordered(@color: #f04) { 11 | border-top: dotted 1px @color; 12 | border-bottom: solid 2px @color; 13 | } 14 | #menu a { 15 | .bordered(#f00); color:#111; 16 | } 17 | 18 | // Nested 19 | #header { 20 | h1 { font-size: 12px; } 21 | .logo { 22 | width: 300px; 23 | :hover { text-decoration: none } 24 | } 25 | } 26 | 27 | // Operations 28 | @base: 5%; 29 | @filler: @base * 2; 30 | @other: @base + @filler; 31 | td { 32 | background-color: @base-color + #111; 33 | height: 100% / 2 + @filler; 34 | } 35 | 36 | /* 37 | Accessors 38 | */ 39 | .comment { 40 | width: #defaults[@width]; 41 | color: .article['color']; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/appden/less.tmbundle/a202dd9942f96bac0ee3c42552a35480682790c9/sample.png --------------------------------------------------------------------------------