Skip to content

Commit 72c43c0

Browse files
committed
实现范围格式化
1 parent cf7bb1d commit 72c43c0

File tree

14 files changed

+200
-13
lines changed

14 files changed

+200
-13
lines changed

CodeFormatServer/src/LanguageService.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ bool LanguageService::Initialize()
2525
_handles["textDocument/formatting"] = DynamicBind(OnFormatting, vscode::DocumentFormattingParams);
2626
_handles["textDocument/didClose"] = DynamicBind(OnClose, vscode::DidCloseTextDocumentParams);
2727
_handles["updateEditorConfig"] = DynamicBind(OnEditorConfigUpdate, vscode::EditorConfigUpdateParams);
28+
_handles["textDocument/rangeFormatting"] = DynamicBind(OnRangeFormatting, vscode::DocumentRangeFormattingParams);
2829
return true;
2930
}
3031

@@ -44,6 +45,7 @@ std::shared_ptr<vscode::InitializeResult> LanguageService::OnInitialize(std::sha
4445
auto result = std::make_shared<vscode::InitializeResult>();
4546

4647
result->capabilities.documentFormattingProvider = true;
48+
result->capabilities.documentRangeFormattingProvider = true;
4749
result->capabilities.textDocumentSync.change = vscode::TextDocumentSyncKind::Full;
4850
result->capabilities.textDocumentSync.openClose = true;
4951

@@ -52,7 +54,7 @@ std::shared_ptr<vscode::InitializeResult> LanguageService::OnInitialize(std::sha
5254
{
5355
LanguageClient::GetInstance().UpdateOptions(configFile.workspace, configFile.path);
5456
}
55-
result->capabilities.codeActionProvider = true;
57+
5658

5759
return result;
5860
}
@@ -144,3 +146,41 @@ std::shared_ptr<vscode::Serializable> LanguageService::OnEditorConfigUpdate(
144146

145147
return nullptr;
146148
}
149+
150+
std::shared_ptr<vscode::Serializable> LanguageService::OnRangeFormatting(
151+
std::shared_ptr<vscode::DocumentRangeFormattingParams> param)
152+
{
153+
auto text = LanguageClient::GetInstance().GetFile(param->textDocument.uri);
154+
155+
auto result = std::make_shared<vscode::DocumentFormattingResult>();
156+
157+
if (text.empty())
158+
{
159+
result->hasError = true;
160+
return result;
161+
}
162+
163+
auto options = LanguageClient::GetInstance().GetOptions(param->textDocument.uri);
164+
165+
std::shared_ptr<LuaParser> parser = LuaParser::LoadFromBuffer(std::move(text));
166+
parser->BuildAstWithComment();
167+
168+
if (parser->HasError())
169+
{
170+
result->hasError = true;
171+
return result;
172+
}
173+
174+
LuaFormatter formatter(parser, *options);
175+
formatter.BuildFormattedElement();
176+
177+
auto& edit = result->edits.emplace_back();
178+
LuaFormatRange formattedRange(param->range.start.line, param->range.end.line);
179+
180+
edit.newText = formatter.GetRangeFormattedText(formattedRange);
181+
edit.range = vscode::Range(
182+
vscode::Position(formattedRange.StartLine, 0),
183+
vscode::Position(formattedRange.EndLine + 1, 0)
184+
);
185+
return result;
186+
}

CodeFormatServer/src/VSCode.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ std::shared_ptr<vscode::Serializable> vscode::MakeFromRequest(std::string_view m
3939
{
4040
return MakeRequestObject<EditorConfigUpdateParams>(json);
4141
}
42+
else if (method == "textDocument/rangeFormatting")
43+
{
44+
return MakeRequestObject<DocumentRangeFormattingParams>(json);
45+
}
4246

4347
return nullptr;
4448
}
@@ -189,7 +193,7 @@ nlohmann::json vscode::ServerCapabilities::Serialize()
189193
auto object = nlohmann::json::object();
190194
object["textDocumentSync"] = textDocumentSync.Serialize();
191195
object["documentFormattingProvider"] = documentFormattingProvider;
192-
// object["codeActionProvider"] = codeActionProvider;
196+
object["documentRangeFormattingProvider"] = documentRangeFormattingProvider;
193197
return object;
194198
}
195199

