diff --git a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs index f5c4ed6e4..3854b8506 100644 --- a/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs +++ b/src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs @@ -1063,32 +1063,43 @@ protected async Task HandleCommentHelpRequest( RequestContext requestContext) { var scriptFile = this.editorSession.Workspace.GetFile(requestParams.DocumentUri); - var expectedFunctionLine = requestParams.TriggerPosition.Line + 2; + var triggerLine0b = requestParams.TriggerPosition.Line; + var triggerLine1b = triggerLine0b + 1; string helpLocation; - var functionDefinitionAst = this.editorSession.LanguageService.GetFunctionDefinitionForHelpComment( + var functionDefinitionAst = editorSession.LanguageService.GetFunctionDefinitionForHelpComment( scriptFile, - requestParams.TriggerPosition.Line + 1, + triggerLine1b, out helpLocation); var result = new CommentHelpRequestResult(); if (functionDefinitionAst != null) { + var funcExtent = functionDefinitionAst.Extent; + var funcText = funcExtent.Text; + if (helpLocation.Equals("begin")) + { + // check if the previous character is `<` because it invalidates + // the param block the follows it. + var lines = ScriptFile.GetLines(funcText).ToArray(); + var relativeTriggerLine0b = triggerLine1b - funcExtent.StartLineNumber; + if (relativeTriggerLine0b > 0 && lines[relativeTriggerLine0b].IndexOf("<") > -1) + { + lines[relativeTriggerLine0b] = string.Empty; + } + + funcText = string.Join("\n", lines); + } + var analysisResults = await this.editorSession.AnalysisService.GetSemanticMarkersAsync( - functionDefinitionAst.Extent.Text, + funcText, AnalysisService.GetCommentHelpRuleSettings( true, false, requestParams.BlockComment, true, helpLocation)); - result.Content = analysisResults? - .FirstOrDefault()? - .Correction? - .Edits[0] - .Text - .Split('\n') - .Select(x => x.Trim('\r')) - .ToArray(); + var help = analysisResults?.FirstOrDefault()?.Correction?.Edits[0].Text; + result.Content = help == null ? null : ScriptFile.GetLines(help).ToArray(); if (helpLocation != null && !helpLocation.Equals("before", StringComparison.OrdinalIgnoreCase)) { diff --git a/src/PowerShellEditorServices/Workspace/ScriptFile.cs b/src/PowerShellEditorServices/Workspace/ScriptFile.cs index 3336dae80..039b2aa85 100644 --- a/src/PowerShellEditorServices/Workspace/ScriptFile.cs +++ b/src/PowerShellEditorServices/Workspace/ScriptFile.cs @@ -192,6 +192,21 @@ public ScriptFile ( #region Public Methods + /// + /// Get the lines in a string. + /// + /// Input string to be split up into lines. + /// The lines in the string. + public static IEnumerable GetLines(string text) + { + if (text == null) + { + throw new ArgumentNullException(nameof(text)); + } + + return text.Split('\n').Select(line => line.TrimEnd('\r')); + } + /// /// Gets a line from the file's contents. /// @@ -479,11 +494,7 @@ private void SetFileContents(string fileContents) { // Split the file contents into lines and trim // any carriage returns from the strings. - this.FileLines = - fileContents - .Split('\n') - .Select(line => line.TrimEnd('\r')) - .ToList(); + this.FileLines = GetLines(fileContents).ToList(); // Parse the contents to get syntax tree and errors this.ParseFileContents();