Skip to content

Commit 72dcd9d

Browse files
committed
(GH-793) Add support for Folding Range client settings
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
1 parent 83b4d14 commit 72dcd9d

File tree

4 files changed

+93
-22
lines changed

4 files changed

+93
-22
lines changed

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1301,10 +1301,13 @@ protected Task HandleEvaluateRequest(
13011301
private FoldingRange[] Fold(
13021302
string documentUri)
13031303
{
1304+
// TODO Should I be using dynamic registrations?
1305+
if (this.currentSettings.CodeFolding.Enable != true) { return null; }
13041306
// TODO Surely there's a better way to do type adapters?
13051307
List<FoldingRange> result = new List<FoldingRange>();
13061308
foreach (FoldingReference fold in TokenOperations.FoldableRegions(
1307-
editorSession.Workspace.GetFile(documentUri).ScriptTokens))
1309+
editorSession.Workspace.GetFile(documentUri).ScriptTokens,
1310+
this.currentSettings.CodeFolding.ShowLastLine))
13081311
{
13091312
FoldingRange item = new FoldingRange();
13101313
item.EndCharacter = fold.EndCharacter;

src/PowerShellEditorServices.Protocol/Server/LanguageServerSettings.cs

+46
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ public class LanguageServerSettings
2020

2121
public CodeFormattingSettings CodeFormatting { get; set; }
2222

23+
public CodeFoldingSettings CodeFolding { get; set; }
24+
2325
public LanguageServerSettings()
2426
{
2527
this.ScriptAnalysis = new ScriptAnalysisSettings();
2628
this.CodeFormatting = new CodeFormattingSettings();
29+
this.CodeFolding = new CodeFoldingSettings();
2730
}
2831

2932
public void Update(
@@ -39,6 +42,7 @@ public void Update(
3942
workspaceRootPath,
4043
logger);
4144
this.CodeFormatting = new CodeFormattingSettings(settings.CodeFormatting);
45+
this.CodeFolding.Update(settings.CodeFolding, logger);
4246
}
4347
}
4448
}
@@ -261,6 +265,48 @@ private Hashtable GetCustomPSSASettingsHashtable(int tabSize, bool insertSpaces)
261265
}
262266
}
263267

