Sass TextMate Bundle
Written December 24th, 2007
I went a googling, looking for a Sass TextMate bundle. There didn’t seem to be one, so I sat down and threw one together. Hopefully, this should make writing Syntactically Awesome StyleSheets a little easier for TextMate users.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
{
scopeName = 'source.sass';
comment = '';
fileTypes = ( 'sass' );
patterns = (
{ name = 'meta.variable-declaration.sass';
begin = '^(\!)([a-zA-Z0-9_-]+)\s*(=)';
end = '(;)?$';
beginCaptures = {
1 = { name = 'punctuation.definition.entity.css'; };
2 = { name = 'variable.other.sass'; };
3 = { name = 'punctuation.definition.entity.css'; };
};
endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };
patterns = ( { include = '#property-value'; } );
},
{ name = 'meta.selector.sass';
begin = '^(?=[:.*#a-zA-Z])';
end = '(;)?$';
endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };
patterns = (
{ include = '#comment-block'; },
{ name = 'entity.name.tag.sass';
match = '\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|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)\b';
},
{ name = 'entity.other.attribute-name.class.sass';
match = '(\.)[a-zA-Z0-9_-]+';
captures = { 1 = { name = 'punctuation.definition.entity.css'; }; };
},
{ name = 'entity.other.attribute-name.id.sass';
match = '(#)[a-zA-Z][a-zA-Z0-9_-]*';
captures = { 1 = { name = 'punctuation.definition.entity.sass'; }; };
},
{ name = 'entity.name.tag.wildcard.sass';
match = '\*';
},
{ name = 'entity.other.attribute-name.pseudo-element.sass';
match = '(:+)\b(after|before|first-child|first-letter|first-line|selection)\b';
captures = { 1 = { name = 'punctuation.definition.entity.sass'; }; };
},
{ name = 'entity.other.attribute-name.pseudo-class.sass';
match = '(:)\b(active|hover|link|visited|focus)\b';
captures = { 1 = { name = 'punctuation.definition.entity.sass'; }; };
},
{ name = 'meta.attribute-selector.sass';
match = '(?i)(\[)\s*(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)(?:\s*([~|^$*]?=)\s*(?:(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)|((?>([''"])(?:[^\\]|\\.)*?(\6)))))?\s*(\])';
captures = {
1 = { name = 'punctuation.definition.entity.sass'; };
2 = { name = 'entity.other.attribute-name.attribute.sass'; };
3 = { name = 'punctuation.separator.operator.sass'; };
4 = { name = 'string.unquoted.attribute-value.sass'; };
5 = { name = 'string.quoted.double.attribute-value.sass'; };
6 = { name = 'punctuation.definition.string.begin.sass'; };
7 = { name = 'punctuation.definition.string.end.sass'; };
};
},
);
},
{ include = '#comment-block'; },
{ name = 'meta.at-rule.import.sass';
begin = '^\s*((@)import\b)';
end = '(;)?$';
beginCaptures = {
1 = { name = 'keyword.control.at-rule.import.sass'; };
2 = { name = 'punctuation.definition.keyword.sass'; };
};
endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };
patterns = (
{ include = '#string-double'; },
{ begin = '(url)\s*(\()\s*';
end = '\s*(\))\s*';
beginCaptures = {
1 = { name = 'support.function.url.sass'; };
2 = { name = 'punctuation.section.function.sass'; };
};
endCaptures = { 1 = { name = 'punctuation.section.function.sass'; }; };
patterns = (
{ name = 'variable.parameter.url.sass';
match = '[^''") \t]+';
},
{ include = '#string-single'; },
{ include = '#string-double'; },
);
},
{ name = 'variable.parameter.url.sass';
match = '([^"''\n;]+)';
},
);
},
{ name = 'meta.at-rule.media.sass';
begin = '^\s*((@)media)\s+(((all|aural|braille|embossed|handheld|print|projection|screen|tty|tv)\s*,?\s*)+)\s*{';
end = '\s*((?=;|\}))';
captures = {
1 = { name = 'keyword.control.at-rule.media.sass'; };
2 = { name = 'punctuation.definition.keyword.sass'; };
3 = { name = 'support.constant.media.sass'; };
};
patterns = ( { include = '$self'; } );
},
{ name = 'meta.property-name.sass';
begin = '(?<![-a-z])(:)(?=[-a-z])';
end = '(;)?$';
beginCaptures = { 1 = { name = 'punctuation.definition.entity.css'; }; };
endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };
patterns = (
{ name = 'support.type.property-name.sass';
match = '\b(azimuth|background-attachment|background-color|background-image|background-position|background-repeat|background|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|bottom|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|family|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|-moz-border-radius|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|style|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|weight|white-space|widows|width|word-spacing|z-index)\b';
},
{ include = '#property-value'; },
);
},
);
repository = {
comment-block = {
name = 'comment.block.sass';
begin = '(/\*|//)';
end = '$';
captures = { 0 = { name = 'punctuation.definition.comment.sass'; }; };
};
property-value = {
name = 'meta.property-value.sass';
begin = '(:)?\s+';
end = '(;)?$';
beginCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };
endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };
patterns = (
{ name = 'meta.variable-assignment.sass';
begin = '(=)\s*(\!)([a-zA-Z0-9_-]+)';
end = '(;)?$';
beginCaptures = {
1 = { name = 'punctuation.definition.entity.css'; };
2 = { name = 'punctuation.definition.entity.css'; };
3 = { name = 'variable.other.sass'; };
};
endCaptures = { 1 = { name = 'invalid.illegal.punctuation.sass'; }; };
},
{ name = 'support.constant.property-value.sass';
match = '\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|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)\b';
},
{ name = 'support.constant.font-name.sass';
match = '(\b(?i:arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace)\b)';
},
{ name = 'support.constant.color.w3c-standard-color-name.sass';
comment = 'http://www.w3schools.com/css/css_colors.asp';
match = '\b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)\b';
},
{ name = 'invalid.deprecated.color.w3c-non-standard-color-name.sass';
comment = 'These colours are mostly recognised but will not validate. ref: http://www.w3schools.com/css/css_colornames.asp';
match = '\b(seagreen|hotpink|lawngreen|darkgreen|violet|darkred|crimson|green|sandybrown|navy|magenta|darkslategray|steelblue|silver|darkgrey|mistyrose|gray|aliceblue|blueviolet|lightpink|saddlebrown|chocolate|limegreen|lightslategray|yellowgreen|pink|lightskyblue|indigo|lightblue|floralwhite|navajowhite|mediumvioletred|honeydew|aquamarine|blue|olivedrab|palegreen|slategray|lavenderblush|wheat|moccasin|mediumturquoise|mediumspringgreen|lightcoral|mintcream|tomato|lightgrey|black|darkmagenta|dimgray|darkturquoise|midnightblue|plum|indianred|coral|lightcyan|mediumslateblue|darkcyan|darkslateblue|darkkhaki|ivory|azure|khaki|powderblue|darkgoldenrod|orangered|burlywood|turquoise|royalblue|maroon|cornsilk|antiquewhite|yellow|teal|orange|grey|darkslategrey|slateblue|seashell|darkorchid|snow|lightslategrey|cyan|greenyellow|palevioletred|goldenrod|deepskyblue|lightyellow|lightseagreen|sienna|lemonchiffon|darkviolet|paleturquoise|slategrey|skyblue|purple|mediumpurple|cadetblue|fuchsia|chartreuse|darksalmon|lightgoldenrodyellow|white|springgreen|olive|forestgreen|peachpuff|peru|dimgrey|mediumseagreen|thistle|firebrick|darkgray|mediumaquamarine|darkolivegreen|mediumblue|palegoldenrod|blanchedalmond|ghostwhite|gold|gainsboro|darkseagreen|cornflowerblue|lime|lavender|beige|orchid|mediumorchid|whitesmoke|bisque|lightgray|tan|salmon|rosybrown|red|dodgerblue|brown|aqua|oldlace|deeppink|papayawhip|lightsalmon|lightsteelblue|darkorange|darkblue|linen|lightgreen)\b';
},
{ name = 'constant.numeric.sass';
match = '(-|\+)?\s*[0-9]+(\.[0-9]+)?';
},
{ name = 'keyword.other.unit.sass';
match = '(?<=[\d])(px|pt|cm|mm|in|em|ex|pc)\b|%';
},
{ name = 'constant.other.color.rgb-value.sass';
match = '(#)([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b';
captures = { 1 = { name = 'punctuation.definition.constant.sass'; }; };
},
{ include = '#string-double'; },
{ include = '#string-single'; },
{ begin = '(rgb|url|attr|counter|counters)\s*(\()';
end = '(\))';
beginCaptures = {
1 = { name = 'support.function.misc.sass'; };
2 = { name = 'punctuation.section.function.sass'; };
};
endCaptures = { 1 = { name = 'punctuation.section.function.sass'; }; };
patterns = (
{ include = '#string-single'; },
{ include = '#string-double'; },
{ name = 'constant.other.color.rgb-value.sass';
match = '(\b0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*)(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*)(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\b)';
},
{ name = 'constant.other.color.rgb-percentage.sass';
match = '\b([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%';
},
{ name = 'variable.parameter.misc.sass';
match = '[^''") \t]+';
},
);
},
{ name = 'keyword.other.important.sass';
match = '\!\s*important';
},
);
};
string-double = {
name = 'string.quoted.double.sass';
begin = '"';
end = '"';
beginCaptures = { 0 = { name = 'punctuation.definition.string.begin.sass'; }; };
endCaptures = { 0 = { name = 'punctuation.definition.string.end.sass'; }; };
patterns = (
{ name = 'constant.character.escape.sass';
match = '\\.';
},
);
};
string-single = {
name = 'string.quoted.single.sass';
begin = "'";
end = "'";
beginCaptures = { 0 = { name = 'punctuation.definition.string.begin.sass'; }; };
endCaptures = { 0 = { name = 'punctuation.definition.string.end.sass'; }; };
patterns = (
{ name = 'constant.character.escape.sass';
match = '\\.';
},
);
};
};
}
|
This code was based on the existing CSS bundle, and may still have bugs. This is my first serious attempt at writing a bundle, so it probably needs work in spots. Let me know if you find any issues. I’ll update this entry with any changes made.
The HAML bundle is really a HAML/SASS bundle. But thanks for coming up with an alternative.
-Matt
Ok, maybe I have a different bundle than you. The Haml bundle I have installed is definitely Haml-only.
I took a look at the newer version of the Haml bundle you were talking about. My version looks a lot nicer, uses more correct scope selectors, and highlights invalid syntax, so I’m going to stick with it.
Thanks. You may send this bundle to textmate bundles svn, to easily deliver changes to users. All information about this is here: http://article.gmane.org/gmane.editors.textmate.general/20994/match=submit+new+bundle
Ugggh.. that didn’t work for me at all. What’s it supposed to look like? Can you add some screenshots and maybe some better install instructions?
Thanks
jc:
You need to create a Sass bundle and a Sass language. Paste the above property list in as the content of the Sass language. That pretty much covers it.
Excellent bundle! This is a notch better than the HAML/SASS bundle, thanks for the effort in producing it.
One note, though, in this code:
#content.summarizer_configs.show #filter_configs :margin 0.5em 0 0 0 .tag :padding 2px :text-decoration none &:hover :background-color = !button_selected_color .tag.disabled :background-color = !section_background_color :color greyMy color ‘grey’ is being highlighted as invalid markup. I might be mistaken, but I’m pretty sure HAML supports using HTML4 colors.
Just my 2 cents, thanks again!
Actually, it does support it, and if you run your code through the Sass engine, I believe it’ll produce the expected output. In fact, most browsers won’t choke on it. But what you wanted was “gray” not “grey”. Usage of “grey” has been deprecated for quite some time.
I’m using e-texteditor for windows http://e-texteditor.com/forum/ and I haven’t been able to get this to work. Can anyone provide a rar/zipfile with the actual SASS bundle so I can just unzip it into the bundles dir?
+1 vote for getting a SASS bundle for “e”. :)
Well, I probably should get around to submitting the bundle.
+1 for submitting this as a bundle, I spent 15 minutes yesterday googling for a piece of software that converts your sample to a .plist file that my e text editor on windows wants … I found a python tool but it expected python code …
Thanks for the bundle :). I had some problems installing it (at first the text was all white). But after fiddling with it for a while it starting working (I think hitting reload a lot and changing the language from sass to plain text and back to sass did it.
Anyways I wanted to mention that syntax highlighting for multiple lines does not seem to work. It adds the comments but only the first line appears grey and everything in between is white.
Rob:
Well, the colors aren’t fixed in the bundle. Those are set in Textmate’s preferences. You may want to check there. If the standard CSS bundle produces sane-looking syntax highlighting, this should produce equally sane highlighting for SASS.
Bob, I don’t think I was clear enough. This is the problem I’m having with comments
The CSS bundle handles this situation correctly and all lines are highlighted.
I noticed that nested selectors weren’t syntax highlighted so I read through the language file, and tried to understand it to the best of my knowledge (I don’t know TextMate Bundle Development at all). I came up with a fix but not sure if I did it 100% correctly, anyway here is some stuff:
div :color red h3 <-- this wasn't the same color as "div" is :font-size 15pxIn the ‘meta.selector.sass’, I changed begin from:
to this:
Let me know what you think of this change, hopefully you can make whatever I changed a bit better since you know the TM Bundle Dev a lot better than I :)
Rob:
Ahh, ok. I understand now. You’re right, that’s a bug.
Arya:
That’s also a bug. I’ll try to get both fixed.
Also, thanks so much for this bundle, I can see how difficult it must have been. I really appreciate it :)
Actually, the real problem with that is that it crashes TextMate. :-P
I’ve solved the issue with nested selectors. Still working on a suitable fix for comments. However, it should be noted that even Sass itself has issues with this form of comments. I would highly recommend using the following form instead, even after I figure out how to get the syntax highlighting working.
This seems to work:
Hey, I would love to use this for the e text editor… can you please submit this bundle so that I may use it with e? Thank you.
Hi,
Thanks for this, it’s much better than what’s include in the HAML bundle. I just noticed a few bugs (nothing important)
!dark_red won’t be recognized as a constant here: :border = 1px solid !dark_red
and !padding here
:width = !width4 – !padding * 2 – 2px
Thanks, Maxime
I have not had any luck with this. I went into the Bundle Editor, I created a new bundle and named it ‘Sass’, then created a new Language under that, and called it ‘Sass’. Then I pasted your code and saved. I tried both reloading the bundle, and restarting TextMate. The only thing that appears to be highlighted is color constants. No variable highlighting, no keyword highlighting. Any ideas?
Hi, has this bundle been submited to the textmate repository ? Or maybe is there a subversion rep that we could fetch it from. That would definitely be useful. By the way, thx for the great work !!
Oh, yes, this is much nicer than the Haml bundle. Thanks!
Maxime:
I’ve fixed the issue with variable usage. I’m working on packaging up the bundle and getting it submitted now.
So what’s the word on this? Any new news on getting it installed?
By the way, to those trying to get it installed in it’s current state:
.sass files should now be recognized.
Sorry for the three comments in a row, there’s no way to edit.
This bundle only works for people that use the weird :selector attribution style… if you use the sensible selector: attribution style, it all shows up as white.
Also, weird colorization issues: http://tinyurl.com/2a7dqd
Elliott:
The bundle was submitted to the Textmate developers list for review the other day. I suspect that it will be awhile before that process is done, however.
I will look into the selector and colorization issues you brought up ASAP.
I think you should be able to check the bundle out of Subversion right now though:
I have updated the Bundle to include the Snippets from the CSS bundle. More info at http://www.aussiegeek.net/posts/3-Snippets-for-Sass-Bundle
great minds think alike. it did take a while to find a sass bundle. i’ve got one that’s based on minimal design’s css bundle, and managed through git at:
http://github.com/seaofclouds/sass-textmate-bundle
Leave a Response