diff --git a/src/Eto.DevExtension.LanguageServer/CompletionService.cs b/src/Eto.DevExtension.LanguageServer/CompletionService.cs index 54f38bd..043a2a8 100644 --- a/src/Eto.DevExtension.LanguageServer/CompletionService.cs +++ b/src/Eto.DevExtension.LanguageServer/CompletionService.cs @@ -44,6 +44,9 @@ static CompletionService() // a comma between json properties is too early; the space or quote after it opens completion instead if (triggerCharacter == "," && format == CompletionFormat.Json && !context.Quoted) return results; + // a quote that ends a value has nothing to complete until the next space + if ((triggerCharacter == "\"" || triggerCharacter == "'") && !context.Quoted) + return results; var range = ToRange(text, context.Start, context.End); var eventRequest = EventCompletion.Read(context); @@ -53,6 +56,11 @@ static CompletionService() return results; } + // typing the closing quote accepts a value, and the editor then steps over the one already there + var quote = context.Start > 0 ? text[context.Start - 1] : '\0'; + var commitCharacters = context.Quoted && context.Info.Mode == CompletionMode.Value && context.Binding == null && context.Markup == null && (quote == '"' || quote == '\'') + ? new List { quote.ToString() } + : null; foreach (var item in DocumentCompletion.GetItems(context)) { var snippet = snippets && item.ValueText != null; @@ -72,6 +80,7 @@ static CompletionService() ? new Command { Title = "Suggest", Name = triggerSuggestCommand } : null, // lets a client without snippets, such as Visual Studio, add the value itself + CommitCharacters = commitCharacters, Data = item.ValueText == null ? null : new CompletionData { ValueText = item.ValueText, ValueReplaces = item.ValueReplaces }, AdditionalTextEdits = item.NamespaceEdit == null ? null : new List { diff --git a/src/Eto.DevExtension.LanguageServer/Lsp/Protocol.cs b/src/Eto.DevExtension.LanguageServer/Lsp/Protocol.cs index 6d9808d..1453fe3 100644 --- a/src/Eto.DevExtension.LanguageServer/Lsp/Protocol.cs +++ b/src/Eto.DevExtension.LanguageServer/Lsp/Protocol.cs @@ -40,6 +40,7 @@ public class CompletionItem public TextEdit TextEdit { get; set; } public List AdditionalTextEdits { get; set; } public int? InsertTextFormat { get; set; } + public List CommitCharacters { get; set; } public Command Command { get; set; } public CompletionData Data { get; set; } } diff --git a/src/Eto.DevExtension.VSCode/package.json b/src/Eto.DevExtension.VSCode/package.json index d265583..57ca6d8 100644 --- a/src/Eto.DevExtension.VSCode/package.json +++ b/src/Eto.DevExtension.VSCode/package.json @@ -28,6 +28,14 @@ "onLanguage:jeto" ], "contributes": { + "configurationDefaults": { + "[xeto]": { + "editor.autoClosingOvertype": "always" + }, + "[jeto]": { + "editor.autoClosingOvertype": "always" + } + }, "keybindings": [ { "key": "=", diff --git a/src/Eto.DevExtension.VisualStudio.Windows/Intellisense/JetoCompletionSource.cs b/src/Eto.DevExtension.VisualStudio.Windows/Intellisense/JetoCompletionSource.cs index 30c9a0d..5570089 100644 --- a/src/Eto.DevExtension.VisualStudio.Windows/Intellisense/JetoCompletionSource.cs +++ b/src/Eto.DevExtension.VisualStudio.Windows/Intellisense/JetoCompletionSource.cs @@ -46,8 +46,8 @@ public CompletionStartData InitializeCompletion(CompletionTrigger trigger, Snaps if (context == null) return CompletionStartData.DoesNotParticipateInCompletion; - // a comma between properties is too early; the space or quote after it opens completion instead - if (trigger.Reason == CompletionTriggerReason.Insertion && trigger.Character == ',' && !context.Quoted) + // a comma between properties, or a quote ending a string, is too early; the space or quote after it opens completion instead + if (trigger.Reason == CompletionTriggerReason.Insertion && (trigger.Character == ',' || trigger.Character == '"' || trigger.Character == '\'') && !context.Quoted) return CompletionStartData.DoesNotParticipateInCompletion; var span = new SnapshotSpan(triggerLocation.Snapshot, context.Start, context.End - context.Start);