29 Commits

Author SHA1 Message Date
Benjamin Sago
a1f5dad700 Readme updates
- Link to the new Wiki pages
- Rewrite compilation notes
- Offer to download the zip instead of going through the whole git process
2015-12-08 19:34:24 +00:00
Ben S
43eee05c44 Add very basic rustfmt Text Filter 2015-12-08 07:29:33 +00:00
Ben S
86c005e015 Add some Terminal+Cargo AppleScripts 2015-12-08 07:29:07 +00:00
Ben S
2defa5f908 Move Generate Implementation script into a folder 2015-12-08 07:28:44 +00:00
Ben S
75ef4092ec Add doc-splitter to the helper toolbox
This helper tool uses BBEdit's Preview Windows to preview Markdown syntax in your rustdocs. It has the following components:

- A binary Preview Filter
- The source for the filter, written in Rust, as a binary in the toolbox
- The Preview CSS that uses the classes outputted by the filter
2015-12-08 07:11:29 +00:00
Ben S
9e44cd4eb8 Rename impl-generator-bin to impl-generator
This will start transitioning the impl generator to be a more generic helper tool, with the impl generator as one of its component.

Also, drop the "-bin" from the name, because what else is it going to be?
2015-12-07 23:52:14 +00:00
Ben S
cf99295fa1 Cargo.toml clippings 2015-12-07 22:14:51 +00:00
Ben S
8b4069c4a6 TOML improvements
- Now it properly handles strings and numbers (without underscores) and dates and comments
- Sections are now in the function dropdown thing in the navigation bar
- Whitespace!
2015-12-07 22:14:30 +00:00
Ben S
eb478ce254 Clean up the plist, and add search URL template
- Add whitespace to make it readable
- Add BBLMIsSourceKind and BBLMIsHeaderKind to the BBLMSuffixMap, which I don't think actually do anything but they're there now
- Add BBLMReferenceSearchURLTemplate to search the libstd docs
2015-12-07 16:26:37 +00:00
Ben S
3fe8f93cec Update the screenshots (about time!) 2015-11-23 19:02:37 +00:00
Ben S
8ee5fa4793 Add a bunch more Clippings 2015-11-23 18:24:46 +00:00
Ben S
dea280c188 Update the binary and Xcode stuffs 2015-11-23 18:23:05 +00:00
Ben S
85a4eb2830 Be a bit more pragmatic with language guessing 2015-11-23 13:32:57 +00:00
Ben S
487b87d13a Avoid highlighting tuple indexes as numbers 2015-11-23 13:30:03 +00:00
Ben S
012448ebe8 Fix bug in attribute value highlighting
Any newlines within strings are now properly catered for.

Fixes #3.
2015-11-23 12:56:37 +00:00
Ben S
2c27300233 Clippings for regexen 2015-10-01 00:48:08 +01:00
Ben S
7fe432c069 Cargo.lock is TOML, too 2015-09-23 21:07:35 +01:00
Ben S
4e6a94bcef Add Toml CLM! 2015-09-09 15:10:12 +01:00
Ben S
4ee8768ce3 Add macro_rules! clipping 2015-08-01 22:17:15 +01:00
Ben S
77b2980f41 'us' and 'is' -> 'usize' and 'isize' 2015-08-01 22:17:07 +01:00
Ben S
11aa41ff48 Fix all the std::fmt function signatures 2015-07-24 18:20:42 +01:00
Ben S
53cf427f4f Macro variables shouldn't use spaces like this 2015-07-22 21:23:19 +01:00
Benjamin Sago
0ec4a6ccd1 Add std::iter traits 2015-07-19 19:50:42 +01:00
Benjamin Sago
19aecb6e55 impl-generator documentation. 2015-07-19 18:58:36 +01:00
Benjamin Sago
f53dfbc9fc Fix regex and add tests
The previous regex failed against Test 5 (generic_generics).
2015-07-19 17:23:38 +01:00
Ben S
55bb739dbe Add impl-generator script! 2015-07-15 16:56:41 +01:00
Ben S
eb06c53efc Add a bunch of clippings! 2015-07-15 15:14:26 +01:00
Ben S
d8fd3d0bd1 Update installation instructions 2015-07-15 14:23:02 +01:00
Ben S
2e92e9cd82 Start including a compiled version in the repo
This makes it possible for users to upgrade with a simple `git pull`,
rather than having to re-download the latest release from GitHub each
time - after checking that there is one, first!

It also converts it from just a `.bblm` file to an entire `.bbprojectd`
file, allowing me to add things like Clippings and Text Filters in the
future. (Planned!)
2015-07-15 14:14:53 +01:00
53 changed files with 1459 additions and 39 deletions

4
.gitignore vendored
View File

