Add details to indentation stack
This makes more advanced state handling easily possible. Also moved isWrapIndent/isTempIndent into this, which allows for exceptions for certain tokens and more control.
This commit is contained in:
parent
6e4136a353
commit
053b775cd1
|
@ -1240,8 +1240,13 @@ private:
|
||||||
break;
|
break;
|
||||||
case tok!"]":
|
case tok!"]":
|
||||||
indents.popWrapIndents();
|
indents.popWrapIndents();
|
||||||
if (indents.topIs(tok!"]"))
|
if (indents.topIsTemp(tok!"]"))
|
||||||
newline();
|
{
|
||||||
|
if (!indents.topDetails.mini)
|
||||||
|
newline();
|
||||||
|
else
|
||||||
|
indents.pop();
|
||||||
|
}
|
||||||
writeToken();
|
writeToken();
|
||||||
if (currentIs(tok!"identifier"))
|
if (currentIs(tok!"identifier"))
|
||||||
write(" ");
|
write(" ");
|
||||||
|
@ -1402,7 +1407,7 @@ private:
|
||||||
: tokens[i .. $].countUntil!(t => t.index == r.front) + i;
|
: tokens[i .. $].countUntil!(t => t.index == r.front) + i;
|
||||||
immutable size_t j = min(expressionEndIndex(i), ufcsBreakLocation);
|
immutable size_t j = min(expressionEndIndex(i), ufcsBreakLocation);
|
||||||
// Use magical negative value for array literals and wrap indents
|
// Use magical negative value for array literals and wrap indents
|
||||||
immutable inLvl = (indents.topIsWrap() || indents.topIs(tok!"]")) ? -indentLevel
|
immutable inLvl = (indents.topIsWrap() || indents.topIsTemp(tok!"]")) ? -indentLevel
|
||||||
: indentLevel;
|
: indentLevel;
|
||||||
linebreakHints = chooseLineBreakTokens(i, tokens[i .. j], depths[i .. j],
|
linebreakHints = chooseLineBreakTokens(i, tokens[i .. j], depths[i .. j],
|
||||||
config, currentLineLength, inLvl);
|
config, currentLineLength, inLvl);
|
||||||
|
@ -1528,7 +1533,7 @@ private:
|
||||||
else if (currentIs(tok!"]"))
|
else if (currentIs(tok!"]"))
|
||||||
{
|
{
|
||||||
indents.popWrapIndents();
|
indents.popWrapIndents();
|
||||||
if (indents.topIs(tok!"]"))
|
if (indents.topIsTemp(tok!"]"))
|
||||||
{
|
{
|
||||||
indents.pop();
|
indents.pop();
|
||||||
indentLevel = indents.indentLevel;
|
indentLevel = indents.indentLevel;
|
||||||
|
@ -1671,13 +1676,21 @@ private:
|
||||||
void pushWrapIndent(IdType type = tok!"")
|
void pushWrapIndent(IdType type = tok!"")
|
||||||
{
|
{
|
||||||
immutable t = type == tok!"" ? tokens[index].type : type;
|
immutable t = type == tok!"" ? tokens[index].type : type;
|
||||||
|
IndentStack.Details detail;
|
||||||
|
detail.wrap = isWrapIndent(t);
|
||||||
|
detail.temp = isTempIndent(t);
|
||||||
|
pushWrapIndent(t, detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushWrapIndent(IdType type, IndentStack.Details detail)
|
||||||
|
{
|
||||||
if (parenDepth == 0)
|
if (parenDepth == 0)
|
||||||
{
|
{
|
||||||
if (indents.wrapIndents == 0)
|
if (indents.wrapIndents == 0)
|
||||||
indents.push(t);
|
indents.push(type, detail);
|
||||||
}
|
}
|
||||||
else if (indents.wrapIndents < 1)
|
else if (indents.wrapIndents < 1)
|
||||||
indents.push(t);
|
indents.push(type, detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
const pure @safe @nogc:
|
const pure @safe @nogc:
|
||||||
|
|
|
@ -7,6 +7,8 @@ module dfmt.indentation;
|
||||||
|
|
||||||
import dparse.lexer;
|
import dparse.lexer;
|
||||||
|
|
||||||
|
import std.bitmanip : bitfields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns: true if the given token type is a wrap indent type
|
* Returns: true if the given token type is a wrap indent type
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +31,20 @@ bool isTempIndent(IdType type) pure nothrow @nogc @safe
|
||||||
*/
|
*/
|
||||||
struct IndentStack
|
struct IndentStack
|
||||||
{
|
{
|
||||||
|
static struct Details
|
||||||
|
{
|
||||||
|
mixin(bitfields!(
|
||||||
|
// generally true for all operators except {, case, @, ], (, )
|
||||||
|
bool, "wrap", 1,
|
||||||
|
// temporary indentation which get's reverted when a block starts
|
||||||
|
// generally true for all tokens except ), {, case, @
|
||||||
|
bool, "temp", 1,
|
||||||
|
// emit minimal newlines
|
||||||
|
bool, "mini", 1,
|
||||||
|
bool, "isAA", 1,
|
||||||
|
uint, "", 28));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the indent size at the most recent occurrence of the given indent type
|
* Get the indent size at the most recent occurrence of the given indent type
|
||||||
*/
|
*/
|
||||||
|
@ -55,7 +71,7 @@ struct IndentStack
|
||||||
int tempIndentCount = 0;
|
int tempIndentCount = 0;
|
||||||
for (size_t i = index; i > 0; i--)
|
for (size_t i = index; i > 0; i--)
|
||||||
{
|
{
|
||||||
if (!isWrapIndent(arr[i - 1]) && arr[i - 1] != tok!"]")
|
if (!details[i - 1].wrap && arr[i - 1] != tok!"]")
|
||||||
break;
|
break;
|
||||||
tempIndentCount++;
|
tempIndentCount++;
|
||||||
}
|
}
|
||||||
|
@ -66,8 +82,20 @@ struct IndentStack
|
||||||
* Pushes the given indent type on to the stack.
|
* Pushes the given indent type on to the stack.
|
||||||
*/
|
*/
|
||||||
void push(IdType item) pure nothrow
|
void push(IdType item) pure nothrow
|
||||||
|
{
|
||||||
|
Details detail;
|
||||||
|
detail.wrap = isWrapIndent(item);
|
||||||
|
detail.temp = isTempIndent(item);
|
||||||
|
push(item, detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes the given indent type on to the stack.
|
||||||
|
*/
|
||||||
|
void push(IdType item, Details detail) pure nothrow
|
||||||
{
|
{
|
||||||
arr[index] = item;
|
arr[index] = item;
|
||||||
|
details[index] = detail;
|
||||||
//FIXME this is actually a bad thing to do,
|
//FIXME this is actually a bad thing to do,
|
||||||
//we should not just override when the stack is
|
//we should not just override when the stack is
|
||||||
//at it's limit
|
//at it's limit
|
||||||
|
@ -91,7 +119,7 @@ struct IndentStack
|
||||||
*/
|
*/
|
||||||
void popWrapIndents() pure nothrow @safe @nogc
|
void popWrapIndents() pure nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
while (index > 0 && isWrapIndent(arr[index - 1]))
|
while (index > 0 && details[index - 1].wrap)
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +128,7 @@ struct IndentStack
|
||||||
*/
|
*/
|
||||||
void popTempIndents() pure nothrow @safe @nogc
|
void popTempIndents() pure nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
while (index > 0 && isTempIndent(arr[index - 1]))
|
while (index > 0 && details[index - 1].temp)
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +153,15 @@ struct IndentStack
|
||||||
*/
|
*/
|
||||||
bool topIsTemp()
|
bool topIsTemp()
|
||||||
{
|
{
|
||||||
return index > 0 && index <= arr.length && isTempIndent(arr[index - 1]);
|
return index > 0 && index <= arr.length && details[index - 1].temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns: `true` if the top of the indent stack is a temporary indent with the specified token
|
||||||
|
*/
|
||||||
|
bool topIsTemp(IdType item)
|
||||||
|
{
|
||||||
|
return index > 0 && index <= arr.length && arr[index - 1] == item && details[index - 1].temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,7 +169,15 @@ struct IndentStack
|
||||||
*/
|
*/
|
||||||
bool topIsWrap()
|
bool topIsWrap()
|
||||||
{
|
{
|
||||||
return index > 0 && index <= arr.length && isWrapIndent(arr[index - 1]);
|
return index > 0 && index <= arr.length && details[index - 1].wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns: `true` if the top of the indent stack is a temporary indent with the specified token
|
||||||
|
*/
|
||||||
|
bool topIsWrap(IdType item)
|
||||||
|
{
|
||||||
|
return index > 0 && index <= arr.length && arr[index - 1] == item && details[index - 1].wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,6 +200,11 @@ struct IndentStack
|
||||||
return arr[index - 1];
|
return arr[index - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Details topDetails() const pure nothrow @property @safe @nogc
|
||||||
|
{
|
||||||
|
return details[index - 1];
|
||||||
|
}
|
||||||
|
|
||||||
int indentLevel() const pure nothrow @property @safe @nogc
|
int indentLevel() const pure nothrow @property @safe @nogc
|
||||||
{
|
{
|
||||||
return indentSize();
|
return indentSize();
|
||||||
|
@ -183,6 +232,7 @@ private:
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
||||||
IdType[256] arr;
|
IdType[256] arr;
|
||||||
|
Details[arr.length] details;
|
||||||
|
|
||||||
int indentSize(const size_t k = size_t.max) const pure nothrow @safe @nogc
|
int indentSize(const size_t k = size_t.max) const pure nothrow @safe @nogc
|
||||||
{
|
{
|
||||||
|
@ -196,17 +246,17 @@ private:
|
||||||
{
|
{
|
||||||
immutable int pc = (arr[i] == tok!"!" || arr[i] == tok!"(" || arr[i] == tok!")") ? parenCount + 1
|
immutable int pc = (arr[i] == tok!"!" || arr[i] == tok!"(" || arr[i] == tok!")") ? parenCount + 1
|
||||||
: parenCount;
|
: parenCount;
|
||||||
if ((isWrapIndent(arr[i]) || arr[i] == tok!"(") && parenCount > 1)
|
if ((details[i].wrap || arr[i] == tok!"(") && parenCount > 1)
|
||||||
{
|
{
|
||||||
parenCount = pc;
|
parenCount = pc;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i + 1 < index)
|
if (i + 1 < index)
|
||||||
{
|
{
|
||||||
if (arr[i] == tok!"]")
|
if (arr[i] == tok!"]" && details[i].temp)
|
||||||
continue;
|
continue;
|
||||||
immutable currentIsNonWrapTemp = !isWrapIndent(arr[i])
|
immutable currentIsNonWrapTemp = !details[i].wrap
|
||||||
&& isTempIndent(arr[i]) && arr[i] != tok!")" && arr[i] != tok!"!";
|
&& details[i].temp && arr[i] != tok!")" && arr[i] != tok!"!";
|
||||||
if (arr[i] == tok!"static"
|
if (arr[i] == tok!"static"
|
||||||
&& arr[i + 1].among!(tok!"if", tok!"else", tok!"foreach", tok!"foreach_reverse")
|
&& arr[i + 1].among!(tok!"if", tok!"else", tok!"foreach", tok!"foreach_reverse")
|
||||||
&& (i + 2 >= index || arr[i + 2] != tok!"{"))
|
&& (i + 2 >= index || arr[i + 2] != tok!"{"))
|
||||||
|
|
Loading…
Reference in New Issue