Skip to content

Commit

Permalink
(PowerShellGH-793) Add support for Folding Range client settings
Browse files Browse the repository at this point in the history
This commit uses the the client configuration settings to modify the behaviour
of the server. In particular the Enable and ShowLastLine setting.

* The enable setting will change the provider to return null when disabled
* The ShowLastLine setting emulates the behaviour in PowerShell/vscode-powershell#1557
  * Modifies conversion method for the internal region class to FoldingRange
    object to show/hide the last line based on the extension settings
  * Modifies the tests for the default value and adds tests for the show and hide
    scenarios
  • Loading branch information
glennsarti committed Nov 14, 2018
1 parent e0dfc4d commit 61014e1
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1301,10 +1301,13 @@ protected Task HandleEvaluateRequest(
private FoldingRange[] Fold(
string documentUri)
{
// TODO Should I be using dynamic registrations?
if (this.currentSettings.CodeFolding.Enable != true) { return null; }
// TODO Surely there's a better way to do type adapters?
List<FoldingRange> result = new List<FoldingRange>();
foreach (FoldingReference fold in TokenOperations.FoldableRegions(
editorSession.Workspace.GetFile(documentUri).ScriptTokens))
editorSession.Workspace.GetFile(documentUri).ScriptTokens,
this.currentSettings.CodeFolding.ShowLastLine))
{
FoldingRange item = new FoldingRange();
item.EndCharacter = fold.EndCharacter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ public class LanguageServerSettings

public CodeFormattingSettings CodeFormatting { get; set; }

public CodeFoldingSettings CodeFolding { get; set; }

public LanguageServerSettings()
{
this.ScriptAnalysis = new ScriptAnalysisSettings();
this.CodeFormatting = new CodeFormattingSettings();
this.CodeFolding = new CodeFoldingSettings();
}

public void Update(
Expand All @@ -39,6 +42,7 @@ public void Update(
workspaceRootPath,
logger);
this.CodeFormatting = new CodeFormattingSettings(settings.CodeFormatting);
this.CodeFolding.Update(settings.CodeFolding, logger);
}
}
}
Expand Down Expand Up @@ -261,6 +265,48 @@ private Hashtable GetCustomPSSASettingsHashtable(int tabSize, bool insertSpaces)
}
}

/// <summary>
/// Code folding settings
/// </summary>
public class CodeFoldingSettings
{
/// <summary>
/// Whether the folding is enabled. Default is true as per VSCode
/// </summary>
public bool Enable { get; set; } = true;

/// <summary>
/// Whether to show or hide the last line of a folding region. Default is true as per VSCode
/// </summary>
public bool ShowLastLine { get; set; } = true;

/// <summary>
/// Settings constructor; including the default settings.
/// </summary>
public CodeFoldingSettings()
{
}

/// <summary>
/// Update these settings from another settings object
/// </summary>
public void Update(
CodeFoldingSettings settings,
ILogger logger)
{
if (settings != null) {
if (settings.Enable != null) {
this.Enable = settings.Enable;
logger.Write(LogLevel.Verbose, string.Format("Using Code Folding Enabled - {0}", this.Enable));
}
if (settings.ShowLastLine != null) {
this.ShowLastLine = settings.ShowLastLine;
logger.Write(LogLevel.Verbose, string.Format("Using Code Folding ShowLastLine - {0}", this.ShowLastLine));
}
}
}
}