@@ -327,3 +331,9 @@ void vscode::EditorConfigUpdateParams::Deserialize(nlohmann::json json)
327331
type = json["type"];
328332
source.Deserialize(json["source"]);
329333
}
334+
335+
void vscode::DocumentRangeFormattingParams::Deserialize(nlohmann::json json)
336+
{
337+
textDocument.Deserialize(json["textDocument"]);
338+
range.Deserialize(json["range"]);
339+
}

CodeService/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ target_sources(CodeService
5555
${CodeService_SOURCE_DIR}/src/FormatElement/KeepElement.cpp
5656
${CodeService_SOURCE_DIR}/src/FormatElement/SubExpressionElement.cpp
5757
${CodeService_SOURCE_DIR}/src/FormatElement/DiagnosisContext.cpp
58+
${CodeService_SOURCE_DIR}/src/FormatElement/RangeFormatContext.cpp
5859
${CodeService_SOURCE_DIR}/src/LuaCodeStyleOptions.cpp
5960
${CodeService_SOURCE_DIR}/src/LanguageTranslator.cpp
6061
)

CodeService/src/FormatElement/FormatContext.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "CodeService/FormatElement/FormatContext.h"
2+
#include "CodeService/FormatElement/TextElement.h"
23

34
FormatContext::FormatContext(std::shared_ptr<LuaParser> parser, LuaCodeStyleOptions& options)
45
: _options(options),
@@ -8,15 +9,19 @@ FormatContext::FormatContext(std::shared_ptr<LuaParser> parser, LuaCodeStyleOpti
89
{
910
}
1011

11-
void FormatContext::Print(std::string_view text)
12+
FormatContext::~FormatContext()
13+
{
14+
}
15+
16+
void FormatContext::Print(TextElement& textElement)
1217
{
1318
auto& indentState = _indentStack.top();
1419
if (static_cast<int>(_characterCount) < indentState.Indent)
1520
{
1621
PrintIndent(indentState.Indent - static_cast<int>(_characterCount), indentState.IndentString);
1722
}
18-
_os << text;
19-
_characterCount += text.size();
23+
_os << textElement.GetText();
24+
_characterCount += textElement.GetText().size();
2025
}
2126

2227
void FormatContext::PrintLine(int line)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "CodeService/FormatElement/RangeFormatContext.h"
2+
#include "CodeService/FormatElement/TextElement.h"
3+
4+
RangeFormatContext::RangeFormatContext(std::shared_ptr<LuaParser> parser, LuaCodeStyleOptions& options,
5+
LuaFormatRange validRange)
6+
: FormatContext(parser, options),
7+
_validRange(validRange),
8+
_inFormattedRange(false)
9+
10+
{
11+
}
12+
13+
void RangeFormatContext::Print(TextElement& textElement)
14+
{
15+
int offset = textElement.GetTextRange().StartOffset;
16+
int offsetLine = _parser->GetLine(offset);
17+
if (offsetLine < _validRange.StartLine || offsetLine > _validRange.EndLine)
18+
{
19+
_characterCount += textElement.GetText().size();
20+
_inFormattedRange = false;
21+
return;
22+
}
23+
24+
_inFormattedRange = true;
25+
26+
auto& indentState = _indentStack.top();
27+
if (static_cast<int>(_characterCount) < indentState.Indent)
28+
{
29+
PrintIndent(indentState.Indent - static_cast<int>(_characterCount), indentState.IndentString);
30+
}
31+
_os << textElement.GetText();
32+
_characterCount += textElement.GetText().size();
33+
34+
int endOffsetLine = _parser->GetLine(textElement.GetTextRange().EndOffset);
35+
if (endOffsetLine > _validRange.EndLine)
36+
{
37+
_validRange.EndLine = endOffsetLine;
38+
}
39+
}
40+
41+
void RangeFormatContext::PrintBlank(int blank)
42+
{
43+
for (int i = 0; i < blank; i++)
44+
{
45+
_characterCount++;
46+
}
47+
if (_inFormattedRange)
48+
{
49+
for (int i = 0; i < blank; i++)
50+
{
51+
_os << ' ';
52+
}
53+
}
54+
}
55+
56+
void RangeFormatContext::PrintLine(int line)
57+
{
58+
_characterCount = 0;
59+
if (_inFormattedRange)
60+
{
61+
for (int i = 0; i < line; i++)
62+
{
63+
_os << _options.line_separator;
64+
}
65+
}
66+
}
67+
68+
LuaFormatRange RangeFormatContext::GetFormattedRange()
69+
{
70+
return _validRange;
71+
}

CodeService/src/FormatElement/TextElement.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ FormatElementType TextElement::GetType()
1919

2020
void TextElement::Serialize(FormatContext& ctx, int position, FormatElement& parent)
2121
{
22-
ctx.Print(_text);
22+
ctx.Print(*this);
2323
}
2424

2525
void TextElement::Diagnosis(DiagnosisContext& ctx, int position, FormatElement& parent)

CodeService/src/LuaFormatter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "CodeService/FormatElement/AlignToFirstElement.h"
1313
#include "CodeService/FormatElement/KeepElement.h"
1414
#include "CodeService/FormatElement/LongExpressionLayoutElement.h"
15+
#include "CodeService/FormatElement/RangeFormatContext.h"
1516
#include "CodeService/FormatElement/SubExpressionElement.h"
1617

1718
bool nextMatch(int currentIndex, LuaAstNodeType type, const std::vector<std::shared_ptr<LuaAstNode>>& vec)
@@ -57,6 +58,14 @@ std::string LuaFormatter::GetFormattedText()
5758
return ctx.GetText();
5859
}
5960