@@ -3,6 +3,10 @@ build/*
*.pbxuser
xcuserdata
*.mode1v3
xcshareddata
# cargo noise
target
# osx noise
.DS_Store

View File

@@ -0,0 +1,2 @@
[dependencies.#PLACEHOLDERSTART#...#PLACEHOLDEREND#]
version = "#PLACEHOLDERSTART#...#PLACEHOLDEREND#"

View File

@@ -0,0 +1,2 @@
[dependencies.#PLACEHOLDERSTART#...#PLACEHOLDEREND#]
git = "#PLACEHOLDERSTART#...#PLACEHOLDEREND#"

View File

@@ -0,0 +1,2 @@
[dependencies.#PLACEHOLDERSTART#...#PLACEHOLDEREND#]
path = "#PLACEHOLDERSTART#...#PLACEHOLDEREND#"

View File

@@ -0,0 +1,7 @@
[profile.bench]
opt-level = 3
debug = false
rpath = false
lto = false
debug-assertions = false
codegen-units = 1

View File

@@ -0,0 +1,7 @@
[profile.dev]
opt-level = 0
debug = true
rpath = false
lto = false
debug-assertions = true
codegen-units = 1

View File

@@ -0,0 +1,7 @@
[profile.doc]
opt-level = 0
debug = true
rpath = false
lto = false
debug-assertions = true
codegen-units = 1

View File

@@ -0,0 +1,7 @@
[profile.release]
opt-level = 3
debug = false
rpath = false
lto = false
debug-assertions = false
codegen-units = 1

View File

@@ -0,0 +1,7 @@
[profile.test]
opt-level = 0
debug = true
rpath = false
lto = false
debug-assertions = true
codegen-units = 1

View File

@@ -0,0 +1,3 @@
#INDENT#static ref #PLACEHOLDERSTART#...#PLACEHOLDEREND#: Regex = Regex::new(r##"(?x)
#PLACEHOLDERSTART#...#PLACEHOLDEREND#
"##).unwrap();

View File

@@ -0,0 +1,3 @@
#INDENT#static ref #PLACEHOLDERSTART#...#PLACEHOLDEREND#: Regex = Regex::new(r##"(?x) ^
#PLACEHOLDERSTART#...#PLACEHOLDEREND#
$ "##).unwrap();

View File

@@ -0,0 +1 @@
#[derive(#placeholderstart#...#placeholderend#)]

View File

@@ -0,0 +1,3 @@
#indent#fn main() {
#placeholderstart#...#placeholderend#
}

View File

@@ -0,0 +1 @@
static #PLACEHOLDERSTART#NAME#PLACEHOLDEREND#: &'static str = "#PLACEHOLDERSTART#...#PLACEHOLDEREND#";

View File

@@ -0,0 +1,3 @@
#INDENT#static #PLACEHOLDERSTART#NAME#PLACEHOLDEREND#: &'static [&'static str] = &[
#PLACEHOLDERSTART#...#PLACEHOLDEREND#
];

View File

@@ -0,0 +1,4 @@
\#[test]
#indent#fn #placeholderstart#test#placeholderend#() {
#placeholderstart#...#placeholderend#
}

View File

@@ -0,0 +1,8 @@
#indent#macro_rules! #placeholderstart#name#placeholderend# {
($name:ident: $input:expr => $result:expr) => {
\#[test]
fn $name() {
assert_eq!($input, $result);
}
};
}

View File

@@ -0,0 +1,9 @@
#indent#\#[cfg(test)]
mod test {
use super::*;
\#[test]
fn #placeholderstart#test#placeholderend#() {
#placeholderstart#...#placeholderend#
}
}

View File

@@ -0,0 +1,3 @@
//! ```
//! #placeholderstart##placeholderend#
//! ```

View File

@@ -0,0 +1,5 @@
#INDENT#/// ### Examples
///
/// ```
/// #PLACEHOLDERSTART#...#PLACEHOLDEREND#
/// ```

View File

@@ -0,0 +1,3 @@
#INDENT#/// ### Panics
///
/// #PLACEHOLDERSTART#...#PLACEHOLDEREND#

View File

@@ -0,0 +1,3 @@
#indent#if let Some(#placeholderstart#variable#placeholderend#) = #placeholderstart#...#placeholderend# {
#placeholderstart#...#placeholderend#
}

View File

@@ -0,0 +1,4 @@
#indent#match #placeholderstart#...#placeholderend# {
Some(#placeholderstart#...#placeholderend#) => #placeholderstart#...#placeholderend#,
None => #placeholderstart#...#placeholderend#,
}

View File

@@ -0,0 +1,4 @@
#indent#match #placeholderstart#...#placeholderend# {
Ok(#placeholderstart#...#placeholderend#) => #placeholderstart#...#placeholderend#,
Err(#placeholderstart#...#placeholderend#) => #placeholderstart#...#placeholderend#,
}

View File

@@ -0,0 +1,7 @@
#INDENT#let mut f = try!(File::open("log.txt"));
let mut reader = BufReader::new(f);
for line in reader.lines() {
let line = line.unwrap();
#PLACEHOLDERSTART#...#PLACEHOLDEREND#
}

View File

@@ -0,0 +1,6 @@
#INDENT#let stdin = io::stdin();
for line in stdin.lock().lines() {
let line = line.unwrap();
#PLACEHOLDERSTART#...#PLACEHOLDEREND#
}

View File

@@ -0,0 +1,5 @@
#INDENT#macro_rules! #PLACEHOLDERSTART#...#PLACEHOLDEREND# {
(#PLACEHOLDERSTART#...#PLACEHOLDEREND#) => {
#PLACEHOLDERSTART#...#PLACEHOLDEREND#
}
}

View File

@@ -0,0 +1 @@
println!("#PLACEHOLDERSTART#...#PLACEHOLDEREND#");

View File

@@ -0,0 +1 @@
println!("{:?}", #placeholderstart#...#placeholderend#);

View File

@@ -0,0 +1 @@
unimplemented!()

View File

@@ -0,0 +1 @@
unreachable!()

View File

@@ -0,0 +1,277 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>15B42</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Rust</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>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>8.0</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>7B91b</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>15A278</string>
<key>DTSDKName</key>
<string>macosx10.11</string>
<key>DTXcode</key>
<string>0710</string>
<key>DTXcodeBuild</key>
<string>7B91b</string>
<key>com.barebones.bblminfo</key>
<array>
<dict>
<key>BBLMCanGuessLanguage</key>
<true/>
<key>BBLMColorsSyntax</key>
<true/>
<key>BBLMCommentLineDefault</key>
<string>// </string>
<key>BBLMCommentPrefixDefault</key>
<string>/* </string>
<key>BBLMCommentSuffixDefault</key>
<string> */</string>
<key>BBLMDroppedFilePathStyle</key>
<string>POSIX</string>
<key>BBLMEntryPointName</key>
<string>rustMain</string>
<key>BBLMFunctionScannerDoesFoldsToo</key>
<true/>
<key>BBLMIsCaseSensitive</key>
<true/>
<key>BBLMKeywords</key>
<array>
<dict>
<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>
<key>RunKind</key>
<string>com.barebones.bblm.keyword</string>
</dict>
<dict>
<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>
<key>RunKind</key>
<string>com.barebones.bblm.predefined-symbol</string>
</dict>
</array>
<key>BBLMLanguageCode</key>
<string>Rust</string>
<key>BBLMLanguageDisplayName</key>
<string>Rust</string>
<key>BBLMNonSpellableRunKinds</key>
<array>
<string>com.barebones.bblm.code</string>
<string>com.barebones.bblm.double-string</string>
</array>
<key>BBLMRunColors</key>
<dict>
<key>me.bsago.bblm.rust.function</key>
<string>rgb(219, 135, 2)</string>
<key>me.bsago.bblm.rust.identifier</key>
<string>rgb(61, 153, 112)</string>
<key>me.bsago.bblm.rust.lifetime</key>
<string>rgb(133, 20, 75)</string>
<key>me.bsago.bblm.rust.module</key>
<string>rgb(135, 2, 219)</string>
</dict>
<key>BBLMRunNames</key>
<dict>
<key>me.bsago.bblm.rust.function</key>
<string>fn functionname</string>
<key>me.bsago.bblm.rust.identifier</key>
<string>Identifier</string>
<key>me.bsago.bblm.rust.lifetime</key>
<string>'lifetime</string>
<key>me.bsago.bblm.rust.module</key>
<string>mod modulename</string>
</dict>
<key>BBLMScansFunctions</key>
<true/>
<key>BBLMSpellableRunKinds</key>
<array>
<string>com.barebones.bblm.line-comment</string>
<string>com.barebones.bblm.block-comment</string>
</array>
<key>BBLMReferenceSearchURLTemplate</key>
<string>https://doc.rust-lang.org/std/?search=__SYMBOLNAME__</string>
<key>BBLMSuffixMap</key>
<array>
<dict>
<key>BBLMLanguageSuffix</key>
<string>.rs</string>
<key>BBLMIsSourceKind</key>
<true/>
<key>BBLMIsHeaderKind</key>
<false/>
</dict>
</array>
<key>BBLMUseHTMLFileSearchRules</key>
<false/>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BBEditDocumentType</key>
<string>CodelessLanguageModule</string>
<key>BBLMColorsSyntax</key>
<true/>
<key>BBLMIsCaseSensitive</key>
<true/>
<key>BBLMKeywords</key>
<array>
<dict>
<key>RunKind</key>
<string>com.barebones.bblm.predefined-symbol</string>
<key>Keywords</key>
<array>
<string>true</string>
<string>false</string>
</array>
</dict>
</array>
<key>BBLMKeywordPatterns</key>
<array>
<dict>
<key>RunKind</key>
<string>com.barebones.bblm.sgml-tag</string>
<key>Pattern</key>
<string>^\[.*\]$</string>
</dict>
</array>
<key>BBLMSuffixMap</key>
<array>
<dict>
<key>BBLMLanguageSuffix</key>
<string>.toml</string>
</dict>
<dict>
<key>BBLMLanguageSuffix</key>
<string>.lock</string>
</dict>
</array>
<key>BBLMLanguageCode</key>
<string>TOML</string>
<key>BBLMLanguageDisplayName</key>
<string>TOML</string>
<key>BBLMScansFunctions</key>
<true/>
<key>Language Features</key>
<dict>
<key>Close Strings 1</key>
<string>'</string>
<key>Close Strings 2</key>
<string>"</string>
<key>End-of-line Ends Strings 1</key>
<false/>
<key>End-of-line Ends Strings 2</key>
<false/>
<key>Escape Char in Strings 1</key>
<string>\</string>
<key>Escape Char in Strings 2</key>
<string>\</string>
<key>Identifier and Keyword Characters</key>
<string>0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-abcdefghijklmnopqrstuvwxyz[]</string>
<key>Open Line Comments</key>
<string>#</string>
<key>Open Parameter Lists</key>
<string>{</string>
<key>Open Statement Blocks</key>
<string>{</string>
<key>Open Strings 1</key>
<string>'</string>
<key>Open Strings 2</key>
<string>"</string>
<key>Comment Pattern</key>
<string><![CDATA[(?x:
(?> [\#] .* $ )
)]]></string>
<key>Skip Pattern</key>
<string><![CDATA[(?x:
(?>
(?P>comment) |
(?P>string)
)
)]]></string>
<key>String Pattern</key>
<string><![CDATA[(?x:
(?> """ (?s: \\. | [^"] )*? (?: """ ) ) |
(?> ''' (?s: . )*? (?: ''' ) ) |
(?> " (?s: \\. | [^"] )*? (?: " ) ) |
(?> ' (?s: [^'] )*? (?: ' ) ) |
(?>
\d{4} - \d{2} - \d{2}
(?: T
\d{2} : \d{2} : \d{2} (?: \. \d+ )?
(?: Z | ([+-]) \d{2} : \d{2} )?
)?
)
)]]></string>
<key>Function Pattern</key>
<string><![CDATA[(?x:
(?P<function>
\[
(?P<function_name>
(\[* [\w/._-]+ \]*)
)
\]
)
)]]></string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,72 @@
/*
* These styles are a poor imitation of the standard rustdoc styles. They should
* contain just enough to look more-or-less like rustdocs output, but large
* parts of the official stylesheet arent relevant, and Im not even sure if
* Im allowed to distribute its webfonts! So this will have to do.
*/
body {
padding: 0;
margin: 0;
font: 16px/1.4 Georgia; /* Georgia is like Source Serif Pro, right? */
}
.docs pre, .docs code, .docs span {
font-family: Monaco; /* Monaco is like Source Code Pro, right? */
font-size: 12px;
}
.docs {
padding: 20px 20px 10px 20px;
color: #333;
}
.docs.module {
background-color: #F7F3F7;
border-bottom: 1px solid #D8CAD8;
}
/*
* We want to keep the docs above a piece of code close to that code in the
* preview, as docs usually refer to the code below them.
*/
.code {
border-top: 1px solid #BDC3C7;
border-bottom: 1px solid #BDC3C7;
background-color: #ECF0F1;
font-size: 10px;
font-family: Monaco;
color: #666;
padding: 10px 20px;
margin: 0em;
}
p:last-child {
padding: 0;
margin: 0;
}
/*
* The headings have borders below them, just like rustdoc!
*/
h2 {
font-size: 1.4em;
}
h3 {
font-size: 1.3em;
}
h1, h2, h3 {
font-family: "Helvetica Neue"; /* Helvetica is like Fira Sans, right? */
border-bottom: 1px solid #ddd;
color: #000;
font-weight: 500;
margin: 20px 0 15px 0;
padding-bottom: 6px;
}

Binary file not shown.

BIN
Contents/Resources/impl-generator Executable file

Binary file not shown.

View File

@@ -0,0 +1,17 @@
tell application "BBEdit"
tell front text document
if modified = true then
save its document
end if
set the_file to its file
if the_file ­ missing value then
set the_path to POSIX path of ((the_file as text) & "::")
else
error "Document does not point to a file"
end if
end tell
end tell
tell application "Terminal"
do script "cd " & (quoted form of the_path) & "; cargo build"
end tell

View File

@@ -0,0 +1,17 @@
tell application "BBEdit"
tell front text document
if modified = true then
save its document
end if
set the_file to its file
if the_file ­ missing value then
set the_path to POSIX path of ((the_file as text) & "::")
else
error "Document does not point to a file"
end if
end tell
end tell
tell application "Terminal"
do script "cd " & (quoted form of the_path) & "; cargo doc --open"
end tell

View File

@@ -0,0 +1,17 @@
tell application "BBEdit"
tell front text document
if modified = true then
save its document
end if
set the_file to its file
if the_file ­ missing value then
set the_path to POSIX path of ((the_file as text) & "::")
else
error "Document does not point to a file"
end if
end tell
end tell
tell application "Terminal"
do script "cd " & (quoted form of the_path) & "; cargo test"
end tell

Binary file not shown.

2
Contents/Text Filters/rustfmt Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
rustfmt --write-mode=display

7
Makefile Normal file
View File

@@ -0,0 +1,7 @@
all:
xcodebuild -configuration Release
cp -r build/Release/Rust.bblm Contents/"Language Modules"
cd helper-tool; cargo build --release; cp target/release/impl-generator ../Contents/Resources/impl-generator; cp target/release/doc-splitter ../Contents/"Preview Filters"/"Rust Markdown"
clean:
rm -r build; cd helper-tool; cargo clean

View File

@@ -1,29 +1,47 @@
BBEdit language module for Rust
===============================
BBEdit Package for Rust
=======================
!["A screenshot of the language module"](https://raw.githubusercontent.com/ogham/Rust.bblm/master/screenshot.png)
!["Screenshots of the Rust BBEdit language module"](screenshots.png)
This is a BBEdit 11 Language Module for [Rust](http://www.rust-lang.org). It provides the following features:
This is a BBEdit 11 Package 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 editor](http://barebones.com/products/bbedit/bbedit11.html)
- Language features
- Go to start of/end of/previous/next function
- Go to named symbol
- Go to symbol
- [Find in Reference support](https://github.com/ogham/Rust-BBEdit/wiki/Find-in-Reference)
- Indexed function menu
- Code folding
- Integration and helpers
- [Rustdoc preview](https://github.com/ogham/Rust-BBEdit/wiki/Rustdoc-Preview) to check your docs Markdown syntax
- Clippings for common code patterns
- [Implementation generator](https://github.com/ogham/Rust-BBEdit/wiki/impl-Generator) for standard library traits
- [TOML support](https://github.com/ogham/Rust-BBEdit/wiki/TOML) for Cargo and suchlike
- [rustfmt support](https://github.com/ogham/Rust-BBEdit/wiki/rustfmt)
- [Cargo build scripts](https://github.com/ogham/Rust-BBEdit/wiki/Cargo)
See the Wiki pages for more information and screenshots.
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.4.0) and put it in this folder:
To install this package, simply clone the repo into BBEdits Packages folder:
~/Application Support/BBEdit/Language Modules
```bash
$ git clone https://github.com/ogham/Rust-BBEdit.git ~/Library/Application\ Support/BBEdit/Packages/Rust.bbpackage
```
Then restart your BBEdit and it should be picked up. Its necessary for the filename to end in `.bbpackage`.
Alternatively, just [download this .zip of the source](https://github.com/ogham/Rust-BBEdit/archive/master.zip) and extract it to that directory.
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`.
To compile your own version, youll need Xcode, Rust, and Cargo. The default schema outputs a `.bblm`, and comes with a Run build step so you can debug the module while BBEdit is running. Youll also need the [BBEdit SDK](http://www.barebones.com/support/develop/). The project assumes its mounted under `/Volumes/BBEdit SDK`.
Once youve got all that set up, simply run `make` and itll compile the language module and Rust helper tools for you.
Note that compiled versions of these tools already exist in the repository—you wont be generating anything that doesnt already exist!

View File

@@ -49,7 +49,6 @@
name = Rust;
productInstallPath = "$(HOME)/Library/Bundles";
productName = "Hello World";
productReference = B57F6C2519FD60C000FDB959 /* Rust.bblm */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
@@ -97,10 +96,11 @@
INFOPLIST_FILE = Info.plist;
INSTALL_MODE_FLAG = "ug+w,o-w,a+rX";
MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "";
PRODUCT_NAME = Rust;
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES;
SDKROOT = macosx10.10;
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "/Volumes/BBEdit\\ SDK/Interfaces/Language\\ Modules/";
WRAPPER_EXTENSION = bblm;
};
@@ -114,10 +114,11 @@
INFOPLIST_FILE = Info.plist;
INSTALL_MODE_FLAG = "ug+w,o-w,a+rX";
MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "";
PRODUCT_NAME = Rust;
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES = YES;
SDKROOT = macosx10.10;
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "/Volumes/BBEdit\\ SDK/Interfaces/Language\\ Modules/";
WRAPPER_EXTENSION = bblm;
};

87
helper-tool/Cargo.lock generated Normal file
View File

@@ -0,0 +1,87 @@
[root]
name = "rust-bbedit-helpers"
version = "0.1.0"
dependencies = [
"hoedown 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "advapi32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aho-corasick"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gcc"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hoedown"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"

18
helper-tool/Cargo.toml Normal file
View File

@@ -0,0 +1,18 @@
[package]
name = "rust-bbedit-helpers"
version = "0.1.0"
authors = ["Ben S <ogham@bsago.me>"]
[[bin]]
name = "doc-splitter"
path = "src/doc-splitter.rs"
test = true
[[bin]]
name = "impl-generator"
path = "src/impl-generator.rs"
test = true
[dependencies]
regex = "0.1"
hoedown = "3.0"

View File

@@ -0,0 +1,87 @@
extern crate hoedown;
use hoedown::{Markdown, Html, Render, Extension};
use hoedown::renderer::html::{self, HARD_WRAP};
use std::io::{self, BufRead};
fn main() {
let extensions: Extension =
hoedown::AUTOLINK |
hoedown::FENCED_CODE |
hoedown::FOOTNOTES |
hoedown::NO_INTRA_EMPHASIS |
hoedown::STRIKETHROUGH |
hoedown::SUPERSCRIPT |
hoedown::TABLES;
let stdin = io::stdin();
let mut buffer = String::new();
let mut was_doc = false;
let mut was_module_comment = false;
let mut flags = html::Flags::all();
flags.remove(HARD_WRAP);
let print_markdown = |buf: &str, mod_comment: bool| {
let doc = Markdown::new(buf.trim_right()).extensions(extensions);
let mut html = Html::new(flags, 0);
let classes = match mod_comment {
true => "docs module",
false => "docs",
};
println!("<div class=\"{}\">{}</div>", classes, html.render(&doc).to_str().unwrap());
};
let print_code = |buf: &str| {
println!("<pre class=\"code\">{}</pre>", buf.trim_right().replace("<", "&lt;").replace(">", "&gt;"));
};
for line in stdin.lock().lines() {
let line = line.unwrap();
let mut slice = &line[..];
let mut is_doc = false;
if let Some(first_char) = line.find(|c: char| !c.is_whitespace()) {
let line = &line[first_char ..];
if line.starts_with("//! ") || line.starts_with("/// ") {
slice = &slice[4 + first_char ..];
is_doc = true;
}
else if line.starts_with("//!") || line.starts_with("///") {
slice = &slice[3 + first_char ..];
is_doc = true;
}
}
if !buffer.trim().is_empty() {
if is_doc && !was_doc {
print_code(&*buffer);
buffer.clear();
}
else if !is_doc && was_doc {
print_markdown(&*buffer, was_module_comment);
buffer.clear();
}
}
buffer.push_str(slice);
buffer.push('\n');
was_doc = is_doc;
was_module_comment = line.starts_with("//!");
}
if !was_doc {
print_code(&*buffer);
buffer.clear();
}
else {
print_markdown(&*buffer, false);
buffer.clear();
}
}

View File

@@ -0,0 +1,515 @@
extern crate regex;
use regex::Regex;
use std::fmt;
use std::io::{self, BufRead};
use std::process;
use std::string::ToString;
/// The string pattern that every incoming string should match against.
pub static REGEX: &'static str = r##"(?x)
# example:
^ impl # impl
(?: < .+ >)? \s+ # <'a>
([ A-Z a-z 0-9 _ : ]+) # ops::Add
(< .+ >)? \s+ # <MyValue<'a>>
for \s+ # for
([ A-Z a-z 0-9 _ : ]+) # MyOtherValue
(< .+ >)? \s* # <'a>
\{? $
"##;
fn main() {
let regex = Regex::new(REGEX).unwrap();
let stdin = io::stdin();
let line = stdin.lock().lines().next().unwrap_or_else(||fail("Failed to read line")).unwrap();
let caps = regex.captures(&*line).unwrap_or_else(||fail("Invalid impl line"));
let trait_name = caps.at(1).unwrap_or("");
let trait_args = caps.at(2).unwrap_or("");
let type_name = caps.at(3).unwrap_or("");
let type_args = caps.at(4).unwrap_or("");
if let Some(components) = get_components(trait_name) {
// Print the first line...
println!("impl{} {}{} for {}{} {{", type_args, trait_name,trait_args, type_name,type_args);
// Then print all the components, with a blank line between each one:
let mut printed_anything = false;
for component in components.iter() {
if printed_anything == false {
printed_anything = true;
}
else {
println!("");
}
let text = component.to_string();
// There are three patterns that get replaced before a template is
// printed out:
//
// - SELF, which gets replaced with the name of the type the trait
// is being implemented for;
// - PARAM, which gets replaced with the *parameter* of the trait;
// - RHS, which gets replaced with the parameter if one exists,
// and the name of the type (like SELF) otherwise.
if text.contains("PARAM") && trait_args.is_empty() {
fail(&*format!("Trait {} needs a generic argument", trait_name));
}
// Remove the < and > from the trait's parameter if one exists.
let rhs = if trait_args.is_empty() { type_name } else { &trait_args[1 .. trait_args.len() - 1] };
let text = text.replace("SELF", &*format!("{}{}", type_name, type_args))
.replace("PARAM", rhs)
.replace("RHS", rhs);
println!("{}", text);
}
// And finally the last line.
println!("}}");
}
else {
fail(&*format!("Unknown trait name: {}", trait_name));
}
}
/// A **component** forms part of the resulting template.
#[derive(Copy, Clone)]
enum Component<'a> {
/// An associated type that has to be specified for this implementation.
AssocType(&'a str),
/// A function definition that must be specified for this trait.
Function {
name: &'a str,
input: &'a str,
output: Option<&'a str>,
params: Option<&'a str>,
},
}
impl<'a> fmt::Display for Component<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Component::AssocType(name) => {
write!(f, " type {} = <#...#>;", name)
},
Component::Function { name, input, output, params } => {
try!(write!(f, " fn {}", name));
if let Some(params) = params {
try!(write!(f, "<{}>", params));
}
try!(write!(f, "({})", input));
if let Some(output) = output {
try!(write!(f, " -> {}", output));
}
write!(f, " {{\n <#...#>\n }}")
},
}
}
}
/// Return a vector of components for a trait if the trait exists; returns
/// `None` otherwise.
fn get_components(trait_name: &str) -> Option<Vec<Component<'static>>> {
use self::Component::*;
let bits = match trait_name {
// -- std::borrow --
"Borrow" => vec![
Function {
name: "borrow",
input: "&self",
output: Some("&PARAM"),
params: None,
}
],
"BorrowMut" => vec![
Function {
name: "borrow_mut",
input: "&mut self",
output: Some("&mut PARAM"),
params: None,
}
],
"IntoCow" => vec![
Function {
name: "into_cow",
input: "self",
output: Some("Cow<PARAM>"),
params: None,
}
],
"ToOwned" => vec![
AssocType("Owned"),
Function {
name: "to_owned",
input: "&self",
output: Some("Self::Owned"),
params: None,
}
],
// -- std::clone --
"Clone" => vec![
Function {
name: "clone",
input: "&self",
output: Some("SELF"),
params: None,
}
],
// -- std::cmp --
"PartialEq" => vec![
Function {
name: "eq",
input: "&self, other: &RHS",
output: Some("bool"),
params: None,
}
],
"PartialOrd" => vec![
Function {
name: "partial_cmp",
input: "&self, other: &RHS",
output: Some("Option<Ordering>"),
params: None,
}
],
// -- std::convert --
"AsMut" => vec![
Function {
name: "as_mut",
input: "&mut self",
output: Some("&mut PARAM"),
params: None,
}
],
"AsRef" => vec![
Function {
name: "as_ref",
input: "&self",
output: Some("&PARAM"),
params: None,
}
],
"From" => vec![
Function {
name: "from",
input: "PARAM",
output: Some("SELF"),
params: None,
}
],
"Into" => vec![
Function {
name: "into",
input: "self",
output: Some("PARAM"),
params: None,
}
],
// -- std::default --
"Default" => vec![
Function {
name: "default",
input: "",
output: Some("SELF"),
params: None,
}
],
// -- std::error --
"Error" => vec![
Function {
name: "description",
input: "&self",
output: Some("&str"),
params: None,
},
Function {
name: "cause",
input: "&self",
output: Some("Option<&Error>"),
params: None,
}
],
// -- std::fmt --
"Binary" | "Debug" | "Display" | "LowerExp" | "LowerHex" | "Octal" |
"Pointer" | "UpperExp" | "UpperHex"
=> format(),
// -- std::hash --
"Hash" => vec![
Function {
name: "hash",
input: "&self, state: &mut H",
output: None,
params: Some("H: Hasher"),
}
],
// -- std::iter --
"Iterator" => vec![
AssocType("Item"),
Function {
name: "next",
input: "&mut self",
output: Some("Option<Self::Item>"),
params: None,
},
],
"ExactLenIterator" => vec![
Function {
name: "len",
input: "&self",
output: Some("usize"),
params: None,
},
],
"FromIterator" => vec![
Function {
name: "from_iter",
input: "iterator: T",
output: Some("SELF"),
params: Some("T: IntoIterator<Item=PARAM>"),
},
],
"DoubleEndedIterator" => vec![
Function {
name: "next_back",
input: "&mut self",
output: Some("Option<Self::Item>"),
params: None,
},
],
"IntoIterator" => vec![
AssocType("Item"),
AssocType("IntoIter"),
Function {
name: "into_iter",
input: "self",
output: Some("Self::IntoIter"),
params: None,
}
],
"Extend" => vec![
Function {
name: "extend",
input: "&mut self, iterable: T",
output: None,
params: Some("T: IntoIterator<Item=PARAM>"),
}
],
// -- std::ops --
"Add" => maths("add"),
"BitAnd" => maths("bitand"),
"BitOr" => maths("bitor"),
"BitXor" => maths("bitxor"),
"Div" => maths("div"),
"Mul" => maths("mul"),
"Rem" => maths("rem"),
"Shl" => maths("shl"),
"Shr" => maths("shr"),
"Sub" => maths("sub"),
"Not" => vec![
AssocType("Output"),
Function {
name: "not",
input: "self",
output: Some("Self::Output"),
params: None,
},
],
"Neg" => vec![
AssocType("Output"),
Function {
name: "neg",
input: "self",
output: Some("Self::Output"),
params: None,
},
],
"Deref" => vec![
AssocType("Target"),
Function {
name: "deref",
input: "&'a self",
output: Some("&'a Self::Target"),
params: Some("'a"),
},
],
"DerefMut" => vec![
AssocType("Target"),
Function {
name: "deref_mut",
input: "&'a mut self",
output: Some("&'a mut Self::Target"),
params: Some("'a"),
},
],
"Index" => vec![
AssocType("Output"),
Function {
name: "index",
input: "&'a self, index: PARAM",
output: Some("&'a Self::Output"),
params: Some("'a"),
},
],
"IndexMut" => vec![
AssocType("Output"),
Function {
name: "index",
input: "&'a mut self, index: PARAM",
output: Some("&'a mut Self::Output"),
params: Some("'a"),
},
],
// -- std::str --
"FromStr" => vec![
AssocType("Err"),
Function {
name: "from_str",
input: "s: &str",
output: Some("Result<SELF, Self::Err>"),
params: None,
},
],
_ => return None,
};
Some(bits)
}
/// Return the components for a mathematical operator, all of which follow the
/// same pattern.
fn maths(name: &'static str) -> Vec<Component<'static>> {
vec![
Component::AssocType("Output"),
Component::Function {
name: name,
input: "self, rhs: RHS",
output: Some("Self::Output"),
params: None,
},
]
}
/// Return the components for a formatting trait, which all look exactly the
/// same.
fn format() -> Vec<Component<'static>> {
vec![
Component::Function {
name: "fmt",
input: "&self, f: &mut fmt::Formatter",
output: Some("Result<(), fmt::Error>"),
params: None,
}
]
}
/// Print the given message, and exit the program, returning failure.
fn fail(message: &str) -> ! {
println!("{}", message);
process::exit(1);
}
#[cfg(test)]
mod test {
use regex::Regex;
use super::*;
#[test]
fn base() {
let regex = Regex::new(REGEX).unwrap();
assert!(regex.is_match("impl Foo for Bar"));
}
#[test]
fn open_bracket() {
let regex = Regex::new(REGEX).unwrap();
assert!(regex.is_match("impl Foo for Bar {"));
}
#[test]
fn generics() {
let regex = Regex::new(REGEX).unwrap();
assert!(regex.is_match("impl<'a> Foo<'a> for Bar<'a>"));
}
#[test]
fn more_generics() {
let regex = Regex::new(REGEX).unwrap();
assert!(regex.is_match("impl<'a, T> Foo<'a, T> for Bar<'a, T>"));
}
#[test]
fn generic_generics() {
let regex = Regex::new(REGEX).unwrap();
assert!(regex.is_match("impl<T<'a>> Foo<T<'a>> for Bar<T<'a>>"));
}
}

58
rust.mm
View File

@@ -31,7 +31,7 @@ SInt32 skipString(BBLMTextIterator &iter)
{
SInt32 length = 1;
UniChar ch;
if (iter.strcmp("\"", 1) == 0)
{
iter += 1;
@@ -63,7 +63,7 @@ SInt32 skipRawString(BBLMTextIterator &iter)
{
SInt32 length = 4;
UniChar ch;
if (iter.strcmp("r##\"", 4) == 0)
{
iter += 4;
@@ -72,7 +72,7 @@ SInt32 skipRawString(BBLMTextIterator &iter)
{
return 0;
}
while ((ch = iter.GetNextChar()))
{
length++;
@@ -82,14 +82,14 @@ SInt32 skipRawString(BBLMTextIterator &iter)
iter += 3;
break;
}
if (ch == '\\')
{
iter++;
length++;
}
}
return length;
}
@@ -198,7 +198,7 @@ SInt32 skipAttribute(BBLMTextIterator &iter)
{
return 0;
}
while ((ch = iter.GetNextChar()))
{
if (ch == ']')
@@ -206,6 +206,12 @@ SInt32 skipAttribute(BBLMTextIterator &iter)
length++;
break;
}
else if (ch == '"')
{
// We only want to skip newlines in attributes if they're within a string.
iter--;
length += skipString(iter);
}
else if (ch == '\n' || ch == '\r')
{
break;
@@ -276,10 +282,10 @@ SInt32 skipNumber(BBLMTextIterator &iter)
else if (ch == 'f' || ch == 'u' || ch == 'i')
{
length++;
if (ch != 'f' && iter.strcmp("s", 1) == 0)
if (ch != 'f' && iter.strcmp("size", 4) == 0)
{
// Parse 'us' or 'is' machine-dependent suffixes
length++;
// Parse 'usize' or 'isize' machine-dependent suffixes
length += 4;
}
else
{
@@ -402,7 +408,7 @@ SInt32 scanForSymbol(BBLMTextIterator &iter,
iter -= keywordLen + whitespaceLen;
return 0;
}
SInt32 start_of_name = iter.Offset();
SInt32 start_of_function;
while ((ch = iter.GetNextChar()))
@@ -423,7 +429,7 @@ SInt32 scanForSymbol(BBLMTextIterator &iter,
break;
}
}
iter--;
start_of_function = iter.Offset();
break;
@@ -442,9 +448,9 @@ SInt32 scanForSymbol(BBLMTextIterator &iter,
return 0;
}
}
UInt32 funLen = skipToEndOfFunction(iter);
// Skip over trait method definitions and extern functions
if (funLen == 0)
{
@@ -453,7 +459,7 @@ SInt32 scanForSymbol(BBLMTextIterator &iter,
UInt32 tokenOffset, funIndex;
UInt32 nameLen;
iter -= (wordLen + funLen);
iter -= (keywordLen + whitespaceLen);
@@ -482,7 +488,7 @@ SInt32 scanForSymbol(BBLMTextIterator &iter,
// 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;
}
@@ -610,13 +616,13 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
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--;
@@ -807,18 +813,18 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
{
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;
@@ -882,7 +888,7 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
if (!addRun(kBBLMPreprocessorRunKind, runStart, runLen, *callbacks)) return noErr;
runStart = iter.Offset();
}
else if (ch == '$')
{
iter--;
@@ -933,7 +939,9 @@ OSErr calculateRuns(BBLMParamBlock &params, const BBLMCallbackBlock *callbacks)
runStart = iter.Offset();
}
wordchr = isalpha(ch) || isdigit(ch) || ch == '_';
// '.' is considered a word char to avoid the "0.0" in "tuple.0.0"
// being classified as a floating-point number.
wordchr = isalpha(ch) || isdigit(ch) || ch == '_' || ch == '.';
}
makeCodeRun(iter, runStart, *callbacks);
@@ -971,10 +979,14 @@ OSErr guessLanguage(BBLMParamBlock &params)
{
BBLMTextIterator iter(params);
if (iter.strcmp("use ", 4) == 0 || iter.strcmp("#![crate_id", 11) == 0)
if (iter.strcmp("#![crate_name", 13) == 0)
{
params.fGuessLanguageParams.fGuessResult = kBBLMGuessDefiniteYes;
}
else if (iter.strcmp("use ", 4) == 0 || iter.strcmp("//! ", 4) == 0)
{
params.fGuessLanguageParams.fGuessResult = kBBLMGuessMaybe;
}
return noErr;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 KiB

BIN
screenshots.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 KiB

View File

@@ -85,8 +85,11 @@
5.974e24 // lowercase e
7.348e+22 // uppercase E and plus
.1234 // no leading zero (invalid)
let tuple = ((8, 4), 48);
let a = tuple.0.0;
tuple.0
tuple.0.0 // tuple indexing (not really numbers)
// Numeric Suffixes
// ----------------
@@ -94,13 +97,14 @@
123i32, 123u32 // numbers can have literals
123_u32, 0xff_u8
0o70_i16, 0b1111_1111_1001_0000_i32
0us, 7is
0usize, 7isize
123.0f64
0.1f64
0.1f32
12E+99_f64
2.f64 // Invalid!
0us, 7is // Invalid!
2.f64 // Also invalid!
// Attributes
// ----------
@@ -112,6 +116,12 @@
#[macro_use] use this_is_not_an_attribute;
#[unfinished_attribute // not a comment
and this should be back to regular code. // back to comments again
#[unfinished_attribute="but look \ // not a comment
a string!"] // back to comments again
// Macros
// ------