34 Commits
0.2 ... 0.4.0

Author SHA1 Message Date
Ben S
6bc2dac873 Another version bump! 2015-05-03 12:25:52 +01:00
Ben S
07b020f253 Detab the plist 2015-05-03 12:24:31 +01:00
Ben S
ec10c4bf7f Add loads more built-in types 2015-05-03 12:24:22 +01:00
Ben S
e28267063f Update README 2015-03-16 22:02:24 +00:00
Ben S
adbf51d973 Add code folding!
Also, fix weird-looking function definitions.
2015-03-16 21:49:15 +00:00
Ben S
439556cbe4 Check end of word after scanning functions
'enumerate' is not 'enum' with some bits after it!
2015-03-16 18:35:00 +00:00
Ben S
0fe7412e14 Parse definitions with lifetimes correctly
This is actually achieved by making the parsing *more lenient* instead of more strict. The view looks more cluttered as a result, but at least it's *correct*. Nothing I can do about the clutter, as far as I know - BBEdit only allows us to use substrings of the document in the menu, so I can't strip out the lifetimes.
2015-03-16 18:19:56 +00:00
Ben S
565243f64b Update screenshot 2015-02-21 13:44:55 +00:00
Ben S
46fe844c16 Version bump 2015-02-21 13:29:11 +00:00
Ben S
bfdc57e356 Fix infinite loop when writing code at end of file
This resulted in my BBEdit hanging.
2015-02-21 13:27:29 +00:00
Ben S
1154b0df63 Highlight module names in 'use...as' statements 2015-02-21 13:27:05 +00:00
Ben S
2c05ab8682 Download link bump 2015-02-15 14:06:55 +00:00
Ben S
822eb95303 But there's only one type of string 2015-02-15 13:48:41 +00:00
Ben S
da342c1b7d Simplify macro-highlighting code 2015-02-15 13:43:15 +00:00
Ben S
81197c7d45 Detect r##"raw strings"## 2015-02-15 13:23:32 +00:00
Ben S
e6c0074733 Smarten up attribute highlighting 2015-02-15 13:07:24 +00:00
Ben S
5452afbb9c Replace identifier colour with preprocessor colour 2015-02-15 13:07:10 +00:00
Ben S
2c06798f84 Allow 'us' and 'is' machine-dependent suffixes 2015-02-15 12:54:55 +00:00
Ben S
d2549503b5 Add smoke test thing to save me from testing 2015-02-15 12:49:34 +00:00
Ben S
3b9fc0817c Add all the other keywords I missed 2015-02-15 12:27:35 +00:00
Ben S
82931045a2 Highlight macro_rules! definitions + arguments 2015-02-15 02:44:29 +00:00
Ben S
51e8755030 where wasn't a keyword already? 2015-02-15 02:24:35 +00:00
Benjamin Sago
9932fb4761 Replace int/uint with isize/usize 2015-01-11 12:43:57 +01:00
Ben S
79a65307f0 Changes to the way numbers are highlighted
They were being highlighted after underscores in variable names, and underscores weren't being catered for in non-base-ten numeric literals. Now, fixed!
2014-12-24 14:11:32 +00:00
Ben S
c98ec54134 Skip over modules called 'test' 2014-12-05 21:47:52 +00:00
Ben S
98a15cf36a Skip over empty function/module definitions 2014-12-05 20:51:08 +00:00
Ben S
34bbe47973 Turns out numbers are valid identifier components 2014-12-05 20:08:26 +00:00
Ben S
69e12ea420 Subtly change the way 'use' lines are highlighted 2014-12-05 20:07:08 +00:00
Ben S
92862fc0a3 Merge pull request #1 from crdx/trailing-spaces
remove trailing spaces
2014-11-29 16:45:23 +00:00
Sean S
dbb13d4816 remove trailing spaces 2014-11-29 16:43:56 +00:00
Ben S
38deac77fe oops 2014-11-28 23:38:42 +00:00
Ben S
affebcf878 Bump release link 2014-11-28 23:38:30 +00:00
Ben S
55bbe945ae And add the screenshot to the readme! 2014-11-28 23:18:16 +00:00
Ben S
3b76b3429f Add a screenshot 2014-11-28 23:16:22 +00:00
5 changed files with 672 additions and 299 deletions

View File

