Skip to content

Commit 59d02b6

Browse files
committed
实现行宽超过指定宽度尽可能折行的特性
1 parent 871fe48 commit 59d02b6

File tree

9 files changed

+132
-101
lines changed

9 files changed

+132
-101
lines changed

CodeService/src/FormatElement/AlignToFirstElement.cpp

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "CodeService/FormatElement/AlignToFirstElement.h"
22

3+
#include "CodeService/FormatElement/KeepElement.h"
4+
35
AlignToFirstElement::AlignToFirstElement()
46
{
57
}
@@ -62,7 +64,16 @@ void AlignToFirstElement::Serialize(SerializeContext& ctx, ChildIterator selfIt,
6264
ctx.AddIndent(indentState);
6365
}
6466

65-
child->Serialize(ctx, it, *this);
67+
if (child->Is(FormatElementType::KeepElement))
68+
{
69+
auto keepElement = std::dynamic_pointer_cast<KeepElement>(child);
70+
71+
keepElement->AllowBreakLineSerialize(ctx, it, *this);
72+
}
73+
else
74+
{
75+
child->Serialize(ctx, it, *this);
76+
}
6677
}
6778

6879
if (!_children.empty())
@@ -83,43 +94,43 @@ void AlignToFirstElement::Diagnosis(DiagnosisContext& ctx, ChildIterator selfIt,
8394
switch (indentState.Style)
8495
{
8596
case IndentStyle::Space:
86-
{
87-
if (writeCount > indentState.SpaceIndent)
88-
{
89-
indentState.SpaceIndent = writeCount;
90-
}
91-
else
9297
{
93-
indentState.SpaceIndent = ctx.GetColumn(child->GetTextRange().StartOffset);
98+
if (writeCount > indentState.SpaceIndent)
99+
{
100+
indentState.SpaceIndent = writeCount;
101+
}
102+
else
103+
{
104+
indentState.SpaceIndent = ctx.GetColumn(child->GetTextRange().StartOffset);
105+
}
106+
break;
94107
}
95-
break;
96-
}
97108
case IndentStyle::Tab:
98-
{
99-
if (writeCount > indentState.TabIndent)
100-
{
101-
indentState.SpaceIndent += writeCount - indentState.TabIndent;
102-
}
103-
else
104109
{
105-
auto& options = ctx.GetOptions();
106-
auto state = ctx.CalculateIndentState(child->GetTextRange().StartOffset);
107-
if (state.TabIndent < indentState.TabIndent)
110+
if (writeCount > indentState.TabIndent)
108111
{
109-
auto diff = (indentState.TabIndent - state.TabIndent) * options.tab_width;
110-
if (state.SpaceIndent > diff)
111-
{
112-
indentState.SpaceIndent = state.SpaceIndent - diff;
113-
}
112+
indentState.SpaceIndent += writeCount - indentState.TabIndent;
114113
}
115114
else
116115
{
117-
indentState.SpaceIndent = (state.TabIndent - indentState.TabIndent) * options.tab_width +
118-
state.SpaceIndent;
116+
auto& options = ctx.GetOptions();
117+
auto state = ctx.CalculateIndentState(child->GetTextRange().StartOffset);
118+
if (state.TabIndent < indentState.TabIndent)
119+
{
120+
auto diff = (indentState.TabIndent - state.TabIndent) * options.tab_width;
121+
if (state.SpaceIndent > diff)
122+
{
123+
indentState.SpaceIndent = state.SpaceIndent - diff;
124+
}
125+
}
126+
else
127+
{
128+
indentState.SpaceIndent = (state.TabIndent - indentState.TabIndent) * options.tab_width +
129+
state.SpaceIndent;
130+
}
119131
}
132+
break;
120133
}
121-
break;
122-
}
123134
}
124135
ctx.AddIndent(indentState);
125136
}

CodeService/src/FormatElement/AlignmentLayoutElement.cpp

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -76,56 +76,6 @@ int AlignmentLayoutElement::GetAlignPosition(FormatContext& ctx)
7676
return alignOffset + static_cast<int>(indentState.SpaceIndent + indentState.TabIndent);
7777
}
7878

