Skip to content

Commit b86ce2b

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 17f79aa commit b86ce2b

File tree

4 files changed

+105
-22
lines changed

4 files changed

+105
-22
lines changed

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1303,10 +1303,13 @@ protected Task HandleEvaluateRequest(
13031303
private FoldingRange[] Fold(
13041304
string documentUri)
13051305
{
1306+
// TODO Should I be using dynamic registrations?
1307+
if (this.currentSettings.CodeFolding.Enable != true) { return null; }
13061308
// TODO Surely there's a better way to do type adapters?
13071309
List<FoldingRange> result = new List<FoldingRange>();
13081310
foreach (FoldingReference fold in TokenOperations.FoldableRegions(
1309-
editorSession.Workspace.GetFile(documentUri).ScriptTokens))
1311+
editorSession.Workspace.GetFile(documentUri).ScriptTokens,
1312+
this.currentSettings.CodeFolding.ShowLastLine ?? this.currentSettings.CodeFolding.DefaultShowLastLine))
13101313
{
13111314
FoldingRange item = new FoldingRange();
13121315
item.endCharacter = fold.endCharacter;

src/PowerShellEditorServices.Protocol/Server/LanguageServerSettings.cs

+58
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,60 @@ 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
275+
/// </summary>
276+
public bool? Enable { get; set; }
277+
278+
/// <summary>
279+
/// Whether to show or hide the last line of a folding region
280+
/// </summary>
281+
public bool? ShowLastLine { get; set; }
282+
283+
/// <summary>
284+
/// Default value for Enable property. Default is true as per VSCode
285+
/// </summary>
286+
public bool DefaultEnable { get { return true; }}
287+
288+
/// <summary>
289+
/// Default value for ShowLastLine property. Default is true as per VSCode
290+
/// </summary>
291+
public bool DefaultShowLastLine { get { return true; }}
292+
293+
/// <summary>
294+
/// Settings constructor; including the default settings.
295+
/// </summary>
296+
public CodeFoldingSettings()
297+
{
298+
this.Enable = this.DefaultEnable;
299+
this.ShowLastLine = this.DefaultShowLastLine;
300+
}
301+
302+
/// <summary>
303+
/// Update these settings from another settings object
304+
/// </summary>
305+
public void Update(
306+
CodeFoldingSettings settings,
307+
ILogger logger)
308+
{
309+
if (settings != null) {
310+
if (settings.Enable != null) {
311+
this.Enable = settings.Enable;
312+
logger.Write(LogLevel.Verbose, $"Using Code Folding Enabled - '{this.Enable.ToString()}'");
313+
}
314+
if (settings.ShowLastLine != null) {
315+
this.ShowLastLine = settings.ShowLastLine;
316+
logger.Write(LogLevel.Verbose, $"Using Code Folding ShowLastLine - '{this.ShowLastLine.ToString()}'");
317+
}
318+
}
319+
}
320+
}
321+
264322
public class LanguageServerSettingsWrapper
265323
{
266324
// NOTE: This property is capitalized as 'Powershell' because the

src/PowerShellEditorServices/Language/TokenOperations.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ internal static class TokenOperations
1818
/// <summary>
1919
/// Extracts all of the unique foldable regions in a script given the list tokens
2020
/// </summary>
21-
static public FoldingReference[] FoldableRegions(Token[] tokens) {
21+
static public FoldingReference[] FoldableRegions(
22+
Token[] tokens,
23+
bool ShowLastLine)
24+
{
2225
List<FoldingReference> foldableRegions = new List<FoldingReference>();
2326

2427
// Find matching braces { -> }
@@ -89,6 +92,12 @@ static public FoldingReference[] FoldableRegions(Token[] tokens) {
8992
return (item.startLine == foldableRegions[index - 1].startLine);
9093
});
9194

95+
// Some editors have different folding UI, sometimes the lastline should be displayed
96+
// If we do want to show the last line, just change the region to be one line less
97+
if (ShowLastLine) {
98+
foldableRegions.ForEach( item => { item.endLine--; });
99+
}
100+
92101
return foldableRegions.ToArray();
93102
}
94103

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)