268+
/// <summary>
269+
/// Code folding settings
270+
/// </summary>
271+
public class CodeFoldingSettings
272+
{
273+
/// <summary>
274+
/// Whether the folding is enabled. Default is true as per VSCode
275+
/// </summary>
276+
public bool Enable { get; set; } = true;
277+
278+
/// <summary>
279+
/// Whether to show or hide the last line of a folding region. Default is true as per VSCode
280+
/// </summary>
281+
public bool ShowLastLine { get; set; } = true;
282+
283+
/// <summary>
284+
/// Settings constructor; including the default settings.
285+
/// </summary>
286+
public CodeFoldingSettings()
287+
{
288+
}
289+
290+
/// <summary>
291+
/// Update these settings from another settings object
292+
/// </summary>
293+
public void Update(
294+
CodeFoldingSettings settings,
295+
ILogger logger)
296+
{
297+
if (settings != null) {
298+
if (settings.Enable != null) {
299+
this.Enable = settings.Enable;
300+
logger.Write(LogLevel.Verbose, string.Format("Using Code Folding Enabled - {0}", this.Enable));
301+
}
302+
if (settings.ShowLastLine != null) {
303+
this.ShowLastLine = settings.ShowLastLine;
304+
logger.Write(LogLevel.Verbose, string.Format("Using Code Folding ShowLastLine - {0}", this.ShowLastLine));
305+
}
306+
}
307+
}
308+
}
309+
264310
public class LanguageServerSettingsWrapper
265311
{
266312
// NOTE: This property is capitalized as 'Powershell' because the

src/PowerShellEditorServices/Language/TokenOperations.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ internal static class TokenOperations
2121
/// <summary>
2222
/// Extracts all of the unique foldable regions in a script given the list tokens
2323
/// </summary>
24-
static public FoldingReference[] FoldableRegions(Token[] tokens) {
24+
static public FoldingReference[] FoldableRegions(
25+
Token[] tokens,
26+
bool ShowLastLine)
27+
{
2528
List<FoldingReference> foldableRegions = new List<FoldingReference>();
2629

2730
// Find matching braces { -> }
@@ -92,6 +95,12 @@ static public FoldingReference[] FoldableRegions(Token[] tokens) {
9295
return (item.StartLine == foldableRegions[index - 1].StartLine);
9396
});
9497

98+
// Some editors have different folding UI, sometimes the lastline should be displayed
99+
// If we do want to show the last line, just change the region to be one line less
100+
if (ShowLastLine) {
101+
foldableRegions.ForEach( item => { item.EndLine--; });
102+
}
103+
95104
return foldableRegions.ToArray();
96105
}
97106

test/PowerShellEditorServices.Test/Language/TokenOperationsTests.cs

+33-20
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ public class TokenOperationsTests
1313
/// <summary>
1414
/// Helper methiod to create a stub script file and then call FoldableRegions
1515
/// </summary>
16-
private FoldingReference[] GetRegions(string text) {
16+
private FoldingReference[] GetRegions(string text, bool showLastLine = true) {
1717
ScriptFile scriptFile = new ScriptFile(
1818
"testfile",
1919
"clienttestfile",
2020
text,
2121
Version.Parse("5.0"));
22-
return Microsoft.PowerShell.EditorServices.TokenOperations.FoldableRegions(scriptFile.ScriptTokens);
22+
return Microsoft.PowerShell.EditorServices.TokenOperations.FoldableRegions(scriptFile.ScriptTokens, showLastLine);
2323
}
2424

2525
// This PowerShell script will exercise all of the
@@ -100,21 +100,21 @@ double quoted herestrings should also fold
100100
$something = $true
101101
#endregion Comment Block 3";
102102
private FoldingReference[] expectedAllInOneScriptFolds = {
103-
new FoldingReference(0, 0, 4, 10, "region"),
104-
new FoldingReference(1, 0, 3, 2, "comment"),
105-
new FoldingReference(10, 0, 15, 2, "comment"),
106-
new FoldingReference(16, 30, 60, 1, null),
107-
new FoldingReference(17, 0, 22, 2, "comment"),
108-
new FoldingReference(23, 7, 26, 2, null),
109-
new FoldingReference(28, 5, 31, 2, null),
110-
new FoldingReference(35, 2, 37, 0, "comment"),
111-
new FoldingReference(39, 2, 49, 14, "region"),
112-
new FoldingReference(41, 4, 45, 14, "region"),
113-
new FoldingReference(51, 7, 53, 3, null),
114-
new FoldingReference(56, 7, 59, 3, null),
115-
new FoldingReference(64, 0, 66, 0, "comment"),
116-
new FoldingReference(67, 0, 72, 26, "region"),
117-
new FoldingReference(68, 0, 70, 0, "comment")
103+
new FoldingReference(0, 0, 3, 10, "region"),
104+
new FoldingReference(1, 0, 2, 2, "comment"),
105+
new FoldingReference(10, 0, 14, 2, "comment"),
106+
new FoldingReference(16, 30, 59, 1, null),
107+
new FoldingReference(17, 0, 21, 2, "comment"),
108+
new FoldingReference(23, 7, 25, 2, null),
109+
new FoldingReference(28, 5, 30, 2, null),
110+
new FoldingReference(35, 2, 36, 0, "comment"),
111+
new FoldingReference(39, 2, 48, 14, "region"),
112+
new FoldingReference(41, 4, 44, 14, "region"),
113+
new FoldingReference(51, 7, 52, 3, null),
114+
new FoldingReference(56, 7, 58, 3, null),
115+
new FoldingReference(64, 0, 65, 0, "comment"),
116+
new FoldingReference(67, 0, 71, 26, "region"),
117+
new FoldingReference(68, 0, 69, 0, "comment")
118118
};
119119

120120
/// <summary>
@@ -155,6 +155,19 @@ public void LaguageServiceFindsFoldablRegionsWithCRLF() {
155155
AssertFoldingReferenceArrays(expectedAllInOneScriptFolds, result);
156156
}
157157

158+
[Fact]
159+
public void LaguageServiceFindsFoldablRegionsWithoutLastLine() {
160+
FoldingReference[] result = GetRegions(allInOneScript, false);
161+
// Incrememnt the end line of the expected regions by one as we will
162+
// be hiding the last line
163+
FoldingReference[] expectedFolds = expectedAllInOneScriptFolds.Clone() as FoldingReference[];
164+
for (int index = 0; index < expectedFolds.Length; index++)
165+
{
166+
expectedFolds[index].EndLine++;
167+
}
168+
AssertFoldingReferenceArrays(expectedFolds, result);
169+
}
170+
158171
[Fact]
159172
public void LaguageServiceFindsFoldablRegionsWithMismatchedRegions() {
160173
string testString =
@@ -167,7 +180,7 @@ public void LaguageServiceFindsFoldablRegionsWithMismatchedRegions() {
167180
#region should not fold - mismatched
168181
";
169182
FoldingReference[] expectedFolds = {
170-
new FoldingReference(2, 0, 4, 10, "region")
183+
new FoldingReference(2, 0, 3, 10, "region")
171184
};
172185

173186
FoldingReference[] result = GetRegions(testString);
@@ -184,8 +197,8 @@ public void LaguageServiceFindsFoldablRegionsWithDuplicateRegions() {
184197
})
185198
";
186199
FoldingReference[] expectedFolds = {
187-
new FoldingReference(1, 64, 2, 27, null),
188-
new FoldingReference(2, 35, 4, 2, null)
200+
new FoldingReference(1, 64, 1, 27, null),
201+
new FoldingReference(2, 35, 3, 2, null)
189202
};
190203

191204
FoldingReference[] result = GetRegions(testString);

0 commit comments

Comments
 (0)