Skip to content

Commit ef9925e

Browse files
formatting support
1 parent 63d679c commit ef9925e

File tree

2 files changed

+177
-1
lines changed

2 files changed

+177
-1
lines changed

src/PowerShellEditorServices.Engine/LanguageServer/OmnisharpLanguageServer.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ public async Task StartAsync()
7373
.WithHandler<TextDocumentHandler>()
7474
.WithHandler<GetVersionHandler>()
7575
.WithHandler<ConfigurationHandler>()
76-
.WithHandler<FoldingRangeHandler>();
76+
.WithHandler<FoldingRangeHandler>()
77+
.WithHandler<DocumentFormattingHandler>()
78+
.WithHandler<DocumentRangeFormattingHandler>();
7779
});
7880

7981
_serverStart.SetResult(true);
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.PowerShell.EditorServices;
7+
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
8+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
9+
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
10+
11+
namespace PowerShellEditorServices.Engine.Services.Handlers
12+
{
13+
public class DocumentFormattingHandler : IDocumentFormattingHandler
14+
{
15+
private readonly DocumentSelector _documentSelector = new DocumentSelector(
16+
new DocumentFilter()
17+
{
18+
Pattern = "**/*.ps*1"
19+
}
20+
);
21+
22+
private readonly ILogger _logger;
23+
private readonly AnalysisService _analysisService;
24+
private readonly ConfigurationService _configurationService;
25+
private readonly WorkspaceService _workspaceService;
26+
private DocumentFormattingCapability _capability;
27+
28+
public DocumentFormattingHandler(ILoggerFactory factory, AnalysisService analysisService, ConfigurationService configurationService, WorkspaceService workspaceService)
29+
{
30+
_logger = factory.CreateLogger<DocumentFormattingHandler>();
31+
_analysisService = analysisService;
32+
_configurationService = configurationService;
33+
_workspaceService = workspaceService;
34+
}
35+
36+
public TextDocumentRegistrationOptions GetRegistrationOptions()
37+
{
38+
return new TextDocumentRegistrationOptions
39+
{
40+
DocumentSelector = _documentSelector
41+
};
42+
}
43+
44+
public async Task<TextEditContainer> Handle(DocumentFormattingParams request, CancellationToken cancellationToken)
45+
{
46+
var scriptFile = _workspaceService.GetFile(request.TextDocument.Uri.ToString());
47+
var pssaSettings = _configurationService.CurrentSettings.CodeFormatting.GetPSSASettingsHashtable(
48+
(int)request.Options.TabSize,
49+
request.Options.InsertSpaces);
50+
51+
52+
// TODO raise an error event in case format returns null;
53+
string formattedScript;
54+
Range editRange;
55+
var extent = scriptFile.ScriptAst.Extent;
56+
57+
// todo create an extension for converting range to script extent
58+
editRange = new Range
59+
{
60+
Start = new Position
61+
{
62+
Line = extent.StartLineNumber - 1,
63+
Character = extent.StartColumnNumber - 1
64+
},
65+
End = new Position
66+
{
67+
Line = extent.EndLineNumber - 1,
68+
Character = extent.EndColumnNumber - 1
69+
}
70+
};
71+
72+
formattedScript = await _analysisService.FormatAsync(
73+
scriptFile.Contents,
74+
pssaSettings,
75+
null);
76+
formattedScript = formattedScript ?? scriptFile.Contents;
77+
78+
return new TextEditContainer(new TextEdit
79+
{
80+
NewText = formattedScript,
81+
Range = editRange
82+
});
83+
}
84+
85+
public void SetCapability(DocumentFormattingCapability capability)
86+
{
87+
_capability = capability;
88+
}
89+
}
90+
91+
public class DocumentRangeFormattingHandler : IDocumentRangeFormattingHandler
92+
{
93+
private readonly DocumentSelector _documentSelector = new DocumentSelector(
94+
new DocumentFilter()
95+
{
96+
Pattern = "**/*.ps*1"
97+
}
98+
);
99+
100+
private readonly ILogger _logger;
101+
private readonly AnalysisService _analysisService;
102+
private readonly ConfigurationService _configurationService;
103+
private readonly WorkspaceService _workspaceService;
104+
private DocumentRangeFormattingCapability _capability;
105+
106+
public DocumentRangeFormattingHandler(ILoggerFactory factory, AnalysisService analysisService, ConfigurationService configurationService, WorkspaceService workspaceService)
107+
{
108+
_logger = factory.CreateLogger<DocumentRangeFormattingHandler>();
109+
_analysisService = analysisService;
110+
_configurationService = configurationService;
111+
_workspaceService = workspaceService;
112+
}
113+
114+
public TextDocumentRegistrationOptions GetRegistrationOptions()
115+
{
116+
return new TextDocumentRegistrationOptions
117+
{
118+
DocumentSelector = _documentSelector
119+
};
120+
}
121+
122+
public async Task<TextEditContainer> Handle(DocumentRangeFormattingParams request, CancellationToken cancellationToken)
123+
{
124+
var scriptFile = _workspaceService.GetFile(request.TextDocument.Uri.ToString());
125+
var pssaSettings = _configurationService.CurrentSettings.CodeFormatting.GetPSSASettingsHashtable(
126+
(int)request.Options.TabSize,
127+
request.Options.InsertSpaces);
128+
129+
// TODO raise an error event in case format returns null;
130+
string formattedScript;
131+
Range editRange;
132+
var extent = scriptFile.ScriptAst.Extent;
133+
134+
// TODO create an extension for converting range to script extent
135+
editRange = new Range
136+
{
137+
Start = new Position
138+
{
139+
Line = extent.StartLineNumber - 1,
140+
Character = extent.StartColumnNumber - 1
141+
},
142+
End = new Position
143+
{
144+
Line = extent.EndLineNumber - 1,
145+
Character = extent.EndColumnNumber - 1
146+
}
147+
};
148+
149+
Range range = request.Range;
150+
var rangeList = range == null ? null : new int[] {
151+
(int)range.Start.Line + 1,
152+
(int)range.Start.Character + 1,
153+
(int)range.End.Line + 1,
154+
(int)range.End.Character + 1};
155+
156+
formattedScript = await _analysisService.FormatAsync(
157+
scriptFile.Contents,
158+
pssaSettings,
159+
rangeList);
160+
formattedScript = formattedScript ?? scriptFile.Contents;
161+
162+
return new TextEditContainer(new TextEdit
163+
{
164+
NewText = formattedScript,
165+
Range = editRange
166+
});
167+
}
168+
169+
public void SetCapability(DocumentRangeFormattingCapability capability)
170+
{
171+
_capability = capability;
172+
}
173+
}
174+
}

0 commit comments

Comments
 (0)