Line wrapping improvements
This commit is contained in:
parent
4206c1f8d1
commit
6d23aaaef5
62
src/dfmt.d
62
src/dfmt.d
|
|
@ -422,9 +422,7 @@ private:
|
||||||
writeToken();
|
writeToken();
|
||||||
write(" ");
|
write(" ");
|
||||||
}
|
}
|
||||||
immutable size_t i = expressionEndIndex();
|
regenLineBreakHintsIfNecessary(index - 1);
|
||||||
linebreakHints = chooseLineBreakTokens(index, tokens[index .. i],
|
|
||||||
config, currentLineLength, indentLevel);
|
|
||||||
break;
|
break;
|
||||||
case tok!"=":
|
case tok!"=":
|
||||||
case tok!">=":
|
case tok!">=":
|
||||||
|
|
@ -440,15 +438,11 @@ private:
|
||||||
write(" ");
|
write(" ");
|
||||||
writeToken();
|
writeToken();
|
||||||
write(" ");
|
write(" ");
|
||||||
immutable size_t i = expressionEndIndex();
|
regenLineBreakHintsIfNecessary(index - 1);
|
||||||
linebreakHints = chooseLineBreakTokens(index, tokens[index .. i],
|
|
||||||
config, currentLineLength, indentLevel);
|
|
||||||
break;
|
break;
|
||||||
case tok!"&&":
|
case tok!"&&":
|
||||||
case tok!"||":
|
case tok!"||":
|
||||||
immutable size_t i = expressionEndIndex();
|
regenLineBreakHintsIfNecessary(index);
|
||||||
linebreakHints = chooseLineBreakTokens(index, tokens[index .. i],
|
|
||||||
config, currentLineLength, indentLevel);
|
|
||||||
goto case;
|
goto case;
|
||||||
case tok!"^^":
|
case tok!"^^":
|
||||||
case tok!"^=":
|
case tok!"^=":
|
||||||
|
|
@ -506,6 +500,16 @@ private:
|
||||||
assert (false, str(current.type));
|
assert (false, str(current.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void regenLineBreakHintsIfNecessary(immutable size_t i)
|
||||||
|
{
|
||||||
|
if (linebreakHints.length == 0 || linebreakHints[$ - 1] <= i - 1)
|
||||||
|
{
|
||||||
|
immutable size_t j = expressionEndIndex(i);
|
||||||
|
linebreakHints = chooseLineBreakTokens(i, tokens[i .. j],
|
||||||
|
config, currentLineLength, indentLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Pushes a temporary indent level
|
/// Pushes a temporary indent level
|
||||||
void pushIndent()
|
void pushIndent()
|
||||||
{
|
{
|
||||||
|
|
@ -520,14 +524,14 @@ private:
|
||||||
tempIndent--;
|
tempIndent--;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t expressionEndIndex() const pure @safe @nogc
|
size_t expressionEndIndex(size_t i) const pure @safe @nogc
|
||||||
{
|
{
|
||||||
size_t i = index;
|
|
||||||
int parenDepth = 0;
|
int parenDepth = 0;
|
||||||
loop: while (i < tokens.length) switch (tokens[i].type)
|
loop : while (i < tokens.length)
|
||||||
{
|
switch (tokens[i].type)
|
||||||
case tok!"(":
|
{
|
||||||
parenDepth++;
|
case tok!"(":
|
||||||
|
parenDepth++;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
case tok!")":
|
case tok!")":
|
||||||
|
|
@ -616,6 +620,8 @@ private:
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
|
import std.range : assumeSorted;
|
||||||
|
|
||||||
immutable t = tempIndent;
|
immutable t = tempIndent;
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
do
|
do
|
||||||
|
|
@ -631,15 +637,15 @@ private:
|
||||||
{
|
{
|
||||||
writeToken();
|
writeToken();
|
||||||
depth++;
|
depth++;
|
||||||
immutable size_t i = expressionEndIndex();
|
if (!assumeSorted(linebreakHints).equalRange(index - 1).empty
|
||||||
linebreakHints = chooseLineBreakTokens(index, tokens[index .. i],
|
|| (linebreakHints.length == 0
|
||||||
config, currentLineLength, indentLevel);
|
&& currentLineLength > config.columnSoftLimit
|
||||||
if (linebreakHints.length == 0 && currentLineLength > config.columnSoftLimit
|
&& current.type != tok!")"))
|
||||||
&& current.type != tok!")")
|
|
||||||
{
|
{
|
||||||
pushIndent();
|
pushIndent();
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
|
regenLineBreakHintsIfNecessary(index - 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (current.type == tok!")")
|
else if (current.type == tok!")")
|
||||||
|
|
@ -1086,6 +1092,7 @@ bool isBreakToken(IdType t)
|
||||||
case tok!"||":
|
case tok!"||":
|
||||||
case tok!"&&":
|
case tok!"&&":
|
||||||
case tok!"(":
|
case tok!"(":
|
||||||
|
case tok!"[":
|
||||||
case tok!",":
|
case tok!",":
|
||||||
case tok!"^^":
|
case tok!"^^":
|
||||||
case tok!"^=":
|
case tok!"^=":
|
||||||
|
|
@ -1142,6 +1149,7 @@ int breakCost(IdType t)
|
||||||
case tok!"||":
|
case tok!"||":
|
||||||
case tok!"&&":
|
case tok!"&&":
|
||||||
return 0;
|
return 0;
|
||||||
|
case tok!"[":
|
||||||
case tok!"(":
|
case tok!"(":
|
||||||
case tok!",":
|
case tok!",":
|
||||||
return 10;
|
return 10;
|
||||||
|
|
@ -1205,7 +1213,7 @@ struct State
|
||||||
import std.algorithm : map, sum;
|
import std.algorithm : map, sum;
|
||||||
|
|
||||||
this._cost = breaks.map!(b => breakCost(tokens[b].type)).sum()
|
this._cost = breaks.map!(b => breakCost(tokens[b].type)).sum()
|
||||||
+ (depth * 300);
|
+ (depth * 500);
|
||||||
int ll = currentLineLength;
|
int ll = currentLineLength;
|
||||||
size_t breakIndex = 0;
|
size_t breakIndex = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
@ -1287,17 +1295,20 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens,
|
||||||
import std.algorithm : filter, min;
|
import std.algorithm : filter, min;
|
||||||
import core.memory : GC;
|
import core.memory : GC;
|
||||||
|
|
||||||
enum ALGORITHMIC_COMPLEXITY_SUCKS = 20;
|
enum ALGORITHMIC_COMPLEXITY_SUCKS = 25;
|
||||||
immutable size_t tokensEnd = min(tokens.length, ALGORITHMIC_COMPLEXITY_SUCKS);
|
immutable size_t tokensEnd = min(tokens.length, ALGORITHMIC_COMPLEXITY_SUCKS);
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
auto open = new RedBlackTree!State;
|
auto open = new RedBlackTree!State;
|
||||||
open.insert(State(cast(size_t[])[], tokens[0 .. tokensEnd], depth,
|
open.insert(State(cast(size_t[])[], tokens[0 .. tokensEnd], depth,
|
||||||
formatterConfig, currentLineLength, indentLevel));
|
formatterConfig, currentLineLength, indentLevel));
|
||||||
|
State lowest;
|
||||||
GC.disable();
|
GC.disable();
|
||||||
scope(exit) GC.enable();
|
scope(exit) GC.enable();
|
||||||
while (!open.empty)
|
while (!open.empty)
|
||||||
{
|
{
|
||||||
State current = open.front();
|
State current = open.front();
|
||||||
|
if (current.cost < lowest.cost)
|
||||||
|
lowest = current;
|
||||||
open.removeFront();
|
open.removeFront();
|
||||||
if (current.solved)
|
if (current.solved)
|
||||||
{
|
{
|
||||||
|
|
@ -1311,7 +1322,10 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (open.empty)
|
if (open.empty)
|
||||||
return (tokens.length > 0 && isBreakToken(tokens[0].type)) ? [index] : [];
|
{
|
||||||
|
lowest.breaks[] += index;
|
||||||
|
return lowest.breaks;
|
||||||
|
}
|
||||||
foreach (r; open[].filter!(a => a.solved))
|
foreach (r; open[].filter!(a => a.solved))
|
||||||
{
|
{
|
||||||
r.breaks[] += index;
|
r.breaks[] += index;
|
||||||
|
|
@ -1330,7 +1344,7 @@ State[] validMoves(const Token[] tokens, ref const State current,
|
||||||
State[] states;
|
State[] states;
|
||||||
foreach (i, token; tokens)
|
foreach (i, token; tokens)
|
||||||
{
|
{
|
||||||
if (!isBreakToken(token.type) || current.breaks.canFind(i))
|
if (current.breaks.canFind(i) || !isBreakToken(token.type))
|
||||||
continue;
|
continue;
|
||||||
size_t[] breaks;
|
size_t[] breaks;
|
||||||
breaks ~= current.breaks;
|
breaks ~= current.breaks;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import std.stdio, std.random, std.typecons, std.conv, std.string, std.range;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
immutable interval = tuple(1, 100);
|
immutable interval = tuple(1, 100);
|
||||||
writefln("Guess my target number that is between "
|
writefln("Guess my target number that is between " ~ "%d and %d (inclusive).\n",
|
||||||
~ "%d and %d (inclusive).\n", interval[]);
|
interval[]);
|
||||||
immutable target = uniform!"[]"(interval[]);
|
immutable target = uniform!"[]"(interval[]);
|
||||||
foreach (immutable i; sequence!q{n})
|
foreach (immutable i; sequence!q{n})
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
void main(string[] args)
|
||||||
|
{
|
||||||
|
if (prevLocation != size_t.max)
|
||||||
|
{
|
||||||
|
addErrorMessage(line, column, KEY, "Expression %s is true: already checked on line %d.".format(expressions[prevLocation].formatted, expressions[prevLocation].line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
void main(string[] args)
|
||||||
|
{
|
||||||
|
if (prevLocation != size_t.max)
|
||||||
|
{
|
||||||
|
addErrorMessage(line, column, KEY,
|
||||||
|
"Expression %s is true: already checked on line %d.".format(
|
||||||
|
expressions[prevLocation].formatted, expressions[prevLocation].line));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue