private Task SendSignatureHelpAsync(SignatureHelpItemsData?items, ICommandResultSender sender, CancellationToken cancellationToken) { var writer = sender.StartJsonMessage("signatures"); if (items == null) { return(sender.SendJsonMessageAsync(cancellationToken)); } var selectedItemIndex = items.SelectedItemIndex; writer.WriteSpanProperty("span", items.ApplicableSpan); writer.WritePropertyStartArray("signatures"); var itemIndex = 0; foreach (var item in items.Items) { writer.WriteStartObject(); if (selectedItemIndex == null && items.ArgumentCount <= item.ParameterCount) { selectedItemIndex = itemIndex; } if (itemIndex == selectedItemIndex) { writer.WriteProperty("selected", true); } writer.WritePropertyStartArray("parts"); writer.WriteTaggedTexts(item.PrefixDisplayParts); var parameterIndex = 0; foreach (var parameter in item.Parameters) { if (parameterIndex > 0) { writer.WriteTaggedTexts(item.SeparatorDisplayParts); } var selected = items.ArgumentIndex == parameterIndex; writer.WriteTaggedTexts(parameter.PrefixDisplayParts, selected); writer.WriteTaggedTexts(parameter.DisplayParts, selected); writer.WriteTaggedTexts(parameter.SuffixDisplayParts, selected); parameterIndex += 1; } writer.WriteTaggedTexts(item.SuffixDisplayParts); writer.WriteEndArray(); writer.WriteEndObject(); itemIndex += 1; } writer.WriteEndArray(); return(sender.SendJsonMessageAsync(cancellationToken)); }
private async Task SendOptionsEchoAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { if (session.IsRoslyn) { session.Roslyn.CurrentCodeActions.Clear(); } var writer = sender.StartJsonMessage("optionsEcho"); writer.WritePropertyStartObject("options"); foreach (var pair in session.RawOptionsFromClient) { writer.WriteProperty(pair.Key, pair.Value); } writer.WriteEndObject(); await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false); }
private async Task ExecuteForRoslynAsync( int cursorPosition, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken ) { var info = await session.Roslyn.QuickInfoService .GetQuickInfoAsync(session.Roslyn.Document, cursorPosition, cancellationToken) .ConfigureAwait(false); if (IsNullOrEmpty(info)) { return; } await SendInfoTipAsync(info, sender, cancellationToken).ConfigureAwait(false); }
private Task SendCompletionListAsync(CompletionList completionList, ICommandResultSender sender, CancellationToken cancellationToken) { var completionSpan = completionList.Span; var writer = sender.StartJsonMessage("completions"); writer.WriteProperty("commitChars", completionList.Rules.DefaultCommitCharacters); writer.WritePropertyName("span"); writer.WriteSpan(completionSpan); var suggestionItem = completionList.SuggestionModeItem; if (suggestionItem != null) { writer.WritePropertyStartObject("suggestion"); writer.WriteProperty("displayText", suggestionItem.DisplayText); writer.WriteEndObject(); } writer.WritePropertyStartArray("completions"); foreach (var item in completionList.Items) { writer.WriteStartObject(); writer.WriteProperty("filterText", item.FilterText); writer.WriteProperty("displayText", item.DisplayText); writer.WritePropertyStartArray("tags"); foreach (var tag in item.Tags) { writer.WriteValue(tag.ToLowerInvariant()); } writer.WriteEndArray(); if (item.Span != completionSpan) { writer.WritePropertyName("span"); writer.WriteSpan(item.Span); } if (item.Rules.MatchPriority > 0) { writer.WriteProperty("priority", item.Rules.MatchPriority); } writer.WriteEndObject(); } writer.WriteEndArray(); return(sender.SendJsonMessageAsync(cancellationToken)); }
public Task ApplyTypedCharAsync(char @char, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { var current = session.CurrentCompletion; if (current.List != null) { return(Task.CompletedTask); } if (current.ChangeEchoPending) { current.PendingChar = @char; return(Task.CompletedTask); } var trigger = CompletionTrigger.CreateInsertionTrigger(@char); return(CheckCompletionAsync(trigger, session, sender, cancellationToken)); }
public async Task SendItemInfoAsync(int selectedIndex, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { var item = session.CurrentCompletion.List.Items[selectedIndex]; var description = await session.LanguageSession.GetCompletionDescriptionAsync(item, cancellationToken).ConfigureAwait(false); if (description == null) { return; } var writer = sender.StartJsonMessage("completionInfo"); writer.WriteProperty("index", selectedIndex); writer.WritePropertyStartArray("parts"); writer.WriteTaggedTexts(description.TaggedParts); writer.WriteEndArray(); await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false); }
public Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { var writer = sender.StartJsonMessage("self:debug"); writer.WritePropertyStartArray("log"); // ReSharper disable once PossibleNullReferenceException foreach (var entry in session.SelfDebug.GetLogEntries()) { writer.WriteStartObject(); writer.WriteProperty("time", entry.DateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffK")); writer.WriteProperty("event", entry.EventType); writer.WriteProperty("message", entry.Message); writer.WriteProperty("cursor", entry.CursorPosition); writer.WriteProperty("text", entry.Text); writer.WriteEndObject(); } writer.WriteEndArray(); return(sender.SendJsonMessageAsync(cancellationToken)); }
public Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { var first = data.GetFirst(); var firstByte = first.Array[first.Offset]; if (firstByte == (byte)'X') { return(_completion.CancelCompletionAsync(session, sender, cancellationToken)); } if (firstByte == (byte)'F') { return(_completion.ForceCompletionAsync(session, sender, cancellationToken)); } var itemIndex = FastConvert.Utf8ByteArrayToInt32(first); return(_completion.SelectCompletionAsync(itemIndex, session, sender, cancellationToken)); }
private Task SendSignatureHelpAsync(SignatureHelpItemsData?items, ICommandResultSender sender, CancellationToken cancellationToken) { var writer = sender.StartJsonMessage("signatures"); if (items == null) { return(sender.SendJsonMessageAsync(cancellationToken)); } var selectedItemIndex = items.SelectedItemIndex; writer.WriteSpanProperty("span", items.ApplicableSpan); writer.WritePropertyStartArray("signatures"); var itemIndex = 0; foreach (var item in items.Items) { writer.WriteStartObject(); if (selectedItemIndex == null && items.ArgumentCount <= item.ParameterCount) { selectedItemIndex = itemIndex; } var isSelected = (itemIndex == selectedItemIndex); if (isSelected) { writer.WriteProperty("selected", true); } WriteSignatureParts(writer, item, items, out var selectedParameter); if (isSelected) { WriteSignatureDocumentation(writer, item, selectedParameter, cancellationToken); } writer.WriteEndObject(); itemIndex += 1; } writer.WriteEndArray(); return(sender.SendJsonMessageAsync(cancellationToken)); }
public async Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { // this doesn't happen too often, so microptimizations are not required var optionsString = await AsyncDataConvert.ToUtf8StringAsync(data, 0, _charArrayPool).ConfigureAwait(false); var options = optionsString .Split(Comma) .Select(p => p.Split(EqualsSign)) .ToDictionary(p => p[0], p => p[1]); if (options.TryGetValue(LanguageOptionName, out var language)) { // this has to be done first, as it might reset other options SetLanguage(session, language); session.RawOptionsFromClient[LanguageOptionName] = language; } foreach (var option in options) { var(name, value) = (option.Key, option.Value); if (name == LanguageOptionName) { continue; } if (name.StartsWith("x-")) { if (!(_extension?.TrySetOption(session, name, value) ?? false)) { throw new FormatException($"Extension option '{name}' was not recognized."); } session.RawOptionsFromClient[name] = value; continue; } throw new FormatException($"Option '{name}' was not recognized (to use {nameof(ISetOptionsFromClientExtension)}, make sure your option name starts with 'x-')."); } await SendOptionsEchoAsync(session, sender, cancellationToken).ConfigureAwait(false); }
public async Task ExecuteAsync(AsyncData data, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { // Temporary suppression, need to figure out the best approach here. // ReSharper disable once HeapView.BoxingAllocation var diagnostics = (IReadOnlyList <Diagnostic>) await session.LanguageSession.GetDiagnosticsAsync(cancellationToken).ConfigureAwait(false); object extensionResult = null; try { if (_extension != null) { var mutableDiagnostics = diagnostics.ToList(); extensionResult = await _extension.ProcessAsync(session, mutableDiagnostics, cancellationToken).ConfigureAwait(false); diagnostics = mutableDiagnostics; } await SendSlowUpdateAsync(diagnostics, session, extensionResult, sender, cancellationToken).ConfigureAwait(false); } finally { (extensionResult as IDisposable)?.Dispose(); } }
public Task ApplyTypedCharAsync(char @char, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { if (!session.IsRoslyn) { return(Task.CompletedTask); } var trigger = new SignatureHelpTriggerInfoData(SignatureHelpTriggerReason.TypeCharCommand, @char); if (session.Roslyn.CurrentSignatureHelp != null) { var provider = session.Roslyn.CurrentSignatureHelp.Value.Provider; if (provider.IsRetriggerCharacter(@char)) { session.Roslyn.CurrentSignatureHelp = null; return(SendSignatureHelpAsync(null, sender, cancellationToken)); } return(TryApplySignatureHelpAsync(provider, trigger, session, sender, cancellationToken, sendIfEmpty: true)); } return(TryApplySignatureHelpAsync(session, sender, cancellationToken, trigger)); }
private Task SendInfoTipAsync(QuickInfoItem info, ICommandResultSender sender, CancellationToken cancellationToken) { var writer = sender.StartJsonMessage("infotip"); if (IsNullOrEmpty(info)) { return(sender.SendJsonMessageAsync(cancellationToken)); } writer.WriteTagsProperty("kinds", info.Tags); writer.WritePropertyStartArray("sections"); foreach (var section in info.Sections) { writer.WriteStartObject(); writer.WriteProperty("kind", FastConvert.StringToLowerInvariantString(section.Kind)); writer.WritePropertyStartArray("parts"); writer.WriteTaggedTexts(section.TaggedParts); writer.WriteEndArray(); writer.WriteEndObject(); } writer.WriteEndArray(); writer.WriteSpanProperty("span", info.Span); return(sender.SendJsonMessageAsync(cancellationToken)); }
public Task ApplyCursorPositionChangeAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { if (!session.IsRoslyn) { return(Task.CompletedTask); } var currentHelp = session.Roslyn.CurrentSignatureHelp; if (currentHelp == null) { return(Task.CompletedTask); } if (!currentHelp.Value.Items.ApplicableSpan.Contains(session.CursorPosition)) { session.Roslyn.CurrentSignatureHelp = null; return(SendSignatureHelpAsync(null, sender, cancellationToken)); } // not sure if there is any better way to recalculate the selected parameter only, // but doesn't seem so at the moment return(TryApplySignatureHelpAsync(currentHelp.Value.Provider, new SignatureHelpTriggerInfoData(SignatureHelpTriggerReason.RetriggerCommand), session, sender, cancellationToken, true)); }
private async Task SendSlowUpdateAsync(IReadOnlyList <Diagnostic> diagnostics, WorkSession session, object extensionResult, ICommandResultSender sender, CancellationToken cancellationToken) { if (session.IsRoslyn) { session.Roslyn.CurrentCodeActions.Clear(); } var writer = sender.StartJsonMessage("slowUpdate"); writer.WritePropertyStartArray("diagnostics"); foreach (var diagnostic in diagnostics) { writer.WriteStartObject(); writer.WriteProperty("id", diagnostic.Id); writer.WriteProperty("message", diagnostic.GetMessage()); writer.WriteProperty("severity", FastConvert.EnumToLowerInvariantString(diagnostic.Severity)); writer.WritePropertyStartArray("tags"); foreach (var tag in diagnostic.Descriptor.CustomTags) { if (tag != WellKnownDiagnosticTags.Unnecessary) { continue; } writer.WriteValue(tag.ToLowerInvariant()); } writer.WriteEndArray(); writer.WriteSpanProperty("span", diagnostic.Location.SourceSpan); var actions = await GetCodeActionsAsync(diagnostic, session, cancellationToken).ConfigureAwait(false); if (actions.Length > 0) { writer.WritePropertyStartArray("actions"); WriteActions(writer, actions, session); writer.WriteEndArray(); } writer.WriteEndObject(); } writer.WriteEndArray(); if (_extension != null) { writer.WritePropertyName("x"); _extension.WriteResult(writer, extensionResult, session); } await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false); }
public async Task SelectCompletionAsync(int selectedIndex, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { var current = session.CurrentCompletion; // ReSharper disable once PossibleNullReferenceException var completionList = current.List; // ReSharper disable once PossibleNullReferenceException var item = completionList.Items[selectedIndex]; var change = await session.LanguageSession.GetCompletionChangeAsync(completionList.Span, item, cancellationToken : cancellationToken).ConfigureAwait(false); current.List = null; var textChange = ReplaceIncompleteText(session, completionList, change.TextChange); current.ChangeEchoPending = true; var writer = sender.StartJsonMessage("changes"); writer.WriteProperty("reason", ChangeReasonCompletion); writer.WritePropertyStartArray("changes"); writer.WriteChange(textChange); writer.WriteEndArray(); await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false); }
public async Task ApplyTypedCharAsync(char @char, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { await _completion.ApplyTypedCharAsync(@char, session, sender, cancellationToken).ConfigureAwait(false); await _signatureHelp.ApplyTypedCharAsync(@char, session, sender, cancellationToken).ConfigureAwait(false); }
private Task CheckCompletionAsync(CompletionTrigger trigger, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { if (!session.LanguageSession.ShouldTriggerCompletion(session.CursorPosition, trigger)) { return(Task.CompletedTask); } return(TriggerCompletionAsync(session, sender, cancellationToken, trigger)); }
public Task ApplyReplacedTextAsync(string reason, ITypedCharEffects typedCharEffects, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { if (reason != ChangeReasonCompletion) { return(Task.CompletedTask); } var pendingChar = session.CurrentCompletion.PendingChar; session.CurrentCompletion.ResetPending(); if (pendingChar == null) { return(Task.CompletedTask); } return(typedCharEffects.ApplyTypedCharAsync(pendingChar.Value, session, sender, cancellationToken)); }
public Task ForceSignatureHelpAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { var trigger = new SignatureHelpTriggerInfoData(SignatureHelpTriggerReason.InvokeSignatureHelpCommand); return(TryApplySignatureHelpAsync(session, sender, cancellationToken, trigger)); }
public Task CancelCompletionAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { session.CurrentCompletion.ResetPending(); session.CurrentCompletion.List = null; return(Task.CompletedTask); }
public Task ForceCompletionAsync(WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { return(TriggerCompletionAsync(session, sender, cancellationToken, CompletionTrigger.Invoke)); }
private async Task <bool> TryApplySignatureHelpAsync(ISignatureHelpProviderWrapper provider, SignatureHelpTriggerInfoData trigger, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken, bool sendIfEmpty = false) { // ReSharper disable once PossibleInvalidOperationException if (trigger.TriggerReason == SignatureHelpTriggerReason.TypeCharCommand && !provider.IsTriggerCharacter(trigger.TriggerCharacter.Value)) { return(false); } var help = await provider.GetItemsAsync(session.Roslyn.Document, session.CursorPosition, trigger, cancellationToken).ConfigureAwait(false); if (!sendIfEmpty && help == null) { return(false); } session.Roslyn.CurrentSignatureHelp = help != null ? new CurrentSignatureHelp(provider, help) : (CurrentSignatureHelp?)null; await SendSignatureHelpAsync(help, sender, cancellationToken).ConfigureAwait(false); return(true); }
public async Task SelectCompletionAsync(int selectedIndex, WorkSession session, ICommandResultSender sender, CancellationToken cancellationToken) { var current = session.CurrentCompletion; var completionList = current.List; if (completionList == null) { throw new InvalidOperationException("Cannot select completion when completion list is not active."); } var item = completionList.Items[selectedIndex]; var change = await session.LanguageSession.GetCompletionChangeAsync(completionList.Span, item, cancellationToken : cancellationToken).ConfigureAwait(false); current.List = null; var textChange = ReplaceIncompleteText(session, completionList, change.TextChange); current.ChangeEchoPending = true; var writer = sender.StartJsonMessage("changes"); writer.WriteProperty("reason", ChangeReasonCompletion); writer.WritePropertyStartArray("changes"); writer.WriteChange(textChange); writer.WriteEndArray(); await sender.SendJsonMessageAsync(cancellationToken).ConfigureAwait(false); }