public class LanguageServerSettingsWrapper
{
// NOTE: This property is capitalized as 'Powershell' because the
Expand Down
11 changes: 10 additions & 1 deletion src/PowerShellEditorServices/Language/TokenOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ internal static class TokenOperations
/// <summary>
/// Extracts all of the unique foldable regions in a script given the list tokens
/// </summary>
static public FoldingReference[] FoldableRegions(Token[] tokens) {
static public FoldingReference[] FoldableRegions(
Token[] tokens,
bool ShowLastLine)
{
List<FoldingReference> foldableRegions = new List<FoldingReference>();

// Find matching braces { -> }
Expand Down Expand Up @@ -89,6 +92,12 @@ static public FoldingReference[] FoldableRegions(Token[] tokens) {
return (item.StartLine == foldableRegions[index - 1].StartLine);
});

// Some editors have different folding UI, sometimes the lastline should be displayed
// If we do want to show the last line, just change the region to be one line less
if (ShowLastLine) {
foldableRegions.ForEach( item => { item.EndLine--; });
}

return foldableRegions.ToArray();
}

Expand Down
53 changes: 33 additions & 20 deletions test/PowerShellEditorServices.Test/Language/TokenOperationsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ public class TokenOperationsTests
/// <summary>
/// Helper methiod to create a stub script file and then call FoldableRegions
/// </summary>
private FoldingReference[] GetRegions(string text) {
private FoldingReference[] GetRegions(string text, bool showLastLine = true) {
ScriptFile scriptFile = new ScriptFile(
"testfile",
"clienttestfile",
text,
Version.Parse("5.0"));
return Microsoft.PowerShell.EditorServices.TokenOperations.FoldableRegions(scriptFile.ScriptTokens);
return Microsoft.PowerShell.EditorServices.TokenOperations.FoldableRegions(scriptFile.ScriptTokens, showLastLine);
}

// This PowerShell script will exercise all of the
Expand Down Expand Up @@ -100,21 +100,21 @@ double quoted herestrings should also fold
$something = $true
#endregion Comment Block 3";
private FoldingReference[] expectedAllInOneScriptFolds = {
new FoldingReference(0, 0, 4, 10, "region"),
new FoldingReference(1, 0, 3, 2, "comment"),
new FoldingReference(10, 0, 15, 2, "comment"),
new FoldingReference(16, 30, 60, 1, null),
new FoldingReference(17, 0, 22, 2, "comment"),
new FoldingReference(23, 7, 26, 2, null),
new FoldingReference(28, 5, 31, 2, null),
new FoldingReference(35, 2, 37, 0, "comment"),
new FoldingReference(39, 2, 49, 14, "region"),
new FoldingReference(41, 4, 45, 14, "region"),
new FoldingReference(51, 7, 53, 3, null),
new FoldingReference(56, 7, 59, 3, null),
new FoldingReference(64, 0, 66, 0, "comment"),
new FoldingReference(67, 0, 72, 26, "region"),
new FoldingReference(68, 0, 70, 0, "comment")
new FoldingReference(0, 0, 3, 10, "region"),
new FoldingReference(1, 0, 2, 2, "comment"),
new FoldingReference(10, 0, 14, 2, "comment"),
new FoldingReference(16, 30, 59, 1, null),
new FoldingReference(17, 0, 21, 2, "comment"),
new FoldingReference(23, 7, 25, 2, null),
new FoldingReference(28, 5, 30, 2, null),
new FoldingReference(35, 2, 36, 0, "comment"),
new FoldingReference(39, 2, 48, 14, "region"),
new FoldingReference(41, 4, 44, 14, "region"),
new FoldingReference(51, 7, 52, 3, null),
new FoldingReference(56, 7, 58, 3, null),
new FoldingReference(64, 0, 65, 0, "comment"),
new FoldingReference(67, 0, 71, 26, "region"),
new FoldingReference(68, 0, 69, 0, "comment")
};

/// <summary>
Expand Down Expand Up @@ -155,6 +155,19 @@ public void LaguageServiceFindsFoldablRegionsWithCRLF() {
AssertFoldingReferenceArrays(expectedAllInOneScriptFolds, result);
}

[Fact]
public void LaguageServiceFindsFoldablRegionsWithoutLastLine() {
FoldingReference[] result = GetRegions(allInOneScript, false);
// Incrememnt the end line of the expected regions by one as we will
// be hiding the last line
FoldingReference[] expectedFolds = expectedAllInOneScriptFolds.Clone() as FoldingReference[];
for (int index = 0; index < expectedFolds.Length; index++)
{
expectedFolds[index].EndLine++;
}
AssertFoldingReferenceArrays(expectedFolds, result);
}

[Fact]
public void LaguageServiceFindsFoldablRegionsWithMismatchedRegions() {
string testString =
Expand All @@ -167,7 +180,7 @@ public void LaguageServiceFindsFoldablRegionsWithMismatchedRegions() {
#region should not fold - mismatched
";
FoldingReference[] expectedFolds = {
new FoldingReference(2, 0, 4, 10, "region")
new FoldingReference(2, 0, 3, 10, "region")
};

FoldingReference[] result = GetRegions(testString);
Expand All @@ -184,8 +197,8 @@ public void LaguageServiceFindsFoldablRegionsWithDuplicateRegions() {
})
";
FoldingReference[] expectedFolds = {
new FoldingReference(1, 64, 2, 27, null),
new FoldingReference(2, 35, 4, 2, null)
new FoldingReference(1, 64, 1, 27, null),
new FoldingReference(2, 35, 3, 2, null)
};

FoldingReference[] result = GetRegions(testString);
Expand Down

0 comments on commit 61014e1

Please sign in to comment.