diff options
author | Mikayla Hutchinson <m.j.hutchinson@gmail.com> | 2017-01-31 21:15:43 +0300 |
---|---|---|
committer | Mikayla Hutchinson <m.j.hutchinson@gmail.com> | 2017-01-31 23:12:21 +0300 |
commit | 17b9404d3a33ff34cc204998b62e944c879d3dd1 (patch) | |
tree | 72d2d653d10cb171447c81beef82fa0c7528e939 /main/src | |
parent | a80a642a5e3a3f925fe6f852d6f2844023e50c8b (diff) | |
parent | 26ad42f934f962a4c11f02e129e0461be2e96ed9 (diff) |
Merge remote-tracking branch 'origin/vNext' into roslyn-ivt
Diffstat (limited to 'main/src')
117 files changed, 8060 insertions, 1171 deletions
diff --git a/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs b/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs index 6e245ce749..aca34d220e 100644 --- a/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs +++ b/main/src/addins/AspNet/Razor/RazorCSharpEditorExtension.cs @@ -442,16 +442,24 @@ namespace MonoDevelop.AspNet.Razor return hiddenOff; } - public override async System.Threading.Tasks.Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) + public override async System.Threading.Tasks.Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, System.Threading.CancellationToken token) { + if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand) { + if (hiddenInfo != null && (isInCSharpContext || Tracker.Engine.CurrentState is RazorState) + && !(Tracker.Engine.Nodes.Peek () is XElement)) { + InitializeCodeCompletion (); + return await completionBuilder.HandlePopupCompletion (defaultEditor, defaultDocumentContext, hiddenInfo); + } + } char previousChar = defaultEditor.CaretOffset > 1 ? defaultEditor.GetCharAt ( defaultEditor.CaretOffset - 2) : ' '; - + if (triggerInfo.CompletionTriggerReason != CompletionTriggerReason.CharTyped) + return null; // Don't show completion window when directive's name is being typed var directive = Tracker.Engine.Nodes.Peek () as RazorDirective; if (directive != null && !directive.FirstBracket.HasValue) return null; - + var completionChar = triggerInfo.TriggerCharacter.Value; if (hiddenInfo != null && isInCSharpContext) { var list = (CompletionDataList) await completionBuilder.HandleCompletion (defaultEditor, defaultDocumentContext, completionContext, hiddenInfo, completionChar, token); @@ -472,7 +480,7 @@ namespace MonoDevelop.AspNet.Razor return list; } - return await base.HandleCodeCompletionAsync (completionContext, completionChar, token); + return await base.HandleCodeCompletionAsync (completionContext, triggerInfo, token); } //recreating the list is over 2x as fast as using remove operations, saves typically 10ms @@ -552,16 +560,6 @@ namespace MonoDevelop.AspNet.Razor return list; } - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - if (hiddenInfo != null && (isInCSharpContext || Tracker.Engine.CurrentState is RazorState) - && !(Tracker.Engine.Nodes.Peek () is XElement)) { - InitializeCodeCompletion (); - return completionBuilder.HandlePopupCompletion (defaultEditor, defaultDocumentContext, hiddenInfo); - } - - return base.CodeCompletionCommand (completionContext); - } /* public override bool GetParameterCompletionCommandOffset (out int cpos) { diff --git a/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs b/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs index a82c38ef35..a1b618bb15 100644 --- a/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs +++ b/main/src/addins/AspNet/Tests/Razor/RazorCompletionTesting.cs @@ -59,19 +59,19 @@ namespace MonoDevelop.AspNet.Tests.Razor int cursorPosition = text.IndexOf ('$');
var ctx = GetCodeCompletionContext (isInCSharpContext, ed.View, ed.Extension.hiddenInfo.UnderlyingDocument);
-
+ + Task<ICompletionDataList> task;
if (isCtrlSpace) {
- var result = await ed.Extension.CodeCompletionCommand (ctx) as CompletionDataList;
- TypeSystemServiceTestExtensions.UnloadSolution (solution);
- return result;
+ task = ed.Extension.HandleCodeCompletionAsync (ctx, CompletionTriggerInfo.CodeCompletionCommand, default (CancellationToken));
} else {
- var task = ed.Extension.HandleCodeCompletionAsync (ctx, ed.EditorText [cursorPosition - 1], default(CancellationToken));
- TypeSystemServiceTestExtensions.UnloadSolution (solution); - if (task != null) { - return await task as CompletionDataList; - } - return null;
+ task = ed.Extension.HandleCodeCompletionAsync (ctx, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, ed.EditorText [cursorPosition - 1]), default (CancellationToken)); }
+ + TypeSystemServiceTestExtensions.UnloadSolution (solution); + if (task != null) { + return await task as CompletionDataList; + } + return null; }
static CodeCompletionContext GetCodeCompletionContext (bool cSharpContext, TestViewContent sev, UnderlyingDocument underlyingDocument)
diff --git a/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs b/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs index 1f8273e471..9143fa4793 100644 --- a/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs +++ b/main/src/addins/AspNet/Tests/WebForms/WebFormsTesting.cs @@ -53,9 +53,9 @@ namespace MonoDevelop.AspNet.Tests.WebForms var ctx = textEditorCompletion.GetCodeCompletionContext (sev); if (isCtrlSpace) - return await textEditorCompletion.CodeCompletionCommand (ctx) as CompletionDataList; + return await textEditorCompletion.HandleCodeCompletionAsync (ctx, CompletionTriggerInfo.CodeCompletionCommand) as CompletionDataList; else { - var task = textEditorCompletion.HandleCodeCompletionAsync (ctx, editorText [cursorPosition - 1]); + var task = textEditorCompletion.HandleCodeCompletionAsync (ctx, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, editorText [cursorPosition - 1])); if (task != null) { return await task as CompletionDataList; } diff --git a/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs b/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs index 317ab2acb8..6d1533318f 100644 --- a/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs +++ b/main/src/addins/AspNet/WebForms/WebFormsEditorExtension.cs @@ -237,17 +237,17 @@ namespace MonoDevelop.AspNet.WebForms // }; } - + /* public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) { -/* //completion for ASP.NET expressions + //completion for ASP.NET expressions // TODO: Detect <script> state here !!! if (documentBuilder != null && Tracker.Engine.CurrentState is WebFormsExpressionState) { InitializeCodeCompletion ('\0'); return documentBuilder.HandlePopupCompletion (defaultEditor, defaultDocumentContext, documentInfo, localDocumentInfo); - }*/ + } return base.CodeCompletionCommand (completionContext); - } + }*/ protected override void Initialize () { diff --git a/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs b/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs index 6a39304a4f..8076890f66 100644 --- a/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs +++ b/main/src/addins/CSharpBinding/AspNet/RazorCSharpCompletionBuilder.cs @@ -79,7 +79,7 @@ namespace MonoDevelop.CSharp.Completion {
CodeCompletionContext ccc;
var completion = CreateCompletionAndUpdate (editor, context, docInfo, out ccc);
- return completion.CodeCompletionCommand (ccc);
+ return completion.HandleCodeCompletionAsync (ccc, CompletionTriggerInfo.CodeCompletionCommand);
}
public Task<ICompletionDataList> HandleCompletion (MonoDevelop.Ide.Editor.TextEditor editor, DocumentContext context, CodeCompletionContext completionContext,
@@ -87,7 +87,7 @@ namespace MonoDevelop.CSharp.Completion {
CodeCompletionContext ccc;
var completion = CreateCompletionAndUpdate (editor, context, docInfo, out ccc);
- return completion.HandleCodeCompletionAsync (completionContext, currentChar, token);
+ return completion.HandleCodeCompletionAsync (completionContext, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, currentChar), token);
}
public Task<ParameterHintingResult> HandleParameterCompletion (MonoDevelop.Ide.Editor.TextEditor editor, DocumentContext context, CodeCompletionContext completionContext,
diff --git a/main/src/addins/CSharpBinding/CSharpBinding.csproj b/main/src/addins/CSharpBinding/CSharpBinding.csproj index 3088f2abce..766f788e88 100644 --- a/main/src/addins/CSharpBinding/CSharpBinding.csproj +++ b/main/src/addins/CSharpBinding/CSharpBinding.csproj @@ -367,8 +367,6 @@ <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionContext.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionEngine.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionResult.cs" /> - <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionTriggerInfo.cs" /> - <Compile Include="MonoDevelop.CSharp.Features\Completion\CompletionTriggerReason.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\EditorBrowsableBehavior.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\ICompletionDataFactory.cs" /> <Compile Include="MonoDevelop.CSharp.Features\Completion\ContextHandler\CastCompletionContextHandler.cs" /> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs index e99be8c015..fb8d0f7abd 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs @@ -301,7 +301,7 @@ namespace MonoDevelop.CSharp.ClassOutline Runtime.AssertMainThread (); Gdk.Threads.Enter (); refreshingOutline = false; - if (outlineTreeStore == null || !outlineTreeView.IsRealized) { + if (outlineTreeStore == null || outlineTreeView == null || !outlineTreeView.IsRealized) { refillOutlineStoreId = 0; return false; } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs index 2b93167c62..7452d57f3c 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs @@ -274,33 +274,67 @@ namespace MonoDevelop.CSharp.Completion { HandleDocumentParsed (null, null); } - - public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) + + public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default (CancellationToken)) { -// if (!EnableCodeCompletion) -// return null; - if (!IdeApp.Preferences.EnableAutoCodeCompletion && char.IsLetter (completionChar)) + // if (!EnableCodeCompletion) + // return null; + if (!IdeApp.Preferences.EnableAutoCodeCompletion) return null; - - // var timer = Counters.ResolveTime.BeginTiming (); - try { - int triggerWordLength = 0; - if (char.IsLetterOrDigit (completionChar) || completionChar == '_') { - if (completionContext.TriggerOffset > 1 && char.IsLetterOrDigit (Editor.GetCharAt (completionContext.TriggerOffset - 2))) - return null; - triggerWordLength = 1; + int triggerWordLength = -1; + switch (triggerInfo.CompletionTriggerReason) { + case CompletionTriggerReason.CharTyped: + // var timer = Counters.ResolveTime.BeginTiming (); + try { + var completionChar = triggerInfo.TriggerCharacter.Value; + if (char.IsLetterOrDigit (completionChar) || completionChar == '_') { + if (completionContext.TriggerOffset > 1 && char.IsLetterOrDigit (Editor.GetCharAt (completionContext.TriggerOffset - 2))) + return null; + triggerWordLength = 1; + } + return InternalHandleCodeCompletion (completionContext, completionChar, false, triggerWordLength, token); + } catch (Exception e) { + LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + + "FileName: " + DocumentContext.Name + Environment.NewLine + + "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + + "Line text: " + Editor.GetLineText (completionContext.TriggerLine), + e); + return null; + } finally { + // if (timer != null) + // timer.Dispose (); } - return InternalHandleCodeCompletion (completionContext, completionChar, false, triggerWordLength, token); - } catch (Exception e) { - LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + - "FileName: " + DocumentContext.Name + Environment.NewLine + - "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + - "Line text: " + Editor.GetLineText (completionContext.TriggerLine), - e); - return null; - } finally { - // if (timer != null) - // timer.Dispose (); + case CompletionTriggerReason.BackspaceOrDeleteCommand: + //char completionChar = Editor.GetCharAt (completionContext.TriggerOffset - 1); + //Console.WriteLine ("completion char: " + completionChar); + // var timer = Counters.ResolveTime.BeginTiming (); + char ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; + char ch2 = completionContext.TriggerOffset < Editor.Length ? Editor.GetCharAt (completionContext.TriggerOffset) : '\0'; + if (!IsIdentifierPart (ch) && !IsIdentifierPart (ch2)) + return null; + try { + return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, token).ContinueWith (t => { + var result = (CompletionDataList)t.Result; + if (result == null) + return null; + result.AutoCompleteUniqueMatch = false; + result.AutoCompleteEmptyMatch = false; + return (ICompletionDataList)result; + }); + } catch (Exception e) { + LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + + "FileName: " + DocumentContext.Name + Environment.NewLine + + "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + + "Line text: " + Editor.GetLineText (completionContext.TriggerLine), + e); + return null; + } finally { + // if (timer != null) + // timer.Dispose (); + } + default: + ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; + return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, default (CancellationToken)); } } @@ -309,44 +343,6 @@ namespace MonoDevelop.CSharp.Completion return char.IsLetterOrDigit (ch) || ch == '_'; } - public override Task<ICompletionDataList> HandleBackspaceOrDeleteCodeCompletionAsync (CodeCompletionContext completionContext, SpecialKey key, char triggerCharacter, CancellationToken token = default(CancellationToken)) - { - if (!IdeApp.Preferences.EnableAutoCodeCompletion) - return null; - if (!char.IsLetterOrDigit (triggerCharacter) && triggerCharacter != '_') - return null; - //char completionChar = Editor.GetCharAt (completionContext.TriggerOffset - 1); - //Console.WriteLine ("completion char: " + completionChar); - // var timer = Counters.ResolveTime.BeginTiming (); - - if (key == SpecialKey.BackSpace || key == SpecialKey.Delete) { - char ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; - char ch2 = completionContext.TriggerOffset < Editor.Length ? Editor.GetCharAt (completionContext.TriggerOffset) : '\0'; - if (!IsIdentifierPart (ch) && !IsIdentifierPart (ch2)) - return null; - } - try { - int triggerWordLength = 0; - return InternalHandleCodeCompletion (completionContext, triggerCharacter, true, triggerWordLength, token).ContinueWith ( t => { - var result = (CompletionDataList)t.Result; - if (result == null) - return null; - result.AutoCompleteUniqueMatch = false; - result.AutoCompleteEmptyMatch = false; - return (ICompletionDataList)result; - }); - } catch (Exception e) { - LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + - "FileName: " + DocumentContext.Name + Environment.NewLine + - "Position: line=" + completionContext.TriggerLine + " col=" + completionContext.TriggerLineOffset + Environment.NewLine + - "Line text: " + Editor.GetLineText (completionContext.TriggerLine), - e); - return null; - } finally { - // if (timer != null) - // timer.Dispose (); - } } - internal class CSharpCompletionDataList : CompletionDataList { } @@ -521,13 +517,7 @@ namespace MonoDevelop.CSharp.Completion return (ICompletionDataList)list; }); } - - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - int triggerWordLength = 0; - char ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; - return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, default(CancellationToken)); - } + static bool HasAllUsedParameters (MonoDevelop.Ide.CodeCompletion.ParameterHintingData provider, string[] list) { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs index 39faa5e6fe..a033a8be29 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/RoslynSymbolCompletionData.cs @@ -174,7 +174,25 @@ namespace MonoDevelop.CSharp.Completion return tooltipInfo; }); } - + + static string GetCurrentWordForMethods (CompletionListWindow window, MonoDevelop.Ide.Editor.Extension.KeyDescriptor descriptor) + { + int partialWordLength = window.PartialWord != null ? window.PartialWord.Length : 0; + int replaceLength; + if (descriptor.SpecialKey == SpecialKey.Return || descriptor.SpecialKey == SpecialKey.Tab) { + replaceLength = window.CodeCompletionContext.TriggerWordLength + partialWordLength - window.InitialWordLength; + } else { + replaceLength = partialWordLength; + } + int endOffset = Math.Min (window.StartOffset + replaceLength, window.CompletionWidget.TextLength); + if (descriptor.KeyChar == '(' && IdeApp.Preferences.AddParenthesesAfterCompletion) { + endOffset++; + if (DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket) + endOffset++; + } + var result = window.CompletionWidget.GetText (window.StartOffset, endOffset); + return result; + } public override void InsertCompletionText (CompletionListWindow window, ref KeyActions ka, MonoDevelop.Ide.Editor.Extension.KeyDescriptor descriptor) { string partialWord = GetCurrentWord (window, descriptor); @@ -187,9 +205,11 @@ namespace MonoDevelop.CSharp.Completion bool addOpeningOnly = IdeApp.Preferences.AddOpeningOnly; var Editor = ext.Editor; var Policy = ext.FormattingPolicy; + var ctx = window.CodeCompletionContext; string insertionText = this.GetInsertionText(); if (addParens && !IsDelegateExpected && method != null && !IsBracketAlreadyInserted (ext, method)) { + partialWord = GetCurrentWordForMethods (window, descriptor); var line = Editor.GetLine (Editor.CaretLine); //var start = window.CodeCompletionContext.TriggerOffset + partialWord.Length + 2; //var end = line.Offset + line.Length; @@ -209,7 +229,7 @@ namespace MonoDevelop.CSharp.Completion //int pos; var keys = new [] { SpecialKey.Return, SpecialKey.Tab, SpecialKey.Space }; - if (keys.Contains (descriptor.SpecialKey) || descriptor.KeyChar == '.') { + if (keys.Contains (descriptor.SpecialKey) || descriptor.KeyChar == '.' || descriptor.KeyChar == '(') { if (HasAnyOverloadWithParameters (method)) { if (addOpeningOnly) { insertionText += RequireGenerics (method) ? "<|" : (addSpace ? " (|" : "(|"); @@ -281,6 +301,7 @@ namespace MonoDevelop.CSharp.Completion } ka |= KeyActions.Ignore; } + if ((DisplayFlags & DisplayFlags.NamedArgument) == DisplayFlags.NamedArgument && IdeApp.Preferences.AddParenthesesAfterCompletion && (descriptor.SpecialKey == SpecialKey.Tab || @@ -293,7 +314,7 @@ namespace MonoDevelop.CSharp.Completion insertionText += " "; runCompletionCompletionCommand = true; } - window.CompletionWidget.SetCompletionText (window.CodeCompletionContext, partialWord, insertionText); + window.CompletionWidget.SetCompletionText (ctx, partialWord, insertionText); int offset = Editor.CaretOffset; for (int i = skipChars; i --> 0;) { Editor.StartSession (new SkipCharSession (Editor.GetCharAt (offset + i))); diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs index 6205134ebd..ce7ebe7a22 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Formatting/OnTheFlyFormatter.cs @@ -115,10 +115,15 @@ namespace MonoDevelop.CSharp.Formatting var changeEnd = delta + change.Span.End - 1; if (changeEnd < editor.Length && changeEnd >= 0 && editor.GetCharAt (changeEnd) == '\r') length--; - editor.ReplaceText (delta + change.Span.Start, length, newText); + var replaceOffset = delta + change.Span.Start; + editor.ReplaceText (replaceOffset, length, newText); delta = delta - length + newText.Length; - if (delta + change.Span.Start < caretEndOffset) { - caretEndOffset += newText.Length - length; + if (change.Span.Start < caretOffset) { + if (change.Span.End < caretOffset) { + caretEndOffset += newText.Length - length; + } else { + caretEndOffset = replaceOffset; + } } } if (startOffset < caretOffset) { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Tooltips/LanguageItemTooltipProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Tooltips/LanguageItemTooltipProvider.cs index 3a8919db6e..88bd8ac655 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Tooltips/LanguageItemTooltipProvider.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Tooltips/LanguageItemTooltipProvider.cs @@ -68,14 +68,26 @@ namespace MonoDevelop.SourceEditor } if (!syntaxToken.Span.IntersectsWith (offset)) return null; - var symbolInfo = unit.GetSymbolInfo (syntaxToken.Parent, token); - var symbol = symbolInfo.Symbol ?? unit.GetDeclaredSymbol (syntaxToken.Parent, token); + var node = GetBestFitResolveableNode (syntaxToken.Parent); + var symbolInfo = unit.GetSymbolInfo (node, token); + var symbol = symbolInfo.Symbol ?? unit.GetDeclaredSymbol (node, token); var tooltipInformation = await CreateTooltip (symbol, syntaxToken, editor, ctx, offset); if (tooltipInformation == null || string.IsNullOrEmpty (tooltipInformation.SignatureMarkup)) return null; return new TooltipItem (tooltipInformation, syntaxToken.Span.Start, syntaxToken.Span.Length); } - + + static SyntaxNode GetBestFitResolveableNode (SyntaxNode node) + { + // case constructor name : new Foo (); 'Foo' only resolves to the type not to the constructor + if (node.Parent.IsKind (SyntaxKind.ObjectCreationExpression)) { + var oce = (ObjectCreationExpressionSyntax)node.Parent; + if (oce.Type == node) + return oce; + } + return node; + } + static TooltipInformationWindow lastWindow = null; static void DestroyLastTooltipWindow () diff --git a/main/src/addins/Deployment/MonoDevelop.Deployment.Linux/MonoDevelop.Deployment.Linux/LinuxDeployData.cs b/main/src/addins/Deployment/MonoDevelop.Deployment.Linux/MonoDevelop.Deployment.Linux/LinuxDeployData.cs index aed6187f73..e3ce030a58 100644 --- a/main/src/addins/Deployment/MonoDevelop.Deployment.Linux/MonoDevelop.Deployment.Linux/LinuxDeployData.cs +++ b/main/src/addins/Deployment/MonoDevelop.Deployment.Linux/MonoDevelop.Deployment.Linux/LinuxDeployData.cs @@ -66,7 +66,7 @@ namespace MonoDevelop.Deployment.Linux var data = ser.Serialize (this); XmlDocument doc = new XmlDocument (); - var writer = new XmlConfigurationWriter { Namespace = MSBuildProject.Schema }; + var writer = new XmlConfigurationWriter { Namespace = entry.MSBuildProject.Namespace }; var elem = writer.Write (doc, data); entry.MSBuildProject.SetMonoDevelopProjectExtension ("Deployment.LinuxDeployData", elem); diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs index 03ed55ae84..fc54bee313 100644 --- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs +++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserViewContent.cs @@ -76,7 +76,9 @@ namespace MonoDevelop.AssemblyBrowser { ContentName = GettextCatalog.GetString ("Assembly Browser"); var loader = widget.AddReferenceByFileName (fileOpenInformation.FileName); - widget.SelectAssembly (loader.UnresolvedAssembly.AssemblyName); + loader.LoadingTask.ContinueWith (delegate { + widget.SelectAssembly (loader); + }); return Task.FromResult (true); } diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs index 84bacba198..bfde716324 100644 --- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs +++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs @@ -1437,31 +1437,23 @@ namespace MonoDevelop.AssemblyBrowser }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current); } - public void SelectAssembly (string fileName) + internal void SelectAssembly (AssemblyLoader loader) { - AssemblyDefinition cu = null; - foreach (var unit in definitions) { - if (unit.UnresolvedAssembly.AssemblyName == fileName || unit.UnresolvedAssembly.Location == fileName) { - cu = unit.CecilLoader.GetCecilObject (unit.UnresolvedAssembly); - unit.LoadingTask.ContinueWith (t => { - Application.Invoke (delegate { - ITreeNavigator nav = TreeView.GetRootNode (); - if (nav == null) - return; - - do { - if (nav.DataItem == cu || (nav.DataItem as AssemblyLoader)?.Assembly == cu) { - nav.ExpandToNode (); - nav.Selected = true; - nav.ScrollToNode (); - return; - } - } while (nav.MoveNext ()); - }); - }); + AssemblyDefinition cu = loader.CecilLoader.GetCecilObject (loader.UnresolvedAssembly); + Application.Invoke (delegate { + ITreeNavigator nav = TreeView.GetRootNode (); + if (nav == null) return; - } - } + + do { + if (nav.DataItem == cu || (nav.DataItem as AssemblyLoader)?.Assembly == cu) { + nav.ExpandToNode (); + nav.Selected = true; + nav.ScrollToNode (); + return; + } + } while (nav.MoveNext ()); + }); } void Dispose (ITreeNavigator nav) diff --git a/main/src/addins/MonoDevelop.Autotools/MakefileData.cs b/main/src/addins/MonoDevelop.Autotools/MakefileData.cs index 01b78a04dc..73ae0e9219 100644 --- a/main/src/addins/MonoDevelop.Autotools/MakefileData.cs +++ b/main/src/addins/MonoDevelop.Autotools/MakefileData.cs @@ -81,8 +81,18 @@ namespace MonoDevelop.Autotools public XmlElement Write () { + string xmlns = MSBuildProject.Schema; + var msbuildProject = ownerProject?.MSBuildProject; + if (msbuildProject != null) + xmlns = msbuildProject.Namespace; + + return Write (xmlns); + } + + XmlElement Write (string xmlns) + { XmlDataSerializer ser = new XmlDataSerializer (new DataContext ()); - ser.Namespace = MSBuildProject.Schema; + ser.Namespace = xmlns; var sw = new StringWriter (); ser.Serialize (new XmlTextWriter (sw), this); XmlDocument doc = new XmlDocument (); diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs index e1ef5546ae..68c8843843 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs @@ -186,6 +186,11 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol return ""; } + protected override void OnAttachToProcess (long processId) + { + Attach (processId); + } + protected override void OnRun (DebuggerStartInfo startInfo) { Launch (startInfo); diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/CorApi/CorApi.csproj b/main/src/addins/MonoDevelop.Debugger.Win32/CorApi/CorApi.csproj index 2caff90533..d4f4e6e160 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/CorApi/CorApi.csproj +++ b/main/src/addins/MonoDevelop.Debugger.Win32/CorApi/CorApi.csproj @@ -64,5 +64,6 @@ <Compile Include="RawAssemblyAttributes.cs" /> <Compile Include="WindowsImports.cs" /> </ItemGroup> + <Import Project="..\..\..\..\external\debugger-libs\Mono.Debugging.settings" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> </Project> diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/CorApi2.csproj b/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/CorApi2.csproj index 1b39e0e24e..184f092098 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/CorApi2.csproj +++ b/main/src/addins/MonoDevelop.Debugger.Win32/CorApi2/CorApi2.csproj @@ -131,6 +131,7 @@ <Compile Include="Extensions\ProcessExtensions.cs" /> <Compile Include="Extensions\DebuggerExtensions.cs" /> </ItemGroup> + <Import Project="..\..\..\..\\external\debugger-libs\Mono.Debugging.settings" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32.sln b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32.sln new file mode 100644 index 0000000000..9bfe1ee53e --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32.sln @@ -0,0 +1,40 @@ +
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Debugging.Win32", "Mono.Debugging.Win32\Mono.Debugging.Win32.csproj", "{74704C00-5861-4F86-920C-865148A175C5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CorApi2", "CorApi2\CorApi2.csproj", "{69136056-BFD3-4CEC-BB41-D9991C79593C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CorApi", "CorApi\CorApi.csproj", "{9FBCC262-10DC-4E84-A5C4-17230BBF8862}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Debugging", "..\..\..\external\debugger-libs\Mono.Debugging\Mono.Debugging.csproj", "{90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {74704C00-5861-4F86-920C-865148A175C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74704C00-5861-4F86-920C-865148A175C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74704C00-5861-4F86-920C-865148A175C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74704C00-5861-4F86-920C-865148A175C5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {69136056-BFD3-4CEC-BB41-D9991C79593C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {69136056-BFD3-4CEC-BB41-D9991C79593C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {69136056-BFD3-4CEC-BB41-D9991C79593C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {69136056-BFD3-4CEC-BB41-D9991C79593C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9FBCC262-10DC-4E84-A5C4-17230BBF8862}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9FBCC262-10DC-4E84-A5C4-17230BBF8862}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9FBCC262-10DC-4E84-A5C4-17230BBF8862}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9FBCC262-10DC-4E84-A5C4-17230BBF8862}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90C99ADB-7D4B-4EB4-98C2-40BD1B14C7D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerBacktrace.cs b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerBacktrace.cs index 5de0135b49..ea3d64e164 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerBacktrace.cs +++ b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerBacktrace.cs @@ -7,6 +7,7 @@ using Microsoft.Samples.Debugging.CorMetadata; using Mono.Debugging.Client;
using Mono.Debugging.Evaluation;
using System.Linq;
+using System.Runtime.InteropServices;
namespace Mono.Debugging.Win32
{
@@ -29,12 +30,27 @@ namespace Mono.Debugging.Win32 internal static IEnumerable<CorFrame> GetFrames (CorThread thread)
{
- foreach (CorChain chain in thread.Chains) {
- if (!chain.IsManaged)
- continue;
- foreach (CorFrame frame in chain.Frames)
- yield return frame;
+ var corFrames = new List<CorFrame> ();
+ try {
+ foreach (CorChain chain in thread.Chains) {
+ if (!chain.IsManaged)
+ continue;
+ try {
+ var chainFrames = chain.Frames;
+
+ foreach (CorFrame frame in chainFrames)
+ corFrames.Add (frame);
+ }
+ catch (COMException e) {
+ DebuggerLoggingService.LogMessage ("Failed to enumerate frames of chain: {0}", e.Message);
+ }
+ }
+
+ }
+ catch (COMException e) {
+ DebuggerLoggingService.LogMessage ("Failed to enumerate chains of thread: {0}", e.Message);
}
+ return corFrames;
}
internal List<CorFrame> FrameList {
diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerSession.cs b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerSession.cs index e8f7ec0b68..acf6bbafa8 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerSession.cs +++ b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorDebuggerSession.cs @@ -888,13 +888,15 @@ namespace Mono.Debugging.Win32 {
MtaThread.Run (delegate
{
- CorBreakpoint bp = binfo.Handle as CorFunctionBreakpoint;
- if (bp != null) {
- try {
- bp.Activate (enable);
- }
- catch (COMException e) {
- HandleBreakpointException (binfo, e);
+ var bpList = binfo.Handle as List<CorFunctionBreakpoint>;
+ if (bpList != null) {
+ foreach (var bp in bpList) {
+ try {
+ bp.Activate (enable);
+ }
+ catch (COMException e) {
+ HandleBreakpointException (binfo, e);
+ }
}
}
});
@@ -1040,16 +1042,21 @@ namespace Mono.Debugging.Win32 // FIXME: implement breaking on function name
binfo.SetStatus (BreakEventStatus.Invalid, "Function breakpoint is not implemented");
return binfo;
- } else {
- DocInfo doc = null;
+ }
+ else {
+ var docInfos = new List<DocInfo> ();
lock (appDomainsLock) {
foreach (var appDomainInfo in appDomains) {
var documents = appDomainInfo.Value.Documents;
- if (documents.TryGetValue (Path.GetFullPath (bp.FileName), out doc)) {
- break;
+ DocInfo docInfo = null;
+ if (documents.TryGetValue (Path.GetFullPath (bp.FileName), out docInfo)) {
+ docInfos.Add (docInfo);
}
}
}
+
+ var doc = docInfos.FirstOrDefault (); //get info about source position using SymbolReader of first DocInfo
+
if (doc == null) {
binfo.SetStatus (BreakEventStatus.NotBound, string.Format("{0} is not found among the loaded symbol documents", bp.FileName));
return binfo;
@@ -1145,16 +1152,22 @@ namespace Mono.Debugging.Win32 return binfo;
}
- CorFunction func = doc.ModuleInfo.Module.GetFunctionFromToken (bestMethod.Token.GetToken ());
- try {
- CorFunctionBreakpoint corBp = func.ILCode.CreateBreakpoint (bestSp.Offset);
- breakpoints[corBp] = binfo;
- binfo.Handle = corBp;
- corBp.Activate (bp.Enabled);
- binfo.SetStatus (BreakEventStatus.Bound, null);
- }
- catch (COMException e) {
- HandleBreakpointException (binfo, e);
+ foreach (var docInfo in docInfos) {
+ CorFunction func = docInfo.ModuleInfo.Module.GetFunctionFromToken (bestMethod.Token.GetToken ());
+
+ try {
+ CorFunctionBreakpoint corBp = func.ILCode.CreateBreakpoint (bestSp.Offset);
+ breakpoints[corBp] = binfo;
+
+ if (binfo.Handle == null)
+ binfo.Handle = new List<CorFunctionBreakpoint> ();
+ (binfo.Handle as List<CorFunctionBreakpoint>).Add (corBp);
+ corBp.Activate (bp.Enabled);
+ binfo.SetStatus (BreakEventStatus.Bound, null);
+ }
+ catch (COMException e) {
+ HandleBreakpointException (binfo, e);
+ }
}
return binfo;
}
@@ -1298,12 +1311,14 @@ namespace Mono.Debugging.Win32 MtaThread.Run (delegate
{
- CorFunctionBreakpoint corBp = (CorFunctionBreakpoint)bi.Handle;
- try {
- corBp.Activate (false);
- }
- catch (COMException e) {
- HandleBreakpointException (bi, e);
+ var corBpList = (List<CorFunctionBreakpoint>)bi.Handle;
+ foreach (var corBp in corBpList) {
+ try {
+ corBp.Activate (false);
+ }
+ catch (COMException e) {
+ HandleBreakpointException (bi, e);
+ }
}
});
}
diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorObjectAdaptor.cs b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorObjectAdaptor.cs index fc7694427f..f43c6d913d 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorObjectAdaptor.cs +++ b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/CorObjectAdaptor.cs @@ -154,7 +154,7 @@ namespace Mono.Debugging.Win32 }
catch (Exception ex) {
DebuggerLoggingService.LogError ("Exception in GetTypeName()", ex);
- return t.FullName;
+ return "[Unknown type]";
}
}
diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/Mono.Debugging.Win32.csproj b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/Mono.Debugging.Win32.csproj index 1c43f87bca..7565b34341 100644 --- a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/Mono.Debugging.Win32.csproj +++ b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/Mono.Debugging.Win32.csproj @@ -91,6 +91,7 @@ <Name>CorApi</Name> </ProjectReference> </ItemGroup> + <Import Project="..\..\..\..\\external\debugger-libs\Mono.Debugging.settings" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/Mono.Debugging.Win32.nuspec b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/Mono.Debugging.Win32.nuspec new file mode 100644 index 0000000000..53cf655d2d --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger.Win32/Mono.Debugging.Win32/Mono.Debugging.Win32.nuspec @@ -0,0 +1,24 @@ +<?xml version="1.0"?>
+<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+ <id>Mono.Debugging.Win32</id>
+ <version>$buildver$</version>
+ <title>Mono.Debugging.Win32</title>
+ <authors>MonoDevelop team</authors>
+ <owners>MonoDevelop team</owners>
+ <licenseUrl>http://opensource.org/licenses/mit-license.php</licenseUrl>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <projectUrl>https://github.com/mono/monodevelop</projectUrl>
+ <summary>Debugger implementation for CorDebug</summary>
+ <description>Debugger implementation for CorDebug</description>
+ <language>en-US</language>
+ <tags>mono debug debugger cordebug</tags>
+ <dependencies>
+ <dependency id="Mono.Debugging" version="$buildver$" />
+ </dependencies>
+ </metadata>
+ <files>
+ <file src="bin\$Configuration$\CorApi.dll" target="lib/net45" />
+ <file src="bin\$Configuration$\CorApi2.dll" target="lib/net45" />
+ </files>
+</package>
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs index ed9f3dead5..149c0d5d7f 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs @@ -2413,11 +2413,8 @@ namespace MonoDevelop.Debugger } } - class DebugCompletionDataList: List<MonoDevelop.Ide.CodeCompletion.CompletionData>, ICompletionDataList + class DebugCompletionDataList: CompletionDataList { - public int TriggerWordStart { get; set; } - public int TriggerWordLength { get; set; } - public bool IsSorted { get; set; } public DebugCompletionDataList (Mono.Debugging.Client.CompletionData data) { IsSorted = false; @@ -2425,45 +2422,6 @@ namespace MonoDevelop.Debugger Add (new DebugCompletionData (it)); AutoSelect =true; } - public bool AutoSelect { get; set; } - public string DefaultCompletionString { - get { - return string.Empty; - } - } - - public bool AutoCompleteUniqueMatch { - get { return false; } - } - - public bool AutoCompleteEmptyMatch { - get { return false; } - } - public bool AutoCompleteEmptyMatchOnCurlyBrace { - get { return false; } - } - public bool CloseOnSquareBrackets { - get { - return false; - } - } - - public CompletionSelectionMode CompletionSelectionMode { - get; set; - } - - static readonly List<ICompletionKeyHandler> keyHandler = new List<ICompletionKeyHandler> (); - public IEnumerable<ICompletionKeyHandler> KeyHandler { get { return keyHandler;} } - - public void OnCompletionListClosed (EventArgs e) - { - var handler = CompletionListClosed; - - if (handler != null) - handler (this, e); - } - - public event EventHandler CompletionListClosed; } class DebugCompletionData : MonoDevelop.Ide.CodeCompletion.CompletionData diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj index 05a470b2a5..12bb610210 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests.csproj @@ -33,6 +33,7 @@ </PropertyGroup> <ItemGroup> <Reference Include="System" /> + <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs" /> @@ -64,6 +65,11 @@ <Name>UnitTests</Name> <Private>False</Private> </ProjectReference> + <ProjectReference Include="..\..\MonoDevelop.PackageManagement\MonoDevelop.PackageManagement.csproj"> + <Project>{F218643D-2E74-4309-820E-206A54B7133F}</Project> + <Name>MonoDevelop.PackageManagement</Name> + <Private>False</Private> + </ProjectReference> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> </Project> diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs index 39280bfb9d..b63299ea3a 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreMSBuildProjectTests.cs @@ -68,6 +68,7 @@ namespace MonoDevelop.DotNetCore.Tests void ReadProject () { + project.ReadProjectHeader (msbuildProject); project.ReadProject (msbuildProject); } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreProjectTests.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreProjectTests.cs index d7fe12f60d..7fd1161308 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreProjectTests.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Tests/MonoDevelop.DotNetCore.Tests/DotNetCoreProjectTests.cs @@ -26,6 +26,8 @@ using System.Linq; using System.Threading.Tasks; +using System.Xml; +using MonoDevelop.PackageManagement; using MonoDevelop.Projects; using NUnit.Framework; using UnitTests; @@ -62,5 +64,32 @@ namespace MonoDevelop.DotNetCore.Tests Assert.IsNull (project.MSBuildProject.DefaultTargets); Assert.AreEqual ("15.0", project.MSBuildProject.ToolsVersion); } + + [Test] + public async Task SdkConsoleProject_AddPackageReference_VersionWrittenAsAttribute () + { + string solutionFileName = Util.GetSampleProject ("dotnetcore-console", "dotnetcore-sdk-console.sln"); + var solution = (Solution) await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solutionFileName); + var project = solution.GetAllProjects ().Single (); + string projectFileName = project.FileName; + + var packageReference = ProjectPackageReference.Create ("Test", "1.2.3"); + project.Items.Add (packageReference); + + await project.SaveAsync (Util.GetMonitor ()); + + // Reload project. + var doc = new XmlDocument (); + doc.Load (projectFileName); + + var itemGroupElement = (XmlElement)doc.DocumentElement.ChildNodes[1]; + var packageReferenceElement = (XmlElement)itemGroupElement.ChildNodes[1]; + + Assert.AreEqual ("PackageReference", packageReferenceElement.Name); + Assert.AreEqual ("Test", packageReferenceElement.GetAttribute ("Include")); + Assert.AreEqual ("1.2.3", packageReferenceElement.GetAttribute ("Version")); + Assert.AreEqual (0, packageReferenceElement.ChildNodes.Count); + Assert.IsTrue (packageReferenceElement.IsEmpty); + } } }
\ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj index 542fb8f1c9..12158322e7 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.csproj @@ -57,6 +57,7 @@ <Compile Include="MonoDevelop.DotNetCore\DotNetCoreSdkPaths.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreMSBuildProject.cs" /> <Compile Include="MonoDevelop.DotNetCore\DotNetCoreCanReferenceProjectExtension.cs" /> + <Compile Include="MonoDevelop.DotNetCore\DotNetCoreProjectBuilderMaintainer.cs" /> </ItemGroup> <ItemGroup> <Folder Include="MonoDevelop.DotNetCore\" /> diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs index 67d819598e..8c3a4567f3 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreMSBuildProject.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Linq; +using MonoDevelop.PackageManagement; using MonoDevelop.Projects; using MonoDevelop.Projects.MSBuild; @@ -52,13 +53,28 @@ namespace MonoDevelop.DotNetCore get { return Sdk != null; } } + public bool HasToolsVersion () + { + return !string.IsNullOrEmpty (ToolsVersion); + } + public CompileTarget DefaultCompileTarget { get { return defaultCompileTarget; } } - public void ReadProject (MSBuildProject project) + /// <summary> + /// Ensure MSBuildProject has ToolsVersion set to 15.0 so the correct + /// MSBuild targets are imported. + /// </summary> + public void ReadProjectHeader (MSBuildProject project) { ToolsVersion = project.ToolsVersion; + if (!HasToolsVersion ()) + project.ToolsVersion = "15.0"; + } + + public void ReadProject (MSBuildProject project) + { IsOutputTypeDefined = project.IsOutputTypeDefined (); targetFrameworks = project.GetTargetFrameworks ().ToList (); hasRootNamespace = project.HasGlobalProperty ("RootNamespace"); @@ -87,7 +103,7 @@ namespace MonoDevelop.DotNetCore project.DefaultTargets = null; - if (!string.IsNullOrEmpty (ToolsVersion)) + if (HasToolsVersion ()) project.ToolsVersion = ToolsVersion; if (HasSdk) { @@ -96,6 +112,12 @@ namespace MonoDevelop.DotNetCore } } + public void AddKnownItemAttributes (MSBuildProject project) + { + if (HasSdk) + ProjectPackageReference.AddKnownItemAttributes (project); + } + public bool AddInternalSdkImports (MSBuildProject project, DotNetCoreSdkPaths sdkPaths) { return AddInternalSdkImports (project, sdkPaths.MSBuildSDKsPath, sdkPaths.ProjectImportProps, sdkPaths.ProjectImportTargets); diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectBuilderMaintainer.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectBuilderMaintainer.cs new file mode 100644 index 0000000000..16b70001ae --- /dev/null +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectBuilderMaintainer.cs @@ -0,0 +1,71 @@ +// +// DotNetCoreProjectBuilderMaintainer.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Collections.Generic; +using MonoDevelop.PackageManagement; +using MonoDevelop.Projects; +using System.Linq; + +namespace MonoDevelop.DotNetCore +{ + class DotNetCoreProjectBuilderMaintainer + { + /// <summary> + /// If the target framework of the project has changed then non .NET Core projects + /// that reference this project may need their project builders refreshed so + /// that the correct build result occurs. If the new framework is incompatible + /// then without the project builder refresh then the build error will not appear + /// until the solution is reloaded. + /// </summary> + public static void OnProjectReload (ProjectReloadedEventArgs reloadEventArgs) + { + var reloadedProject = reloadEventArgs.NewProject.DotNetProject; + foreach (var project in GetAllNonDotNetCoreProjectsReferencingProject (reloadedProject)) { + project.ReloadProjectBuilder (); + } + } + + static IEnumerable<DotNetProject> GetAllNonDotNetCoreProjects (Solution parentSolution) + { + return parentSolution.GetAllDotNetProjects () + .Where (project => !project.HasFlavor<DotNetCoreProjectExtension> ()); + } + + static IEnumerable<DotNetProject> GetAllNonDotNetCoreProjectsReferencingProject (DotNetProject dotNetCoreProject) + { + foreach (DotNetProject project in GetAllNonDotNetCoreProjects (dotNetCoreProject.ParentSolution)) { + foreach (ProjectReference projectReference in project.References) { + if (projectReference.ReferenceType == ReferenceType.Project) { + Project resolvedProject = projectReference.ResolveProject (project.ParentSolution); + if (resolvedProject == dotNetCoreProject) { + yield return project; + } + } + } + } + } + } +} diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs index bf1e90dd7b..1697d3adf2 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectExtension.cs @@ -31,6 +31,7 @@ using System.Threading.Tasks; using MonoDevelop.Core; using MonoDevelop.Core.Execution; using MonoDevelop.PackageManagement; +using MonoDevelop.PackageManagement.Commands; using MonoDevelop.Projects; using MonoDevelop.Projects.MSBuild; @@ -91,8 +92,16 @@ namespace MonoDevelop.DotNetCore return DotNetCoreFrameworkCompatibility.CanReferenceNetStandardProject (Project.TargetFramework.Id, targetProject); } + protected override void OnReadProjectHeader (ProgressMonitor monitor, MSBuildProject msproject) + { + dotNetCoreMSBuildProject.ReadProjectHeader (msproject); + base.OnReadProjectHeader (monitor, msproject); + } + protected override void OnReadProject (ProgressMonitor monitor, MSBuildProject msproject) { + dotNetCoreMSBuildProject.AddKnownItemAttributes (Project.MSBuildProject); + base.OnReadProject (monitor, msproject); dotNetCoreMSBuildProject.ReadProject (msproject); @@ -320,5 +329,37 @@ namespace MonoDevelop.DotNetCore return filteredFiles.ToArray (); } + + protected override void OnSetFormat (MSBuildFileFormat format) + { + // Do not call base class since the solution's FileFormat will be used which is + // VS 2012 and this will set the ToolsVersion to "4.0" which we are preventing. + // Setting the ToolsVersion to "4.0" can cause the MSBuild tasks such as + // ResolveAssemblyReferences to fail for .NET Core projects when the project + // xml is generated in memory for the project builder at the same time as the + // project file is being saved. + } + + protected override void OnReferenceAddedToProject (ProjectReferenceEventArgs e) + { + base.OnReferenceAddedToProject (e); + + if (!Project.Loading) + RestoreNuGetPackages (); + } + + protected override void OnReferenceRemovedFromProject (ProjectReferenceEventArgs e) + { + base.OnReferenceRemovedFromProject (e); + + if (!Project.Loading) + RestoreNuGetPackages (); + } + + void RestoreNuGetPackages () + { + Runtime.AssertMainThread (); + RestorePackagesInProjectHandler.Run (Project); + } } } diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs index 7678458a26..d118d6f94d 100644 --- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs +++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectReloadMonitor.cs @@ -31,6 +31,7 @@ using System.Threading.Tasks; using MonoDevelop.Core; using MonoDevelop.Ide; using MonoDevelop.PackageManagement; +using MonoDevelop.PackageManagement.Commands; using MonoDevelop.Projects; namespace MonoDevelop.DotNetCore @@ -74,9 +75,8 @@ namespace MonoDevelop.DotNetCore void OnDotNetCoreProjectReloaded (ProjectReloadedEventArgs e) { - var action = new RestoreNuGetPackagesInDotNetCoreProject (e.NewProject.DotNetProject); - var message = ProgressMonitorStatusMessageFactory.CreateRestoringPackagesInProjectMessage (); - PackageManagementServices.BackgroundPackageActionRunner.Run (message, action); + DotNetCoreProjectBuilderMaintainer.OnProjectReload (e); + RestorePackagesInProjectHandler.Run (e.NewProject.DotNetProject); } async void FileChanged (object sender, FileEventArgs e) diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs index 0ddb461fc4..05f8b43288 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeNuGetPackageManager.cs @@ -87,7 +87,7 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers public ILogger GetLatestVersionLogger; public CancellationToken GetLatestVersionCancellationToken; - public Task<NuGetVersion> GetLatestVersionAsync ( + public Task<ResolvedPackage> GetLatestVersionAsync ( string packageId, NuGetProject project, ResolutionContext resolutionContext, @@ -102,7 +102,8 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers GetLatestVersionLogger = log; GetLatestVersionCancellationToken = token; - return Task.FromResult (LatestVersion); + var resolvedPackage = new ResolvedPackage (LatestVersion, true); + return Task.FromResult (resolvedPackage); } public List<FakeNuGetProjectAction> InstallActions = new List<FakeNuGetProjectAction> (); diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageRestoreManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageRestoreManager.cs index dcc24d3e9c..76972ec662 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageRestoreManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageRestoreManager.cs @@ -137,6 +137,13 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers { throw new NotImplementedException (); } + + public IEnumerable<PackageRestoreData> GetPackagesRestoreData ( + string solutionDirectory, + Dictionary<PackageReference, List<string>> packageReferencesDict) + { + throw new NotImplementedException (); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageSearchMetadata.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageSearchMetadata.cs index 1bf857f1b7..19ead089a6 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageSearchMetadata.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakePackageSearchMetadata.cs @@ -69,6 +69,8 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers public string Title { get; set; } + public bool IsListed { get; set; } + public Task<IEnumerable<VersionInfo>> GetVersionsAsync () { throw new NotImplementedException (); diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs index 03f09a0b13..37c33445cd 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/FakeSolutionManager.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using NuGet.Configuration; using NuGet.PackageManagement; using NuGet.ProjectManagement; @@ -92,6 +93,7 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers public event EventHandler<NuGetProjectEventArgs> NuGetProjectRemoved; public event EventHandler<NuGetProjectEventArgs> NuGetProjectRenamed; public event EventHandler<NuGetProjectEventArgs> AfterNuGetProjectRenamed; + public event EventHandler<NuGetProjectEventArgs> NuGetProjectUpdated; public event EventHandler SolutionClosed; public event EventHandler SolutionClosing; public event EventHandler SolutionOpened; @@ -154,6 +156,11 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers public void ClearProjectCache () { } + + public Task<NuGetProject> UpdateNuGetProjectToPackageRef (NuGetProject oldProject) + { + throw new NotImplementedException (); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableProjectPackageReference.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableProjectPackageReference.cs index 781603602c..20a18a7c08 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableProjectPackageReference.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.Helpers/TestableProjectPackageReference.cs @@ -24,6 +24,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +using MonoDevelop.Projects.MSBuild; + namespace MonoDevelop.PackageManagement.Tests.Helpers { class TestableProjectPackageReference : ProjectPackageReference @@ -33,5 +35,10 @@ namespace MonoDevelop.PackageManagement.Tests.Helpers Include = id; Metadata.SetValue ("Version", version); } + + public void CallWrite (MSBuildItem buildItem) + { + base.Write (null, buildItem); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj index d90a7eb80c..10052bfc57 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests.csproj @@ -199,6 +199,7 @@ <Compile Include="MonoDevelop.PackageManagement.Tests\PackageSpecCreatorTests.cs" /> <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\FakeMSBuildEvaluatedPropertyCollection.cs" /> <Compile Include="MonoDevelop.PackageManagement.Tests.Helpers\TestableProjectPackageReference.cs" /> + <Compile Include="MonoDevelop.PackageManagement.Tests\ProjectPackageReferenceTests.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\..\core\MonoDevelop.Core\MonoDevelop.Core.csproj"> diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs index 0523739cb1..a3cc11c99e 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/DotNetCoreNuGetProjectTests.cs @@ -197,14 +197,13 @@ namespace MonoDevelop.PackageManagement.Tests public async Task GetPackageSpecsAsync_NewProject_BaseIntermediatePathUsedForProjectAssetsJsonFile () { CreateNuGetProject ("MyProject", @"d:\projects\MyProject\MyProject.csproj"); - string expectedAssetsFilePath = @"d:\projects\MyProject\obj\project.assets.json".ToNativePath (); PackageSpec spec = await GetPackageSpecsAsync (); - Assert.AreEqual (expectedAssetsFilePath, spec.FilePath); + Assert.AreEqual (dotNetProject.FileName.ToString (), spec.FilePath); Assert.AreEqual ("MyProject", spec.Name); Assert.AreEqual ("1.0.0", spec.Version.ToString ()); - Assert.AreEqual (RestoreOutputType.NETCore, spec.RestoreMetadata.OutputType); + Assert.AreEqual (ProjectStyle.PackageReference, spec.RestoreMetadata.ProjectStyle); Assert.AreEqual ("MyProject", spec.RestoreMetadata.ProjectName); Assert.AreEqual (dotNetProject.FileName.ToString (), spec.RestoreMetadata.ProjectPath); Assert.AreEqual (dotNetProject.FileName.ToString (), spec.RestoreMetadata.ProjectUniqueName); diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackageSpecCreatorTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackageSpecCreatorTests.cs index d62372d8c5..2c4aef7797 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackageSpecCreatorTests.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/PackageSpecCreatorTests.cs @@ -84,14 +84,14 @@ namespace MonoDevelop.PackageManagement.Tests CreateProject ("MyProject", @"d:\projects\MyProject\MyProject.csproj"); project.BaseIntermediateOutputPath = @"d:\projects\MyProject\obj".ToNativePath (); AddTargetFramework ("netcoreapp1.0"); - string expectedAssetsFilePath = @"d:\projects\MyProject\obj\project.assets.json".ToNativePath (); + string expectedFilePath = @"d:\projects\MyProject\MyProject.csproj".ToNativePath (); CreatePackageSpec (); - Assert.AreEqual (expectedAssetsFilePath, spec.FilePath); + Assert.AreEqual (expectedFilePath, spec.FilePath); Assert.AreEqual ("MyProject", spec.Name); Assert.AreEqual ("1.0.0", spec.Version.ToString ()); - Assert.AreEqual (RestoreOutputType.NETCore, spec.RestoreMetadata.OutputType); + Assert.AreEqual (ProjectStyle.PackageReference, spec.RestoreMetadata.ProjectStyle); Assert.AreEqual ("MyProject", spec.RestoreMetadata.ProjectName); Assert.AreEqual (project.FileName.ToString (), spec.RestoreMetadata.ProjectPath); Assert.AreEqual (project.FileName.ToString (), spec.RestoreMetadata.ProjectUniqueName); @@ -111,7 +111,7 @@ namespace MonoDevelop.PackageManagement.Tests var targetFramework = spec.TargetFrameworks.Single (); var dependency = targetFramework.Dependencies.Single (); Assert.AreEqual ("MyProject", spec.Name); - Assert.AreEqual (RestoreOutputType.NETCore, spec.RestoreMetadata.OutputType); + Assert.AreEqual (ProjectStyle.PackageReference, spec.RestoreMetadata.ProjectStyle); Assert.AreEqual ("MyProject", spec.RestoreMetadata.ProjectName); Assert.AreEqual ("netcoreapp1.0", spec.RestoreMetadata.OriginalTargetFrameworks.Single ()); Assert.AreEqual (".NETCoreApp,Version=v1.0", targetFramework.FrameworkName.ToString ()); diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/ProjectPackageReferenceTests.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/ProjectPackageReferenceTests.cs new file mode 100644 index 0000000000..77dcc6c343 --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Tests/MonoDevelop.PackageManagement.Tests/ProjectPackageReferenceTests.cs @@ -0,0 +1,61 @@ +// +// ProjectPackageReferenceTests.cs +// +// Author: +// Matt Ward <matt.ward@xamarin.com> +// +// Copyright (c) 2017 Xamarin Inc. (http://xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Xml; +using MonoDevelop.PackageManagement.Tests.Helpers; +using MonoDevelop.Projects.MSBuild; +using NUnit.Framework; + +namespace MonoDevelop.PackageManagement.Tests +{ + [TestFixture] + public class ProjectPackageReferenceTests + { + [Test] + public void Write_Version_WrittenAsAttribute () + { + var p = new MSBuildProject (); + p.LoadXml ("<Project ToolsVersion=\"15.0\" />"); + ProjectPackageReference.AddKnownItemAttributes (p); + + var item = p.AddNewItem ("PackageReference", "Test"); + var packageReference = new TestableProjectPackageReference ("Test", "1.2.3"); + packageReference.CallWrite (item); + + string xml = p.SaveToString (); + var doc = new XmlDocument (); + doc.LoadXml (xml); + + var itemGroupElement = (XmlElement)doc.DocumentElement.ChildNodes[0]; + var packageReferenceElement = (XmlElement)itemGroupElement.ChildNodes[0]; + + Assert.AreEqual ("PackageReference", packageReferenceElement.Name); + Assert.AreEqual ("1.2.3", packageReferenceElement.GetAttribute ("Version")); + Assert.AreEqual (0, packageReferenceElement.ChildNodes.Count); + Assert.IsTrue (packageReferenceElement.IsEmpty); + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj index 36355fd328..b21c550981 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj @@ -629,6 +629,7 @@ </ItemGroup> <ItemGroup> <InternalsVisibleTo Include="MonoDevelop.DotNetCore" /> + <InternalsVisibleTo Include="MonoDevelop.DotNetCore.Tests" /> <InternalsVisibleTo Include="MonoDevelop.PackageManagement.Cmdlets" /> <InternalsVisibleTo Include="MonoDevelop.PackageManagement.Extensions" /> <InternalsVisibleTo Include="MonoDevelop.PackageManagement.Tests" /> diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs index 63e10d7e7f..584e5e3d85 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/DotNetCoreNuGetProject.cs @@ -294,10 +294,21 @@ namespace MonoDevelop.PackageManagement public bool ProjectRequiresReloadAfterRestore () { - if (project.DotNetCoreNuGetMSBuildFilesExist ()) - return false; - - return true; + // Disabled. Newer Sdk style projects no longer need to be + // re-evaluated since the sdk imports are not downloaded + // from NuGet. Possibly a check should be made for the + // generated nuget.g.targets and nuget.g.props files. These + // are still generated by the latest .NET Core SDK on restore + // but they do not contain any Sdk imports. Disabling this + // also reduces the chance of the project model and project + // builder reading/writing the MSBuildProject at the same time + // causing inconsistencies. + return false; + + //if (project.DotNetCoreNuGetMSBuildFilesExist ()) + // return false; + + //return true; } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs index 4f4b75056e..7bbcddf983 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/INuGetPackageManager.cs @@ -32,7 +32,6 @@ using NuGet.PackageManagement; using NuGet.Packaging.Core; using NuGet.ProjectManagement; using NuGet.Protocol.Core.Types; -using NuGet.Versioning; namespace MonoDevelop.PackageManagement { @@ -71,7 +70,7 @@ namespace MonoDevelop.PackageManagement INuGetProjectContext nuGetProjectContext, CancellationToken token); - Task<NuGetVersion> GetLatestVersionAsync ( + Task<ResolvedPackage> GetLatestVersionAsync ( string packageId, NuGetProject project, ResolutionContext resolutionContext, diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/InstallNuGetPackageAction.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/InstallNuGetPackageAction.cs index ee750254c3..bcb237d790 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/InstallNuGetPackageAction.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/InstallNuGetPackageAction.cs @@ -135,7 +135,8 @@ namespace MonoDevelop.PackageManagement async Task ExecuteAsync (CancellationToken cancellationToken)
{
if (Version == null) {
- Version = await GetLatestPackageVersion (PackageId, cancellationToken);
+ ResolvedPackage resolvedPackage = await GetLatestPackageVersion (PackageId, cancellationToken);
+ Version = resolvedPackage?.LatestVersion;
}
var identity = new PackageIdentity (PackageId, Version);
@@ -174,7 +175,7 @@ namespace MonoDevelop.PackageManagement await project.RunPostProcessAsync (context, cancellationToken);
}
- Task<NuGetVersion> GetLatestPackageVersion (string packageId, CancellationToken cancellationToken)
+ Task<ResolvedPackage> GetLatestPackageVersion (string packageId, CancellationToken cancellationToken)
{
return packageManager.GetLatestVersionAsync (
packageId,
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs index 68d1c0b29f..fd33dc0dd8 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopNuGetPackageManager.cs @@ -36,7 +36,6 @@ using NuGet.Packaging.Core; using NuGet.ProjectManagement; using NuGet.ProjectManagement.Projects; using NuGet.Protocol.Core.Types; -using NuGet.Versioning; namespace MonoDevelop.PackageManagement { @@ -87,7 +86,7 @@ namespace MonoDevelop.PackageManagement token); } - public Task<NuGetVersion> GetLatestVersionAsync ( + public Task<ResolvedPackage> GetLatestVersionAsync ( string packageId, NuGetProject project, ResolutionContext resolutionContext, diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopPackageRestoreManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopPackageRestoreManager.cs index 8883cbd20e..131eec2365 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopPackageRestoreManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopPackageRestoreManager.cs @@ -30,6 +30,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using NuGet.PackageManagement; +using NuGet.Packaging; using NuGet.ProjectManagement; using NuGet.Protocol.Core.Types; @@ -111,6 +112,13 @@ namespace MonoDevelop.PackageManagement token ); } + + public IEnumerable<PackageRestoreData> GetPackagesRestoreData ( + string solutionDirectory, + Dictionary<PackageReference, List<string>> packageReferencesDict) + { + return restoreManager.GetPackagesRestoreData (solutionDirectory, packageReferencesDict); + } } internal static class PackageRestoreManagerExtensions diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopSolutionManager.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopSolutionManager.cs index 7795147682..1418537719 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopSolutionManager.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopSolutionManager.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using MonoDevelop.Core;
using MonoDevelop.Projects;
using NuGet.Configuration;
@@ -97,6 +98,7 @@ namespace MonoDevelop.PackageManagement public event EventHandler<NuGetProjectEventArgs> NuGetProjectRemoved;
public event EventHandler<NuGetProjectEventArgs> NuGetProjectRenamed;
public event EventHandler<NuGetProjectEventArgs> AfterNuGetProjectRenamed;
+ public event EventHandler<NuGetProjectEventArgs> NuGetProjectUpdated;
public event EventHandler SolutionClosed;
public event EventHandler SolutionClosing;
public event EventHandler SolutionOpened;
@@ -191,6 +193,11 @@ namespace MonoDevelop.PackageManagement public void EnsureSolutionIsLoaded ()
{
+ }
+
+ public Task<NuGetProject> UpdateNuGetProjectToPackageRef (NuGetProject oldProject)
+ {
+ return Task.FromResult (oldProject);
} }
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSpecCreator.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSpecCreator.cs index 9dafae7f4c..6035de1d38 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSpecCreator.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageSpecCreator.cs @@ -42,7 +42,7 @@ namespace MonoDevelop.PackageManagement public static PackageSpec CreatePackageSpec (IDotNetProject project) { var packageSpec = new PackageSpec (GetTargetFrameworks (project)); - packageSpec.FilePath = project.BaseIntermediateOutputPath.Combine (LockFileFormat.AssetsFileName); + packageSpec.FilePath = project.FileName; packageSpec.Name = project.Name; packageSpec.Version = GetVersion (project); @@ -87,7 +87,7 @@ namespace MonoDevelop.PackageManagement static ProjectRestoreMetadata CreateRestoreMetadata (PackageSpec packageSpec, IDotNetProject project) { return new ProjectRestoreMetadata { - OutputType = RestoreOutputType.NETCore, + ProjectStyle = ProjectStyle.PackageReference, ProjectPath = project.FileName, ProjectName = packageSpec.Name, ProjectUniqueName = project.FileName, diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectPackageReference.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectPackageReference.cs index 5cb98c8379..44fdfae7c9 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectPackageReference.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/ProjectPackageReference.cs @@ -104,5 +104,10 @@ namespace MonoDevelop.PackageManagement { return string.Format ("[PackageReference: {0} {1}]", Include, Metadata.GetValue ("Version")); } + + public static void AddKnownItemAttributes (MSBuildProject project) + { + project.AddKnownItemAttribute ("PackageReference", "Version"); + } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInDotNetCoreProject.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInDotNetCoreProject.cs index 7754594e33..2d51c97468 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInDotNetCoreProject.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RestoreNuGetPackagesInDotNetCoreProject.cs @@ -76,13 +76,5 @@ namespace MonoDevelop.PackageManagement packageManagementEvents.OnPackagesRestored (); } - - static void RefreshProjectReferences (DotNetProject project) - { - Runtime.RunInMainThread (() => { - project.ReloadProjectBuilder (); - project.NotifyModified ("References"); - }); - } } } diff --git a/main/src/addins/MonoDevelop.PackageManagement/NuGet.PackageManagement.UI/PackageItemLoader.cs b/main/src/addins/MonoDevelop.PackageManagement/NuGet.PackageManagement.UI/PackageItemLoader.cs index 8aca38e310..608fec4852 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/NuGet.PackageManagement.UI/PackageItemLoader.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/NuGet.PackageManagement.UI/PackageItemLoader.cs @@ -20,9 +20,8 @@ namespace NuGet.PackageManagement.UI private readonly IPackageFeed _packageFeed;
//private PackageCollection _installedPackages;
- private SearchFilter SearchFilter => new SearchFilter
+ private SearchFilter SearchFilter => new SearchFilter(includePrerelease: _includePrerelease)
{
- IncludePrerelease = _includePrerelease,
SupportedFrameworks = _context.GetSupportedFrameworks()
};
diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/GutterMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/GutterMargin.cs index 73503866d4..88111e3109 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/GutterMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/GutterMargin.cs @@ -32,6 +32,7 @@ using System.Linq; using MonoDevelop.Components; using MonoDevelop.Ide.Editor; using MonoDevelop.Ide.Editor.Highlighting; +using MonoDevelop.Core.Text; namespace Mono.TextEditor { @@ -45,11 +46,12 @@ namespace Mono.TextEditor { this.editor = editor; - this.editor.Document.LineChanged += UpdateWidth; + this.editor.Document.TextChanged += UpdateWidth; this.editor.Document.TextSet += HandleEditorDocumenthandleTextSet; this.editor.Caret.PositionChanged += EditorCarethandlePositionChanged; } + void HandleEditorDocumenthandleTextSet (object sender, EventArgs e) { UpdateWidth (null, null); @@ -84,7 +86,7 @@ namespace Mono.TextEditor } } - void UpdateWidth (object sender, LineEventArgs args) + void UpdateWidth (object sender, TextChangeEventArgs args) { int currentLineCountLog10 = (int)System.Math.Log10 (LineCountMax); if (oldLineCountLog10 != currentLineCountLog10) { @@ -182,7 +184,7 @@ namespace Mono.TextEditor this.editor.Caret.PositionChanged -= EditorCarethandlePositionChanged; this.editor.Document.TextSet -= HandleEditorDocumenthandleTextSet; - this.editor.Document.LineChanged -= UpdateWidth; + this.editor.Document.TextChanged -= UpdateWidth; // layout = layout.Kill (); base.Dispose (); } diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs index 6b03298829..b0a8cb44c0 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextArea.cs @@ -334,7 +334,6 @@ namespace Mono.TextEditor textEditorData.RecenterEditor += TextEditorData_RecenterEditor; textEditorData.Document.TextChanged += OnDocumentStateChanged; textEditorData.Document.TextSet += OnTextSet; - textEditorData.Document.LineChanged += UpdateLinesOnTextMarkerHeightChange; textEditorData.Document.MarkerAdded += HandleTextEditorDataDocumentMarkerChange; textEditorData.Document.MarkerRemoved += HandleTextEditorDataDocumentMarkerChange; @@ -798,7 +797,6 @@ namespace Mono.TextEditor Document.HeightChanged -= TextEditorDatahandleUpdateAdjustmentsRequested; Document.TextChanged -= OnDocumentStateChanged; Document.TextSet -= OnTextSet; - Document.LineChanged -= UpdateLinesOnTextMarkerHeightChange; Document.MarkerAdded -= HandleTextEditorDataDocumentMarkerChange; Document.MarkerRemoved -= HandleTextEditorDataDocumentMarkerChange; @@ -2955,6 +2953,15 @@ namespace Mono.TextEditor var start = editor.Document.OffsetToLineNumber (args.Offset); var end = editor.Document.OffsetToLineNumber (args.Offset + args.InsertionLength); editor.Document.CommitMultipleLineUpdate (start, end); + + // TODO: Not sure if the update is needed anymore (I don't think so atm - since extending text line markers update itself) + //if (Document.CurrentAtomicUndoOperationType == OperationType.Format) + // return; + //if (!e.Line.Markers.Any (m => m is IExtendingTextLineMarker)) + // return; + //var line = e.Line.LineNumber; + //textEditorData.HeightTree.SetLineHeight (line, GetLineHeight (e.Line)); + //RedrawLine (line); } void OnTextSet (object sender, EventArgs e) @@ -3165,17 +3172,6 @@ namespace Mono.TextEditor requestResetCaretBlink = true; } - void UpdateLinesOnTextMarkerHeightChange (object sender, LineEventArgs e) - { - if (Document.CurrentAtomicUndoOperationType == OperationType.Format) - return; - if (!e.Line.Markers.Any (m => m is IExtendingTextLineMarker)) - return; - var line = e.Line.LineNumber; - textEditorData.HeightTree.SetLineHeight (line, GetLineHeight (e.Line)); - RedrawLine (line); - } - class SetCaret { MonoTextEditor view; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs index 4d486be143..024c3cb082 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs @@ -137,7 +137,6 @@ namespace Mono.TextEditor textEditor.Document.TextChanged += HandleTextReplaced; base.cursor = xtermCursor; textEditor.HighlightSearchPatternChanged += TextEditor_HighlightSearchPatternChanged; - textEditor.Document.LineChanged += TextEditorDocumentLineChanged; textEditor.GetTextEditorData ().SearchChanged += HandleSearchChanged; markerLayout = PangoUtil.CreateLayout (textEditor); defaultLayout = PangoUtil.CreateLayout (textEditor); @@ -180,11 +179,6 @@ namespace Mono.TextEditor } } - void TextEditorDocumentLineChanged (object sender, LineEventArgs e) - { - RemoveCachedLine (e.Line); - } - void HandleVAdjustmentValueChanged (object sender, EventArgs e) { //We don't want to invalidate 5 lines before start @@ -470,7 +464,6 @@ namespace Mono.TextEditor textEditor.HighlightSearchPatternChanged -= TextEditor_HighlightSearchPatternChanged; textEditor.Document.TextChanged -= HandleTextReplaced; - textEditor.Document.LineChanged -= TextEditorDocumentLineChanged; textEditor.TextArea.FocusInEvent -= HandleFocusInEvent; textEditor.TextArea.FocusOutEvent -= HandleFocusOutEvent; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskMiniMapMode.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskMiniMapMode.cs index 7887c4115f..2b9dfb7e47 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskMiniMapMode.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskMiniMapMode.cs @@ -214,12 +214,13 @@ namespace MonoDevelop.SourceEditor.QuickTasks curHeight = Math.Max (Allocation.Height, (int)(lineHeight * (TextEditor.GetTextEditorData ().VisibleLineCount))); if (GdkWindow == null || curWidth < 1 || curHeight < 1) return; - backgroundPixbuf = new Pixmap (GdkWindow, curWidth, curHeight); - backgroundBuffer = new Pixmap (GdkWindow, curWidth, curHeight); - + var displayScale = Platform.IsWindows ? GtkWorkarounds.GetScaleFactor (this) : 1.0; + backgroundPixbuf = new Pixmap (GdkWindow, (int)(curWidth * displayScale), (int)(curHeight * displayScale)); + backgroundBuffer = new Pixmap (GdkWindow, (int)(curWidth * displayScale), (int)(curHeight * displayScale)); + if (TextEditor.EditorTheme != null) { using (var cr = Gdk.CairoHelper.Create (backgroundPixbuf)) { - cr.Rectangle (0, 0, curWidth, curHeight); + cr.Rectangle (0, 0, curWidth * displayScale, curHeight * displayScale); cr.SetSourceColor (SyntaxHighlightingService.GetColor (TextEditor.EditorTheme, EditorThemeColors.Background)); cr.Fill (); } @@ -245,7 +246,7 @@ namespace MonoDevelop.SourceEditor.QuickTasks this.mode = mode; cr = Gdk.CairoHelper.Create (mode.backgroundBuffer); - + cr.LineWidth = 1; int w = mode.backgroundBuffer.ClipRegion.Clipbox.Width; int h = mode.backgroundBuffer.ClipRegion.Clipbox.Height; @@ -311,7 +312,8 @@ namespace MonoDevelop.SourceEditor.QuickTasks int GetBufferYOffset () { - int h = backgroundPixbuf.ClipRegion.Clipbox.Height - Allocation.Height; + var displayScale = Platform.IsWindows ? GtkWorkarounds.GetScaleFactor (this) : 1.0; + int h = (int)(backgroundPixbuf.ClipRegion.Clipbox.Height / displayScale) - Allocation.Height; if (h < 0) return 0; return Math.Max (0, (int)(h * (vadjustment.Value) / (vadjustment.Upper - vadjustment.Lower - vadjustment.PageSize))); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs index a58493159c..bf4e80d695 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs @@ -870,6 +870,8 @@ namespace MonoDevelop.SourceEditor.QuickTasks using (Cairo.Context cr = Gdk.CairoHelper.Create (e.Window)) { var allocation = Allocation; + var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor (this) : 1.0; + cr.Scale (1 / displayScale, 1 / displayScale); if (indicatorSurface != null) { cr.SetSourceSurface (indicatorSurface.Surface, 0, 0); cr.Paint (); @@ -877,7 +879,7 @@ namespace MonoDevelop.SourceEditor.QuickTasks CachedDraw (cr, ref backgroundSurface, allocation, - draw: (c, o) => DrawBackground (c, allocation)); + draw: (c, o) => DrawBackground (c, allocation), forceScale: displayScale); } if (TextEditor == null) return true; @@ -919,15 +921,17 @@ namespace MonoDevelop.SourceEditor.QuickTasks } } + var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor (mode) : 1.0; if (surface == null) { using (var similiar = CairoHelper.Create (IdeApp.Workbench.RootWindow.GdkWindow)) - surface = new SurfaceWrapper (similiar, allocation.Width, allocation.Height); + surface = new SurfaceWrapper (similiar, (int)(allocation.Width * displayScale), (int)(allocation.Height * displayScale)); } searchResults = mode.TextEditor.TextViewMargin.SearchResults.ToList().GetEnumerator (); allUsages = mode.AllUsages.GetEnumerator (); allTasks = mode.AllTasks.GetEnumerator (); cr = new Cairo.Context (surface.Surface); + cr.Scale (displayScale, displayScale); GLib.Idle.Add (RunHandler); } @@ -953,7 +957,8 @@ namespace MonoDevelop.SourceEditor.QuickTasks bool nextStep = false; switch (drawingStep) { case 0: - CachedDraw (cr, ref mode.backgroundSurface, allocation, draw: (c, o) => mode.DrawBackground (c, allocation)); + var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor (mode) : 1.0; + CachedDraw (cr, ref mode.backgroundSurface, allocation, draw: (c, o) => mode.DrawBackground (c, allocation), forceScale: displayScale); drawingStep++; return true; case 1: @@ -1048,12 +1053,22 @@ namespace MonoDevelop.SourceEditor.QuickTasks if (redraw) { surface.Data = parameters; using (var context = new Cairo.Context (surface.Surface)) { - draw(context, 1.0f); + context.Operator = Cairo.Operator.Clear; + context.Paint (); + context.Operator = Cairo.Operator.Over; + context.Save (); + context.Scale (displayScale, displayScale); + draw (context, 1.0f); + context.Restore (); } } + self.Save (); + self.Translate (region.X, region.Y); + self.Scale (1 / displayScale, 1 / displayScale); self.SetSourceSurface (surface.Surface, 0, 0); - self.Paint (); + self.PaintWithAlpha (opacity); + self.Restore (); } void DrawBackground (Cairo.Context cr, Gdk.Rectangle allocation) diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs index 0015bc4d46..aa9a628d1a 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs @@ -188,9 +188,6 @@ namespace MonoDevelop.SourceEditor widget = new SourceEditorWidget (this, doc); widget.TextEditor.Document.TextChanged += HandleTextReplaced; - widget.TextEditor.Document.LineChanged += HandleLineChanged; - widget.TextEditor.Document.LineInserted += HandleLineChanged; - widget.TextEditor.Document.LineRemoved += HandleLineChanged; widget.TextEditor.Document.BeginUndo += HandleBeginUndo; widget.TextEditor.Document.EndUndo += HandleEndUndo; @@ -271,22 +268,6 @@ namespace MonoDevelop.SourceEditor base.OnContentNameChanged (); } - void HandleLineChanged (object sender, Mono.TextEditor.LineEventArgs e) - { - UpdateBreakpoints (); - UpdateWidgetPositions (); - if (messageBubbleCache != null && messageBubbleCache.RemoveLine (e.Line)) { - MessageBubbleTextMarker marker = currentErrorMarkers.FirstOrDefault (m => m.LineSegment == e.Line); - if (marker != null) { - widget.TextEditor.TextViewMargin.RemoveCachedLine (e.Line); - // ensure that the line cache is renewed - marker.GetLineHeight (widget.TextEditor); - } - } - var handler = LineChanged; - if (handler != null) - handler (this, new MonoDevelop.Ide.Editor.LineEventArgs (e.Line)); - } void HandleTextReplaced (object sender, TextChangeEventArgs args) { @@ -301,6 +282,18 @@ namespace MonoDevelop.SourceEditor } } ResetRemoveMarker (); + + UpdateBreakpoints (); + UpdateWidgetPositions (); + /*if (messageBubbleCache != null && messageBubbleCache.RemoveLine (e.Line)) { + MessageBubbleTextMarker marker = currentErrorMarkers.FirstOrDefault (m => m.LineSegment == e.Line); + if (marker != null) { + widget.TextEditor.TextViewMargin.RemoveCachedLine (e.Line); + // ensure that the line cache is renewed + marker.GetLineHeight (widget.TextEditor); + } + }*/ + } void HandleEndUndo (object sender, TextDocument.UndoOperationEventArgs e) @@ -999,7 +992,6 @@ namespace MonoDevelop.SourceEditor ClipbardRingUpdated -= UpdateClipboardRing; widget.TextEditor.Document.TextChanged -= HandleTextReplaced; - widget.TextEditor.Document.LineChanged -= HandleLineChanged; widget.TextEditor.Document.BeginUndo -= HandleBeginUndo; widget.TextEditor.Document.EndUndo -= HandleEndUndo; widget.TextEditor.Caret.PositionChanged -= HandlePositionChanged; @@ -1824,6 +1816,7 @@ namespace MonoDevelop.SourceEditor var editor = widget.TextEditor; if (editor == null) return result; + result.Version = editor.Document.Version; result.TriggerOffset = triggerOffset; var loc = editor.Caret.Location; result.TriggerLine = loc.Line; @@ -1886,6 +1879,11 @@ namespace MonoDevelop.SourceEditor int triggerOffset = ctx.TriggerOffset; int length = String.IsNullOrEmpty (partialWord) ? 0 : partialWord.Length; + if (ctx.TriggerWordLength > 0 && ctx.Version != null) { + int translatedEndOffset = ctx.Version.MoveOffsetTo (data.Version, ctx.TriggerOffset + ctx.TriggerWordLength); + length = translatedEndOffset - triggerOffset; + } + // for named arguments invoke(arg:<Expr>); if (completeWord.EndsWith (":", StringComparison.Ordinal)) { if (data.GetCharAt (triggerOffset + length) == ':') @@ -3168,26 +3166,6 @@ namespace MonoDevelop.SourceEditor bracketMarkers.Clear (); } - public event EventHandler<MonoDevelop.Ide.Editor.LineEventArgs> LineChanged; - - public event EventHandler<MonoDevelop.Ide.Editor.LineEventArgs> LineInserted; - - void HandleLineInserted (object sender, Mono.TextEditor.LineEventArgs e) - { - var handler = LineInserted; - if (handler != null) - handler (this, new MonoDevelop.Ide.Editor.LineEventArgs (e.Line)); - } - - public event EventHandler<MonoDevelop.Ide.Editor.LineEventArgs> LineRemoved; - - void HandleLineRemoved (object sender, Mono.TextEditor.LineEventArgs e) - { - var handler = LineRemoved; - if (handler != null) - handler (this, new MonoDevelop.Ide.Editor.LineEventArgs (e.Line)); - } - public double ZoomLevel { get { return TextEditor != null && TextEditor.Options != null ? TextEditor.Options.Zoom : 1d; } set { if (TextEditor != null && TextEditor.Options != null) TextEditor.Options.Zoom = value; } @@ -3605,7 +3583,7 @@ namespace MonoDevelop.SourceEditor return TextEditor.GetLineHeight (line); } - bool ITextEditorImpl.HasFocus { + public bool HasFocus { get { return this.TextEditor.HasFocus; } diff --git a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs index dc4afb12c9..520954efab 100644 --- a/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs +++ b/main/src/addins/TextTemplating/MonoDevelop.TextTemplating/Gui/T4EditorExtension.cs @@ -99,19 +99,20 @@ namespace MonoDevelop.TextTemplating.Gui #region Code completion - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) + public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken)) { - int pos = completionContext.TriggerOffset; - if (pos <= 0) - return null; - return HandleCodeCompletion ((CodeCompletionContext) completionContext, true); - } + if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CharTyped) { + char completionChar = triggerInfo.TriggerCharacter.Value; + int pos = completionContext.TriggerOffset; + if (pos > 0 && Editor.GetCharAt (pos - 1) == completionChar) { + return HandleCodeCompletion (completionContext, false); + } + } else if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand) { + int pos = completionContext.TriggerOffset; + if (pos <= 0) + return null; + return HandleCodeCompletion ((CodeCompletionContext)completionContext, true); - public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) - { - int pos = completionContext.TriggerOffset; - if (pos > 0 && Editor.GetCharAt (pos - 1) == completionChar) { - return HandleCodeCompletion (completionContext, false); } return null; } diff --git a/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs b/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs index 192a4f2288..592e62c538 100644 --- a/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs +++ b/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs @@ -108,7 +108,6 @@ namespace MonoDevelop.VBNet null, new [] { projectInfo } ); - workspace.OpenSolutionInfo (sInfo); Editor.SyntaxHighlighting = new ClassificationSyntaxHighlighting (workspace, documentId); diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/CredentialsDialog.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/CredentialsDialog.cs index e8652e774a..752929fdc9 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/CredentialsDialog.cs +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/CredentialsDialog.cs @@ -41,7 +41,7 @@ namespace MonoDevelop.VersionControl.Git this.UseNativeContextMenus (); - labelTop1.Text = string.Format (labelTop1.Text, uri); + labelTop1.LabelProp = string.Format (labelTop1.LabelProp, uri); var table = new Table (0, 0, false); table.ColumnSpacing = 6; diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs index 4ce6bd2ce9..af5426c485 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitRepository.cs @@ -619,13 +619,17 @@ namespace MonoDevelop.VersionControl.Git func (credType); GitCredentials.StoreCredentials (credType); retry = false; - } catch (AuthenticationException) { + } catch (AuthenticationException e) { GitCredentials.InvalidateCredentials (credType); - retry = true; + retry = AlertButton.Yes == MessageService.AskQuestion ( + GettextCatalog.GetString ("Remote server error: {0}", e.Message), + GettextCatalog.GetString ("Retry authentication?"), + AlertButton.Yes, AlertButton.No); + if (!retry) + monitor?.ReportError (e.Message, null); } catch (VersionControlException e) { GitCredentials.InvalidateCredentials (credType); - if (monitor != null) - monitor.ReportError (e.Message, null); + monitor?.ReportError (e.Message, null); retry = false; } catch (UserCancelledException) { GitCredentials.StoreCredentials (credType); @@ -633,7 +637,7 @@ namespace MonoDevelop.VersionControl.Git } catch (LibGit2SharpException e) { GitCredentials.InvalidateCredentials (credType); - if (!tfsSession.Disposed) { + if (credType == GitCredentialsType.Tfs) { retry = true; tfsSession.Dispose (); continue; diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitService.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitService.cs index b36b67eb2a..0105cbf529 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitService.cs +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Git/MonoDevelop.VersionControl.Git/GitService.cs @@ -25,6 +25,7 @@ // THE SOFTWARE. using System; +using System.Linq; using MonoDevelop.Core; using MonoDevelop.Ide; using MonoDevelop.Ide.ProgressMonitoring; @@ -42,6 +43,15 @@ namespace MonoDevelop.VersionControl.Git public static void Push (GitRepository repo) { + bool hasCommits = repo.RootRepository.Commits.Any (); + if (!hasCommits) { + MessageService.ShowMessage ( + GettextCatalog.GetString ("There are no changes to push."), + GettextCatalog.GetString ("Create an initial commit first.") + ); + return; + } + var dlg = new PushDialog (repo); try { if (MessageService.RunCustomDialog (dlg) != (int) Gtk.ResponseType.Ok) diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Subversion/gtk-gui/objects.xml b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Subversion/gtk-gui/objects.xml index aa41067faf..f87c293eb8 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl.Subversion/gtk-gui/objects.xml +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl.Subversion/gtk-gui/objects.xml @@ -1,304 +1 @@ -<objects attr-sync="on"> - <object type="MonoDevelop.VersionControl.CommitMessageStylePanelWidget" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals> - <itemgroup label="CommitMessageStylePanelWidget Signals"> - <signal name="Changed" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.VersionControl.Views.ComparisonWidget" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.VersionControl.Views.DropDownBox" palette-category="General" allow-children="false" base-type="Gtk.Button"> - <itemgroups> - <itemgroup label="DropDownBox Properties"> - <property name="Text" /> - <property name="DefaultIconHeight" /> - <property name="DefaultIconWidth" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.VersionControl.Views.ChangeSetView" palette-category="General" allow-children="false" base-type="Gtk.ScrolledWindow"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.VersionControl.Views.LogWidget" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Ide.Gui.Components.ExtensibleTreeView" palette-category="General" allow-children="false" base-type="MonoDevelop.Components.CompactScrolledWindow"> - <itemgroups> - <itemgroup label="ExtensibleTreeView Properties"> - <property name="Id" /> - <property name="Zoom" /> - <property name="ShowSelectionPopupButton" /> - </itemgroup> - </itemgroups> - <signals> - <itemgroup label="ExtensibleTreeView Signals"> - <signal name="CurrentItemActivated" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Ide.Gui.Components.ExecutionModeComboBox" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals> - <itemgroup label="ExecutionModeComboBox Signals"> - <signal name="SelectionChanged" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Ide.Gui.Components.LogView" palette-category="General" allow-children="false" base-type="MonoDevelop.Components.CompactScrolledWindow"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Components.FileEntry" palette-category="General" allow-children="false" base-type="Gtk.HBox"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Components.FolderEntry" palette-category="General" allow-children="false" base-type="Gtk.HBox"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Components.IconView" palette-category="General" allow-children="false" base-type="Gtk.ScrolledWindow"> - <itemgroups /> - <signals> - <itemgroup label="IconView Signals"> - <signal name="IconSelected" /> - <signal name="IconDoubleClicked" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Components.NotebookButtonBar" palette-category="General" allow-children="false" base-type="Gtk.Toolbar"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Components.MenuButton" palette-category="General" allow-children="false" base-type="Gtk.Button"> - <itemgroups> - <itemgroup label="MenuButton Properties"> - <property name="Label" /> - <property name="UseUnderline" /> - <property name="UseMarkup" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.Components.FixedWidthWrapLabel" palette-category="General" allow-children="false" base-type="Gtk.Widget"> - <itemgroups> - <itemgroup label="FixedWidthWrapLabel Properties"> - <property name="MaxWidth" /> - <property name="Markup" /> - <property name="Text" /> - <property name="Indent" /> - <property name="BreakOnPunctuation" /> - <property name="BreakOnCamelCasing" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.Components.ListView" palette-category="General" allow-children="false" base-type="Gtk.DrawingArea"> - <itemgroups> - <itemgroup label="ListView Properties"> - <property name="AllowMultipleSelection" /> - <property name="SelectedRow" /> - <property name="SelectionDisabled" /> - <property name="Page" /> - </itemgroup> - </itemgroups> - <signals> - <itemgroup label="ListView Signals"> - <signal name="SelectionChanged" /> - <signal name="ItemActivated" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Components.FolderListSelector" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Components.SearchEntry" palette-category="General" allow-children="false" base-type="Gtk.EventBox"> - <itemgroups> - <itemgroup label="SearchEntry Properties"> - <property name="ForceFilterButtonVisible" /> - <property name="HasFrame" /> - <property name="RoundedShape" /> - <property name="IsCheckMenu" /> - <property name="ActiveFilterID" /> - <property name="EmptyMessage" /> - <property name="Query" /> - <property name="Ready" /> - <property name="HasFocus" /> - </itemgroup> - </itemgroups> - <signals> - <itemgroup label="SearchEntry Signals"> - <signal name="Changed" /> - <signal name="Activated" /> - <signal name="FilterChanged" /> - <signal name="RequestMenu" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Components.PropertyGrid.PropertyGrid" palette-category="General" allow-children="false" base-type="Gtk.VBox"> - <itemgroups> - <itemgroup label="PropertyGrid Properties"> - <property name="ShowToolbar" /> - <property name="ShowHelp" /> - </itemgroup> - </itemgroups> - <signals> - <itemgroup label="PropertyGrid Signals"> - <signal name="Changed" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Components.MenuButtonEntry" palette-category="General" allow-children="false" base-type="Gtk.HBox"> - <itemgroups> - <itemgroup label="MenuButtonEntry Properties"> - <property name="Text" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.Ide.Gui.Components.ProjectFileEntry" palette-category="General" allow-children="false" base-type="Gtk.HBox"> - <itemgroups> - <itemgroup label="ProjectFileEntry Properties"> - <property name="DialogTitle" /> - <property name="DefaultFilter" /> - <property name="VerifyFileExistsInProject" /> - <property name="EntryIsEditable" /> - </itemgroup> - </itemgroups> - <signals> - <itemgroup label="ProjectFileEntry Signals"> - <signal name="Changed" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Ide.Projects.CombineEntryFeatureSelector" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Ide.Projects.OptionPanels.BaseDirectoryPanelWidget" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups> - <itemgroup label="BaseDirectoryPanelWidget Properties"> - <property name="BaseDirectory" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.Ide.Gui.Components.EnvVarList" palette-category="General" allow-children="false" base-type="Gtk.ScrolledWindow"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Ide.Gui.Components.StringTagSelectorButton" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Components.CompactScrolledWindow" palette-category="General" allow-children="false" base-type="Gtk.ScrolledWindow"> - <itemgroups> - <itemgroup label="CompactScrolledWindow Properties"> - <property name="ShowBorderLine" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.Components.DropDownBox" palette-category="General" allow-children="false" base-type="Gtk.Button"> - <itemgroups> - <itemgroup label="DropDownBox Properties"> - <property name="Text" /> - <property name="DrawRightBorder" /> - <property name="DefaultIconHeight" /> - <property name="DefaultIconWidth" /> - <property name="DrawButtonShape" /> - <property name="DrawLeftBorder" /> - <property name="FixedWidth" /> - <property name="FixedHeight" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.Ide.Gui.Components.ProjectSelectorWidget" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups> - <itemgroup label="ProjectSelectorWidget Properties"> - <property name="ShowCheckboxes" /> - <property name="CascadeCheckboxSelection" /> - </itemgroup> - </itemgroups> - <signals> - <itemgroup label="ProjectSelectorWidget Signals"> - <signal name="SelectionChanged" /> - <signal name="ActiveChanged" /> - </itemgroup> - </signals> - </object> - <object type="MonoDevelop.Ide.ProgressMonitoring.ProgressBarMonitor" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups> - <itemgroup label="ProgressBarMonitor Properties"> - <property name="AllowCancel" /> - <property name="ShowErrorsDialog" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="MonoDevelop.Ide.Gui.Components.PriorityList" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Ide.Projects.OptionPanels.PortableRuntimeOptionsPanelWidget" palette-category="General" allow-children="false" base-type="Gtk.Bin"> - <itemgroups /> - <signals /> - </object> - <object type="MonoDevelop.Components.ProgressControl" palette-category="General" allow-children="false" base-type="Gtk.DrawingArea"> - <itemgroups /> - <signals /> - </object> - <object type="Mono.TextEditor.PopupWindow.TooltipWindow.FixedWidthWrapLabel" palette-category="General" allow-children="false" base-type="Gtk.Widget"> - <itemgroups> - <itemgroup label="FixedWidthWrapLabel Properties"> - <property name="MaxWidth" /> - <property name="Markup" /> - <property name="Text" /> - <property name="Indent" /> - <property name="BreakOnPunctuation" /> - <property name="BreakOnCamelCasing" /> - </itemgroup> - </itemgroups> - <signals /> - </object> - <object type="Mono.TextEditor.Theatrics.AnimatedVBox" palette-category="General" allow-children="false" base-type="Gtk.Container"> - <itemgroups /> - <signals /> - </object> - <object type="Mono.TextEditor.TextEditor" palette-category="General" allow-children="false" base-type="Gtk.Container"> - <itemgroups> - <itemgroup label="TextEditor Properties"> - <property name="TabsToSpaces" /> - <property name="IMModule" /> - <property name="LineHeight" /> - <property name="SelectedText" /> - <property name="SelectionAnchor" /> - <property name="Text" /> - <property name="SearchPattern" /> - <property name="HighlightSearchPattern" /> - <property name="IsCaseSensitive" /> - <property name="IsWholeWordOnly" /> - </itemgroup> - </itemgroups> - <signals> - <itemgroup label="TextEditor Signals"> - <signal name="VScroll" /> - <signal name="HScroll" /> - <signal name="SelectionChanged" /> - <signal name="Painted" /> - <signal name="LinkRequest" /> - <signal name="EditorOptionsChanged" /> - <signal name="HighlightSearchPatternChanged" /> - <signal name="BeginHover" /> - </itemgroup> - </signals> - </object> -</objects>
\ No newline at end of file +<objects attr-sync="on"></objects>
\ No newline at end of file diff --git a/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs b/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs index cf5c788089..762e9a596f 100644 --- a/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs +++ b/main/src/addins/Xml/Editor/BaseXmlEditorExtension.cs @@ -261,22 +261,23 @@ namespace MonoDevelop.Xml.Editor #region Code completion - public override Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - int pos = completionContext.TriggerOffset; - if (pos <= 0) - return null; - tracker.UpdateEngine (); - return HandleCodeCompletion (completionContext, true, default(CancellationToken)); - } - public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) + public override Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken)) { - int pos = completionContext.TriggerOffset; - char ch = CompletionWidget != null ? CompletionWidget.GetChar (pos - 1) : Editor.GetCharAt (pos - 1); - if (pos > 0 && ch == completionChar) { + if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CharTyped) { + int pos = completionContext.TriggerOffset; + char ch = CompletionWidget != null ? CompletionWidget.GetChar (pos - 1) : Editor.GetCharAt (pos - 1); + if (pos > 0 && ch == triggerInfo.TriggerCharacter.Value) { + tracker.UpdateEngine (); + return HandleCodeCompletion (completionContext, false, token); + } + } else if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand) { + int pos = completionContext.TriggerOffset; + if (pos <= 0) + return null; tracker.UpdateEngine (); - return HandleCodeCompletion (completionContext, false, token); + return HandleCodeCompletion (completionContext, true, default (CancellationToken)); + } return null; } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/CaretImpl.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/CaretImpl.cs index eb3cd50d4c..44b6951a64 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/CaretImpl.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/CaretImpl.cs @@ -53,7 +53,7 @@ namespace Mono.TextEditor CheckLine (); SetColumn (); UpdateCaretOffset (); - OnPositionChanged (new DocumentLocationEventArgs (old)); + OnPositionChanged (new CaretLocationEventArgs (old, CaretChangeReason.Movement)); } } } @@ -72,7 +72,7 @@ namespace Mono.TextEditor CheckColumn (); SetDesiredColumn (); UpdateCaretOffset (); - OnPositionChanged (new DocumentLocationEventArgs (old)); + OnPositionChanged (new CaretLocationEventArgs (old, CaretChangeReason.Movement)); } } } @@ -92,7 +92,7 @@ namespace Mono.TextEditor CheckColumn (); SetDesiredColumn (); UpdateCaretOffset (); - OnPositionChanged (new DocumentLocationEventArgs (old)); + OnPositionChanged (new CaretLocationEventArgs (old, CaretChangeReason.Movement)); } } } @@ -120,7 +120,7 @@ namespace Mono.TextEditor CheckLine (); CheckColumn (); SetDesiredColumn (); - OnPositionChanged (new DocumentLocationEventArgs (old)); + OnPositionChanged (new CaretLocationEventArgs (old, CaretChangeReason.Movement)); } } @@ -159,8 +159,6 @@ namespace Mono.TextEditor set { if (value != autoScrollToCaret) { autoScrollToCaret = value; - if (autoScrollToCaret) - OnPositionChanged (new DocumentLocationEventArgs (Location)); } } } @@ -269,7 +267,7 @@ namespace Mono.TextEditor } UpdateCaretOffset (); - OnPositionChanged (new DocumentLocationEventArgs (old)); + OnPositionChanged (new CaretLocationEventArgs (old, CaretChangeReason.Movement)); } void SetDesiredColumn () @@ -300,7 +298,7 @@ namespace Mono.TextEditor var old = Location; DesiredColumn = desiredColumn; SetColumn (); - OnPositionChanged (new DocumentLocationEventArgs (old)); + OnPositionChanged (new CaretLocationEventArgs (old, CaretChangeReason.Movement)); } public override string ToString () @@ -324,7 +322,7 @@ namespace Mono.TextEditor Offset = offset; } - protected override void OnPositionChanged (DocumentLocationEventArgs args) + protected override void OnPositionChanged (CaretLocationEventArgs args) { TextEditorData.Document.EnsureOffsetIsUnfolded (Offset); base.OnPositionChanged (args); @@ -375,7 +373,7 @@ namespace Mono.TextEditor var curLine = TextEditorData.GetLine (newLocation.Line); if (TextEditorData.HasIndentationTracker && TextEditorData.Options.IndentStyle == IndentStyle.Virtual && curLine.Length == 0) { - var indentColumn = TextEditorData.GetVirtualIndentationColumn (Location); + var indentColumn = TextEditorData.GetVirtualIndentationColumn (newLocation); if (column == indentColumn) { newColumn = indentColumn; } @@ -389,7 +387,7 @@ namespace Mono.TextEditor SetDesiredColumn (); UpdateCaretOffset (); - OnPositionChanged (new DocumentLocationEventArgs (old)); + OnPositionChanged (new CaretLocationEventArgs (old, CaretChangeReason.BufferChange)); } public void SetDocument (TextDocument doc) diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs index b0744e1866..94e440e50b 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs @@ -64,41 +64,37 @@ namespace Mono.TextEditor trackDocument = document; } - void HandleLineRemoved (object sender, LineEventArgs e) + void TrackDocument_TextChanging (object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) { - if (lineStates == null) + if (lineStates == null) return; + var startLine = trackDocument.GetLineByOffset (e.Offset); + var endRemoveLine = trackDocument.GetLineByOffset (e.Offset + e.RemovalLength); try { - - lineStates.RemoveAt (e.LineNumber); + var lineNumber = startLine.LineNumber; + lineStates.RemoveRange (lineNumber, endRemoveLine.LineNumber - lineNumber); } catch (Exception ex) { - Console.WriteLine ("error while DiffTracker.HandleLineRemoved:" + ex); + Console.WriteLine ("error while DiffTracker.TrackDocument_TextChanging:" + ex); } } - void HandleLineInserted (object sender, LineEventArgs e) + void TrackDocument_TextChanged (object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) { - if (lineStates == null) - return; + var startLine = trackDocument.GetLineByOffset (e.Offset); + var endLine = trackDocument.GetLineByOffset (e.Offset + e.InsertionLength); + var lineNumber = startLine.LineNumber; + var insertedLines = endLine.LineNumber - lineNumber; try { - lineStates.Insert(e.Line.LineNumber, new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Dirty)); - } catch (Exception ex) { - Console.WriteLine ("error while DiffTracker.HandleLineInserted:" + ex); - } - } - - void HandleLineChanged (object sender, LineEventArgs e) - { - var lineNumber = e.Line.LineNumber; - try { - if (lineStates [lineNumber].state == Mono.TextEditor.TextDocument.LineState.Dirty) - return; lineStates [lineNumber] = new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Dirty); if (trackDocument != null) - trackDocument.CommitLineUpdate (lineNumber); + trackDocument.CommitLineUpdate (lineNumber); + while (insertedLines-- > 0) { + lineStates.Insert (lineNumber, new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Dirty)); + } } catch (Exception ex) { - Console.WriteLine ("error while DiffTracker.HandleLineChanged:" + ex); + Console.WriteLine ("error while DiffTracker.TrackDocument_TextChanged:" + ex); } + } public void SetBaseDocument (TextDocument document) @@ -111,10 +107,8 @@ namespace Mono.TextEditor } else { lineStates = new CompressingTreeList<LineChangeInfo>((x, y) => x.Equals(y)); lineStates.InsertRange(0, document.LineCount + 1, new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Unchanged)); - - trackDocument.Splitter.LineChanged += HandleLineChanged; - trackDocument.Splitter.LineInserted += HandleLineInserted; - trackDocument.Splitter.LineRemoved += HandleLineRemoved; + trackDocument.TextChanging += TrackDocument_TextChanging; + trackDocument.TextChanged += TrackDocument_TextChanged; } } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/ILineSplitter.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/ILineSplitter.cs index 2f81117052..016a06d3d9 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/ILineSplitter.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/ILineSplitter.cs @@ -39,9 +39,5 @@ namespace Mono.TextEditor IEnumerable<DocumentLine> GetLinesBetween (int startLine, int endLine); IEnumerable<DocumentLine> GetLinesStartingAt (int startLine); IEnumerable<DocumentLine> GetLinesReverseStartingAt (int startLine); - - event EventHandler<LineEventArgs> LineChanged; - event EventHandler<LineEventArgs> LineInserted; - event EventHandler<LineEventArgs> LineRemoved; } } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/LazyLineSplitter.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/LazyLineSplitter.cs index 0f317bdcd4..74c0e5143b 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/LazyLineSplitter.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/LazyLineSplitter.cs @@ -115,13 +115,6 @@ namespace Mono.TextEditor } #region ILineSplitter implementation - - event EventHandler<LineEventArgs> ILineSplitter.LineChanged { add { /* unused */ } remove { /* unused */ } } - - event EventHandler<LineEventArgs> ILineSplitter.LineInserted { add { /* unused */ } remove { /* unused */ } } - - event EventHandler<LineEventArgs> ILineSplitter.LineRemoved { add { /* unused */ } remove { /* unused */ } } - public void Clear () { } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/PrimitiveLineSplitter.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/PrimitiveLineSplitter.cs index 8351fd17c8..989308a027 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/PrimitiveLineSplitter.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/PrimitiveLineSplitter.cs @@ -156,10 +156,5 @@ namespace Mono.TextEditor yield return Get (i); } - event EventHandler<LineEventArgs> ILineSplitter.LineChanged { add { /* unused */ } remove { /* unused */ } } - - event EventHandler<LineEventArgs> ILineSplitter.LineInserted { add { /* unused */ } remove { /* unused */ } } - - event EventHandler<LineEventArgs> ILineSplitter.LineRemoved { add { /* unused */ } remove { /* unused */ } } } } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs index 7895c06c92..e6c907bf79 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs @@ -210,7 +210,7 @@ namespace Mono.TextEditor { this.buffer = buffer; this.splitter = splitter; - splitter.LineRemoved += HandleSplitterLineSegmentTreeLineRemoved; + TextChanging += HandleSplitterLineSegmentTreeLineRemoved; foldSegmentTree.tree.NodeRemoved += HandleFoldSegmentTreetreeNodeRemoved; textSegmentMarkerTree.InstallListener (this); this.diffTracker.SetTrackDocument (this); @@ -240,21 +240,6 @@ namespace Mono.TextEditor }; } - public event EventHandler<LineEventArgs> LineChanged { - add { splitter.LineChanged += value; } - remove { splitter.LineChanged -= value; } - } - - public event EventHandler<LineEventArgs> LineInserted { - add { splitter.LineInserted += value; } - remove { splitter.LineInserted -= value; } - } - - public event EventHandler<LineEventArgs> LineRemoved { - add { splitter.LineRemoved += value; } - remove { splitter.LineRemoved -= value; } - } - #region Buffer implementation public int Length { @@ -1566,17 +1551,24 @@ namespace Mono.TextEditor #endregion - void HandleSplitterLineSegmentTreeLineRemoved (object sender, LineEventArgs e) - { - foreach (TextLineMarker marker in e.Line.Markers) { - if (marker is IExtendingTextLineMarker) { - UnRegisterVirtualTextMarker ((IExtendingTextLineMarker)marker); - lock (extendingTextMarkers) { - extendingTextMarkers.Remove (marker); - OnHeightChanged (EventArgs.Empty); + void HandleSplitterLineSegmentTreeLineRemoved (object sender, TextChangeEventArgs e) + { + var line = GetLineByOffset (e.Offset); + var endOffset = e.Offset + e.RemovalLength; + var offset = line.Offset; + do { + foreach (TextLineMarker marker in line.Markers) { + if (marker is IExtendingTextLineMarker) { + UnRegisterVirtualTextMarker ((IExtendingTextLineMarker)marker); + lock (extendingTextMarkers) { + extendingTextMarkers.Remove (marker); + OnHeightChanged (EventArgs.Empty); + } } } - } + offset += line.LengthIncludingDelimiter; + line = line.NextLine; + } while (line != null && offset < endOffset); } public bool Contains (int offset) diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs index affd7bc413..6157abccef 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/HeightTree.cs @@ -59,27 +59,22 @@ namespace Mono.TextEditor public HeightTree (TextEditorData editor) { this.editor = editor; - this.editor.Document.Splitter.LineRemoved += HandleLineRemoved; - this.editor.Document.Splitter.LineInserted += HandleLineInserted; + this.editor.Document.TextChanged += Document_TextChanged; ; this.editor.Document.FoldTreeUpdated += HandleFoldTreeUpdated; } - void HandleLineInserted (object sender, LineEventArgs e) - { - InsertLine (e.Line.LineNumber); - } - void HandleLineRemoved (object sender, LineEventArgs e) + void Document_TextChanged (object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) { Rebuild (); - OnLineUpdateFrom (new HeightChangedEventArgs (e.Line.LineNumber - 1)); - //RemoveLine (e.Line.LineNumber); + var lineNumber = this.editor.OffsetToLineNumber (e.Offset); + OnLineUpdateFrom (new HeightChangedEventArgs (lineNumber - 1)); } + public void Dispose () { - this.editor.Document.Splitter.LineRemoved -= HandleLineRemoved; - this.editor.Document.Splitter.LineInserted -= HandleLineInserted; + this.editor.Document.TextChanged -= Document_TextChanged; ; this.editor.Document.FoldTreeUpdated -= HandleFoldTreeUpdated; } @@ -271,7 +266,7 @@ namespace Mono.TextEditor return result; } } - + public void Unfold (FoldMarker marker, int lineNumber, int count) { lock (tree) { diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs index 93a9248e43..8da0920235 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs @@ -84,19 +84,22 @@ namespace Mono.TextEditor this.style = style; this.startColumn = startColumn; this.endColumn = endColumn; - doc.LineChanged += HandleDocLineChanged; } - - void HandleDocLineChanged (object sender, LineEventArgs e) + + + void Doc_TextChanging (object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) { - if (line == e.Line) + var lineSegment = line.Segment; + if (lineSegment.IsInside (e.Offset) || lineSegment.IsInside (e.Offset + e.RemovalLength) || + e.Offset <= lineSegment.Offset && lineSegment.Offset <= e.Offset + e.RemovalLength) { doc.RemoveMarker (this); + } } - + public void Dispose () { if (doc != null) { - doc.LineChanged -= HandleDocLineChanged; + doc.TextChanging -= Doc_TextChanging; doc = null; } line = null; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs index e466073a95..7a7195950b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs @@ -86,7 +86,8 @@ namespace MonoDevelop.Projects.MSBuild var val = prop.GetValue (ob); if (val != null) { if (cwriter == null) { - cwriter = new XmlConfigurationWriter { Namespace = MSBuildProject.Schema, StoreAllInElements = true }; + string xmlns = (mso?.ParentProject != null) ? mso.ParentProject.Namespace : MSBuildProject.Schema; + cwriter = new XmlConfigurationWriter { Namespace = xmlns, StoreAllInElements = true }; xdoc = new XmlDocument (); } var data = prop.Serialize (ser.SerializationContext, ob, val); @@ -381,7 +382,7 @@ namespace MonoDevelop.Projects.MSBuild if (data != null) { data.Name = prop.Name; if (writer == null) - writer = new XmlConfigurationWriter { Namespace = MSBuildProject.Schema }; + writer = new XmlConfigurationWriter { Namespace = project.Namespace }; XmlDocument doc = new XmlDocument (); var elem = writer.Write (doc, data); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs index bc821dad2e..20964d9e74 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildImport.cs @@ -79,7 +79,7 @@ namespace MonoDevelop.Projects.MSBuild base.Write (writer, context); } - void WritePatchedImport (XmlWriter writer, string newTarget) + internal void WritePatchedImport (XmlWriter writer, string newTarget) { /* If an import redirect exists, add a fake import to the project which will be used only if the original import doesn't exist. That is, the following import: @@ -99,9 +99,10 @@ namespace MonoDevelop.Projects.MSBuild if (!string.IsNullOrEmpty (Condition)) cond = "( " + Condition + " ) AND " + cond; - writer.WriteStartElement ("Import", MSBuildProject.Schema); + writer.WriteStartElement ("Import", Namespace); writer.WriteAttributeString ("Project", target); writer.WriteAttributeString ("Condition", cond); + writer.WriteEndElement (); // Now add the fake import, with a condition so that it will be used only if the original // import does not exist. @@ -110,9 +111,10 @@ namespace MonoDevelop.Projects.MSBuild if (!string.IsNullOrEmpty (Condition)) cond = "( " + Condition + " ) AND " + cond; - writer.WriteStartElement ("Import", MSBuildProject.Schema); + writer.WriteStartElement ("Import", Namespace); writer.WriteAttributeString ("Project", MSBuildProjectService.ToMSBuildPath (null, newTarget)); writer.WriteAttributeString ("Condition", cond); + writer.WriteEndElement (); } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildItem.cs index c944ccdf85..119cee9ecd 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildItem.cs @@ -66,11 +66,15 @@ namespace MonoDevelop.Projects.MSBuild get { return !string.IsNullOrEmpty (include); } } - static readonly string [] knownAttributes = { "Include", "Exclude", "Condition", "Label", "Remove", "Update" }; + internal static readonly string [] KnownAttributes = { "Include", "Exclude", "Condition", "Label", "Remove", "Update" }; internal override string [] GetKnownAttributes () { - return knownAttributes; + var project = ParentProject; + if (project != null) + return project.GetKnownItemAttributes (name); + + return KnownAttributes; } internal override void ReadAttribute (string name, string value) @@ -102,8 +106,31 @@ namespace MonoDevelop.Projects.MSBuild return remove; else if (name == "Update") return string.IsNullOrEmpty (include) && !string.IsNullOrEmpty (update) ? update : null; - else - return base.WriteAttribute (name); + else { + string result = base.WriteAttribute (name); + if (result != null) + return result; + + if (!ExistingPropertyAttribute (name)) + return WritePropertyAsAttribute (name); + + return null; + } + } + + bool ExistingPropertyAttribute (string propertyName) + { + return metadata.PropertiesAttributeOrder.Any (property => property.Name == propertyName); + } + + string WritePropertyAsAttribute (string propertyName) + { + var prop = metadata.GetProperty (propertyName); + if (prop != null) { + prop.FromAttribute = true; + return prop.Value; + } + return null; } internal override void Read (MSBuildXmlReader reader) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs index d538bdba30..e496448b1e 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs @@ -264,8 +264,10 @@ namespace MonoDevelop.Projects.MSBuild } } - internal virtual string Namespace { + public virtual string Namespace { get { + if (ParentObject != null) + return ParentObject.Namespace; return MSBuildProject.Schema; } } @@ -286,7 +288,7 @@ namespace MonoDevelop.Projects.MSBuild internal virtual void WriteContent (XmlWriter writer, WriteContext context) { - var children = GetChildren (); + var children = GetChildren ().Where (c => !c.SkipSerialization); var hasChildren = children.Any (); var hasContent = StartInnerWhitespace != null || EndInnerWhitespace != null; @@ -294,9 +296,7 @@ namespace MonoDevelop.Projects.MSBuild if (hasChildren || emptyElementMode == EmptyElementMode.NotEmpty || (emptyElementMode == EmptyElementMode.Unknown && !PreferEmptyElement)) { MSBuildWhitespace.Write (StartInnerWhitespace, writer); - foreach (var c in GetChildren ()) { - if (c.SkipSerialization) - continue; + foreach (var c in children) { c.Write (writer, context); hasContent = true; } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs index 51506fd44e..fe94d5a5c0 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProject.cs @@ -48,6 +48,7 @@ namespace MonoDevelop.Projects.MSBuild bool hadXmlDeclaration; bool isShared; ConditionedPropertyCollection conditionedProperties = new ConditionedPropertyCollection (); + Dictionary<string, string[]> knownItemAttributes; MSBuildEngineManager engineManager; bool engineManagerIsLocal; @@ -59,7 +60,7 @@ namespace MonoDevelop.Projects.MSBuild TextFormatInfo format = new TextFormatInfo { NewLine = "\r\n" }; - static readonly string [] knownAttributes = { "DefaultTargets", "ToolsVersion", "xmlns" }; + static readonly string [] knownAttributes = { "Sdk", "DefaultTargets", "ToolsVersion", "xmlns" }; public static XmlNamespaceManager XmlNamespaceManager { @@ -295,6 +296,7 @@ namespace MonoDevelop.Projects.MSBuild switch (name) { case "DefaultTargets": defaultTargets = value; return; case "ToolsVersion": toolsVersion = value; return; + case "Sdk": sdk = value; return; } base.ReadAttribute (name, value); } @@ -304,7 +306,8 @@ namespace MonoDevelop.Projects.MSBuild switch (name) { case "DefaultTargets": return defaultTargets; case "ToolsVersion": return toolsVersion; - case "xmlns": return Schema; + case "xmlns": return string.IsNullOrEmpty (Namespace) ? null : Namespace; + case "Sdk": return sdk; } return base.WriteAttribute (name); } @@ -514,6 +517,16 @@ namespace MonoDevelop.Projects.MSBuild } } + string sdk; + + public override string Namespace { + get { + if (sdk != null) + return string.Empty; + return Schema; + } + } + public string [] ProjectTypeGuids { get { return GetGlobalPropertyGroup ().GetValue ("ProjectTypeGuids", "").Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select (t => t.Trim ()).ToArray (); } @@ -863,11 +876,21 @@ namespace MonoDevelop.Projects.MSBuild { var elem = GetProjectExtension ("MonoDevelop"); if (elem != null) - return elem.SelectSingleNode ("tns:Properties/tns:" + section, XmlNamespaceManager) as XmlElement; + return elem.SelectSingleNode ("tns:Properties/tns:" + section, GetNamespaceManagerForProject ()) as XmlElement; else return null; } + XmlNamespaceManager GetNamespaceManagerForProject () + { + if (Namespace == Schema) + return XmlNamespaceManager; + + var namespaceManager = new XmlNamespaceManager (new NameTable ()); + namespaceManager.AddNamespace ("tns", Namespace); + return namespaceManager; + } + public void SetProjectExtension (XmlElement value) { AssertCanModify (); @@ -888,13 +911,13 @@ namespace MonoDevelop.Projects.MSBuild var elem = GetProjectExtension ("MonoDevelop"); if (elem == null) { XmlDocument doc = new XmlDocument (); - elem = doc.CreateElement (null, "MonoDevelop", MSBuildProject.Schema); + elem = doc.CreateElement (null, "MonoDevelop", Namespace); } value = (XmlElement) elem.OwnerDocument.ImportNode (value, true); var parent = elem; - elem = parent ["Properties", MSBuildProject.Schema]; + elem = parent ["Properties", Namespace]; if (elem == null) { - elem = parent.OwnerDocument.CreateElement (null, "Properties", MSBuildProject.Schema); + elem = parent.OwnerDocument.CreateElement (null, "Properties", Namespace); parent.AppendChild (elem); XmlUtil.Indent (format, elem, true); } @@ -907,7 +930,7 @@ namespace MonoDevelop.Projects.MSBuild } XmlUtil.Indent (format, value, false); var xmlns = value.GetAttribute ("xmlns"); - if (xmlns == Schema) + if (xmlns == Namespace) value.RemoveAttribute ("xmlns"); SetProjectExtension (parent); NotifyChanged (); @@ -930,7 +953,7 @@ namespace MonoDevelop.Projects.MSBuild var md = GetProjectExtension ("MonoDevelop"); if (md == null) return; - XmlElement elem = md.SelectSingleNode ("tns:Properties/tns:" + section, XmlNamespaceManager) as XmlElement; + XmlElement elem = md.SelectSingleNode ("tns:Properties/tns:" + section, GetNamespaceManagerForProject ()) as XmlElement; if (elem != null) { var parent = (XmlElement)elem.ParentNode; XmlUtil.RemoveElementAndIndenting (elem); @@ -966,6 +989,29 @@ namespace MonoDevelop.Projects.MSBuild } } } + + public void AddKnownItemAttribute (string itemName, params string[] attributes) + { + AssertCanModify (); + + if (knownItemAttributes == null) + knownItemAttributes = new Dictionary<string, string[]> (); + + var mergedAttributes = MSBuildItem.KnownAttributes.Union (attributes).ToArray (); + knownItemAttributes [itemName] = mergedAttributes; + } + + internal string[] GetKnownItemAttributes (string itemName) + { + if (knownItemAttributes == null) + return MSBuildItem.KnownAttributes; + + string[] attributes = null; + if (knownItemAttributes.TryGetValue (itemName, out attributes)) + return attributes; + + return MSBuildItem.KnownAttributes; + } } static class XmlUtil @@ -1029,19 +1075,6 @@ namespace MonoDevelop.Projects.MSBuild return res.ToString (); } - public static void FormatElement (TextFormatInfo format, XmlElement elem) - { - // Remove duplicate namespace declarations - var nsa = elem.Attributes ["xmlns"]; - if (nsa != null && nsa.Value == MSBuildProject.Schema) - elem.Attributes.Remove (nsa); - - foreach (var e in elem.ChildNodes.OfType<XmlElement> ().ToArray ()) { - Indent (format, e, false); - FormatElement (format, e); - } - } - public static void Indent (TextFormatInfo format, XmlElement elem, bool closeInNewLine) { var prev = FindPreviousSibling (elem); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProperty.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProperty.cs index 23e233bae1..4c91afd8a0 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProperty.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProperty.cs @@ -52,7 +52,11 @@ namespace MonoDevelop.Projects.MSBuild get { return fromAttribute; } + set { + fromAttribute = value; + } } + internal string AfterAttribute { get { return afterAttribute; @@ -197,7 +201,7 @@ namespace MonoDevelop.Projects.MSBuild elem.Read (cr); } elem.ParentNode = this; - elem.SetNamespace (MSBuildProject.Schema); + elem.SetNamespace (Namespace); elem.StartWhitespace = StartWhitespace; elem.EndWhitespace = EndWhitespace; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildXmlElement.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildXmlElement.cs index ce45e64c85..c13588101e 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildXmlElement.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildXmlElement.cs @@ -88,7 +88,7 @@ namespace MonoDevelop.Projects.MSBuild } } - internal override string Namespace { + public override string Namespace { get { if (ns != null) return ns; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs index db08f0005b..cad57828ac 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs @@ -76,6 +76,7 @@ namespace MonoDevelop.Projects public void SetItems (IEnumerable<T> items) { AssertCanWrite (); + items = ReuseExistingItems (items); var newItems = items.Except (list); var removedItems = list.Except (items); list = ImmutableList<T>.Empty.AddRange (items); @@ -85,6 +86,19 @@ namespace MonoDevelop.Projects OnItemsRemoved (removedItems); } + IEnumerable<T> ReuseExistingItems (IEnumerable<T> items) + { + var updatedItems = new List<T> (); + foreach (var item in items) { + int index = list.IndexOf (item); + if (index == -1) + updatedItems.Add (item); + else + updatedItems.Add (list [index]); + } + return updatedItems; + } + public void Insert (int index, T item) { list = list.Insert (index, item); diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs index 5d2ca2cf0b..4882be6603 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs @@ -224,7 +224,9 @@ namespace MonoDevelop.Projects if (etype.IsEnum) { long ival = Convert.ToInt64 (val); bool isFlags = etype.IsDefined (typeof(FlagsAttribute), false); - string flags = ""; + StringBuilder flags = null; + if (isFlags) + flags = new StringBuilder (); IList names = Enum.GetNames (etype); foreach (FieldInfo f in etype.GetFields ()) { if (!names.Contains (f.Name)) @@ -237,12 +239,12 @@ namespace MonoDevelop.Projects } else if (isFlags && (v & ival) != 0) { if (flags.Length > 0) - flags += ","; - flags += sval; + flags.Append (','); + flags.Append (sval); } } if (isFlags) - return flags; + return flags.ToString (); } return val; } @@ -262,8 +264,9 @@ namespace MonoDevelop.Projects ops.Append (", "); var nameAttr = localizedDisplayNameAttributes [prop]; ops.Append (nameAttr.DisplayName); - if (!(pval is bool)) - ops.Append (": " + GetValue (pval)); + if (!(pval is bool)) { + ops.Append (": ").Append (GetValue (pval)); + } } return ops.ToString (); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs index cc5f1662a0..35b5b27987 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectConfiguration.cs @@ -90,7 +90,7 @@ namespace MonoDevelop.Projects } var vars = XElement.Parse (xml); if (vars != null) { - foreach (var val in vars.Elements (XName.Get ("Variable", MSBuildProject.Schema))) { + foreach (var val in vars.Elements (XName.Get ("Variable", GetProjectNamespace ()))) { var name = (string)val.Attribute ("name"); if (name != null) dict [name] = (string)val.Attribute ("value"); @@ -98,6 +98,21 @@ namespace MonoDevelop.Projects } } + string GetProjectNamespace () + { + var msbuildProject = ParentItem?.MSBuildProject; + if (msbuildProject == null) { + var projectObject = properties as IMSBuildProjectObject; + if (projectObject != null) + msbuildProject = projectObject.ParentProject; + } + + if (msbuildProject != null) + return msbuildProject.Namespace; + + return MSBuildProject.Schema; + } + internal protected virtual void Write (IPropertySet pset) { pset.SetPropertyOrder ("DebugSymbols", "DebugType", "Optimize", "OutputPath", "DefineConstants", "ErrorReport"); @@ -131,9 +146,10 @@ namespace MonoDevelop.Projects if (loadedEnvironmentVariables == null || loadedEnvironmentVariables.Count != environmentVariables.Count || loadedEnvironmentVariables.Any (e => !environmentVariables.ContainsKey (e.Key) || environmentVariables[e.Key] != e.Value)) { if (environmentVariables.Count > 0) { - XElement e = new XElement (XName.Get ("EnvironmentVariables", MSBuildProject.Schema)); + string xmlns = GetProjectNamespace (); + XElement e = new XElement (XName.Get ("EnvironmentVariables", xmlns)); foreach (var v in environmentVariables) { - var val = new XElement (XName.Get ("Variable", MSBuildProject.Schema)); + var val = new XElement (XName.Get ("Variable", xmlns)); val.SetAttributeValue ("name", v.Key); val.SetAttributeValue ("value", v.Value); e.Add (val); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs index 130a1c32a1..a356ab36fe 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/MainToolbarController.cs @@ -336,9 +336,9 @@ namespace MonoDevelop.Components.MainToolbar void UpdateBuildConfiguration () { var config = ToolbarView.ActiveConfiguration; - if (config == null || configurationMergers.Count == 0) + if (config == null) return; - if (configurationMergers.Count > 1) { + if (configurationMergers.Count > 1 || configurationMergers.Count == 0) { settingGlobalConfig = true; try { IdeApp.Workspace.ActiveConfigurationId = config.OriginalId; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/EditorManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/EditorManager.cs index 19202cda26..900256746f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/EditorManager.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/EditorManager.cs @@ -167,11 +167,10 @@ namespace MonoDevelop.Components.PropertyGrid public static Type GetCollectionItemType (Type colType)
{
- foreach (PropertyInfo member in colType.GetProperties ()) {
- if (member.Name == "Item") {
- if (member.PropertyType != typeof (object))
- return member.PropertyType;
- }
+ foreach (var member in colType.GetDefaultMembers ()) {
+ var prop = member as PropertyInfo;
+ if (prop != null && prop.Name == "Item" && prop.PropertyType != typeof (object))
+ return prop.PropertyType;
}
return null;
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/PropertyGridTable.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/PropertyGridTable.cs index 24b2c4af33..018fcb173a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/PropertyGridTable.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.PropertyGrid/PropertyGridTable.cs @@ -127,6 +127,16 @@ namespace MonoDevelop.Components.PropertyGrid } } + Gdk.Cursor cursor; + Gdk.Cursor Cursor { + get { return cursor; } + set { + if (cursor == value) + return; + GdkWindow.Cursor = cursor = value; + } + } + public PropertyGridTable (EditorManager editorManager, PropertyGrid parentGrid) { GtkWorkarounds.FixContainerLeak (this); @@ -182,7 +192,10 @@ namespace MonoDevelop.Components.PropertyGrid //make a best attempt using reference equality to match objects and the name to match their properties. expandedStatus = new Dictionary<object,List<string>>(new ReferenceEqualityComparer<object> ()); - foreach (var r in rows.Where (r => r.IsExpandable)) { + foreach (var r in rows) { + if (!r.IsExpandable) + continue; + object key; string val; bool mark; @@ -625,7 +638,7 @@ namespace MonoDevelop.Components.PropertyGrid return GetAllRows (rows, onlyVisible); } - IEnumerable<TableRow> GetAllRows (IEnumerable<TableRow> rows, bool onlyVisible) + IEnumerable<TableRow> GetAllRows (List<TableRow> rows, bool onlyVisible) { foreach (var r in rows) { yield return r; @@ -644,7 +657,7 @@ namespace MonoDevelop.Components.PropertyGrid int dx = (int)((double)Allocation.Width * dividerPosition); if (Math.Abs (dx - evnt.X) < 4) { draggingDivider = true; - GdkWindow.Cursor = resizeCursor; + Cursor = resizeCursor; return true; } @@ -699,18 +712,18 @@ namespace MonoDevelop.Components.PropertyGrid if (row != null && row.IsExpandable) { var bounds = GetInactiveEditorBounds (row); if (bounds.IsEmpty || !bounds.Contains ((int)evnt.X, (int)evnt.Y)) { - GdkWindow.Cursor = handCursor; + Cursor = handCursor; return true; } } int dx = (int)((double)Allocation.Width * dividerPosition); if (Math.Abs (dx - evnt.X) < 4) { - GdkWindow.Cursor = resizeCursor; + Cursor = resizeCursor; return true; } ShowTooltip (evnt); - GdkWindow.Cursor = null; + Cursor = null; return base.OnMotionNotifyEvent (evnt); } @@ -831,7 +844,7 @@ namespace MonoDevelop.Components.PropertyGrid protected override void OnDragLeave (DragContext context, uint time_) { if (!draggingDivider) - GdkWindow.Cursor = null; + Cursor = null; base.OnDragLeave (context, time_); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CodeCompletionContext.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CodeCompletionContext.cs index 27de45aea2..88df9a4a70 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CodeCompletionContext.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CodeCompletionContext.cs @@ -27,6 +27,7 @@ using System; using MonoDevelop.Projects; using Gtk; +using MonoDevelop.Core.Text; namespace MonoDevelop.Ide.CodeCompletion { @@ -40,6 +41,8 @@ namespace MonoDevelop.Ide.CodeCompletion public int TriggerTextHeight { get; set; } public int TriggerWordLength { get; set; } + public ITextSourceVersion Version { get; set; } + public override string ToString () { return string.Format ("[CodeCompletionContext: TriggerOffset={0}, TriggerLine={1}, TriggerLineOffset={2}, TriggerXCoord={3}, TriggerYCoord={4}, TriggerTextHeight={5}, TriggerWordLength={6}]", TriggerOffset, TriggerLine, TriggerLineOffset, TriggerXCoord, TriggerYCoord, TriggerTextHeight, TriggerWordLength); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs index 3091897a50..49f8cb7982 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs @@ -203,6 +203,11 @@ namespace MonoDevelop.Ide.CodeCompletion { return commitChars.Contains (keyChar); } + + public virtual bool MuteCharacter (char keyChar, string partialWord) + { + return false; + } } public class ISymbolCompletionData : CompletionData diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionDataList.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionDataList.cs index eeb9500db7..627544b8ce 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionDataList.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionDataList.cs @@ -30,6 +30,7 @@ using System; using System.Collections.Generic; using System.Linq; using MonoDevelop.Core; +using MonoDevelop.Core.Text; using MonoDevelop.Ide.Editor.Extension; namespace MonoDevelop.Ide.CodeCompletion @@ -54,6 +55,15 @@ namespace MonoDevelop.Ide.CodeCompletion void OnCompletionListClosed (EventArgs e); event EventHandler CompletionListClosed; + + /// <summary> + /// Gives the abilit to override the custom filtering + /// </summary> + /// <returns>The filtered completion list, or null if the default list should be taken.</returns> + /// <param name="input">Contains all information needed to filter the list.</param> + CompletionListFilterResult FilterCompletionList (CompletionListFilterInput input); + int FindMatchedEntry (ICompletionDataList completionDataList, MruCache cache, string partialWord, List<int> filteredItems); + int [] GetHighlightedIndices (CompletionData completionData, string completionString); } @@ -71,7 +81,7 @@ namespace MonoDevelop.Ide.CodeCompletion public class CompletionDataList : List<CompletionData>, ICompletionDataList { public int TriggerWordStart { get; set; } = -1; - public int TriggerWordLength { get; set; } + public int TriggerWordLength { get; set; } = -1; public bool IsSorted { get; set; } public IComparer<CompletionData> Comparer { get; set; } @@ -83,7 +93,12 @@ namespace MonoDevelop.Ide.CodeCompletion public bool AutoCompleteEmptyMatchOnCurlyBrace { get; set; } public CompletionSelectionMode CompletionSelectionMode { get; set; } public bool CloseOnSquareBrackets { get; set; } - + + public virtual CompletionListFilterResult FilterCompletionList (CompletionListFilterInput input) + { + return null; + } + List<ICompletionKeyHandler> keyHandler = new List<ICompletionKeyHandler> (); public IEnumerable<ICompletionKeyHandler> KeyHandler { get { return keyHandler; } @@ -171,7 +186,78 @@ namespace MonoDevelop.Ide.CodeCompletion if (handler != null) handler (this, e); } - + + public virtual int FindMatchedEntry (ICompletionDataList completionDataList, MruCache cache, string partialWord, List<int> filteredItems) + { + // default - word with highest match rating in the list. + int idx = -1; + + StringMatcher matcher = null; + if (!string.IsNullOrEmpty (partialWord)) { + matcher = CompletionMatcher.CreateCompletionMatcher (partialWord); + string bestWord = null; + int bestRank = int.MinValue; + int bestIndex = 0; + int bestIndexPriority = int.MinValue; + for (int i = 0; i < filteredItems.Count; i++) { + int index = filteredItems [i]; + var data = completionDataList [index]; + if (bestIndexPriority > data.PriorityGroup) + continue; + string text = data.DisplayText; + int rank; + if (!matcher.CalcMatchRank (text, out rank)) + continue; + if (rank > bestRank || data.PriorityGroup > bestIndexPriority) { + bestWord = text; + bestRank = rank; + bestIndex = i; + bestIndexPriority = data.PriorityGroup; + } + } + + if (bestWord != null) { + idx = bestIndex; + // exact match found. + if (string.Compare (bestWord, partialWord ?? "", true) == 0) + return idx; + } + } + + CompletionData currentData; + int bestMruIndex; + if (idx >= 0) { + currentData = completionDataList [filteredItems [idx]]; + bestMruIndex = cache.GetIndex (currentData); + } else { + bestMruIndex = int.MaxValue; + currentData = null; + } + for (int i = 0; i < filteredItems.Count; i++) { + var mruData = completionDataList [filteredItems [i]]; + int curMruIndex = cache.GetIndex (mruData); + if (curMruIndex == 1) + continue; + if (curMruIndex < bestMruIndex) { + int r1 = 0, r2 = 0; + if (currentData == null || matcher != null && matcher.CalcMatchRank (mruData.DisplayText, out r1) && matcher.CalcMatchRank (currentData.DisplayText, out r2)) { + if (r1 >= r2 || partialWord.Length == 0 || partialWord.Length == 1 && mruData.DisplayText [0] == partialWord [0]) { + bestMruIndex = curMruIndex; + idx = i; + currentData = mruData; + } + } + } + } + return idx; + } + + public virtual int [] GetHighlightedIndices (CompletionData completionData, string completionString) + { + var matcher = CompletionMatcher.CreateCompletionMatcher (completionString); + return matcher.GetMatch (completionData.DisplayText); + } + public event EventHandler CompletionListClosed; } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs index cc1fb07675..7262320522 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionListWindow.cs @@ -43,6 +43,23 @@ namespace MonoDevelop.Ide.CodeCompletion { CompletionListWindowGtk window; + public CompletionData SelectedItem { + get { + return window.SelectedItem; + } + } + + public int SelectedItemIndex { + get { return window.SelectedItemIndex; } + } + + public event EventHandler SelectionChanged { + add { window.SelectionChanged += value; } + remove { window.SelectionChanged += value; } + } + + + public CompletionListWindow () { window = new CompletionListWindowGtk (this); @@ -372,7 +389,7 @@ namespace MonoDevelop.Ide.CodeCompletion get { return completionDataList; } set { completionDataList = value; - defaultComparer = null; + ListWidget.defaultComparer = null; } } @@ -486,7 +503,7 @@ namespace MonoDevelop.Ide.CodeCompletion ((IDisposable)completionDataList).Dispose (); CloseCompletionList (); completionDataList = null; - defaultComparer = null; + ListWidget.defaultComparer = null; } HideDeclarationView (); @@ -501,6 +518,8 @@ namespace MonoDevelop.Ide.CodeCompletion public void PostProcessKeyEvent (KeyDescriptor descriptor) { + if (this.CompletionDataList == null) + return; KeyActions ka = KeyActions.None; bool keyHandled = false; if (CompletionDataList != null) { @@ -634,9 +653,8 @@ namespace MonoDevelop.Ide.CodeCompletion CompletionWidget = completionWidget; CodeCompletionContext = completionContext; - string text = CompletionWidget.GetCompletionText (CodeCompletionContext); - initialWordLength = CompletionWidget.SelectedLength > 0 ? 0 : text.Length; - StartOffset = CompletionWidget.CaretOffset - initialWordLength; + initialWordLength = CompletionWidget.SelectedLength > 0 ? 0 : CodeCompletionContext.TriggerWordLength; + StartOffset = CodeCompletionContext.TriggerOffset; } internal bool ShowListWindow (ICompletionDataList list, CodeCompletionContext completionContext) @@ -665,9 +683,8 @@ namespace MonoDevelop.Ide.CodeCompletion AutoCompleteEmptyMatchOnCurlyBrace = list.AutoCompleteEmptyMatchOnCurlyBrace; CloseOnSquareBrackets = list.CloseOnSquareBrackets; // makes control-space in midle of words to work - string text = CompletionWidget.GetCompletionText (CodeCompletionContext); DefaultCompletionString = completionDataList.DefaultCompletionString ?? ""; - if (text.Length == 0) { + if (completionContext.TriggerWordLength == 0) { UpdateWordSelection (); initialWordLength = 0; //completionWidget.SelectedLength; @@ -685,8 +702,8 @@ namespace MonoDevelop.Ide.CodeCompletion return true; } - initialWordLength = CompletionWidget.SelectedLength > 0 ? 0 : text.Length; - StartOffset = CompletionWidget.CaretOffset - initialWordLength; + initialWordLength = CompletionWidget.SelectedLength > 0 ? 0 : completionContext.TriggerWordLength; + StartOffset = completionContext.TriggerOffset; HideWhenWordDeleted = initialWordLength != 0; ResetSizes (); UpdateWordSelection (); @@ -704,21 +721,7 @@ namespace MonoDevelop.Ide.CodeCompletion return false; } - class DataItemComparer : IComparer<CompletionData> - { - public int Compare (CompletionData a, CompletionData b) - { - if (a is IComparable && b is IComparable) - return ((IComparable)a).CompareTo (b); - return CompletionData.Compare (a, b); - } - } - IComparer<CompletionData> GetComparerForCompletionList (ICompletionDataList dataList) - { - var concrete = dataList as CompletionDataList; - return concrete != null && concrete.Comparer != null ? concrete.Comparer : new DataItemComparer (); - } bool FillList () { @@ -726,12 +729,12 @@ namespace MonoDevelop.Ide.CodeCompletion return false; Style = CompletionWidget.GtkStyle; - + //sort, sinking obsolete items to the bottoms //the string comparison is ordinal as that makes it an order of magnitude faster, which //which makes completion triggering noticeably more responsive if (!completionDataList.IsSorted) - completionDataList.Sort (GetComparerForCompletionList (completionDataList)); + completionDataList.Sort (ListWidget.GetComparerForCompletionList (completionDataList)); Reposition (true); return true; @@ -813,7 +816,7 @@ namespace MonoDevelop.Ide.CodeCompletion AddWordToHistory (PartialWord, cdItem.CompletionText); OnWordCompleted (new CodeCompletionContextEventArgs (CompletionWidget, CodeCompletionContext, cdItem.CompletionText)); */
- if (item.HasOverloads && declarationviewwindow.CurrentOverload >= 0 && declarationviewwindow.CurrentOverload < item.OverloadedData.Count) { + if (item.HasOverloads && declarationviewwindow != null && declarationviewwindow.CurrentOverload >= 0 && declarationviewwindow.CurrentOverload < item.OverloadedData.Count) { item.OverloadedData[declarationviewwindow.CurrentOverload].InsertCompletionText (facade, ref ka, descriptor); } else { item.InsertCompletionText (facade, ref ka, descriptor); @@ -881,8 +884,7 @@ namespace MonoDevelop.Ide.CodeCompletion // no selection, try to find a selection if (List.SelectedItemIndex < 0 || List.SelectedItemIndex >= completionDataList.Count) { List.CompletionString = PartialWord; - bool hasMismatches; - List.SelectionFilterIndex = FindMatchedEntry (List.CompletionString, out hasMismatches); + List.SelectionFilterIndex = FindMatchedEntry (List.CompletionString); } // no success, hide declaration view if (List.SelectedItemIndex < 0 || List.SelectedItemIndex >= completionDataList.Count) { @@ -957,7 +959,6 @@ namespace MonoDevelop.Ide.CodeCompletion return false; } - static readonly DataItemComparer overloadComparer = new DataItemComparer (); async void DelayedTooltipShowAsync () @@ -982,7 +983,7 @@ namespace MonoDevelop.Ide.CodeCompletion var cs = new CancellationTokenSource (); declarationViewCancelSource = cs; var overloads = new List<CompletionData> (filteredOverloads); - overloads.Sort (overloadComparer); + overloads.Sort (ListWidget.overloadComparer); foreach (var overload in overloads) { await declarationviewwindow.AddOverload ((CompletionData)overload, cs.Token); } @@ -1072,13 +1073,10 @@ namespace MonoDevelop.Ide.CodeCompletion return completionDataList[n]; } - IComparer<CompletionData> defaultComparer; internal int CompareTo (int n, int m) { - var item1 = completionDataList [n]; - var item2 = completionDataList [m]; - return (defaultComparer ?? (defaultComparer = GetComparerForCompletionList (completionDataList))).Compare (item1, item2); + return ListWidget.CompareTo (completionDataList, n, m); } internal Xwt.Drawing.Image GetIcon (int n) diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerInfo.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerInfo.cs index a7b0a42ff1..d3838a005d 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerInfo.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerInfo.cs @@ -26,13 +26,15 @@ using System; -namespace ICSharpCode.NRefactory6.CSharp.Completion +namespace MonoDevelop.Ide.CodeCompletion { /// <summary> /// Provides information about what triggered completion. /// </summary> public struct CompletionTriggerInfo { + public static readonly CompletionTriggerInfo CodeCompletionCommand = new CompletionTriggerInfo (CompletionTriggerReason.CompletionCommand); + /// <summary> /// Provides the reason that completion was triggered. /// </summary> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerReason.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerReason.cs index df9a2edafb..7bb7392395 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionTriggerReason.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionTriggerReason.cs @@ -26,7 +26,7 @@ using System; -namespace ICSharpCode.NRefactory6.CSharp.Completion +namespace MonoDevelop.Ide.CodeCompletion { public enum CompletionTriggerReason { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionWindowManager.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionWindowManager.cs index b693a28e9f..8d05de71d3 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionWindowManager.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionWindowManager.cs @@ -162,7 +162,7 @@ namespace MonoDevelop.Ide.CodeCompletion if (!IsVisible) return false; if (descriptor.KeyChar != '\0') { - wnd.EndOffset = wnd.StartOffset + wnd.CurrentPartialWord.Length + 1; + wnd.EndOffset++; } return wnd.PreProcessKeyEvent (descriptor); } @@ -192,6 +192,8 @@ namespace MonoDevelop.Ide.CodeCompletion if (!IsVisible) return; wnd.PostProcessKeyEvent (descriptor); + if (wnd.CompletionWidget != null) + wnd.EndOffset = wnd.CompletionWidget.CaretOffset; } public static void RepositionWindow () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs index 78ea0e3b83..de8d43e087 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWidget.cs @@ -43,6 +43,53 @@ using MonoDevelop.Ide.Gui; namespace MonoDevelop.Ide.CodeCompletion { + public class CategorizedCompletionItems + { + public CompletionCategory CompletionCategory { + get; + set; + } + + System.Collections.Generic.List<int> items = new System.Collections.Generic.List<int> (); + public List<int> Items { + get { return items; } + set { items = value; } + } + } + + public class CompletionListFilterInput + { + public ICompletionDataList DataList { get; } + public IReadOnlyList<int> FilteredItems { get; } + public string OldCompletionString { get; } + public string CompletionString { get; } + + public CompletionListFilterInput (ICompletionDataList dataList, IReadOnlyList<int> filteredItems, string oldCompletionString, string completionString) + { + DataList = dataList; + FilteredItems = filteredItems; + OldCompletionString = oldCompletionString; + CompletionString = completionString; + } + } + + public class CompletionListFilterResult + { + public readonly List<CategorizedCompletionItems> CategorizedItems; + public readonly List<int> FilteredItems; + + public CompletionListFilterResult (List<int> filteredItems) + { + FilteredItems = filteredItems; + } + + public CompletionListFilterResult (List<int> filteredItems, List<CategorizedCompletionItems> categorizedItems) + { + CategorizedItems = categorizedItems; + FilteredItems = filteredItems; + } + } + class ListWidget : Gtk.DrawingArea { int listWidth = minSize; @@ -65,21 +112,10 @@ namespace MonoDevelop.Ide.CodeCompletion string completionString; - class Category { - public CompletionCategory CompletionCategory { - get; - set; - } - - System.Collections.Generic.List<int> items = new System.Collections.Generic.List<int> (); - public List<int> Items { - get { return items; } - set { items = value; } - } - } - - List<Category> categories = new List<Category> (); + + List<CategorizedCompletionItems> categories = new List<CategorizedCompletionItems> (); + public string CompletionString { get { return completionString; } set { @@ -277,10 +313,10 @@ namespace MonoDevelop.Ide.CodeCompletion int result = -1; int yPos = 0; int curItem = 0; - Iterate (false, ref yPos, delegate (Category category, int ypos) { + Iterate (false, ref yPos, delegate (CategorizedCompletionItems category, int ypos) { if (countCategories) curItem++; - }, delegate (Category curCategory, int item2, int itemIndex, int ypos) { + }, delegate (CategorizedCompletionItems curCategory, int item2, int itemIndex, int ypos) { if (item == item2) { result = curItem; return false; @@ -296,13 +332,13 @@ namespace MonoDevelop.Ide.CodeCompletion int result = -1; int curItem = 0; int yPos = 0; - Iterate (false, ref yPos, delegate (Category category, int ypos) { + Iterate (false, ref yPos, delegate (CategorizedCompletionItems category, int ypos) { if (countCategories) { if (curItem == index) result = category.Items [0]; curItem++; } - }, delegate (Category curCategory, int item, int itemIndex, int ypos) { + }, delegate (CategorizedCompletionItems curCategory, int item, int itemIndex, int ypos) { if (curItem == index) { result = item; return false; @@ -320,7 +356,7 @@ namespace MonoDevelop.Ide.CodeCompletion int next = Math.Min (categories.Count - 1, Math.Max (0, current + relative)); if (next < 0 || next >= categories.Count) return; - Category newCategory = categories[next]; + CategorizedCompletionItems newCategory = categories[next]; SelectionFilterIndex = newCategory.Items[0]; ScrollToSelectedItem (); } @@ -470,8 +506,7 @@ namespace MonoDevelop.Ide.CodeCompletion return false; } - var matcher = CompletionMatcher.CreateCompletionMatcher (CompletionString); - Iterate (true, ref yPos, delegate (Category category, int ypos) { + Iterate (true, ref yPos, delegate (CategorizedCompletionItems category, int ypos) { if (ypos >= height) return; if (ypos < -rowHeight) @@ -498,7 +533,7 @@ namespace MonoDevelop.Ide.CodeCompletion context.MoveTo (x, ypos + (rowHeight - py) / 2); context.SetSourceColor (categoryColor); Pango.CairoHelper.ShowLayout (context, categoryLayout); - }, delegate (Category curCategory, int item, int itemidx, int ypos) { + }, delegate (CategorizedCompletionItems curCategory, int item, int itemidx, int ypos) { if (ypos >= height) return false; if (ypos < -rowHeight) @@ -521,7 +556,7 @@ namespace MonoDevelop.Ide.CodeCompletion string text = win.DataProvider.GetText (item); if (!string.IsNullOrEmpty (text)) { - int [] matchIndices = matcher.GetMatch (text); + int [] matchIndices = win.CompletionDataList.GetHighlightedIndices(win.CompletionDataList[item], CompletionString); if (matchIndices != null) { Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList (); for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++) { @@ -648,13 +683,13 @@ namespace MonoDevelop.Ide.CodeCompletion internal List<int> filteredItems = new List<int> (); - static Category GetCategory (List<Category> categories, CompletionCategory completionCategory) + static CategorizedCompletionItems GetCategory (List<CategorizedCompletionItems> categories, CompletionCategory completionCategory) { foreach (var cat in categories) { if (cat.CompletionCategory == completionCategory) return cat; } - var result = new Category (); + var result = new CategorizedCompletionItems (); result.CompletionCategory = completionCategory; if (completionCategory == null) { categories.Add (result); @@ -666,15 +701,17 @@ namespace MonoDevelop.Ide.CodeCompletion } string oldCompletionString = null; - public void FilterWords () + + + static CompletionListFilterResult DefaultFilterWords (ICompletionDataList dataList, List<int> filteredItems, string oldCompletionString, string CompletionString) { - var newCategories = new List<Category> (); + var newCategories = new List<CategorizedCompletionItems> (); var matcher = CompletionMatcher.CreateCompletionMatcher (CompletionString); if (oldCompletionString == null || !CompletionString.StartsWith (oldCompletionString, StringComparison.Ordinal)) { filteredItems.Clear (); - for (int newSelection = 0; newSelection < win.DataProvider.ItemCount; newSelection++) { - if (string.IsNullOrEmpty (CompletionString) || matcher.IsMatch (win.DataProvider.GetText (newSelection))) { - var completionCategory = win.DataProvider.GetCompletionCategory (newSelection); + for (int newSelection = 0; newSelection < dataList.Count; newSelection++) { + if (string.IsNullOrEmpty (CompletionString) || matcher.IsMatch (dataList [newSelection].DisplayText)) { + var completionCategory = dataList [newSelection].CompletionCategory; GetCategory (newCategories, completionCategory).Items.Add (newSelection); filteredItems.Add (newSelection); } @@ -683,8 +720,8 @@ namespace MonoDevelop.Ide.CodeCompletion var oldItems = filteredItems; filteredItems = new List<int> (); foreach (int newSelection in oldItems) { - if (string.IsNullOrEmpty (CompletionString) || matcher.IsMatch (win.DataProvider.GetText (newSelection))) { - var completionCategory = win.DataProvider.GetCompletionCategory (newSelection); + if (string.IsNullOrEmpty (CompletionString) || matcher.IsMatch (dataList [newSelection].DisplayText)) { + var completionCategory = dataList [newSelection].CompletionCategory; GetCategory (newCategories, completionCategory).Items.Add (newSelection); filteredItems.Add (newSelection); } @@ -692,14 +729,14 @@ namespace MonoDevelop.Ide.CodeCompletion } filteredItems.Sort (delegate (int left, int right) { int rank1, rank2; - var data1 = win.DataProvider.GetCompletionData (left); - var data2 = win.DataProvider.GetCompletionData (right); + var data1 = dataList [left]; + var data2 = dataList [right]; if (data1 == null || data2 == null) return 0; if (data1.PriorityGroup != data2.PriorityGroup) return data2.PriorityGroup.CompareTo (data1.PriorityGroup); if (string.IsNullOrEmpty (CompletionString)) - return win.DataProvider.CompareTo (left, right); + return CompareTo (dataList, left, right); if (!matcher.CalcMatchRank (data1.CompletionText, out rank1)) return 0; @@ -713,11 +750,11 @@ namespace MonoDevelop.Ide.CodeCompletion if (filteredItems.Count > 0) { int idx = 0; int rank; - var data = win.DataProvider.GetCompletionData (filteredItems [0]); + var data = dataList[filteredItems [0]]; int firstGrp = data.PriorityGroup; matcher.CalcMatchRank (data.CompletionText, out rank); for (int i = 1; i < filteredItems.Count; i++) { - var curData = win.DataProvider.GetCompletionData (filteredItems [i]); + var curData = dataList[filteredItems [i]]; if (curData.PriorityGroup == firstGrp) continue; int curRank; @@ -737,15 +774,58 @@ namespace MonoDevelop.Ide.CodeCompletion } } - newCategories.Sort (delegate (Category left, Category right) { + newCategories.Sort (delegate (CategorizedCompletionItems left, CategorizedCompletionItems right) { if (left.CompletionCategory == null) return 1; if (right.CompletionCategory == null) return -1; - + return left.CompletionCategory.CompareTo (right.CompletionCategory); }); - categories = newCategories; + + return new CompletionListFilterResult (filteredItems, newCategories); + } + + + class DataItemComparer : IComparer<CompletionData> + { + public int Compare (CompletionData a, CompletionData b) + { + if (a is IComparable && b is IComparable) + return ((IComparable)a).CompareTo (b); + return CompletionData.Compare (a, b); + } + } + internal static readonly IComparer<CompletionData> overloadComparer = new DataItemComparer (); + internal static IComparer<CompletionData> defaultComparer; + + internal static int CompareTo (ICompletionDataList completionDataList, int n, int m) + { + var item1 = completionDataList [n]; + var item2 = completionDataList [m]; + return (defaultComparer ?? (defaultComparer = GetComparerForCompletionList (completionDataList))).Compare (item1, item2); + } + + internal static IComparer<CompletionData> GetComparerForCompletionList (ICompletionDataList dataList) + { + var concrete = dataList as CompletionDataList; + return concrete != null && concrete.Comparer != null ? concrete.Comparer : new DataItemComparer (); + } + + public void FilterWords () + { + if (win.CompletionDataList == null) + return; + var filterResult = win.CompletionDataList.FilterCompletionList (new CompletionListFilterInput (win.CompletionDataList, filteredItems, oldCompletionString, CompletionString)); + if (filterResult == null) + filterResult = DefaultFilterWords (win.CompletionDataList, filteredItems, oldCompletionString, CompletionString); + + filteredItems = filterResult.FilteredItems; + if (filterResult.CategorizedItems == null) { + categories.Clear (); + } else { + categories = filterResult.CategorizedItems; + } //SelectFirstItemInCategory (); CalcVisibleRows (); @@ -798,8 +878,8 @@ namespace MonoDevelop.Ide.CodeCompletion { int outpos = 0; int yPos = 0; - Iterate (false, ref yPos, delegate (Category category, int ypos) { - }, delegate (Category curCategory, int item, int itemIndex, int ypos) { + Iterate (false, ref yPos, delegate (CategorizedCompletionItems category, int ypos) { + }, delegate (CategorizedCompletionItems curCategory, int item, int itemIndex, int ypos) { if (item == row) { outpos = ypos; return false; @@ -838,14 +918,14 @@ namespace MonoDevelop.Ide.CodeCompletion const int spacing = 2; EditorTheme EditorTheme => SyntaxHighlightingService.GetEditorTheme (IdeApp.Preferences.ColorScheme); - delegate void CategoryAction (Category category, int yPos); - delegate bool ItemAction (Category curCategory, int item, int itemIndex, int yPos); + delegate void CategoryAction (CategorizedCompletionItems category, int yPos); + delegate bool ItemAction (CategorizedCompletionItems curCategory, int item, int itemIndex, int yPos); void Iterate (bool startAtPage, ref int ypos, CategoryAction catAction, ItemAction action) { int curItem = 0; if (InCategoryMode) { - foreach (Category category in this.categories) { + foreach (CategorizedCompletionItems category in this.categories) { var nextYPos = ypos + rowHeight; // if (!startAtPage || nextYPos >= vadj.Value) { if (catAction != null) @@ -878,7 +958,7 @@ namespace MonoDevelop.Ide.CodeCompletion } } - bool IterateItems (Category category, bool startAtPage, ref int ypos, ref int curItem, ItemAction action) + bool IterateItems (CategorizedCompletionItems category, bool startAtPage, ref int ypos, ref int curItem, ItemAction action) { foreach (int item in category.Items) { var nextYpos = ypos + rowHeight; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs index d1a4359785..c4b829e0e4 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/ListWindow.cs @@ -200,7 +200,7 @@ namespace MonoDevelop.Ide.CodeCompletion public CompletionData SelectedItem { get { - return completionDataList [SelectedItemIndex]; + return SelectedItemIndex >= 0 ? completionDataList [SelectedItemIndex] : null; } } @@ -335,18 +335,19 @@ namespace MonoDevelop.Ide.CodeCompletion UpdateWordSelection (); return KeyActions.Process; } + if (SelectedItemIndex < 0) + return KeyActions.Process; var data = DataProvider.GetCompletionData (SelectedItemIndex); if (data.IsCommitCharacter (keyChar, PartialWord)) { - bool hasMismatches; var curword = PartialWord; - int match = FindMatchedEntry (curword, out hasMismatches); + int match = FindMatchedEntry (curword); if (match >= 0 && System.Char.IsPunctuation (keyChar)) { string text = DataProvider.GetCompletionText (FilteredItems [match]); if (!text.ToUpper ().StartsWith (curword.ToUpper (), StringComparison.Ordinal)) match = -1; } - if (match >= 0 && !hasMismatches && keyChar != '<' && keyChar != ' ') { + if (match >= 0 && keyChar != '<' && keyChar != ' ') { ResetSizes (); UpdateWordSelection (); return KeyActions.Process; @@ -493,6 +494,8 @@ namespace MonoDevelop.Ide.CodeCompletion // // AltGr // return KeyActions.Process; } + var data = SelectedItem; + if (descriptor.KeyChar == '\0') return KeyActions.Process; @@ -502,6 +505,14 @@ namespace MonoDevelop.Ide.CodeCompletion if (char.IsDigit (descriptor.KeyChar) && string.IsNullOrEmpty (CurrentCompletionText)) return KeyActions.CloseWindow | KeyActions.Process; + if (data != null && data.MuteCharacter (descriptor.KeyChar, PartialWord)) { + if (data.IsCommitCharacter (descriptor.KeyChar, PartialWord)) { + return KeyActions.CloseWindow | KeyActions.Ignore | KeyActions.Complete; + } + return KeyActions.CloseWindow | KeyActions.Ignore; + } + + // special case end with punctuation like 'param:' -> don't input double punctuation, otherwise we would end up with 'param::' if (char.IsPunctuation (descriptor.KeyChar) && descriptor.KeyChar != '_') { if (descriptor.KeyChar == ':') { @@ -513,8 +524,9 @@ namespace MonoDevelop.Ide.CodeCompletion } } else { var selectedItem = list.SelectedItemIndex; - if (selectedItem < 0 || selectedItem >= DataProvider.ItemCount) + if (selectedItem < 0 || selectedItem >= DataProvider.ItemCount) { return KeyActions.CloseWindow; + } if (DataProvider.GetText (selectedItem).EndsWith (descriptor.KeyChar.ToString (), StringComparison.Ordinal)) { return KeyActions.Complete | KeyActions.CloseWindow | KeyActions.Ignore; } @@ -597,71 +609,11 @@ namespace MonoDevelop.Ide.CodeCompletion } } - protected int FindMatchedEntry (string partialWord, out bool hasMismatches) + protected int FindMatchedEntry (string partialWord) { - // default - word with highest match rating in the list. - hasMismatches = true; - int idx = -1; - - StringMatcher matcher = null; - if (!string.IsNullOrEmpty (partialWord)) { - matcher = CompletionMatcher.CreateCompletionMatcher (partialWord); - string bestWord = null; - int bestRank = int.MinValue; - int bestIndex = 0; - int bestIndexPriority = int.MinValue; - for (int i = 0; i < list.filteredItems.Count; i++) { - int index = list.filteredItems [i]; - var data = DataProvider.GetCompletionData (index); - if (bestIndexPriority > data.PriorityGroup) - continue; - string text = data.DisplayText; - int rank; - if (!matcher.CalcMatchRank (text, out rank)) - continue; - if (rank > bestRank || data.PriorityGroup > bestIndexPriority) { - bestWord = text; - bestRank = rank; - bestIndex = i; - bestIndexPriority = data.PriorityGroup; - } - } - - if (bestWord != null) { - idx = bestIndex; - hasMismatches = false; - // exact match found. - if (string.Compare (bestWord, partialWord ?? "", true) == 0) - return idx; - } - } - - CompletionData currentData; - int bestMruIndex; - if (idx >= 0) { - currentData = completionDataList [list.filteredItems [idx]]; - bestMruIndex = cache.GetIndex (currentData); - } else { - bestMruIndex = int.MaxValue; - currentData = null; - } - for (int i = 0; i < list.filteredItems.Count; i++) { - var mruData = completionDataList [list.filteredItems [i]]; - int curMruIndex = cache.GetIndex (mruData); - if (curMruIndex == 1) - continue; - if (curMruIndex < bestMruIndex) { - int r1 = 0, r2 = 0; - if (currentData == null || matcher != null && matcher.CalcMatchRank (mruData.DisplayText, out r1) && matcher.CalcMatchRank (currentData.DisplayText, out r2)) { - if (r1 >= r2 || PartialWord.Length == 0 || PartialWord.Length == 1 && mruData.DisplayText[0] == PartialWord[0]) { - bestMruIndex = curMruIndex; - idx = i; - currentData = mruData; - } - } - } - } - return idx; + if (completionDataList == null) + return -1; + return completionDataList.FindMatchedEntry (completionDataList, cache, partialWord, list.filteredItems); } void SelectEntry (int n) @@ -681,9 +633,8 @@ namespace MonoDevelop.Ide.CodeCompletion list.Selection = 0; return; }*/ - bool hasMismatches; - int matchedIndex = FindMatchedEntry (s, out hasMismatches); + int matchedIndex = FindMatchedEntry (s); // ResetSizes (); SelectEntry (matchedIndex); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/MruCache.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/MruCache.cs index 90e679af3f..e27131202a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/MruCache.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/MruCache.cs @@ -28,7 +28,7 @@ using System.Collections.Generic; namespace MonoDevelop.Ide.CodeCompletion { - class MruCache + public class MruCache { const int MaxItems = 42; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs index 2c514affc6..92e8c205dd 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/ExpansionObject.cs @@ -184,8 +184,9 @@ namespace MonoDevelop.Ide.CodeTemplates if (ext != null) { if (list == null) - list = ext.CodeCompletionCommand ( - CurrentContext.DocumentContext.GetContent <MonoDevelop.Ide.CodeCompletion.ICompletionWidget> ().CurrentCodeCompletionContext).Result; + list = ext.HandleCodeCompletionAsync ( + CurrentContext.DocumentContext.GetContent <MonoDevelop.Ide.CodeCompletion.ICompletionWidget> ().CurrentCodeCompletionContext, + CompletionTriggerInfo.CodeCompletionCommand).Result; foreach (var data in list.OfType<ISymbolCompletionData> ()) { if (data.Symbol == null) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs index 1906434e54..f923620538 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs @@ -157,7 +157,7 @@ namespace MonoDevelop.Ide.Editor.Extension var caretOffset = Editor.CaretOffset; var token = completionTokenSrc.Token; try { - var task = HandleCodeCompletionAsync (CurrentCompletionContext, descriptor.KeyChar, token); + var task = HandleCodeCompletionAsync (CurrentCompletionContext, new CompletionTriggerInfo (CompletionTriggerReason.CharTyped, descriptor.KeyChar), token); if (task != null) { // Show the completion window in two steps. The call to PrepareShowWindow creates the window but // it doesn't show it. It is used only to process the keys while the completion data is being retrieved. @@ -166,7 +166,6 @@ namespace MonoDevelop.Ide.Editor.Extension completionTokenSrc.Cancel (); }; CompletionWindowManager.WindowClosed += windowClosed; - task.ContinueWith (t => { CompletionWindowManager.WindowClosed -= windowClosed; if (token.IsCancellationRequested) @@ -215,7 +214,7 @@ namespace MonoDevelop.Ide.Editor.Extension var caretOffset = Editor.CaretOffset; var token = completionTokenSrc.Token; try { - var task = HandleBackspaceOrDeleteCodeCompletionAsync (CurrentCompletionContext, descriptor.SpecialKey, deleteOrBackspaceTriggerChar, token); + var task = HandleCodeCompletionAsync (CurrentCompletionContext, new CompletionTriggerInfo (CompletionTriggerReason.BackspaceOrDeleteCommand, deleteOrBackspaceTriggerChar), token); if (task != null) { // Show the completion window in two steps. The call to PrepareShowWindow creates the window but // it doesn't show it. It is used only to process the keys while the completion data is being retrieved. @@ -363,7 +362,11 @@ namespace MonoDevelop.Ide.Editor.Extension } CurrentCompletionContext = CompletionWidget.CreateCodeCompletionContext (cpos); CurrentCompletionContext.TriggerWordLength = wlen; - completionList = await CodeCompletionCommand (CurrentCompletionContext); + completionList = await HandleCodeCompletionAsync (CurrentCompletionContext, new CompletionTriggerInfo (CompletionTriggerReason.CompletionCommand)); + if (completionList.TriggerWordStart >= 0) + CurrentCompletionContext.TriggerOffset = completionList.TriggerWordStart; + if (completionList.TriggerWordLength >= 0) + CurrentCompletionContext.TriggerWordLength = completionList.TriggerWordLength; if (completionList == null || !CompletionWindowManager.ShowWindow (this, (char)0, completionList, CompletionWidget, CurrentCompletionContext)) { CurrentCompletionContext = null; } @@ -466,14 +469,15 @@ namespace MonoDevelop.Ide.Editor.Extension static readonly ICompletionDataList emptyList = new CompletionDataList (); - public virtual Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) + public virtual Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default (CancellationToken)) { return Task.FromResult (emptyList); } - public virtual Task<ICompletionDataList> HandleBackspaceOrDeleteCodeCompletionAsync (CodeCompletionContext completionContext, SpecialKey key, char triggerCharacter, CancellationToken token = default(CancellationToken)) + [Obsolete("Use HandleCodeCompletionAsync")] + public Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) { - return Task.FromResult (emptyList); + return HandleCodeCompletionAsync (completionContext, CompletionTriggerInfo.CodeCompletionCommand); } public virtual Task<ParameterHintingResult> HandleParameterCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token = default(CancellationToken)) @@ -542,27 +546,6 @@ namespace MonoDevelop.Ide.Editor.Extension } return list; } - - public virtual async Task<ICompletionDataList> CodeCompletionCommand (CodeCompletionContext completionContext) - { - // This default implementation of CodeCompletionCommand calls HandleCodeCompletion providing - // the char at the cursor position. If it returns a provider, just return it. - - completionTokenSrc.Cancel (); - completionTokenSrc = new CancellationTokenSource (); - var ctoken = completionTokenSrc.Token; - - int pos = completionContext.TriggerOffset; - if (pos > 0) { - char ch = Editor.GetCharAt (pos - 1); - try { - return await HandleCodeCompletionAsync (completionContext, ch, ctoken); - } catch (TaskCanceledException) { - } catch (AggregateException) { - } - } - return null; - } public virtual async Task<ParameterHintingResult> ParameterCompletionCommand (CodeCompletionContext completionContext) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/Sublime3Format.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/Sublime3Format.cs index 8db85b0459..7e8b8afa6e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/Sublime3Format.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/Sublime3Format.cs @@ -7,6 +7,7 @@ using System.Text; using MonoDevelop.Core; using System.Diagnostics; using System.Xml; +using System.Globalization; namespace MonoDevelop.Ide.Editor.Highlighting { @@ -214,15 +215,28 @@ namespace MonoDevelop.Ide.Editor.Highlighting int[] table = new int [256]; StringBuilder org = new StringBuilder (); List<string> unicodeGroups = new List<string> (); + CharacterClass subClass; public void Push (char ch) { org.Append (ch); switch (ch) { case ':': - if (first) + if (escape) + goto default; + if (first || lastPushedChar == '[') { wordBuilder = new StringBuilder (); - goto default; + subClass = new CharacterClass (); + subClass.Add (':'); + } else { + if (wordBuilder != null) { + ConvertUnicodeCategory (wordBuilder.ToString ()); + wordBuilder = null; + subClass = null; + } else + goto default; + } + break; case '^': if (first) { negativeGroup = true; @@ -244,18 +258,19 @@ namespace MonoDevelop.Ide.Editor.Highlighting case '[': if (escape) goto default; + PushLastChar (); break; case ']': if (escape) goto default; break; case '\\': - if (escape) + if (escape || wordBuilder != null) goto default; escape = true; break; case '-': - if (escape || first) + if (escape || first || wordBuilder != null) goto default; range = true; break; @@ -364,6 +379,8 @@ namespace MonoDevelop.Ide.Editor.Highlighting if (wordBuilder != null) { wordBuilder.Append (ch); + subClass.Push (ch); + break; } if (!hasLast) { @@ -403,6 +420,21 @@ namespace MonoDevelop.Ide.Editor.Highlighting } } + void Add (char ch) + { + table [ch] = negativeGroup ? -1 : 1; + } + + void AddUnicodeCategory (params UnicodeCategory[] categories) + { + for (int i = 0; i < table.Length; i++) { + var cat = char.GetUnicodeCategory ((char)i); + if (categories.Contains (cat)) { + table [i] = negativeGroup ? -1 : 1; + } + } + } + bool HasRange (char fromC, char toC) { for (int i = fromC; i <= toC; i++) { @@ -429,29 +461,60 @@ namespace MonoDevelop.Ide.Editor.Highlighting } + void PrepareGeneration () + { + PushLastChar (); + + if (range) + table ['-'] = negativeGroup ? -1 : 1; + if (escape) + table ['\\'] = negativeGroup ? -1 : 1; + + } public string Generate () { - if (wordBuilder != null && lastPushedChar == ':') { - return ConvertUnicodeCategory (wordBuilder.ToString(1, wordBuilder.Length - 2), false); + if (subClass != null) { + subClass.PrepareGeneration (); + for (int i = 0; i < table.Length; i++) { + if (subClass.table [i] != 0) + table [i] = subClass.table [i]; + } } + PrepareGeneration (); var result = new StringBuilder (); result.Append ('['); if (negativeGroup) result.Append ('^'); - PushLastChar (); - - if (range) - table ['-'] = negativeGroup ? -1 : 1; - if (escape) - table ['\\'] = negativeGroup ? -1 : 1; + + bool hasAllPrintable = true; + for (int i = 0; i < table.Length; i++) { + var ch = (char)i; + if (ch == ' ' || ch == '\t') + continue; + var cat = char.GetUnicodeCategory (ch); + if (cat == UnicodeCategory.Control || cat == UnicodeCategory.LineSeparator) + continue; + if (table [i] == 0) { + hasAllPrintable = false; + } + } - if (HasRange ('a', 'z') && HasRange ('A', 'Z') && HasRange ('0', '9') && table ['_'] != 0) { + if (hasAllPrintable) { + for (int i = 0; i < table.Length; i++) { + var ch = (char)i; + if (ch == ' ' || ch == '\t') + continue; + var cat = char.GetUnicodeCategory (ch); + if (cat == UnicodeCategory.Control || cat == UnicodeCategory.LineSeparator) + continue; + table [i] = 0; + } + result.Append ("\\S"); + } + if (HasRange ('a', 'z') && HasRange ('A', 'Z')) { RemoveRange ('a', 'z'); RemoveRange ('A', 'Z'); - RemoveRange ('0', '9'); - table ['_'] = 0; - result.Append ("\\w"); } @@ -469,12 +532,10 @@ namespace MonoDevelop.Ide.Editor.Highlighting table ['\f'] = 0; } - for (int i = 0; i < table.Length; i++) { int cur = table [i]; if (cur != 0) { AddChar (result, (char)i); - int j = i + 1; for (; j < table.Length; j++) { if (table [j] == 0) @@ -491,7 +552,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting result.Append ("\\p{"); result.Append (grp); result.Append ("}"); -} + } result.Append (']'); return result.ToString (); } @@ -530,6 +591,76 @@ namespace MonoDevelop.Ide.Editor.Highlighting break; } } + + void ConvertUnicodeCategory (string category) + { + switch (category) { + case "alnum": // Alphabetic and numeric character + //return inCharacterClass ? "\\w\\d": "[\\w\\d]"; + AddRange ('a', 'z'); + AddRange ('A', 'Z'); + AddRange ('0', '9'); + break; + case "alpha": // Alphabetic character + AddRange ('a', 'z'); + AddRange ('A', 'Z'); + break; + case "blank": // Space or tab + Add (' '); + Add ('\t'); + break; + case "cntrl": // Control character + AddUnicodeCategory (UnicodeCategory.Control); + break; + case "digit": // Digit + AddRange ('0', '9'); + break; + case "graph": // Non - blank character (excludes spaces, control characters, and similar) + for (int i = 0; i < table.Length; i++) { + var ch = (char)i; + if (ch == ' ' || ch == '\t') + continue; + var cat = char.GetUnicodeCategory (ch); + if (cat == UnicodeCategory.Control || cat == UnicodeCategory.LineSeparator) + continue; + table [i] = negativeGroup ? -1 : 1; + } + break; + case "lower": // Lowercase alphabetical character + AddRange ('a', 'z'); + break; + case "print": // Like [:graph:], but includes the space character + for (int i = 0; i < table.Length; i++) { + var ch = (char)i; + var cat = char.GetUnicodeCategory (ch); + if (cat == UnicodeCategory.Control || cat == UnicodeCategory.LineSeparator) + continue; + table [i] = negativeGroup ? -1 : 1; + } + break; + case "punct": // Punctuation character + AddUnicodeCategory (UnicodeCategory.OpenPunctuation, UnicodeCategory.ClosePunctuation, UnicodeCategory.DashPunctuation, + UnicodeCategory.OtherPunctuation, UnicodeCategory.ConnectorPunctuation, UnicodeCategory.FinalQuotePunctuation, UnicodeCategory.InitialQuotePunctuation); + break; + case "space": // Whitespace character ([:blank:], newline, carriage return, etc.) + Add (' '); + Add ('\t'); + Add ('\r'); + Add ('\n'); + break; + case "upper": // Uppercase alphabetical + AddRange ('A', 'Z'); + break; + case "xdigit": // Digit allowed in a hexadecimal number (i.e., 0 - 9a - fA - F) + AddRange ('a', 'f'); + AddRange ('A', 'F'); + AddRange ('0', '9'); + break; + default: + LoggingService.LogWarning ("unknown unicode category : " + category); + break; + } + } } class Group @@ -628,11 +759,11 @@ namespace MonoDevelop.Ide.Editor.Highlighting case '>': recordGroupName = false; if (replaceGroup) { - foreach (var g in groups) { - if (g.Id == curGroupName.ToString ()) { - result.Append (g.groupContent.ToString ()); - } - } + bool foundGroup = false; + result.Append ("\\k<"); + result.Append (curGroupName.ToString ()); + result.Append (">"); + replaceGroup = false; curGroupName.Length = 0; continue; @@ -688,8 +819,12 @@ namespace MonoDevelop.Ide.Editor.Highlighting } escape = false; addChar: - if (recordGroupName && ch != '<') { - curGroupName.Append (ch); + if (recordGroupName) { + if (ch == '-') + ch = '_'; + if (ch != '<') { + curGroupName.Append (ch); + } } if (replaceGroup) continue; @@ -802,38 +937,6 @@ namespace MonoDevelop.Ide.Editor.Highlighting } } - static string ConvertUnicodeCategory (string category, bool inCharacterClass) - { - switch (category) { - case "alnum": // Alphabetic and numeric character - return inCharacterClass ? "\\w\\d": "[\\w\\d]"; - case "alpha": // Alphabetic character - return "\\w"; - case "blank": // Space or tab - return inCharacterClass ? " \t" : "[ \t]"; - case "cntrl": // Control character - return "\\W"; // TODO - case "digit": // Digit - return "\\d"; - case "graph": // Non - blank character (excludes spaces, control characters, and similar) - return "\\S"; - case "lower": // Lowercase alphabetical character - return inCharacterClass ? "a-z" : "[a-z]"; - case "print": // Like [:graph:], but includes the space character - return inCharacterClass ? "\\S\\ " : "[\\S\\ ]"; - case "punct": // Punctuation character - return "\\W"; // TODO - case "space": // Whitespace character ([:blank:], newline, carriage return, etc.) - return "\\s"; - case "upper": // Uppercase alphabetical - return inCharacterClass ? "A-Z" : "[A-Z]"; - case "xdigit": // Digit allowed in a hexadecimal number (i.e., 0 - 9a - fA - F) - return inCharacterClass ? "0-9a-fA-F" : "[0-9a-fA-F]"; - } - LoggingService.LogWarning ("unknown unicode category : " + category); - return ""; - } - internal static TmSnippet ReadSnippet (Stream stream) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs index ad1f97fe75..70576c62b2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs @@ -13,7 +13,6 @@ using MonoDevelop.Core.Text; namespace MonoDevelop.Ide.Editor.Highlighting { - public class SyntaxHighlighting : ISyntaxHighlighting { readonly SyntaxHighlightingDefinition definition; @@ -163,7 +162,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting this.state = state; } - static readonly TimeSpan matchTimeout = TimeSpan.FromMilliseconds (50); + static readonly TimeSpan matchTimeout = TimeSpan.FromMilliseconds (200); public Task<HighlightedLine> GetColoredSegments (ITextSource text, int offset, int length) { @@ -349,8 +348,6 @@ namespace MonoDevelop.Ide.Editor.Highlighting ScopeStack = ScopeStack.Pop (); } - - void PopMetaContentScopeStack (SyntaxContext currentContext, SyntaxMatch curMatch) { if (ContextStack.Count () == 1) { @@ -378,8 +375,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting ScopeStack = ScopeStack.Pop (); } } - - } + } internal static void ReplaceSegment (List<ColoredSegment> list, ColoredSegment newSegment) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingDefinition.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingDefinition.cs index df253f7975..94f738862e 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingDefinition.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlightingDefinition.cs @@ -377,6 +377,12 @@ namespace MonoDevelop.Ide.Editor.Highlighting public override IEnumerable<SyntaxContext> GetContexts (SyntaxContext context) { + var localContext =context.GetContext (Name); + if (localContext != null) { + yield return localContext; + yield break; + } + foreach (var bundle in SyntaxHighlightingService.AllBundles) { foreach (var highlighting in bundle.Highlightings) { if (highlighting.Name == Name) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/bat/syntaxes/Batch File.tmLanguage b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/bat/syntaxes/BatchFile.tmLanguage index 4990963640..4990963640 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/bat/syntaxes/Batch File.tmLanguage +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/bat/syntaxes/BatchFile.tmLanguage diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/javascript/syntaxes/Regular Expressions (JavaScript).tmLanguage b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/javascript/syntaxes/RegexJavaScript.tmLanguage index 1dda780649..1dda780649 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/javascript/syntaxes/Regular Expressions (JavaScript).tmLanguage +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/VSCodeImport/javascript/syntaxes/RegexJavaScript.tmLanguage diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/csharp.tmLanguage b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/csharp.tmLanguage new file mode 100644 index 0000000000..c85b8760db --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/csharp.tmLanguage @@ -0,0 +1,6523 @@ +<?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>name</key> + <string>C#</string> + <key>scopeName</key> + <string>source.cs</string> + <key>fileTypes</key> + <array> + <string>cs</string> + </array> + <key>uuid</key> + <string>f7de61e2-bdde-4e2a-a139-8221b179584e</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#directives</string> + </dict> + <dict> + <key>include</key> + <string>#declarations</string> + </dict> + <dict> + <key>include</key> + <string>#script-top-level</string> + </dict> + </array> + <key>repository</key> + <dict> + <key>directives</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#extern-alias-directive</string> + </dict> + <dict> + <key>include</key> + <string>#using-directive</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>declarations</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#namespace-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#type-declarations</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>script-top-level</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#method-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>type-declarations</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#storage-modifier</string> + </dict> + <dict> + <key>include</key> + <string>#class-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#delegate-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#enum-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#interface-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#struct-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>class-members</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#storage-modifier</string> + </dict> + <dict> + <key>include</key> + <string>#type-declarations</string> + </dict> + <dict> + <key>include</key> + <string>#event-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#property-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#indexer-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#field-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + <dict> + <key>include</key> + <string>#constructor-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#destructor-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#operator-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#conversion-operator-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#method-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>struct-members</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#storage-modifier</string> + </dict> + <dict> + <key>include</key> + <string>#type-declarations</string> + </dict> + <dict> + <key>include</key> + <string>#event-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#property-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#indexer-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#field-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + <dict> + <key>include</key> + <string>#constructor-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#destructor-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#operator-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#conversion-operator-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#method-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>interface-members</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#event-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#property-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#indexer-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#method-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>statement</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#while-statement</string> + </dict> + <dict> + <key>include</key> + <string>#do-statement</string> + </dict> + <dict> + <key>include</key> + <string>#for-statement</string> + </dict> + <dict> + <key>include</key> + <string>#foreach-statement</string> + </dict> + <dict> + <key>include</key> + <string>#if-statement</string> + </dict> + <dict> + <key>include</key> + <string>#else-part</string> + </dict> + <dict> + <key>include</key> + <string>#switch-statement</string> + </dict> + <dict> + <key>include</key> + <string>#goto-statement</string> + </dict> + <dict> + <key>include</key> + <string>#return-statement</string> + </dict> + <dict> + <key>include</key> + <string>#break-or-continue-statement</string> + </dict> + <dict> + <key>include</key> + <string>#throw-statement</string> + </dict> + <dict> + <key>include</key> + <string>#yield-statement</string> + </dict> + <dict> + <key>include</key> + <string>#try-statement</string> + </dict> + <dict> + <key>include</key> + <string>#checked-unchecked-statement</string> + </dict> + <dict> + <key>include</key> + <string>#lock-statement</string> + </dict> + <dict> + <key>include</key> + <string>#using-statement</string> + </dict> + <dict> + <key>include</key> + <string>#labeled-statement</string> + </dict> + <dict> + <key>include</key> + <string>#local-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>expression</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#checked-unchecked-expression</string> + </dict> + <dict> + <key>include</key> + <string>#typeof-or-default-expression</string> + </dict> + <dict> + <key>include</key> + <string>#nameof-expression</string> + </dict> + <dict> + <key>include</key> + <string>#interpolated-string</string> + </dict> + <dict> + <key>include</key> + <string>#verbatim-interpolated-string</string> + </dict> + <dict> + <key>include</key> + <string>#literal</string> + </dict> + <dict> + <key>include</key> + <string>#this-or-base-expression</string> + </dict> + <dict> + <key>include</key> + <string>#conditional-operator</string> + </dict> + <dict> + <key>include</key> + <string>#expression-operators</string> + </dict> + <dict> + <key>include</key> + <string>#await-expression</string> + </dict> + <dict> + <key>include</key> + <string>#query-expression</string> + </dict> + <dict> + <key>include</key> + <string>#as-expression</string> + </dict> + <dict> + <key>include</key> + <string>#is-expression</string> + </dict> + <dict> + <key>include</key> + <string>#anonymous-method-expression</string> + </dict> + <dict> + <key>include</key> + <string>#object-creation-expression</string> + </dict> + <dict> + <key>include</key> + <string>#array-creation-expression</string> + </dict> + <dict> + <key>include</key> + <string>#anonymous-object-creation-expression</string> + </dict> + <dict> + <key>include</key> + <string>#member-access-expression</string> + </dict> + <dict> + <key>include</key> + <string>#invocation-expression</string> + </dict> + <dict> + <key>include</key> + <string>#element-access-expression</string> + </dict> + <dict> + <key>include</key> + <string>#cast-expression</string> + </dict> + <dict> + <key>include</key> + <string>#parenthesized-expression</string> + </dict> + <dict> + <key>include</key> + <string>#initializer-expression</string> + </dict> + <dict> + <key>include</key> + <string>#identifier</string> + </dict> + </array> + </dict> + <key>extern-alias-directive</key> + <dict> + <key>begin</key> + <string>\s*(extern)\b\s*(alias)\b\s*([_[:alpha:]][_[:alnum:]]*)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.extern.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.alias.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>variable.other.alias.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + </dict> + <key>using-directive</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\b(using)\b\s+(static)\s+</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.using.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.static.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>\b(using)\s+(?=([_[:alpha:]][_[:alnum:]]*)\s*=)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.using.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.type.alias.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#operator-assignment</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>\b(using)\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.using.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>name</key> + <string>entity.name.type.namespace.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + <dict> + <key>include</key> + <string>#operator-assignment</string> + </dict> + </array> + </dict> + </array> + </dict> + <key>attribute-section</key> + <dict> + <key>begin</key> + <string>(\[)(assembly|module|field|event|method|param|property|return|type)?(\:)?</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.open.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.attribute-specifier.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + <key>end</key> + <string>(\])</string> + <key>endCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#attribute</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>attribute</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-name</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-arguments</string> + </dict> + </array> + </dict> + <key>attribute-arguments</key> + <dict> + <key>begin</key> + <string>(\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>(\))</string> + <key>endCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#attribute-named-argument</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>attribute-named-argument</key> + <dict> + <key>begin</key> + <string>([_[:alpha:]][_[:alnum:]]*)\s*(?==)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.variable.property.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=(,|\)))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#operator-assignment</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>namespace-declaration</key> + <dict> + <key>begin</key> + <string>\b(namespace)\s+</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.namespace.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>name</key> + <string>entity.name.type.namespace.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-accessor</string> + </dict> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#declarations</string> + </dict> + <dict> + <key>include</key> + <string>#using-directive</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + </array> + </dict> + <key>storage-modifier</key> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + <key>match</key> + <string>(?<!\.)\b(new|public|protected|internal|private|abstract|virtual|override|sealed|static|partial|readonly|volatile|const|extern|async|unsafe)\b</string> + </dict> + <key>class-declaration</key> + <dict> + <key>begin</key> + <string>(?=\bclass\b)</string> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>(?x) +\b(class)\b\s+ +([_[:alpha:]][_[:alnum:]]*)\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.class.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.type.class.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\{)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#base-types</string> + </dict> + <dict> + <key>include</key> + <string>#generic-constraints</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#class-members</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + </array> + </dict> + <key>delegate-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?:\b(delegate)\b)\s+ +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s+ +(\g<identifier>)\s* +(<([^<>]+)>)?\s* +(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.delegate.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.type.delegate.cs</string> + </dict> + <key>8</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-parameter-list</string> + </dict> + </array> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#parenthesized-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#generic-constraints</string> + </dict> + </array> + </dict> + <key>enum-declaration</key> + <dict> + <key>begin</key> + <string>(?=\benum\b)</string> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>(?=enum)</string> + <key>end</key> + <string>(?=\{)</string> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>(enum)\s+([_[:alpha:]][_[:alnum:]]*)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.enum.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.type.enum.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>begin</key> + <string>:</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\{)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + <dict> + <key>begin</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>entity.name.variable.enum-member.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=(,|\}))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + </array> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + </array> + </dict> + <key>interface-declaration</key> + <dict> + <key>begin</key> + <string>(?=\binterface\b)</string> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>(?x) +(interface)\b\s+ +([_[:alpha:]][_[:alnum:]]*)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.interface.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.type.interface.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\{)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#base-types</string> + </dict> + <dict> + <key>include</key> + <string>#generic-constraints</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#interface-members</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + </array> + </dict> + <key>struct-declaration</key> + <dict> + <key>begin</key> + <string>(?=\bstruct\b)</string> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>(?x) +(struct)\b\s+ +([_[:alpha:]][_[:alnum:]]*)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.struct.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.type.struct.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\{)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#base-types</string> + </dict> + <dict> + <key>include</key> + <string>#generic-constraints</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#struct-members</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + </array> + </dict> + <key>type-parameter-list</key> + <dict> + <key>begin</key> + <string>\<</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.typeparameters.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>\></string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.typeparameters.end.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>\b(in|out)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>\b([_[:alpha:]][_[:alnum:]]*)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.type.type-parameter.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + </array> + </dict> + <key>base-types</key> + <dict> + <key>begin</key> + <string>:</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\{|where)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>generic-constraints</key> + <dict> + <key>begin</key> + <string>(where)\s+([_[:alpha:]][_[:alnum:]]*)\s*(:)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.where.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>storage.type.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\{|where|;)</string> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>keyword.other.class.cs</string> + <key>match</key> + <string>\bclass\b</string> + </dict> + <dict> + <key>name</key> + <string>keyword.other.struct.cs</string> + <key>match</key> + <string>\bstruct\b</string> + </dict> + <dict> + <key>match</key> + <string>(new)\s*(\()\s*(\))</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.new.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + <dict> + <key>include</key> + <string>#generic-constraints</string> + </dict> + </array> + </dict> + <key>field-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s+ +(\g<identifier>)\s* # first field name +(?!=>|==)(?=,|;|=)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>6</key> + <dict> + <key>name</key> + <string>entity.name.variable.field.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>entity.name.variable.field.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + </array> + </dict> + <key>property-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?!.*\b(?:class|interface|struct|enum|event)\b)\s* +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(?<property-name>\g<identifier>)\s* +(?=\{|=>|$)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-accessor</string> + </dict> + </array> + </dict> + <key>8</key> + <dict> + <key>name</key> + <string>entity.name.variable.property.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#property-accessors</string> + </dict> + <dict> + <key>include</key> + <string>#expression-body</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + </array> + </dict> + <key>indexer-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(?<indexer-name>this)\s* +(?=\[)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-accessor</string> + </dict> + </array> + </dict> + <key>8</key> + <dict> + <key>name</key> + <string>keyword.other.this.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#bracketed-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#property-accessors</string> + </dict> + <dict> + <key>include</key> + <string>#expression-body</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + </array> + </dict> + <key>event-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +\b(event)\b\s* +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(?<event-names>\g<identifier>(?:\s*,\s*\g<identifier>)*)\s* +(?=\{|;|$)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.event.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>8</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-accessor</string> + </dict> + </array> + </dict> + <key>9</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>entity.name.variable.event.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#event-accessors</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>property-accessors</key> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + <key>match</key> + <string>\b(private|protected|internal)\b</string> + </dict> + <dict> + <key>name</key> + <string>keyword.other.get.cs</string> + <key>match</key> + <string>\b(get)\b</string> + </dict> + <dict> + <key>name</key> + <string>keyword.other.set.cs</string> + <key>match</key> + <string>\b(set)\b</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>event-accessors</key> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>keyword.other.add.cs</string> + <key>match</key> + <string>\b(add)\b</string> + </dict> + <dict> + <key>name</key> + <string>keyword.other.remove.cs</string> + <key>match</key> + <string>\b(remove)\b</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <key>method-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(\g<identifier>)\s* +(<([^<>]+)>)?\s* +(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-accessor</string> + </dict> + </array> + </dict> + <key>8</key> + <dict> + <key>name</key> + <string>entity.name.function.cs</string> + </dict> + <key>9</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-parameter-list</string> + </dict> + </array> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#parenthesized-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#generic-constraints</string> + </dict> + <dict> + <key>include</key> + <string>#expression-body</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>constructor-declaration</key> + <dict> + <key>begin</key> + <string>(?=[_[:alpha:]][_[:alnum:]]*\s*\()</string> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>\b([_[:alpha:]][_[:alnum:]]*)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.function.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>begin</key> + <string>(:)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\{|=>)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#constructor-initializer</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#parenthesized-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#expression-body</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>constructor-initializer</key> + <dict> + <key>begin</key> + <string>\b(?:(base)|(this))\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.base.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.this.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#argument-list</string> + </dict> + </array> + </dict> + <key>destructor-declaration</key> + <dict> + <key>begin</key> + <string>(~)([_[:alpha:]][_[:alnum:]]*)\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.tilde.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.function.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#parenthesized-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#expression-body</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>operator-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?<operator-keyword>(?:\b(?:operator)))\s* +(?<operator>(?:\+|-|\*|/|%|&|\||\^|\<\<|\>\>|==|!=|\>|\<|\>=|\<=|!|~|\+\+|--|true|false))\s* +(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>6</key> + <dict> + <key>name</key> + <string>keyword.other.operator-decl.cs</string> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.function.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#parenthesized-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#expression-body</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>conversion-operator-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?<explicit-or-implicit-keyword>(?:\b(?:explicit|implicit)))\s* +(?<operator-keyword>(?:\b(?:operator)))\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>\b(explicit)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.explicit.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>\b(implicit)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.implicit.cs</string> + </dict> + </dict> + </dict> + </array> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.operator-decl.cs</string> + </dict> + <key>3</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#parenthesized-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#expression-body</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>block</key> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>variable-initializer</key> + <dict> + <key>begin</key> + <string>(?<!=|!)(=)(?!=|>)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.operator.assignment.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=[,\);}])</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>expression-body</key> + <dict> + <key>begin</key> + <string>=></string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>keyword.operator.arrow.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=[,\);}])</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>goto-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(goto)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.goto.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\b(case)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.case.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>match</key> + <string>\b(default)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.default.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>name</key> + <string>entity.name.label.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + </array> + </dict> + <key>return-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(return)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.flow.return.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>break-or-continue-statement</key> + <dict> + <key>match</key> + <string>(?<!\.)\b(?:(break)|(continue))\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.flow.break.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.control.flow.continue.cs</string> + </dict> + </dict> + </dict> + <key>throw-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(throw)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.flow.throw.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>yield-statement</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#yield-return-statement</string> + </dict> + <dict> + <key>include</key> + <string>#yield-break-statement</string> + </dict> + </array> + </dict> + <key>yield-return-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(yield)\b\s*\b(return)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.flow.yield.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.control.flow.return.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>yield-break-statement</key> + <dict> + <key>match</key> + <string>(?<!\.)\b(yield)\b\s*\b(break)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.flow.yield.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.control.flow.break.cs</string> + </dict> + </dict> + </dict> + <key>if-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(if)\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.conditional.if.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>else-part</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(else)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.conditional.else.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>switch-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(switch)\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.switch.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#switch-label</string> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + </array> + </dict> + <key>switch-label</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>(?<!\.)\b(case)\b\s+</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.case.cs</string> + </dict> + </dict> + <key>end</key> + <string>:</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>match</key> + <string>(?<!\.)\b(default)\b\s*(:)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.default.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + </dict> + </array> + </dict> + <key>do-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(do)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.loop.do.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|})</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>while-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(while)\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.loop.while.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>for-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(for)\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.loop.for.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#local-variable-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-semicolon</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>foreach-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(foreach)\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.loop.foreach.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>(?x) +(?: + (\bvar\b)| + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + ) +)\s+ +(\g<identifier>)\s+ +\b(in)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.var.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.variable.local.cs</string> + </dict> + <key>8</key> + <dict> + <key>name</key> + <string>keyword.control.loop.in.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>try-statement</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#try-block</string> + </dict> + <dict> + <key>include</key> + <string>#catch-clause</string> + </dict> + <dict> + <key>include</key> + <string>#finally-clause</string> + </dict> + </array> + </dict> + <key>try-block</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(try)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.try.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>finally-clause</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(finally)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.try.finally.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>catch-clause</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(catch)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.try.catch.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>(?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?:\b(\g<identifier>)\b)?</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>6</key> + <dict> + <key>name</key> + <string>entity.name.variable.local.cs</string> + </dict> + </dict> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#when-clause</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>when-clause</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(when)\b\s*(\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.control.try.when.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>checked-unchecked-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(?:(checked)|(unchecked))\b\s*(?!\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.checked.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.unchecked.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#block</string> + </dict> + </array> + </dict> + <key>lock-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(lock)\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.lock.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\})|(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>using-statement</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(using)\b\s*(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.using.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\;|})</string> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#local-variable-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>include</key> + <string>#statement</string> + </dict> + </array> + </dict> + <key>labeled-statement</key> + <dict> + <key>match</key> + <string>([_[:alpha:]][_[:alnum:]]*)\s*(:)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.label.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + </dict> + <key>local-declaration</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#local-constant-declaration</string> + </dict> + <dict> + <key>include</key> + <string>#local-variable-declaration</string> + </dict> + </array> + </dict> + <key>local-variable-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?: + (\bvar\b)| + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + ) +)\s+ +(\g<identifier>)\s* +(?=,|;|=|\))</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.var.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.variable.local.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>entity.name.variable.local.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + </array> + </dict> + <key>local-constant-declaration</key> + <dict> + <key>begin</key> + <string>(?x) +(?<const-keyword>\b(?:const)\b)\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s+ +(\g<identifier>)\s* +(?=,|;|=)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.variable.local.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;)</string> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>entity.name.variable.local.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + </array> + </dict> + <key>checked-unchecked-expression</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(?:(checked)|(unchecked))\b\s*(\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.checked.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.unchecked.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>typeof-or-default-expression</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(?:(typeof)|(default))\b\s*(\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.typeof.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.default.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>nameof-expression</key> + <dict> + <key>begin</key> + <string>(?<!\.)\b(nameof)\b\s*(\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.nameof.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>interpolated-string</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + <key>begin</key> + <string>\$"</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>(")|((?:[^\\\n])$)</string> + <key>endCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.end.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>invalid.illegal.newline.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#string-character-escape</string> + </dict> + <dict> + <key>include</key> + <string>#interpolation</string> + </dict> + </array> + </dict> + <key>verbatim-interpolated-string</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + <key>begin</key> + <string>\$@"</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>"(?=[^"])</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.end.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#verbatim-string-character-escape</string> + </dict> + <dict> + <key>include</key> + <string>#interpolation</string> + </dict> + </array> + </dict> + <key>interpolation</key> + <dict> + <key>name</key> + <string>meta.interpolation.cs</string> + <key>begin</key> + <string>(?<=[^\{])((?:\{\{)*)(\{)(?=[^\{])</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.definition.interpolation.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.interpolation.end.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>literal</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#boolean-literal</string> + </dict> + <dict> + <key>include</key> + <string>#null-literal</string> + </dict> + <dict> + <key>include</key> + <string>#numeric-literal</string> + </dict> + <dict> + <key>include</key> + <string>#char-literal</string> + </dict> + <dict> + <key>include</key> + <string>#string-literal</string> + </dict> + <dict> + <key>include</key> + <string>#verbatim-string-literal</string> + </dict> + </array> + </dict> + <key>boolean-literal</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>constant.language.boolean.true.cs</string> + <key>match</key> + <string>(?<!\.)\btrue\b</string> + </dict> + <dict> + <key>name</key> + <string>constant.language.boolean.false.cs</string> + <key>match</key> + <string>(?<!\.)\bfalse\b</string> + </dict> + </array> + </dict> + <key>null-literal</key> + <dict> + <key>name</key> + <string>constant.language.null.cs</string> + <key>match</key> + <string>(?<!\.)\bnull\b</string> + </dict> + <key>numeric-literal</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>constant.numeric.hex.cs</string> + <key>match</key> + <string>\b0(x|X)[0-9a-fA-F_]+(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b</string> + </dict> + <dict> + <key>name</key> + <string>constant.numeric.binary.cs</string> + <key>match</key> + <string>\b0(b|B)[01_]+(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b</string> + </dict> + <dict> + <key>name</key> + <string>constant.numeric.decimal.cs</string> + <key>match</key> + <string>\b([0-9_]+)?\.[0-9_]+((e|E)[0-9]+)?(F|f|D|d|M|m)?\b</string> + </dict> + <dict> + <key>name</key> + <string>constant.numeric.decimal.cs</string> + <key>match</key> + <string>\b[0-9_]+(e|E)[0-9_]+(F|f|D|d|M|m)?\b</string> + </dict> + <dict> + <key>name</key> + <string>constant.numeric.decimal.cs</string> + <key>match</key> + <string>\b[0-9_]+(F|f|D|d|M|m)\b</string> + </dict> + <dict> + <key>name</key> + <string>constant.numeric.decimal.cs</string> + <key>match</key> + <string>\b[0-9_]+(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b</string> + </dict> + </array> + </dict> + <key>char-literal</key> + <dict> + <key>name</key> + <string>string.quoted.single.cs</string> + <key>begin</key> + <string>'</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.char.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>(\')|((?:[^\\\n])$)</string> + <key>endCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.definition.char.end.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>invalid.illegal.newline.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#string-character-escape</string> + </dict> + </array> + </dict> + <key>string-literal</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + <key>begin</key> + <string>(?<!@)"</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>(")|((?:[^\\\n])$)</string> + <key>endCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.end.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>invalid.illegal.newline.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#string-character-escape</string> + </dict> + </array> + </dict> + <key>string-character-escape</key> + <dict> + <key>name</key> + <string>constant.character.escape.cs</string> + <key>match</key> + <string>\\.</string> + </dict> + <key>verbatim-string-literal</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + <key>begin</key> + <string>@"</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>"(?=[^"])</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.end.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#verbatim-string-character-escape</string> + </dict> + </array> + </dict> + <key>verbatim-string-character-escape</key> + <dict> + <key>name</key> + <string>constant.character.escape.cs</string> + <key>match</key> + <string>""</string> + </dict> + <key>expression-operators</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>keyword.operator.assignment.compound.cs</string> + <key>match</key> + <string>\*=|/=|%=|\+=|-=</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.assignment.compound.bitwise.cs</string> + <key>match</key> + <string>\&=|\^=|<<=|>>=|\|=</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.bitwise.shift.cs</string> + <key>match</key> + <string><<|>></string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.comparison.cs</string> + <key>match</key> + <string>==|!=</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.relational.cs</string> + <key>match</key> + <string><=|>=|<|></string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.logical.cs</string> + <key>match</key> + <string>\!|&&|\|\|</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.bitwise.cs</string> + <key>match</key> + <string>\&|~|\^|\|</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.assignment.cs</string> + <key>match</key> + <string>\=</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.decrement.cs</string> + <key>match</key> + <string>--</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.increment.cs</string> + <key>match</key> + <string>\+\+</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.arithmetic.cs</string> + <key>match</key> + <string>%|\*|/|-|\+</string> + </dict> + <dict> + <key>name</key> + <string>keyword.operator.null-coalescing.cs</string> + <key>match</key> + <string>\?\?</string> + </dict> + </array> + </dict> + <key>conditional-operator</key> + <dict> + <key>begin</key> + <string>(?<!\?)\?(?!\?|\.|\[)</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>keyword.operator.conditional.question-mark.cs</string> + </dict> + </dict> + <key>end</key> + <string>:</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>keyword.operator.conditional.colon.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>await-expression</key> + <dict> + <key>name</key> + <string>keyword.other.await.cs</string> + <key>match</key> + <string>(?!\.)\b(await)\b</string> + </dict> + <key>parenthesized-expression</key> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>initializer-expression</key> + <dict> + <key>begin</key> + <string>\{</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\}</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.curlybrace.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>identifier</key> + <dict> + <key>name</key> + <string>variable.other.readwrite.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + <key>cast-expression</key> + <dict> + <key>match</key> + <string>(?x) +(\()\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(\))(?=\s*[_[:alnum:]\(])</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + </dict> + <key>as-expression</key> + <dict> + <key>match</key> + <string>(?x) +(?<!\.)\b(as)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)?</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.as.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + </dict> + </dict> + <key>is-expression</key> + <dict> + <key>match</key> + <string>(?x) +(?<!\.)\b(is)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)?</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.is.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + </dict> + </dict> + <key>this-or-base-expression</key> + <dict> + <key>match</key> + <string>\b(?:(base)|(this))\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.base.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.this.cs</string> + </dict> + </dict> + </dict> + <key>invocation-expression</key> + <dict> + <key>begin</key> + <string>(?x) +(?:(\?)\s*)? # preceding null-conditional operator? +(?:(\.)\s*)? # preceding dot? +([_[:alpha:]][_[:alnum:]]*)\s* # method name +(?<type-args>\s*<([^<>]|\g<type-args>)+>\s*)?\s* # type arguments +(?=\() # open paren of argument list</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.operator.null-conditional.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.accessor.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>entity.name.function.cs</string> + </dict> + <key>4</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-arguments</string> + </dict> + </array> + </dict> + </dict> + <key>end</key> + <string>(?<=\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#argument-list</string> + </dict> + </array> + </dict> + <key>element-access-expression</key> + <dict> + <key>begin</key> + <string>(?x) +(?:(\?)\s*)? # preceding null-conditional operator? +(?:(\.)\s*)? # preceding dot? +([_[:alpha:]][_[:alnum:]]*)\s* # property name +(?:(\?)\s*)? # null-conditional operator? +(?=\[) # open bracket of argument list</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.operator.null-conditional.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.accessor.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>variable.other.object.property.cs</string> + </dict> + <key>4</key> + <dict> + <key>name</key> + <string>keyword.operator.null-conditional.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=\])</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#bracketed-argument-list</string> + </dict> + </array> + </dict> + <key>member-access-expression</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>(?x) +(?:(\?)\s*)? # preceding null-conditional operator? +(\.)\s* # preceding dot +([_[:alpha:]][_[:alnum:]]*)\s* # property name +(?![_[:alnum:]]|\(|(\?)?\[|<) # next character is not alpha-numeric, nor a (, [, or <. Also, test for ?[</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.operator.null-conditional.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.accessor.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>variable.other.object.property.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>(?x) +(\.)?\s* +([_[:alpha:]][_[:alnum:]]*) +(?<type-params>\s*<([^<>]|\g<type-params>)+>\s*) +(?= + (\s*\?)? + \s*\.\s*[_[:alpha:]][_[:alnum:]]* +)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.accessor.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>variable.other.object.cs</string> + </dict> + <key>3</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type-arguments</string> + </dict> + </array> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>(?x) +([_[:alpha:]][_[:alnum:]]*) +(?= + (\s*\?)? + \s*\.\s*[_[:alpha:]][_[:alnum:]]* +)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>variable.other.object.cs</string> + </dict> + </dict> + </dict> + </array> + </dict> + <key>object-creation-expression</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#object-creation-expression-with-parameters</string> + </dict> + <dict> + <key>include</key> + <string>#object-creation-expression-with-no-parameters</string> + </dict> + </array> + </dict> + <key>object-creation-expression-with-parameters</key> + <dict> + <key>begin</key> + <string>(?x) +(new)\s+ +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?=\()</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.new.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + </dict> + <key>end</key> + <string>(?<=\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#argument-list</string> + </dict> + </array> + </dict> + <key>object-creation-expression-with-no-parameters</key> + <dict> + <key>match</key> + <string>(?x) +(new)\s+ +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?=\{|$)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.new.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + </dict> + </dict> + <key>array-creation-expression</key> + <dict> + <key>begin</key> + <string>(?x) +\b(new)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)?\s* +(?=\[)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.new.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + </dict> + <key>end</key> + <string>(?<=\])</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#bracketed-argument-list</string> + </dict> + </array> + </dict> + <key>anonymous-object-creation-expression</key> + <dict> + <key>begin</key> + <string>\b(new)\b\s*(?=\{|$)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.other.new.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#initializer-expression</string> + </dict> + </array> + </dict> + <key>bracketed-parameter-list</key> + <dict> + <key>begin</key> + <string>(?=(\[))</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=(\]))</string> + <key>endCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>(?<=\[)</string> + <key>end</key> + <string>(?=\])</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + <key>match</key> + <string>\b(ref|params|out)\b</string> + </dict> + <dict> + <key>match</key> + <string>\s+([_[:alpha:]][_[:alnum:]]*)\s*(?=[,\]])</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.variable.parameter.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + </array> + </dict> + <key>parenthesized-parameter-list</key> + <dict> + <key>begin</key> + <string>(\()</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>(\))</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + <key>match</key> + <string>\b(ref|params|out|this)\b</string> + </dict> + <dict> + <key>match</key> + <string>\s+([_[:alpha:]][_[:alnum:]]*)\s*(?=[,)])</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.variable.parameter.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>include</key> + <string>#variable-initializer</string> + </dict> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>argument-list</key> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#named-argument</string> + </dict> + <dict> + <key>include</key> + <string>#argument</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>bracketed-argument-list</key> + <dict> + <key>begin</key> + <string>\[</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\]</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#named-argument</string> + </dict> + <dict> + <key>include</key> + <string>#argument</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>named-argument</key> + <dict> + <key>begin</key> + <string>([_[:alpha:]][_[:alnum:]]*)\s*(:)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.variable.parameter.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=(,|\)|\]))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>argument</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + <key>match</key> + <string>\b(ref|out)\b</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>query-expression</key> + <dict> + <key>begin</key> + <string>(?x) +\b(from)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? +\b(\g<identifier>)\b\s* +\b(in)\b\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.from.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.variable.range-variable.cs</string> + </dict> + <key>8</key> + <dict> + <key>name</key> + <string>keyword.query.in.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#query-body</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>query-body</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#let-clause</string> + </dict> + <dict> + <key>include</key> + <string>#where-clause</string> + </dict> + <dict> + <key>include</key> + <string>#join-clause</string> + </dict> + <dict> + <key>include</key> + <string>#orderby-clause</string> + </dict> + <dict> + <key>include</key> + <string>#select-clause</string> + </dict> + <dict> + <key>include</key> + <string>#group-clause</string> + </dict> + </array> + </dict> + <key>let-clause</key> + <dict> + <key>begin</key> + <string>(?x) +\b(let)\b\s* +\b([_[:alpha:]][_[:alnum:]]*)\b\s* +(=)\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.let.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.variable.range-variable.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>keyword.operator.assignment.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#query-body</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>where-clause</key> + <dict> + <key>begin</key> + <string>(?x) +\b(where)\b\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.where.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#query-body</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>join-clause</key> + <dict> + <key>begin</key> + <string>(?x) +\b(join)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? +\b(\g<identifier>)\b\s* +\b(in)\b\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.join.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.variable.range-variable.cs</string> + </dict> + <key>8</key> + <dict> + <key>name</key> + <string>keyword.query.in.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#join-on</string> + </dict> + <dict> + <key>include</key> + <string>#join-equals</string> + </dict> + <dict> + <key>include</key> + <string>#join-into</string> + </dict> + <dict> + <key>include</key> + <string>#query-body</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>join-on</key> + <dict> + <key>match</key> + <string>\b(on)\b\s*</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.on.cs</string> + </dict> + </dict> + </dict> + <key>join-equals</key> + <dict> + <key>match</key> + <string>\b(equals)\b\s*</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.equals.cs</string> + </dict> + </dict> + </dict> + <key>join-into</key> + <dict> + <key>match</key> + <string>(?x) +\b(into)\b\s* +\b([_[:alpha:]][_[:alnum:]]*)\b\s*</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.into.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.variable.range-variable.cs</string> + </dict> + </dict> + </dict> + <key>orderby-clause</key> + <dict> + <key>begin</key> + <string>\b(orderby)\b\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.orderby.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#ordering-direction</string> + </dict> + <dict> + <key>include</key> + <string>#query-body</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>ordering-direction</key> + <dict> + <key>match</key> + <string>\b(?:(ascending)|(descending))\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.ascending.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.query.descending.cs</string> + </dict> + </dict> + </dict> + <key>select-clause</key> + <dict> + <key>begin</key> + <string>\b(select)\b\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.select.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#query-body</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>group-clause</key> + <dict> + <key>begin</key> + <string>\b(group)\b\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.group.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=;|\))</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#group-by</string> + </dict> + <dict> + <key>include</key> + <string>#group-into</string> + </dict> + <dict> + <key>include</key> + <string>#query-body</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <key>group-by</key> + <dict> + <key>match</key> + <string>\b(by)\b\s*</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.by.cs</string> + </dict> + </dict> + </dict> + <key>group-into</key> + <dict> + <key>match</key> + <string>(?x) +\b(into)\b\s* +\b([_[:alpha:]][_[:alnum:]]*)\b\s*</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.query.into.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.variable.range-variable.cs</string> + </dict> + </dict> + </dict> + <key>anonymous-method-expression</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>(?x) +(?:\b(async)\b\s*)? +\b([_[:alpha:]][_[:alnum:]]*)\b\s* +(=>)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.variable.parameter.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>keyword.operator.arrow.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\)|;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#block</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>(?x) +(?:\b(async)\b\s*)? +(\(.*\))\s* +(=>)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#lambda-parameter-list</string> + </dict> + </array> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>keyword.operator.arrow.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\)|;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#block</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + <dict> + <key>begin</key> + <string>(?x) +(?:\b(async)\b\s*)? +(?:\b(delegate)\b\s*)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.other.delegate.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=\)|;)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#parenthesized-parameter-list</string> + </dict> + <dict> + <key>include</key> + <string>#block</string> + </dict> + <dict> + <key>include</key> + <string>#expression</string> + </dict> + </array> + </dict> + </array> + </dict> + <key>lambda-parameter-list</key> + <dict> + <key>begin</key> + <string>(\()</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>(\))</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#attribute-section</string> + </dict> + <dict> + <key>include</key> + <string>#lambda-parameter</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>lambda-parameter</key> + <dict> + <key>match</key> + <string>(?x) +(ref|out)?\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? +\b(\g<identifier>)\b\s* +(?=[,)])</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>storage.modifier.cs</string> + </dict> + <key>2</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>7</key> + <dict> + <key>name</key> + <string>entity.name.variable.parameter.cs</string> + </dict> + </dict> + </dict> + <key>type</key> + <dict> + <key>name</key> + <string>meta.type.cs</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#tuple-type</string> + </dict> + <dict> + <key>include</key> + <string>#type-builtin</string> + </dict> + <dict> + <key>include</key> + <string>#type-name</string> + </dict> + <dict> + <key>include</key> + <string>#type-arguments</string> + </dict> + <dict> + <key>include</key> + <string>#type-array-suffix</string> + </dict> + <dict> + <key>include</key> + <string>#type-nullable-suffix</string> + </dict> + </array> + </dict> + <key>tuple-type</key> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#tuple-element</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>tuple-element</key> + <dict> + <key>match</key> + <string>(?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +) +(?:\b(?<tuple-name>\g<identifier>)\b)?</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#type</string> + </dict> + </array> + </dict> + <key>6</key> + <dict> + <key>name</key> + <string>entity.name.variable.tuple-element.cs</string> + </dict> + </dict> + </dict> + <key>type-builtin</key> + <dict> + <key>match</key> + <string>\b(bool|byte|char|decimal|double|float|int|long|object|sbyte|short|string|uint|ulong|ushort|void)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.type.cs</string> + </dict> + </dict> + </dict> + <key>type-name</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>([_[:alpha:]][_[:alnum:]]*)\s*(\:\:)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.name.type.alias.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.separator.coloncolon.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>([_[:alpha:]][_[:alnum:]]*)\s*(\.)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>storage.type.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>punctuation.accessor.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>(\.)\s*([_[:alpha:]][_[:alnum:]]*)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.accessor.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>storage.type.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>name</key> + <string>storage.type.cs</string> + <key>match</key> + <string>[_[:alpha:]][_[:alnum:]]*</string> + </dict> + </array> + </dict> + <key>type-arguments</key> + <dict> + <key>begin</key> + <string><</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.typeparameters.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>></string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.typeparameters.end.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#type</string> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>type-array-suffix</key> + <dict> + <key>begin</key> + <string>\[</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\]</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.squarebracket.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + <key>type-nullable-suffix</key> + <dict> + <key>match</key> + <string>\?</string> + <key>captures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.separator.question-mark.cs</string> + </dict> + </dict> + </dict> + <key>operator-assignment</key> + <dict> + <key>name</key> + <string>keyword.operator.assignment.cs</string> + <key>match</key> + <string>(?<!=|!)(=)(?!=)</string> + </dict> + <key>punctuation-comma</key> + <dict> + <key>name</key> + <string>punctuation.separator.comma.cs</string> + <key>match</key> + <string>,</string> + </dict> + <key>punctuation-semicolon</key> + <dict> + <key>name</key> + <string>punctuation.terminator.statement.cs</string> + <key>match</key> + <string>;</string> + </dict> + <key>punctuation-accessor</key> + <dict> + <key>name</key> + <string>punctuation.accessor.cs</string> + <key>match</key> + <string>\.</string> + </dict> + <key>preprocessor</key> + <dict> + <key>name</key> + <string>meta.preprocessor.cs</string> + <key>begin</key> + <string>^\s*(\#)\s*</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.separator.hash.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?<=$)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-define-or-undef</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-if-or-elif</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-else-or-endif</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-warning-or-error</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-region</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-endregion</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-line</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-pragma-warning</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-pragma-checksum</string> + </dict> + </array> + </dict> + <key>preprocessor-define-or-undef</key> + <dict> + <key>match</key> + <string>\b(?:(define)|(undef))\b\s*\b([_[:alpha:]][_[:alnum:]]*)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.define.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.undef.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>entity.name.variable.preprocessor.symbol.cs</string> + </dict> + </dict> + </dict> + <key>preprocessor-if-or-elif</key> + <dict> + <key>begin</key> + <string>\b(?:(if)|(elif))\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.if.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.elif.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=$)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#comment</string> + </dict> + <dict> + <key>include</key> + <string>#preprocessor-expression</string> + </dict> + </array> + </dict> + <key>preprocessor-else-or-endif</key> + <dict> + <key>match</key> + <string>\b(?:(else)|(endif))\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.else.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.endif.cs</string> + </dict> + </dict> + </dict> + <key>preprocessor-warning-or-error</key> + <dict> + <key>match</key> + <string>\b(?:(warning)|(error))\b\s*(.*)(?=$)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.warning.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.error.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>string.unquoted.preprocessor.message.cs</string> + </dict> + </dict> + </dict> + <key>preprocessor-region</key> + <dict> + <key>match</key> + <string>\b(region)\b\s*(.*)(?=$)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.region.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>string.unquoted.preprocessor.message.cs</string> + </dict> + </dict> + </dict> + <key>preprocessor-endregion</key> + <dict> + <key>match</key> + <string>\b(endregion)\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.endregion.cs</string> + </dict> + </dict> + </dict> + <key>preprocessor-line</key> + <dict> + <key>begin</key> + <string>\b(line)\b</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.line.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=$)</string> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>\b(?:(default|hidden))</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.default.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.hidden.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>[0-9]+</string> + <key>captures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>constant.numeric.decimal.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>\"[^"]*\"</string> + <key>captures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + </dict> + </dict> + </dict> + </array> + </dict> + <key>preprocessor-pragma-warning</key> + <dict> + <key>match</key> + <string>\b(pragma)\b\s*\b(warning)\b\s*\b(?:(disable)|(restore))\b(\s*[0-9]+(?:\s*,\s*[0-9]+)?)?</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.pragma.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.warning.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.disable.cs</string> + </dict> + <key>4</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.restore.cs</string> + </dict> + <key>5</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>[0-9]+</string> + <key>captures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>constant.numeric.decimal.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>include</key> + <string>#punctuation-comma</string> + </dict> + </array> + </dict> + </dict> + </dict> + <key>preprocessor-pragma-checksum</key> + <dict> + <key>match</key> + <string>\b(pragma)\b\s*\b(checksum)\b\s*(\"[^"]*\")\s*(\"[^"]*\")\s*(\"[^"]*\")</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.pragma.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.preprocessor.checksum.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + </dict> + <key>4</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + </dict> + <key>5</key> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + </dict> + </dict> + </dict> + <key>preprocessor-expression</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>begin</key> + <string>\(</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.open.cs</string> + </dict> + </dict> + <key>end</key> + <string>\)</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.parenthesis.close.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#preprocessor-expression</string> + </dict> + </array> + </dict> + <dict> + <key>match</key> + <string>\b(?:(true)|(false)|([_[:alpha:]][_[:alnum:]]*))\b</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>constant.language.boolean.true.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>constant.language.boolean.false.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>entity.name.variable.preprocessor.symbol.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>match</key> + <string>(==|!=)|(\!|&&|\|\|)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>keyword.operator.comparison.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>keyword.operator.logical.cs</string> + </dict> + </dict> + </dict> + </array> + </dict> + <key>comment</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>comment.block.cs</string> + <key>begin</key> + <string>/\*</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.comment.cs</string> + </dict> + </dict> + <key>end</key> + <string>\*/</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.comment.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>begin</key> + <string>(^\s+)?(?=//)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.whitespace.comment.leading.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=$)</string> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>comment.block.documentation.cs</string> + <key>begin</key> + <string>(?<!/)///(?!/)</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.comment.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=$)</string> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#xml-doc-comment</string> + </dict> + </array> + </dict> + <dict> + <key>name</key> + <string>comment.line.double-slash.cs</string> + <key>begin</key> + <string>(?<!/)//(?!/)</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.comment.cs</string> + </dict> + </dict> + <key>end</key> + <string>(?=$)</string> + </dict> + </array> + </dict> + </array> + </dict> + <key>xml-doc-comment</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#xml-comment</string> + </dict> + <dict> + <key>include</key> + <string>#xml-character-entity</string> + </dict> + <dict> + <key>include</key> + <string>#xml-cdata</string> + </dict> + <dict> + <key>include</key> + <string>#xml-tag</string> + </dict> + </array> + </dict> + <key>xml-tag</key> + <dict> + <key>name</key> + <string>meta.tag.cs</string> + <key>begin</key> + <string>(?x) +(</?) +( + (?: + ([-_[:alnum:]]+) + (:) + )? + ([-_[:alnum:]]+) +)</string> + <key>beginCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.definition.tag.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.name.tag.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>entity.name.tag.namespace.cs</string> + </dict> + <key>4</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + <key>5</key> + <dict> + <key>name</key> + <string>entity.name.tag.localname.cs</string> + </dict> + </dict> + <key>end</key> + <string>(/?>)</string> + <key>endCaptures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.definition.tag.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#xml-attribute</string> + </dict> + </array> + </dict> + <key>xml-attribute</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>match</key> + <string>(?x) +(?:^|\s+) +( + (?: + ([-_[:alnum:]]+) + (:) + )? + ([-_[:alnum:]]+) +) +(=)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>entity.other.attribute-name.cs</string> + </dict> + <key>2</key> + <dict> + <key>name</key> + <string>entity.other.attribute-name.namespace.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>punctuation.separator.colon.cs</string> + </dict> + <key>4</key> + <dict> + <key>name</key> + <string>entity.other.attribute-name.localname.cs</string> + </dict> + <key>5</key> + <dict> + <key>name</key> + <string>punctuation.separator.equals.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>include</key> + <string>#xml-string</string> + </dict> + </array> + </dict> + <key>xml-cdata</key> + <dict> + <key>name</key> + <string>string.unquoted.cdata.cs</string> + <key>begin</key> + <string><!\[CDATA\[</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>\]\]></string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.end.cs</string> + </dict> + </dict> + </dict> + <key>xml-string</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>string.quoted.single.cs</string> + <key>begin</key> + <string>\'</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>\'</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.end.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#xml-character-entity</string> + </dict> + </array> + </dict> + <dict> + <key>name</key> + <string>string.quoted.double.cs</string> + <key>begin</key> + <string>\"</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.begin.cs</string> + </dict> + </dict> + <key>end</key> + <string>\"</string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.string.end.cs</string> + </dict> + </dict> + <key>patterns</key> + <array> + <dict> + <key>include</key> + <string>#xml-character-entity</string> + </dict> + </array> + </dict> + </array> + </dict> + <key>xml-character-entity</key> + <dict> + <key>patterns</key> + <array> + <dict> + <key>name</key> + <string>constant.character.entity.cs</string> + <key>match</key> + <string>(?x) +(&) +( + (?:[[:alpha:]:_][[:alnum:]:_.-]*)| + (?:\#[[:digit:]]+)| + (?:\#x[[:xdigit:]]+) +) +(;)</string> + <key>captures</key> + <dict> + <key>1</key> + <dict> + <key>name</key> + <string>punctuation.definition.constant.cs</string> + </dict> + <key>3</key> + <dict> + <key>name</key> + <string>punctuation.definition.constant.cs</string> + </dict> + </dict> + </dict> + <dict> + <key>name</key> + <string>invalid.illegal.bad-ampersand.cs</string> + <key>match</key> + <string>&</string> + </dict> + </array> + </dict> + <key>xml-comment</key> + <dict> + <key>name</key> + <string>comment.block.cs</string> + <key>begin</key> + <string><!--</string> + <key>beginCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.comment.cs</string> + </dict> + </dict> + <key>end</key> + <string>--></string> + <key>endCaptures</key> + <dict> + <key>0</key> + <dict> + <key>name</key> + <string>punctuation.definition.comment.cs</string> + </dict> + </dict> + </dict> + </dict> + </dict> +</plist>
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs index 1c88f9a58e..e3f045d934 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs @@ -113,14 +113,16 @@ namespace MonoDevelop.Ide.Editor.TextMate }); } - public override async Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, char completionChar, CancellationToken token) + public override async Task<ICompletionDataList> HandleCodeCompletionAsync (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token) { if (inactive) - return await base.HandleCodeCompletionAsync (completionContext, completionChar, token); + return await base.HandleCodeCompletionAsync (completionContext, triggerInfo, token); - if (!IdeApp.Preferences.EnableAutoCodeCompletion && char.IsLetter (completionChar)) + if (!IdeApp.Preferences.EnableAutoCodeCompletion) return null; - + if (triggerInfo.CompletionTriggerReason != CompletionTriggerReason.CharTyped) + return null; + char completionChar = triggerInfo.TriggerCharacter.Value; int triggerWordLength = 0; if (char.IsLetterOrDigit (completionChar) || completionChar == '_') { if (completionContext.TriggerOffset > 1 && char.IsLetterOrDigit (Editor.GetCharAt (completionContext.TriggerOffset - 2))) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Caret.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Caret.cs index 5c10a3fd8a..db7e5009c5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Caret.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Caret.cs @@ -57,12 +57,27 @@ namespace MonoDevelop.Ide.Editor set; } - protected virtual void OnPositionChanged (DocumentLocationEventArgs args) + protected virtual void OnPositionChanged (CaretLocationEventArgs args) { if (PositionChanged != null) PositionChanged (this, args); } - public event EventHandler<DocumentLocationEventArgs> PositionChanged; + public event EventHandler<CaretLocationEventArgs> PositionChanged; + } + + public enum CaretChangeReason { + BufferChange, + Movement + } + + public class CaretLocationEventArgs : DocumentLocationEventArgs + { + public CaretChangeReason CaretChangeReason { get; } + + public CaretLocationEventArgs (DocumentLocation location, CaretChangeReason reason) : base (location) + { + CaretChangeReason = reason; + } } }
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextEditorImpl.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextEditorImpl.cs index d07aa9dcc0..10517742db 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextEditorImpl.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/InternalExtensionAPI/ITextEditorImpl.cs @@ -180,10 +180,6 @@ namespace MonoDevelop.Ide.Editor void SetSelectionSurroundingProvider (SelectionSurroundingProvider surroundingProvider); void SetTextPasteHandler (TextPasteHandler textPasteHandler); - event EventHandler<LineEventArgs> LineChanged; - event EventHandler<LineEventArgs> LineInserted; - event EventHandler<LineEventArgs> LineRemoved; - #region Internal use only API (do not mirror in TextEditor) TextEditorExtension EditorExtension { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs index 741fabe3c2..66e8b84e4a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedCompletionExtension.cs @@ -250,14 +250,6 @@ namespace MonoDevelop.Ide.Editor.Projection return projectedExtension.CanRunCompletionCommand (); } - public override Task<MonoDevelop.Ide.CodeCompletion.ICompletionDataList> CodeCompletionCommand (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext) - { - var projectedExtension = GetExtensionAt (completionContext.TriggerOffset); - if (projectedExtension == null) - return null; - return projectedExtension.CodeCompletionCommand (ConvertContext (completionContext)); - } - public override bool CanRunParameterCompletionCommand () { var projectedExtension = GetCurrentExtension (); @@ -302,13 +294,13 @@ namespace MonoDevelop.Ide.Editor.Projection return projectedExtension.GuessBestMethodOverload (provider, currentOverload, token); } - public override System.Threading.Tasks.Task<MonoDevelop.Ide.CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) + public override System.Threading.Tasks.Task<MonoDevelop.Ide.CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, System.Threading.CancellationToken token) { var projectedExtension = GetExtensionAt (completionContext.TriggerOffset); if (projectedExtension == null) return null; - return projectedExtension.HandleCodeCompletionAsync (ConvertContext (completionContext), completionChar, token); + return projectedExtension.HandleCodeCompletionAsync (ConvertContext (completionContext), triggerInfo, token); } public override Task<ParameterHintingResult> HandleParameterCompletionAsync (MonoDevelop.Ide.CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs index 934be1340e..9ee715512b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/Projection/ProjectedFilterCompletionTextEditorExtension.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using MonoDevelop.Ide.CodeCompletion; using MonoDevelop.Ide.Editor.Extension; namespace MonoDevelop.Ide.Editor.Projection @@ -140,9 +141,9 @@ namespace MonoDevelop.Ide.Editor.Projection return completionTextEditorExtension.CanRunParameterCompletionCommand (); } - public override System.Threading.Tasks.Task<CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) + public override System.Threading.Tasks.Task<CodeCompletion.ICompletionDataList> HandleCodeCompletionAsync (CodeCompletion.CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, System.Threading.CancellationToken token) { - return completionTextEditorExtension.HandleCodeCompletionAsync (completionContext, completionChar, token); + return completionTextEditorExtension.HandleCodeCompletionAsync (completionContext, triggerInfo, token); } public override System.Threading.Tasks.Task<CodeCompletion.ParameterHintingResult> HandleParameterCompletionAsync (CodeCompletion.CodeCompletionContext completionContext, char completionChar, System.Threading.CancellationToken token) @@ -171,12 +172,6 @@ namespace MonoDevelop.Ide.Editor.Projection return completionTextEditorExtension.ShowCodeTemplatesCommand (completionContext); } - public override Task<CodeCompletion.ICompletionDataList> CodeCompletionCommand (CodeCompletion.CodeCompletionContext completionContext) - { - if (!IsActiveExtension()) return null; - return completionTextEditorExtension.CodeCompletionCommand (completionContext); - } - public override Task<CodeCompletion.ParameterHintingResult> ParameterCompletionCommand (CodeCompletion.CodeCompletionContext completionContext) { if (!IsActiveExtension()) return null; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs index d24ec3c833..107f942e1f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs @@ -1490,23 +1490,23 @@ namespace MonoDevelop.Ide.Editor internal IEnumerable<IDocumentLine> VisibleLines { get { return textEditorImpl.VisibleLines; } } internal event EventHandler<LineEventArgs> LineShown { add { textEditorImpl.LineShown += value; } remove { textEditorImpl.LineShown -= value; } } - internal ITextEditorImpl Implementation { get { return this.textEditorImpl; } }
-
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- public IndentationTracker IndentationTracker
- {
- get
- {
- Runtime.AssertMainThread();
- return textEditorImpl.IndentationTracker;
- }
- set
- {
- Runtime.AssertMainThread();
- textEditorImpl.IndentationTracker = value;
- }
- }
-
+ internal ITextEditorImpl Implementation { get { return this.textEditorImpl; } } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + public IndentationTracker IndentationTracker + { + get + { + Runtime.AssertMainThread(); + return textEditorImpl.IndentationTracker; + } + set + { + Runtime.AssertMainThread(); + textEditorImpl.IndentationTracker = value; + } + } + public event EventHandler FocusLost { add { textEditorImpl.FocusLost += value; } remove { textEditorImpl.FocusLost -= value; } } public new void GrabFocus () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs index 9c12156013..7670501079 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs @@ -849,36 +849,40 @@ namespace MonoDevelop.Ide.Gui if (adhocProject != null) { return Task.CompletedTask; } - if (Editor != null && Editor.MimeType == "text/x-csharp") { - var newProject = Services.ProjectService.CreateDotNetProject ("C#"); - this.adhocProject = newProject; - - newProject.Name = "InvisibleProject"; - newProject.References.Add (ProjectReference.CreateAssemblyReference ("mscorlib")); - newProject.References.Add (ProjectReference.CreateAssemblyReference ("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")); - newProject.References.Add (ProjectReference.CreateAssemblyReference ("System.Core")); - - newProject.FileName = "test.csproj"; - if (!Window.ViewContent.IsUntitled) { - adHocFile = Editor.FileName; - } else { - adHocFile = (Platform.IsWindows ? "C:\\" : "/") + Window.ViewContent.UntitledName + ".cs"; - } - - newProject.Files.Add (new ProjectFile (adHocFile, BuildAction.Compile)); - adhocSolution = new Solution (); - adhocSolution.AddConfiguration ("", true); - adhocSolution.DefaultSolutionFolder.AddItem (newProject); - return TypeSystemService.Load (adhocSolution, new ProgressMonitor (), token).ContinueWith (task => { - if (token.IsCancellationRequested) - return; - UnsubscribeRoslynWorkspace (); - RoslynWorkspace = task.Result.FirstOrDefault(); // 1 solution loaded ->1 workspace as result - SubscribeRoslynWorkspace (); - analysisDocument = RoslynWorkspace.CurrentSolution.Projects.First ().DocumentIds.First (); - TypeSystemService.InformDocumentOpen (RoslynWorkspace, analysisDocument, Editor); - }); + if (Editor != null) { + var node = TypeSystemService.GetTypeSystemParserNode (Editor.MimeType, BuildAction.Compile); + if (Editor.MimeType == "text/x-csharp" || node?.Parser.CanGenerateAnalysisDocument (Editor.MimeType, BuildAction.Compile, new string[0]) == true) { + var newProject = Services.ProjectService.CreateDotNetProject ("C#"); + this.adhocProject = newProject; + + newProject.Name = "InvisibleProject"; + newProject.References.Add (ProjectReference.CreateAssemblyReference ("mscorlib")); + newProject.References.Add (ProjectReference.CreateAssemblyReference ("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")); + newProject.References.Add (ProjectReference.CreateAssemblyReference ("System.Core")); + + newProject.FileName = "test.csproj"; + if (!Window.ViewContent.IsUntitled) { + adHocFile = Editor.FileName; + } else { + adHocFile = (Platform.IsWindows ? "C:\\" : "/") + Window.ViewContent.UntitledName + ".cs"; + } + + newProject.Files.Add (new ProjectFile (adHocFile, BuildAction.Compile)); + + adhocSolution = new Solution (); + adhocSolution.AddConfiguration ("", true); + adhocSolution.DefaultSolutionFolder.AddItem (newProject); + return TypeSystemService.Load (adhocSolution, new ProgressMonitor (), token).ContinueWith (task => { + if (token.IsCancellationRequested) + return; + UnsubscribeRoslynWorkspace (); + RoslynWorkspace = task.Result.FirstOrDefault (); // 1 solution loaded ->1 workspace as result + SubscribeRoslynWorkspace (); + analysisDocument = RoslynWorkspace.CurrentSolution.Projects.First ().DocumentIds.First (); + TypeSystemService.InformDocumentOpen (RoslynWorkspace, analysisDocument, Editor); + }); + } } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs index 93f595f5a0..6d3e08d851 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs @@ -119,7 +119,7 @@ namespace MonoDevelop.Ide.TypeSystem }
services = MefHostServices.Create (assemblies);
}
- +
/// <summary>
/// This bypasses the type system service. Use with care.
/// </summary>
@@ -147,8 +147,8 @@ namespace MonoDevelop.Ide.TypeSystem CancelLoad ();
if (IdeApp.Workspace != null) {
IdeApp.Workspace.ActiveConfigurationChanged -= HandleActiveConfigurationChanged;
- } - foreach (var prj in monoDevelopSolution.GetAllProjects ()) { + }
+ foreach (var prj in monoDevelopSolution.GetAllProjects ()) {
UnloadMonoProject (prj);
}
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemParserNode.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemParserNode.cs index 3dc96d28c0..64db6ef9c5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemParserNode.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemParserNode.cs @@ -73,12 +73,12 @@ namespace MonoDevelop.Ide.TypeSystem public bool CanParse (string mimeType, string buildAction) { if (mimeTypes == null) - mimeTypes = this.mimeType != null ? new HashSet<string> (this.mimeType.Split (',').Select (s => s.Trim ())) : new HashSet<string> (); - if (!mimeTypes.Contains (mimeType, StringComparer.Ordinal)) + mimeTypes = this.mimeType != null ? new HashSet<string> (this.mimeType.Split (',').Select (s => s.Trim ()), StringComparer.Ordinal) : new HashSet<string> (StringComparer.Ordinal); + if (!mimeTypes.Contains (mimeType)) return false; foreach (var action in buildActions) { - if (string.Equals (action, buildAction, StringComparison.OrdinalIgnoreCase)) + if (string.Equals (action, buildAction, StringComparison.OrdinalIgnoreCase) || action == "*") return true; } return false; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj index d600c828ef..b3628e92bd 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj @@ -8072,8 +8072,8 @@ <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\javascript\syntaxes\JavaScript.tmLanguage.json"> <LogicalName>JavaScript.tmLanguage.json</LogicalName> </EmbeddedResource> - <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\javascript\syntaxes\Regular Expressions %28JavaScript%29.tmLanguage"> - <LogicalName>Regular Expressions (JavaScript).tmLanguage</LogicalName> + <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\javascript\syntaxes\RegexJavaScript.tmLanguage"> + <LogicalName>RegexJavaScript.tmLanguage</LogicalName> </EmbeddedResource> <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\xml\syntaxes\xml.json"> <LogicalName>xml.json</LogicalName> @@ -8135,8 +8135,8 @@ <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\swift\syntaxes\swift.json"> <LogicalName>swift.json</LogicalName> </EmbeddedResource> - <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\bat\syntaxes\Batch File.tmLanguage"> - <LogicalName>Batch File.tmLanguage</LogicalName> + <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\bat\syntaxes\BatchFile.tmLanguage"> + <LogicalName>BatchFile.tmLanguage</LogicalName> </EmbeddedResource> <EmbeddedResource Include="MonoDevelop.Ide.Editor.Highlighting\VSCodeImport\objective-c\syntaxes\Objective-C.tmLanguage"> <LogicalName>Objective-C.tmLanguage</LogicalName> @@ -9227,6 +9227,8 @@ <Compile Include="MonoDevelop.Components\RoundedFrameBox.cs" /> <Compile Include="MonoDevelop.Ide.Editor.Highlighting\ScopeStack.cs" /> <Compile Include="MonoDevelop.Ide.Editor.Extension\HighlightUrlExtension.cs" /> + <Compile Include="MonoDevelop.Ide.CodeCompletion\CompletionTriggerInfo.cs" /> + <Compile Include="MonoDevelop.Ide.CodeCompletion\CompletionTriggerReason.cs" /> <Compile Include="MonoDevelop.Ide.TypeSystem\EditorNotificationServiceFactory.cs" /> </ItemGroup> <ItemGroup> diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs index 3b369b289d..e277d65b7c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ImageService.cs @@ -168,6 +168,21 @@ namespace MonoDevelop.Ide return GetIcon (name).WithSize (size); } + public static void AddIcon (string iconId, Xwt.Drawing.Image icon) + { + if (iconId == null) + throw new ArgumentNullException (nameof (iconId)); + if (icon == null) + throw new ArgumentNullException (nameof (icon)); + icons.Add (iconId, icon); + } + + public static bool HasIcon (string iconId) + { + return icons.ContainsKey (iconId); + } + + public static Xwt.Drawing.Image GetIcon (string name) { return GetIcon (name, true); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs index b61878aae1..52d7414fc2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs @@ -1190,7 +1190,9 @@ namespace MonoDevelop.Ide } if (isRebuilding) { - if (EndClean != null) { + if (res.HasErrors) { + CleanDone (monitor, res, entry, tt); + } else if (EndClean != null) { OnEndClean (monitor, tt); } } else { @@ -1198,22 +1200,6 @@ namespace MonoDevelop.Ide } return res; } - - void CleanDone (ProgressMonitor monitor, IBuildTarget entry, ITimeTracker tt) - { - tt.Trace ("Begin reporting clean result"); - try { - monitor.Log.WriteLine (); - monitor.Log.WriteLine (GettextCatalog.GetString ("---------------------- Done ----------------------")); - tt.Trace ("Reporting result"); - monitor.ReportSuccess (GettextCatalog.GetString ("Clean successful.")); - OnEndClean (monitor, tt); - } finally { - monitor.Dispose (); - tt.End (); - } - } - void CleanDone (ProgressMonitor monitor, BuildResult result, IBuildTarget entry, ITimeTracker tt) { @@ -2498,7 +2484,7 @@ namespace MonoDevelop.Ide { if (IdeApp.Workbench != null) { foreach (var doc in IdeApp.Workbench.Documents) { - if (doc.FileName == filePath) { + if (doc.FileName == filePath && doc.Editor != null) { isOpen = true; return doc.Editor; } |