61+
std::string LuaFormatter::GetRangeFormattedText(LuaFormatRange validRange)
62+
{
63+
RangeFormatContext ctx(_parser, _options, validRange);
64+
_env->Format(ctx);
65+
66+
return ctx.GetText();
67+
}
68+
6069
std::vector<LuaDiagnosisInfo> LuaFormatter::GetDiagnosisInfos()
6170
{
6271
DiagnosisContext ctx(_parser, _options);

include/CodeFormatServer/LanguageService.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class LanguageService
3232

3333
std::shared_ptr<vscode::Serializable> OnEditorConfigUpdate(std::shared_ptr<vscode::EditorConfigUpdateParams> param);
3434

35+
std::shared_ptr<vscode::Serializable> OnRangeFormatting(std::shared_ptr<vscode::DocumentRangeFormattingParams> param);
36+
3537
std::map<std::string, MessageHandle, std::less<>> _handles;
3638
};
3739

include/CodeFormatServer/VSCode.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class ServerCapabilities : public Serializable
132132
public:
133133
TextDocumentSyncOptions textDocumentSync;
134134
bool documentFormattingProvider = false;
135-
bool codeActionProvider = false;
135+
bool documentRangeFormattingProvider = false;
136136

137137
nlohmann::json Serialize() override;
138138
};
@@ -258,4 +258,14 @@ class EditorConfigUpdateParams : public Serializable
258258

259259
void Deserialize(nlohmann::json json) override;
260260
};
261+
262+
class DocumentRangeFormattingParams: public Serializable
263+
{
264+
public:
265+
TextDocument textDocument;
266+
Range range;
267+
268+
void Deserialize(nlohmann::json json) override;
269+
};
270+
261271
}

include/CodeService/FormatElement/FormatContext.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "CodeService/LuaCodeStyleOptions.h"
88
#include "LuaParser/LuaParser.h"
99

10+
class TextElement;
11+
1012
class FormatContext
1113
{
1214
public:
@@ -17,14 +19,13 @@ class FormatContext
1719
};
1820

1921
FormatContext(std::shared_ptr<LuaParser> parser, LuaCodeStyleOptions& options);
22+
virtual ~FormatContext();
2023

21-
void Print(std::string_view text);
22-
23-
void PrintLine(int line);
24+
virtual void Print(TextElement& textElement);
2425

25-
void PrintBlank(int blank);
26+
virtual void PrintLine(int line);
2627

27-
void PrintIndent(int indent, const std::string& indentString);
28+
virtual void PrintBlank(int blank);
2829

2930
void AddIndent(int specialIndent = -1);
3031

@@ -42,7 +43,9 @@ class FormatContext
4243

4344
std::shared_ptr<LuaParser> GetParser();
4445

45-
private:
46+
protected:
47+
void PrintIndent(int indent, const std::string& indentString);
48+
4649
std::stack<IndentState, std::vector<IndentState>> _indentStack;
4750
std::map<int, std::string> _indentMap;
4851
std::stringstream _os;

0 commit comments

Comments
 (0)