@@ -1,21 +1,24 @@
BBEdit language module for Rust
===============================
!["A screenshot of the language module"](https://raw.githubusercontent.com/ogham/Rust.bblm/master/screenshot.png)
This is a BBEdit 11 Language Module for [Rust](http://www.rust-lang.org). It provides the following features:
- Complete syntax highlighting
- Special support for lifetimes, attributes, and identifiers
- Customisable colours using the [BBEdit 11 colour thing](http://barebones.com/products/bbedit/bbedit11.html)
- Customisable colours using the [BBEdit 11 colour editor](http://barebones.com/products/bbedit/bbedit11.html)
- Language features
- Go to start of/end of/previous/next function
- Go to named symbol
- Indexed function menu
- Code folding
By default, it highlights anything beginning with a capital letter in a certain colour. To turn this off, just change the Identifier colour to be the same as the default text colour in Preferences.
### Installation
The simplest way is to just [download the package](https://github.com/ogham/Rust.bblm/releases/tag/0.1) and put it in this folder:
The simplest way is to just [download the package](https://github.com/ogham/Rust.bblm/releases/tag/0.4.0) and put it in this folder:
~/Application Support/BBEdit/Language Modules
@@ -24,4 +27,3 @@ Then restart your BBEdit and it should be picked up.
### Compilation
To compile your own version, you'll need Xcode. The default schema outputs a `.bblm`. You'll also need the BBEdit SDK. The project assumes it's mounted under `/Volumes/BBEdit SDK`.

View File

@@ -2,166 +2,205 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>me.bsago.bblm.rust</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSignature</key>
<string>BBLM</string>
<key>CFBundleVersion</key>
<string>8.0</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>com.barebones.bblminfo</key>
<array>
<dict>
<key>BBLMCanGuessLanguage</key>
<true/>
<key>BBLMColorsSyntax</key>
<true/>
<key>BBLMDroppedFilePathStyle</key>
<string>POSIX</string>
<key>BBLMCommentLineDefault</key>
<string>// </string>
<key>BBLMCommentPrefixDefault</key>
<string>/* </string>
<key>BBLMCommentSuffixDefault</key>
<string> */</string>
<key>BBLMIsCaseSensitive</key>
<true/>
<key>BBLMRunNames</key>
<dict>
<key>me.bsago.bblm.rust.lifetime</key>
<string>&apos;lifetime</string>
<key>me.bsago.bblm.rust.identifier</key>
<string>Identifier</string>
<key>me.bsago.bblm.rust.attribute</key>
<string>#[attribute]</string>
<key>me.bsago.bblm.rust.function</key>
<string>fn functionname</string>
<key>me.bsago.bblm.rust.module</key>
<string>mod modulename</string>
</dict>
<key>BBLMRunColors</key>
<dict>
<key>me.bsago.bblm.rust.module</key>
<string>rgb(135, 2, 219)</string>
<key>me.bsago.bblm.rust.lifetime</key>
<string>rgb(133, 20, 75)</string>
<key>me.bsago.bblm.rust.attribute</key>
<string>rgb(177, 13, 201)</string>
<key>me.bsago.bblm.rust.identifier</key>
<string>rgb(61, 153, 112)</string>
<key>me.bsago.bblm.rust.function</key>
<string>rgb(219, 135, 2)</string>
</dict>
<key>BBLMKeywords</key>
<array>
<dict>
<key>RunKind</key>
<string>com.barebones.bblm.keyword</string>
<key>Keywords</key>
<array>
<string>as</string>
<string>box</string>
<string>break</string>
<string>const</string>
<string>continue</string>
<string>crate</string>
<string>else</string>
<string>enum</string>
<string>extern</string>
<string>false</string>
<string>fn</string>
<string>for</string>
<string>if</string>
<string>impl</string>
<string>in</string>
<string>let</string>
<string>loop</string>
<string>macro_rules!</string>
<string>match</string>
<string>mod</string>
<string>mut</string>
<string>priv</string>
<string>proc</string>
<string>pub</string>
<string>ref</string>
<string>return</string>
<string>self</string>
<string>static</string>
<string>struct</string>
<string>super</string>
<string>trait</string>
<string>true</string>
<string>type</string>
<string>unsafe</string>
<string>use</string>
<string>while</string>
</array>
</dict>
<dict>
<key>RunKind</key>
<string>com.barebones.bblm.predefined-symbol</string>
<key>Keywords</key>
<array>
<string>bool</string>
<string>char</string>
<string>f32</string>
<string>f64</string>
<string>float</string>
<string>i16</string>
<string>i32</string>
<string>i64</string>
<string>i8</string>
<string>int</string>
<string>str</string>
<string>u16</string>
<string>u32</string>
<string>u64</string>
<string>u8</string>
<string>uint</string>
</array>
</dict>
</array>
<key>BBLMLanguageCode</key>
<string>Rust</string>
<key>BBLMLanguageDisplayName</key>
<string>Rust</string>
<key>BBLMEntryPointName</key>
<string>rustMain</string>
<key>BBLMScansFunctions</key>
<true/>
<key>BBLMFunctionScannerDoesFoldsToo</key>
<false/>
<key>BBLMSuffixMap</key>
<array>
<dict>
<key>BBLMLanguageSuffix</key>
<string>.rs</string>
</dict>
</array>
<key>BBLMUseHTMLFileSearchRules</key>
<false/>
<key>BBLMSpellableRunKinds</key>
<array>
<string>com.barebones.bblm.line-comment</string>
<string>com.barebones.bblm.block-comment</string>
</array>
<key>BBLMNonSpellableRunKinds</key>
<array>
<string>com.barebones.bblm.code</string>
<string>com.barebones.bblm.double-string</string>
</array>
</dict>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>me.bsago.bblm.rust</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSignature</key>
<string>BBLM</string>
<key>CFBundleVersion</key>
<string>8.0</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>com.barebones.bblminfo</key>
<array>
<dict>
<key>BBLMCanGuessLanguage</key>
<true/>
<key>BBLMColorsSyntax</key>
<true/>
<key>BBLMDroppedFilePathStyle</key>
<string>POSIX</string>
<key>BBLMCommentLineDefault</key>
<string>// </string>
<key>BBLMCommentPrefixDefault</key>
<string>/* </string>
<key>BBLMCommentSuffixDefault</key>
<string> */</string>
<key>BBLMIsCaseSensitive</key>
<true/>
<key>BBLMRunNames</key>
<dict>
<key>me.bsago.bblm.rust.lifetime</key>
<string>&apos;lifetime</string>
<key>me.bsago.bblm.rust.identifier</key>
<string>Identifier</string>
<key>me.bsago.bblm.rust.function</key>
<string>fn functionname</string>
<key>me.bsago.bblm.rust.module</key>
<string>mod modulename</string>
</dict>
<key>BBLMRunColors</key>
<dict>
<key>me.bsago.bblm.rust.module</key>
<string>rgb(135, 2, 219)</string>
<key>me.bsago.bblm.rust.lifetime</key>
<string>rgb(133, 20, 75)</string>
<key>me.bsago.bblm.rust.identifier</key>
<string>rgb(61, 153, 112)</string>
<key>me.bsago.bblm.rust.function</key>
<string>rgb(219, 135, 2)</string>
</dict>
<key>BBLMKeywords</key>
<array>
<dict>
<key>RunKind</key>
<string>com.barebones.bblm.keyword</string>
<key>Keywords</key>
<array>
<string>abstract</string>
<string>alignof</string>
<string>as</string>
<string>become</string>
<string>box</string>
<string>break</string>
<string>const</string>
<string>continue</string>
<string>crate</string>
<string>do</string>
<string>else</string>
<string>enum</string>
<string>extern</string>
<string>false</string>
<string>final</string>
<string>fn</string>
<string>for</string>
<string>if</string>
<string>impl</string>
<string>in</string>
<string>let</string>
<string>loop</string>
<string>macro</string>
<string>macro_rules</string>
<string>match</string>
<string>mod</string>
<string>move</string>
<string>mut</string>
<string>offsetof</string>
<string>override</string>
<string>priv</string>
<string>proc</string>
<string>pub</string>
<string>pure</string>
<string>ref</string>
<string>return</string>
<string>self</string>
<string>sizeof</string>
<string>static</string>
<string>struct</string>
<string>super</string>
<string>trait</string>
<string>true</string>
<string>type</string>
<string>typeof</string>
<string>unsafe</string>
<string>unsized</string>
<string>use</string>
<string>virtual</string>
<string>where</string>
<string>while</string>
<string>yield</string>
</array>
</dict>
<dict>
<key>RunKind</key>
<string>com.barebones.bblm.predefined-symbol</string>
<key>Keywords</key>
<array>
<string>blkcnt_t</string>
<string>blksize_t</string>
<string>bool</string>
<string>c_char</string>
<string>c_double</string>
<string>c_float</string>
<string>c_int</string>
<string>c_long</string>
<string>c_schar</string>
<string>c_short</string>
<string>c_uchar</string>
<string>c_uint</string>
<string>c_ulong</string>
<string>c_ushort</string>
<string>char</string>
<string>clock_t</string>
<string>dev_t</string>
<string>f32</string>
<string>f64</string>
<string>float</string>
<string>gid_t</string>
<string>i16</string>
<string>i32</string>
<string>i64</string>
<string>i8</string>
<string>ino_t</string>
<string>isize</string>
<string>mode_t</string>
<string>nlink_t</string>
<string>off_t</string>
<string>pid_t</string>
<string>ptrdiff_t</string>
<string>size_t</string>
<string>str</string>
<string>suseconds_t</string>
<string>time_t</string>
<string>u16</string>
<string>u32</string>
<string>u64</string>
<string>u8</string>
<string>uid_t</string>
<string>usize</string>
<string>wchar_t</string>
</array>
</dict>
</array>
<key>BBLMLanguageCode</key>
<string>Rust</string>
<key>BBLMLanguageDisplayName</key>
<string>Rust</string>
<key>BBLMEntryPointName</key>
<string>rustMain</string>
<key>BBLMScansFunctions</key>
<true/>
<key>BBLMFunctionScannerDoesFoldsToo</key>
<true/>
<key>BBLMSuffixMap</key>
<array>
<dict>
<key>BBLMLanguageSuffix</key>
<string>.rs</string>
</dict>
</array>
<key>BBLMUseHTMLFileSearchRules</key>
<false/>
<key>BBLMSpellableRunKinds</key>
<array>
<string>com.barebones.bblm.line-comment</string>
<string>com.barebones.bblm.block-comment</string>
</array>
<key>BBLMNonSpellableRunKinds</key>
<array>
<string>com.barebones.bblm.code</string>
<string>com.barebones.bblm.double-string</string>
</array>
</dict>
</array>
</dict>
</plist>

471
rust.mm
View File

@@ -8,10 +8,9 @@
#include "BBLMInterface.h"
#include "BBLMTextIterator.h"
#define kMaxLineLength 256
#define kMaxLineLength 256
static NSString* const identifierColour = @"me.bsago.bblm.rust.identifier";
static NSString* const attributeColour = @"me.bsago.bblm.rust.attribute";
static NSString* const lifetimeColour = @"me.bsago.bblm.rust.lifetime";
static NSString* const functionColour = @"me.bsago.bblm.rust.function";
static NSString* const moduleColour = @"me.bsago.bblm.rust.module";
@@ -31,14 +30,56 @@ static bool addRun(NSString *kind, int start,int len , const BBLMCallbackBlock&
SInt32 skipString(BBLMTextIterator &iter)
{
SInt32 length = 1;
UniChar terminator = iter.GetNextChar();
UniChar ch;
if (iter.strcmp("\"", 1) == 0)
{
iter += 1;
}
else
{
return 0;
}
while ((ch = iter.GetNextChar()))
{
length++;
if (ch == '"')
{
break;
}
if (ch == '\\')
{
iter++;
length++;
}
}
return length;
}
SInt32 skipRawString(BBLMTextIterator &iter)
{
SInt32 length = 4;
UniChar ch;
if (iter.strcmp("r##\"", 4) == 0)
{
iter += 4;
}
else
{
return 0;
}
while ((ch = iter.GetNextChar()))
{
length++;
if (ch == terminator)
if (iter.strcmp("\"##", 3) == 0)
{
length += 3;
iter += 3;
break;
}
@@ -56,7 +97,7 @@ SInt32 skipLineComment(BBLMTextIterator &iter)
{
SInt32 length = 2;
UniChar ch;
iter += 2;
while ((ch = iter.GetNextChar()))
{
@@ -70,7 +111,7 @@ SInt32 skipLineComment(BBLMTextIterator &iter)
length++;
}
}
return length;
}
@@ -84,10 +125,10 @@ SInt32 skipBlockComment(BBLMTextIterator &iter)
iter++;
length++;
}
iter += 2;
length += 2;
return length;
}
@@ -95,7 +136,7 @@ SInt32 skipWhitespace(BBLMTextIterator &iter)
{
SInt32 length = 0;
UniChar ch;
while ((ch = iter.GetNextChar()))
{
if (isspace(ch))
@@ -108,7 +149,7 @@ SInt32 skipWhitespace(BBLMTextIterator &iter)
break;
}
}
return length;
}
@@ -116,10 +157,10 @@ SInt32 skipWord(BBLMTextIterator &iter)
{
SInt32 length = 0;
UniChar ch;
while ((ch = iter.GetNextChar()))
{
if (isalpha(ch) || ch == '_')
if (isalpha(ch) || ch == '_' || (length > 0 && isdigit(ch)))
{
length++;
}
@@ -129,49 +170,52 @@ SInt32 skipWord(BBLMTextIterator &iter)
break;
}
}
return length;
}
SInt32 skipAttribute(BBLMTextIterator &iter)
{
SInt32 length = 1;
UniChar ch;
iter++;
while ((ch = iter.GetNextChar()))
{
if (ch == '\n' || ch == '\r')
{
break;
}
else
{
length++;
}
}
return length;
}
SInt32 skipUse(BBLMTextIterator &iter)
{
SInt32 length = 0;
UniChar ch;
if (iter.strcmp("#[", 2) == 0)
{
length += 2;
iter += 2;
}
else if (iter.strcmp("#![", 3) == 0)
{
length += 3;
iter += 3;
}
else if (iter.strcmp("#", 1) == 0)
{
iter++;
return 1;
}
else
{
return 0;
}
while ((ch = iter.GetNextChar()))
{
if (islower(ch) || ch == ':' || ch == '_' || (length > 0 && isdigit(ch)))
if (ch == ']')
{
length++;
break;
}
else if (ch == '\n' || ch == '\r')
{
break;
}
else
{
iter--;
break;
length++;
}
}
return length;
}
@@ -181,7 +225,7 @@ SInt32 skipNumber(BBLMTextIterator &iter)
UniChar ch = iter.GetNextChar();
bool hasSuffix = false;
int base = 10;
if (ch == '0')
{
ch = iter.GetNextChar();
@@ -210,29 +254,38 @@ SInt32 skipNumber(BBLMTextIterator &iter)
{
iter--;
}
while ((ch = iter.GetNextChar()))
{
if ((base == 10) && (isdigit(ch) || ((ch == '_' || ch == '.') && length > 0)))
{
length++;
}
else if ((base == 2) && (ch == '0' || ch == '1'))
else if ((base == 2) && (ch == '0' || ch == '1' || ((ch == '_' || ch == '.') && length > 0)))
{
length++;
}
else if ((base == 8) && (ch >= '0' && ch <= '7'))
else if ((base == 8) && ((ch >= '0' && ch <= '7') || ((ch == '_' || ch == '.') && length > 0)))
{
length++;
}
else if ((base == 16) && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') || isdigit(ch)))
else if ((base == 16) && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') || isdigit(ch) || ((ch == '_' || ch == '.') && length > 0)))
{
length++;
}
else if (ch == 'f' || ch == 'u' || ch == 'i')
{
hasSuffix = true;
length++;
if (ch != 'f' && iter.strcmp("s", 1) == 0)
{
// Parse 'us' or 'is' machine-dependent suffixes
length++;
}
else
{
// Otherwise, allow for numbers at the end
hasSuffix = true;
}
break;
}
else
@@ -241,7 +294,7 @@ SInt32 skipNumber(BBLMTextIterator &iter)
break;
}
}
if (hasSuffix)
{
if (iter.strcmp("8", 1) == 0)
@@ -255,7 +308,7 @@ SInt32 skipNumber(BBLMTextIterator &iter)
length += 2;
}
}
return length;
}
@@ -264,11 +317,11 @@ SInt32 skipToEndOfFunction(BBLMTextIterator &iter)
SInt32 length = 0;
UniChar ch;
int braceLevel = 0, parenLevel = 0, bracketLevel = 0;
while ((ch = iter.GetNextChar()))
{
length++;
switch (ch) {
case '/':
ch = iter.GetNextChar();
@@ -287,34 +340,42 @@ SInt32 skipToEndOfFunction(BBLMTextIterator &iter)
iter--;
}
break;
case '{':
braceLevel++;
break;
case '}':
braceLevel--;
if (braceLevel < 1) return length;
break;
case ';':
// If the definition just ends with a semicolon, then it's
// either a function in a trait definition, or a C function
// definition in an extern, neither of which we want in the
// function list.
if (braceLevel < 1) return 0;
break;
case '(':
parenLevel++;
break;
case ')':
parenLevel--;
break;
case '[':
bracketLevel++;
break;
case ']':
bracketLevel--;
break;
}
}
return length;
}
@@ -325,56 +386,107 @@ SInt32 scanForSymbol(BBLMTextIterator &iter,
BBLMParamBlock &params,
const BBLMCallbackBlock *callbacks)
{
SInt32 whitespaceLen, wordLen;
SInt32 whitespaceLen, wordLen = 0, parametersLen = 0;
UniChar ch;
int keywordLen = strlen(keyword);
if (iter.strcmp(keyword, keywordLen) == 0)
{
iter += keywordLen;
if ((whitespaceLen = skipWhitespace(iter)))
{
if ((wordLen = skipWord(iter)))
{
UInt32 funLen = skipToEndOfFunction(iter);
UInt32 tokenOffset, funIndex;
UInt32 nameLen;
BBLMProcInfo info;
iter -= (wordLen + funLen);
nameLen = keywordLen + whitespaceLen + wordLen;
iter -= (keywordLen + whitespaceLen);
bblmAddTokenToBuffer(callbacks, params.fFcnParams.fTokenBuffer, iter.Address(),
nameLen, &tokenOffset);
iter += (nameLen - wordLen);
// Check for end of word, so 'enum' doesn't also match 'enumerate'.
// But also check for '<', so 'impl<'a>' is a legit statement, even with no whitespace.
whitespaceLen = skipWhitespace(iter);
if (whitespaceLen == 0 && iter.strcmp("<", 1) != 0)
{
iter -= keywordLen + whitespaceLen;
return 0;
}
SInt32 start_of_name = iter.Offset();
SInt32 start_of_function;
while ((ch = iter.GetNextChar()))
{
if (ch == '{' || ch == ';')
{
iter--;
start_of_function = iter.Offset();
break;
}
else if (ch == '(')
{
while ((ch = iter.GetNextChar()))
{
whitespaceLen++;
if (ch == '{' || ch == ';')
{
break;
}
}
iter -= (keywordLen + whitespaceLen);
info.fFirstChar = info.fFunctionStart = iter.Offset();
info.fSelStart = iter.Offset() + keywordLen + whitespaceLen;
info.fSelEnd = info.fSelStart + wordLen;
info.fFunctionEnd = info.fSelEnd + funLen;
info.fIndentLevel = indentLevel;
info.fKind = typeIfSo;
info.fFlags = 0;
info.fNameStart = tokenOffset;
info.fNameLength = nameLen;
bblmAddFunctionToList(callbacks, params.fFcnParams.fFcnList, info, &funIndex);
iter += (keywordLen + whitespaceLen);
return info.fFunctionEnd;
iter--;
start_of_function = iter.Offset();
break;
}
else if (ch == '\n')
{
start_of_function = iter.Offset();
break;
}
else if (ch)
{
whitespaceLen++;
}
else
{
iter -= (whitespaceLen + keywordLen);
return 0;
}
}
else
UInt32 funLen = skipToEndOfFunction(iter);
// Skip over trait method definitions and extern functions
if (funLen == 0)
{
iter -= keywordLen;
return 0;
}
UInt32 tokenOffset, funIndex;
UInt32 nameLen;
iter -= (wordLen + funLen);
iter -= (keywordLen + whitespaceLen);
nameLen = keywordLen + whitespaceLen + wordLen;
bblmAddTokenToBuffer(callbacks, params.fFcnParams.fTokenBuffer, iter.Address(),
nameLen, &tokenOffset);
iter += (nameLen - wordLen);
iter -= (keywordLen + whitespaceLen);
BBLMProcInfo info;
info.fFirstChar = info.fFunctionStart = iter.Offset();
info.fSelStart = iter.Offset() + keywordLen + whitespaceLen;
info.fSelEnd = info.fSelStart + wordLen;
info.fFunctionStart = start_of_function;
info.fFunctionEnd = info.fSelEnd + funLen;
info.fIndentLevel = indentLevel;
info.fKind = typeIfSo;
info.fFlags = 0;
info.fNameStart = tokenOffset;
info.fNameLength = nameLen;
bblmAddFunctionToList(callbacks, params.fFcnParams.fFcnList, info, &funIndex);
// But still allow the user to fold them
// (the length changes here are to cut off the opening { and closing } from the fold range
bblmAddFoldRange(callbacks, start_of_function + 1, funLen - 2, kBBLMFunctionAutoFold);
iter += (keywordLen + whitespaceLen);
return info.fFunctionEnd;
}
return 0;
}
@@ -384,24 +496,24 @@ static OSErr scanForFunctions(BBLMParamBlock &params, const BBLMCallbackBlock *c
UniChar ch;
std::stack<int> indents;
SInt32 funEnd;
while ((ch = iter.GetNextChar()))
{
while (!indents.empty() && iter.Offset() >= indents.top())
{
indents.pop();
}
const char* symbolToScanFor = NULL;
int typeIfSo;
switch (ch)
{
case '"':
iter--;
skipString(iter);
break;
case '/':
ch = iter.GetNextChar();
if (ch == '/')
@@ -419,38 +531,38 @@ static OSErr scanForFunctions(BBLMParamBlock &params, const BBLMCallbackBlock *c
iter--;
}
break;
case 'e':
symbolToScanFor = "enum";
typeIfSo = kBBLMFunctionMark;
break;
case 'f':
symbolToScanFor = "fn";
typeIfSo = kBBLMFunctionMark;
break;
case 'i':
symbolToScanFor = "impl";
typeIfSo = kBBLMTypedef;
break;
case 'm':
symbolToScanFor = "mod";
typeIfSo = kBBLMFunctionMark;
break;
case 's':
symbolToScanFor = "struct";
typeIfSo = kBBLMFunctionMark;
break;
case 't':
symbolToScanFor = "trait";
typeIfSo = kBBLMFunctionMark;
break;
}
if (symbolToScanFor != NULL)
{
iter--;
@@ -464,7 +576,7 @@ static OSErr scanForFunctions(BBLMParamBlock &params, const BBLMCallbackBlock *c
}
}
}
return noErr;
}
@@ -487,12 +599,25 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
BBLMTextIterator iter(params, 0);
SInt32 runStart = iter.Offset();
SInt32 runLen;
UniChar ch;
bool wordchr = false;
while ((ch = iter.GetNextChar()))
{
if (ch == '"')
if (ch == 'r' && iter.CharsLeft() >= 3 && iter.strcmp("##\"", 3) == 0)
{
iter--;
if (!makeCodeRun(iter, runStart, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = skipRawString(iter);
// Use the heredoc colour to highlight raw strings.
// It's not exactly a heredoc, but it's the closest!
if (!addRun(kBBLMHereDocStringRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
else if (ch == '"')
{
iter--;
if (!makeCodeRun(iter, runStart, *callbacks)) return noErr;
@@ -501,7 +626,7 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
if (!addRun(kBBLMDoubleQuotedStringRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
// Have to distinguish the following things:
// 'a' (character)
// '\a' (escaped character)
@@ -556,7 +681,7 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
}
}
}
else if (!wordchr && ch == 'm')
{
ch = iter.GetNextChar();
@@ -585,12 +710,30 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
iter--;
}
}
else if (ch == 'a' && iter.CharsLeft() >= 10 && iter.strcmp("cro_rules!", 10) == 0)
{
iter += 10;
ch = iter.GetNextChar();
if (isspace(ch))
{
if (!makeCodeRun(iter, runStart, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = skipWhitespace(iter);
runLen += skipWord(iter);
if (!addRun(functionColour, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
else if (ch)
{
iter--;
}
}
else if (ch)
{
iter--;
}
}
else if (!wordchr && ch == 'f')
{
ch = iter.GetNextChar();
@@ -616,7 +759,7 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
iter--;
}
}
else if (!wordchr && ch == 'u')
{
ch = iter.GetNextChar();
@@ -628,17 +771,64 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
ch = iter.GetNextChar();
if (isspace(ch))
{
skipWhitespace(iter);
if (!makeCodeRun(iter, runStart, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = skipWhitespace(iter);
runLen += skipUse(iter);
runLen = 0;
bool spacey = false;
while ((ch = iter.GetNextChar()))
{
if (spacey && isupper(ch))
{
iter--;
if (!addRun(kBBLMFileIncludeRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = skipWord(iter);
if (!addRun(identifierColour, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = 0;
}
else if (ch == ';' || ch == '\n')
{
iter--;
if (!addRun(kBBLMFileIncludeRunKind, runStart, runLen, *callbacks)) return noErr;
break;
}
else if (ch)
{
spacey = isspace(ch) || ch == ':' || ch == '{';
runLen++;
}
else
{
break;
}
if (iter.strcmp(" as ", 4) == 0)
{
if (!addRun(kBBLMFileIncludeRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
iter += 4;
if (!addRun(kBBLMCodeRunKind, runStart, 4, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = skipWord(iter);
if (!addRun(moduleColour, runStart, runLen, *callbacks)) return noErr;
iter++;
runLen = 0;
break;
}
}
if (!addRun(kBBLMFileIncludeRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = skipWord(iter);
if (!addRun(identifierColour, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
else if (ch)
{
@@ -655,7 +845,7 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
iter--;
}
}
else if (ch == '/')
{
ch = iter.GetNextChar();
@@ -682,17 +872,28 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
iter--;
}
}
else if (ch == '#')
{
iter--;
if (!makeCodeRun(iter, runStart, *callbacks)) return noErr;
runStart = iter.Offset();
runLen = skipAttribute(iter);
if (!addRun(attributeColour, runStart, runLen, *callbacks)) return noErr;
if (!addRun(kBBLMPreprocessorRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
else if (ch == '$')
{
iter--;
if (!makeCodeRun(iter, runStart, *callbacks)) return noErr;
runStart = iter.Offset();
iter++;
runLen = skipWord(iter) + 1;
if (runLen > 1 && !addRun(kBBLMVariableRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
else if (!wordchr && isupper(ch))
{
iter--;
@@ -702,7 +903,7 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
if (!addRun(identifierColour, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
else if (!wordchr && (ch == '+' || ch == '-'))
{
ch = iter.GetNextChar();
@@ -721,7 +922,7 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
iter--;
}
}
else if (!wordchr && isdigit(ch))
{
iter--;
@@ -731,10 +932,10 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
if (!addRun(kBBLMNumberRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
wordchr = isalpha(ch) || isdigit(ch);
wordchr = isalpha(ch) || isdigit(ch) || ch == '_';
}
makeCodeRun(iter, runStart, *callbacks);
return noErr;
}
@@ -756,12 +957,12 @@ OSErr adjustRange(BBLMParamBlock &params, const BBLMCallbackBlock &callbacks)
SInt32 charPos;
SInt32 length;
UInt32 index = params.fAdjustRangeParams.fStartIndex;
while (index > 0 && bblmGetRun(&callbacks, index, language, kind, charPos, length)/* && isSpecialKind(kind)*/)
{
index--;
}
params.fAdjustRangeParams.fStartIndex = index;
return noErr;
}
@@ -769,12 +970,12 @@ OSErr adjustRange(BBLMParamBlock &params, const BBLMCallbackBlock &callbacks)
OSErr guessLanguage(BBLMParamBlock &params)
{
BBLMTextIterator iter(params);
if (iter.strcmp("use ", 4) == 0 || iter.strcmp("#![crate_id", 11) == 0)
{
params.fGuessLanguageParams.fGuessResult = kBBLMGuessDefiniteYes;
}
return noErr;
}
@@ -787,29 +988,29 @@ extern "C"
{
// Dispatch message.
OSErr result = noErr;
switch (params.fMessage)
{
case kBBLMDisposeMessage:
case kBBLMSetCategoriesMessage:
// Message understood, but no action required.
break;
case kBBLMInitMessage:
break;
case kBBLMScanForFunctionsMessage:
result = scanForFunctions(params, &bblmCallbacks);
break;
case kBBLMCalculateRunsMessage:
result = calculateRuns(params, &bblmCallbacks);
break;
case kBBLMGuessLanguageMessage:
result = guessLanguage(params);
break;
case kBBLMAdjustRangeMessage:
result = adjustRange(params, bblmCallbacks);
break;
@@ -817,7 +1018,7 @@ extern "C"
default:
result = paramErr;
}
return result;
}
}
}

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

131
smoke.rs Normal file
View File

@@ -0,0 +1,131 @@
// Keywords
// --------
abstract, alignof, as, become, box, break, const, continue, crate, do, else, enum,
extern, false, final, fn, for, if, impl, in, let, loop, macro, match, mod, move, mut,
offsetof, override, priv, pub, pure, ref, return, sizeof, static, self, struct, super,
true, trait, type, typeof, unsafe, unsized, use, virtual, where, while, yield.
// Types
// -----
- ()
- bool, char, str
- u8, u16, u32, u64
- i8, i16, i32, i64
- f32, f64
- usize, isize
- int, uint // these are no longer valid!
// Comments
// --------
// This is a comment
/* So is this */
/// This is a doc comment
/** So is this */
// Characters and Lifetimes
// ------------------------
'a' // a character
'a // a lifetime
'static // also a lifetime
b'a' // a byte
' ' // this is also a character (space)
'\t' // characters can be escaped
'\'' // including the quote character itself!
"geese" // a string
r##"geese"## // a raw string. This part should not be highlighted!
b"geese" // a byte string
br##"geese"## // a raw byte string. This part should still not be highlighted
"there's a \" in this string" // be sure to handle escapes
"\"geese\"" // including at the edges
r##"there's a " in this string"## // the string shouldn't end until ##
r##"there's a # in this string"## // even if there's a # in the middle
// " // in case the above failed :)
// Decimal Numbers
// ---------------
7, 12, 1048576 // are all numbers
1_000_000 // is a number with underscore separators
_, _1000, 1000_ // beware of sole/leading/trailing underscores
// Hex Numbers
// -----------
0xff // hex numbers start with 0x
0xFF // and can be in lowercase or uppercase
0x0123_4567 // and can have separators
// Octal Numbers
// -------------
0o77 // octal numbers start with 0o
0o12345678909 // and should finish after an 8 or 9
// Binary Numbers
// --------------
0b0000_1111 // binary numbers start with 0b
0b01234311 // and should finish after a 2 or higher
// Floating-Point Numbers
// ----------------------
6.022E-23 // floating point notation
5.974e24 // lowercase e
7.348e+22 // uppercase E and plus
let tuple = ((8, 4), 48);
let a = tuple.0.0;
// Numeric Suffixes
// ----------------
123i32, 123u32 // numbers can have literals
123_u32, 0xff_u8
0o70_i16, 0b1111_1111_1001_0000_i32
0us, 7is
123.0f64
0.1f64
0.1f32
12E+99_f64
2.f64 // Invalid!
// Attributes
// ----------
#[attribute]
#[derive(This, That, Other)]
#![top_level_attribute]
#not_an_attribute
#[macro_use] use this_is_not_an_attribute;
// Macros
// ------
macro_rules! parse {
($thing: expr) => { $thing };
}
// `use` statements
// ----------------
use flux;
use flux::capacitor;
use flux::capacitor::Component::*;
use flux::capacitor::Component::{ImpurePalladium, ThinkingAluminium, TimeyWimeyDevice};
use flux::capacitor as cap;
use super;
use self;