79-
// int AlignmentLayoutElement::GetAlignOffset(FormatContext& ctx)
80-
// {
81-
// int alignSignOffset = 0;
82-
// bool firstContainAlignSign = true;
83-
// // 先寻找等号对齐的位置,并且判断连续的带等号的语句是否应该对齐到等号
84-
// // 连续的带等号的语句是否应该对齐到等号,这个行为应该由连续语句的首行决定
85-
// // 如果被子节点内的其他语句共同决定则很难将连续对齐还原为普通排版
86-
// for (auto statIt = _children.begin(); statIt != _children.end(); ++statIt)
87-
// {
88-
// const auto statement = *statIt;
89-
//
90-
// auto& statementChildren = statement->GetChildren();
91-
//
92-
// for (auto it = statementChildren.begin(); it != statementChildren.end(); ++it)
93-
// {
94-
// auto textChild = *it;
95-
// if (textChild->GetType() == FormatElementType::TextElement)
96-
// {
97-
// const auto textElement = std::dynamic_pointer_cast<TextElement>(textChild);
98-
// if (textElement->GetText() == _alignSign)
99-
// {
100-
// const auto signPosition = ctx.GetColumn(textElement->GetTextRange().StartOffset);
101-
// if (firstContainAlignSign && it != statementChildren.begin())
102-
// {
103-
// firstContainAlignSign = false;
104-
// auto lastStatChild = FindLastValidChild(it, statementChildren);
105-
// if (lastStatChild == nullptr)
106-
// {
107-
// return -1;
108-
// }
109-
//
110-
// const auto lastPosition = ctx.GetColumn(lastStatChild->GetTextRange().EndOffset);
111-
//
112-
// if (signPosition - lastPosition <= 2)
113-
// {
114-
// return -1;
115-
// }
116-
// }
117-
//
118-
//
119-
// alignSignOffset = std::max(alignSignOffset,
120-
// signPosition - ctx.GetColumn(statement->GetTextRange().StartOffset)
121-
// );
122-
// }
123-
// }
124-
// }
125-
// }
126-
// return alignSignOffset;
127-
// }
128-
12979
int AlignmentLayoutElement::GetAlignOffsetWithWeakRule(FormatContext& ctx)
13080
{
13181
int alignSignOffset = 0;

CodeService/src/FormatElement/CallArgsListLayoutElement.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "CodeService/FormatElement/CallArgsListLayoutElement.h"
22

3+
#include "CodeService/FormatElement/KeepElement.h"
4+
35
CallArgsListLayoutElement::CallArgsListLayoutElement()
46
: _hasLineBreak(false)
57
{
@@ -39,6 +41,11 @@ void CallArgsListLayoutElement::Serialize(SerializeContext& ctx, ChildIterator s
3941
{
4042
SerializeSubExpression(ctx, arg, true);
4143
}
44+
else if(arg->Is(FormatElementType::KeepElement))
45+
{
46+
auto keepElement = std::dynamic_pointer_cast<KeepElement>(arg);
47+
keepElement->AllowBreakLineSerialize(ctx, it, *this);
48+
}
4249
else
4350
{
4451
arg->Serialize(ctx, it, *this);
@@ -130,18 +137,21 @@ void CallArgsListLayoutElement::SerializeSubExpression(SerializeContext& ctx, st
130137
{
131138
SerializeSubExpression(ctx, child, false);
132139
}
133-
else
134-
{
135-
child->Serialize(ctx, it, *parent);
136-
}
137-
if (child->Is(FormatElementType::KeepElement))
140+
else if(child->Is(FormatElementType::KeepElement))
138141
{
142+
auto keepElement = std::dynamic_pointer_cast<KeepElement>(child);
143+
144+
keepElement->AllowBreakLineSerialize(ctx, it, *parent);
139145
if (ctx.GetCharacterCount() == 0 && !_hasLineBreak)
140146
{
141147
_hasLineBreak = true;
142148
ctx.AddIndent();
143149
}
144150
}
151+
else
152+
{
153+
child->Serialize(ctx, it, *parent);
154+
}
145155
}
146156
}
147157

CodeService/src/FormatElement/IndentOnLineBreakElement.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "CodeService/FormatElement/IndentOnLineBreakElement.h"
22

3+
#include "CodeService/FormatElement/KeepElement.h"
4+
35
IndentOnLineBreakElement::IndentOnLineBreakElement()
46
: FormatElement(),
57
_hasLineBreak(false)
@@ -15,12 +17,22 @@ void IndentOnLineBreakElement::Serialize(SerializeContext& ctx, ChildIterator se
1517
{
1618
for (auto it = _children.begin(); it != _children.end(); ++it)
1719
{
20+
auto& child = *it;
1821
if (ctx.GetCharacterCount() == 0 && !_hasLineBreak)
1922
{
2023
_hasLineBreak = true;
2124
ctx.AddIndent();
2225
}
23-
(*it)->Serialize(ctx, it, *this);
26+
27+
if (child->Is(FormatElementType::KeepElement))
28+
{
29+
auto keepElement = std::dynamic_pointer_cast<KeepElement>(child);
30+
keepElement->AllowBreakLineSerialize(ctx, it, *this);
31+
}
32+
else
33+
{
34+
child->Serialize(ctx, it, *this);
35+
}
2436
}
2537
if (_hasLineBreak)
2638
{

CodeService/src/FormatElement/KeepElement.cpp

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ void KeepElement::Serialize(SerializeContext& ctx, ChildIterator selfIt,
1717
FormatElement& parent)
1818
{
1919
const int lastElementLine = GetLastValidLine(ctx, selfIt, parent);
20-
2120
const auto nextElement = GetNextValidElement(selfIt, parent);
2221
if (!nextElement)
2322
{
@@ -34,13 +33,6 @@ void KeepElement::Serialize(SerializeContext& ctx, ChildIterator selfIt,
3433
// 这个条件的意思是如果上一个元素和下一个元素没有实质的换行则保持一定的空格
3534
if (nextElementLine == lastElementLine && ctx.GetCharacterCount() != 0)
3635
{
37-
// 暂时不打断
38-
// if (nextElement->GetType() == FormatElementType::TextElement && ctx.ShouldBreakLine(nextRange))
39-
// {
40-
// ctx.PrintLine(1);
41-
// return;
42-
// }
43-
4436
ctx.PrintBlank(_keepBlank);
4537
}
4638
else
@@ -87,3 +79,46 @@ void KeepElement::Diagnosis(DiagnosisContext& ctx, ChildIterator selfIt,
8779
ctx.SetCharacterCount(0);
8880
}
8981
}
82+
83+
void KeepElement::AllowBreakLineSerialize(SerializeContext& ctx, ChildIterator selfIt, FormatElement& parent)
84+
{
85+
if(!_allowContinueIndent)
86+
{
87+
return Serialize(ctx, selfIt, parent);
88+
}
89+
90+
const int lastElementLine = GetLastValidLine(ctx, selfIt, parent);
91+
const auto nextElement = GetNextValidElement(selfIt, parent);
92+
if (!nextElement)
93+
{
94+
return;
95+
}
96+
const auto nextRange = nextElement->GetTextRange();
97+
const int nextElementLine = ctx.GetLine(nextRange.StartOffset);
98+
99+
if (nextElementLine == -1)
100+
{
101+
return;
102+
}
103+
104+
// 这个条件的意思是如果上一个元素和下一个元素没有实质的换行则保持一定的空格
105+
if (nextElementLine == lastElementLine && ctx.GetCharacterCount() != 0)
106+
{
107+
if (ctx.ShouldBreakLine(nextRange))
108+
{
109+
ctx.PrintLine(1);
110+
return;
111+
}
112+
ctx.PrintBlank(_keepBlank);
113+
}
114+
else
115+
{
116+
int line = nextElementLine - lastElementLine;
117+
if (_hasLinebreak)
118+
{
119+
line--;
120+
}
121+
122+
ctx.PrintLine(line);
123+
}
124+
}

CodeService/src/FormatElement/LongExpressionLayoutElement.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,20 @@ void LongExpressionLayoutElement::SerializeSubExpression(SerializeContext& ctx,
4141
{
4242
SerializeSubExpression(ctx, *child);
4343
}
44-
else
45-
{
46-
child->Serialize(ctx, it, parent);
47-
}
48-
if (child->Is(FormatElementType::KeepElement))
44+
else if(child->Is(FormatElementType::KeepElement))
4945
{
5046
auto keepElement = std::dynamic_pointer_cast<KeepElement>(child);
47+
48+
keepElement->AllowBreakLineSerialize(ctx, it, parent);
5149
if (keepElement->AllowContinueIndent() && ctx.GetCharacterCount() == 0 && !_hasContinuation)
5250
{
5351
IndentSubExpression(ctx);
5452
}
5553
}
54+
else
55+
{
56+
child->Serialize(ctx, it, parent);
57+
}
5658
}
5759
}
5860

CodeService/src/LuaFormatter.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ std::shared_ptr<FormatElement> LuaFormatter::FormatExpressionStatement(std::shar
11721172
{
11731173
case LuaAstNodeType::CallExpression:
11741174
{
1175-
env->AddChild(FormatNode(child));
1175+
env->AddChild(FormatCallExpression(child));
11761176
break;
11771177
}
11781178
case LuaAstNodeType::Expression:
@@ -1569,7 +1569,14 @@ std::shared_ptr<FormatElement> LuaFormatter::FormatTableExpression(std::shared_p
15691569
{
15701570
if (tableFieldLayout)
15711571
{
1572-
tableFieldLayout->AddChild(FormatAlignTableField(it, leftBraceLine, children));
1572+
auto fields = FormatAlignTableField(it, leftBraceLine, children);
1573+
if (fields->Is(FormatElementType::ExpressionElement)) {
1574+
tableFieldLayout->AddChildren(fields->GetChildren());
1575+
}
1576+
else
1577+
{
1578+
tableFieldLayout->AddChild(fields);
1579+
}
15731580
tableFieldLayout->Add<KeepElement>(1);
15741581
}
15751582
else
@@ -1597,7 +1604,7 @@ std::shared_ptr<FormatElement> LuaFormatter::FormatTableField(std::shared_ptr<Lu
15971604
eqSignFounded = true;
15981605
env->Add<KeepBlankElement>(1);
15991606
env->Add<TextElement>(child);
1600-
env->Add<KeepBlankElement>(1);
1607+
env->Add<KeepElement>(1);
16011608
}
16021609
else
16031610
{
@@ -1804,7 +1811,7 @@ std::shared_ptr<FormatElement> LuaFormatter::FormatAlignTableField(LuaAstNode::C
18041811
canAlign = false;
18051812
layout->AddChild(FormatNode(current));
18061813
// 此时认为table 不应该考虑对齐到等号
1807-
layout->Add<KeepBlankElement>(1);
1814+
layout->Add<KeepElement>(1);
18081815
}
18091816
else if (current->GetType() == LuaAstNodeType::TableField
18101817
&& nextSibling->GetType() == LuaAstNodeType::TableFieldSep)

include/CodeService/FormatElement/FormatElementType.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ enum class FormatElementType
1818
AlignIfLayoutElement,
1919
StringLiteralElement,
2020
CallArgsListLayoutElement,
21+
NormalTableLayoutElement,
2122

2223
ControlStart,
2324
KeepLineElement,

include/CodeService/FormatElement/KeepElement.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ class KeepElement : public FormatElement
1818

1919
void Serialize(SerializeContext& ctx, ChildIterator selfIt, FormatElement& parent) override;
2020
void Diagnosis(DiagnosisContext& ctx, ChildIterator selfIt, FormatElement& parent) override;
21+
22+
void AllowBreakLineSerialize(SerializeContext& ctx, ChildIterator selfIt, FormatElement& parent);
2123
private:
2224
int _keepBlank;
2325
bool _hasLinebreak;
2426
bool _allowContinueIndent;
2527
};
28+

0 commit comments

Comments
 (0)