An interpreter for grammar files as defined by TextMate. TextMate grammars use the oniguruma dialect (https://github.com/kkos/oniguruma). Supports loading grammar files only from JSON format. Cross - grammar injections are currently not supported.
TextMateSharp is a port of microsoft/vscode-textmate that brings TextMate grammars to dotnet ecosystem. The implementation is based the Java port eclipse/tm4e.
TextMateSharp uses a wrapper via nuget packges around Oniguruma regex engine. Thanks @aikawayataro for your contribution.
TextMateSharp is used by AvaloniaEdit.
Just execute dotnet build under the folder TextMateSharp
classProgram{staticvoidMain(string[]args){try{IRegistryOptionsoptions=newLocalRegistryOptions();Registry.Registryregistry=newRegistry.Registry(options);List<string>textLines=newList<string>();textLines.Add("using static System; /* comment here */");textLines.Add("namespace Example");textLines.Add("{");textLines.Add("}");IGrammargrammar=registry.LoadGrammar("source.cs");StackElementruleStack=null;foreach(stringlineintextLines){Console.WriteLine(string.Format("Tokenizing line: {0}",line));ITokenizeLineResultresult=grammar.TokenizeLine(line,ruleStack);ruleStack=result.RuleStack;foreach(ITokentokeninresult.GetTokens()){intstartIndex=(token.StartIndex>line.Length)?line.Length:token.StartIndex;intendIndex=(token.EndIndex>line.Length)?line.Length:token.EndIndex;Console.WriteLine(string.Format(" - token from {0} to {1} -->{2}<-- with scopes {3}",startIndex,endIndex,line.SubstringAtIndexes(startIndex,endIndex),string.Join(",",token.Scopes)));foreach(stringscopeNameintoken.Scopes){Themetheme=registry.GetTheme();List<ThemeTrieElementRule>themeRules=theme.Match(scopeName);foreach(ThemeTrieElementRulethemeRuleinthemeRules){Console.WriteLine(" - Matched theme rule: "+"[bg: {0}, fg:{1}, fontStyle: {2}]",theme.GetColor(themeRule.background),theme.GetColor(themeRule.foreground),themeRule.fontStyle);}}}}}catch(Exceptionex){Console.WriteLine("ERROR: "+ex.Message);}}classLocalRegistryOptions:IRegistryOptions{publicICollection<string>GetInjections(stringscopeName){returnnull;}publicIRawGrammarGetGrammar(stringscopeName){returnnull;}publicIRawThemeGetTheme(stringscopeName){returnnull;}publicIRawThemeGetDefaultTheme(){stringthemePath=Path.GetFullPath(@"../../../../test/themes/dark_vs.json");using(StreamReaderreader=newStreamReader(themePath)){returnThemeReader.ReadThemeSync(reader);}}}}OUTPUT:
Tokenizing line: using static System; /* comment here */
- token from 0 to 5 -->using<-- with scopes source.cs,keyword.other.using.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:#569CD6, fontStyle: -1]
- token from 5 to 6 --> <-- with scopes source.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- token from 6 to 12 -->static<-- with scopes source.cs,keyword.other.static.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:#569CD6, fontStyle: -1]
- token from 12 to 13 --> <-- with scopes source.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- token from 13 to 19 -->System<-- with scopes source.cs,storage.type.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:#569CD6, fontStyle: -1]
- token from 19 to 20 -->;<-- with scopes source.cs,punctuation.terminator.statement.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- token from 20 to 21 --> <-- with scopes source.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- token from 21 to 23 -->/*<-- with scopes source.cs,comment.block.cs,punctuation.definition.comment.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:#6A9955, fontStyle: -1]
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- token from 23 to 37 --> comment here <-- with scopes source.cs,comment.block.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:#6A9955, fontStyle: -1]
- token from 37 to 39 -->*/<-- with scopes source.cs,comment.block.cs,punctuation.definition.comment.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:#6A9955, fontStyle: -1]
- Matched theme rule: [bg: , fg:, fontStyle: -1]
Tokenizing line: namespace Example
- token from 0 to 9 -->namespace<-- with scopes source.cs,keyword.other.namespace.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:#569CD6, fontStyle: -1]
- token from 9 to 10 --> <-- with scopes source.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- token from 10 to 17 -->Example<-- with scopes source.cs,entity.name.type.namespace.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:, fontStyle: -1]
Tokenizing line: {
- token from 0 to 1 -->{<-- with scopes source.cs,punctuation.curlybrace.open.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
- Matched theme rule: [bg: , fg:, fontStyle: -1]
Tokenizing line: }
- token from 0 to 1 -->}<-- with scopes source.cs
- Matched theme rule: [bg: , fg:, fontStyle: -1]
There is a demo project in TextMateSharp.Demo folder.
Build and run:
cd src/TestMateSharp.Demo
dotnet build
dotnet run -- ./testdata/samplefiles/sample.cs
