From 4cebc196ff40ad509d87abd49ebde533fde5ff5a Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Sun, 24 Jul 2016 13:37:10 -0700 Subject: [PATCH] Switch to using sys.tables for autocomplete Move some code into a better class --- src/ServiceHost/Connection/SqlConnection.cs | 4 +- .../LanguageSupport/AutoCompleteService.cs | 63 ++++++++++++++ src/ServiceHost/Server/LanguageServer.cs | 83 +++++++------------ 3 files changed, 98 insertions(+), 52 deletions(-) diff --git a/src/ServiceHost/Connection/SqlConnection.cs b/src/ServiceHost/Connection/SqlConnection.cs index 74104fb9..5bb92553 100644 --- a/src/ServiceHost/Connection/SqlConnection.cs +++ b/src/ServiceHost/Connection/SqlConnection.cs @@ -52,8 +52,10 @@ namespace Microsoft.SqlTools.EditorServices.Connection /// public IEnumerable GetServerObjects() { + // Select the values from sys.tables to give a super basic + // autocomplete experience. This will be replaced by SMO. SqlCommand command = connection.CreateCommand(); - command.CommandText = "SELECT name FROM sys.objects"; + command.CommandText = "SELECT name FROM sys.tables"; command.CommandTimeout = 15; command.CommandType = CommandType.Text; var reader = command.ExecuteReader(); diff --git a/src/ServiceHost/LanguageSupport/AutoCompleteService.cs b/src/ServiceHost/LanguageSupport/AutoCompleteService.cs index 48442b64..2cf98484 100644 --- a/src/ServiceHost/LanguageSupport/AutoCompleteService.cs +++ b/src/ServiceHost/LanguageSupport/AutoCompleteService.cs @@ -4,6 +4,7 @@ // using Microsoft.SqlTools.EditorServices.Connection; +using Microsoft.SqlTools.EditorServices.Protocol.LanguageServer; using System; using System.Collections.Generic; @@ -20,8 +21,14 @@ namespace Microsoft.SqlTools.LanguageSupport private static Lazy instance = new Lazy(() => new AutoCompleteService()); + /// + /// The current autocomplete candidate list + /// private IEnumerable autoCompleteList; + /// + /// Gets the current autocomplete candidate list + /// public IEnumerable AutoCompleteList { get @@ -41,9 +48,65 @@ namespace Microsoft.SqlTools.LanguageSupport } } + /// + /// Update the cached autocomplete candidate list when the user connects to a database + /// + /// public void UpdateAutoCompleteCache(ISqlConnection connection) { this.autoCompleteList = connection.GetServerObjects(); } + + /// + /// Return the completion item list for the current text position + /// + /// + public CompletionItem[] GetCompletionItems(TextDocumentPosition textDocumentPosition) + { + var completions = new List(); + + int i = 0; + + // the completion list will be null is user not connected to server + if (this.AutoCompleteList != null) + { + foreach (var autoCompleteItem in this.AutoCompleteList) + { + // convert the completion item candidates into CompletionItems + completions.Add(new CompletionItem() + { + Label = autoCompleteItem, + Kind = CompletionItemKind.Keyword, + Detail = autoCompleteItem + " details", + Documentation = autoCompleteItem + " documentation", + TextEdit = new TextEdit + { + NewText = autoCompleteItem, + Range = new Range + { + Start = new Position + { + Line = textDocumentPosition.Position.Line, + Character = textDocumentPosition.Position.Character + }, + End = new Position + { + Line = textDocumentPosition.Position.Line, + Character = textDocumentPosition.Position.Character + 5 + } + } + } + }); + + // only show 50 items + if (++i == 50) + { + break; + } + } + } + return completions.ToArray(); + } + } } diff --git a/src/ServiceHost/Server/LanguageServer.cs b/src/ServiceHost/Server/LanguageServer.cs index eb054b45..c2952f92 100644 --- a/src/ServiceHost/Server/LanguageServer.cs +++ b/src/ServiceHost/Server/LanguageServer.cs @@ -175,15 +175,38 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.Server await Task.FromResult(true); } + /// + /// Handle the file open notification + /// + /// + /// protected Task HandleDidOpenTextDocumentNotification( DidOpenTextDocumentNotification openParams, EventContext eventContext) { Logger.Write(LogLevel.Verbose, "HandleDidOpenTextDocumentNotification"); + + // read the SQL file contents into the ScriptFile + ScriptFile openedFile = + editorSession.Workspace.GetFileBuffer( + openParams.Uri, + openParams.Text); + + // run diagnostics on the opened file + this.RunScriptDiagnostics( + new ScriptFile[] { openedFile }, + editorSession, + eventContext); + return Task.FromResult(true); } - protected Task HandleDidCloseTextDocumentNotification( + /// + /// Handle the close document notication + /// + /// + /// + protected Task HandleDidCloseTextDocumentNotification( TextDocumentIdentifier closeParams, EventContext eventContext) { @@ -257,62 +280,20 @@ namespace Microsoft.SqlTools.EditorServices.Protocol.Server await Task.FromResult(true); } + /// + /// Handles the completion list request + /// + /// + /// protected async Task HandleCompletionRequest( TextDocumentPosition textDocumentPosition, RequestContext requestContext) { Logger.Write(LogLevel.Verbose, "HandleCompletionRequest"); - var connectionService = ConnectionService.Instance; - if (connectionService.ActiveConnections.Count > 0) - { - AutoCompleteService.Instance.UpdateAutoCompleteCache( - connectionService.ActiveConnections.First().Value); - } - - var autoCompleteList = AutoCompleteService.Instance.AutoCompleteList; - var completions = new List(); - - int i = 0; - if (autoCompleteList != null) - { - foreach (var autoCompleteItem in autoCompleteList) - { - completions.Add(new CompletionItem() - { - Label = autoCompleteItem, - Kind = CompletionItemKind.Keyword, - Detail = autoCompleteItem + " details", - Documentation = autoCompleteItem + " documentation", - //SortText = "SortText", - TextEdit = new TextEdit - { - NewText = "New Text", - Range = new Range - { - Start = new Position - { - Line = textDocumentPosition.Position.Line, - Character = textDocumentPosition.Position.Character - }, - End = new Position - { - Line = textDocumentPosition.Position.Line, - Character = textDocumentPosition.Position.Character + 5 - } - } - } - }); - - // only show 50 items - if (++i == 50) - { - break; - } - } - } - - await requestContext.SendResult(completions.ToArray()); + // get teh current list of completion items and return to client + var completionItems = AutoCompleteService.Instance.GetCompletionItems(textDocumentPosition); + await requestContext.SendResult(completionItems); } protected async Task HandleCompletionResolveRequest(