nimpretty: nimpretty now understands splitting newlines
This commit is contained in:
parent
7d29f8b1a4
commit
a59f0adc50
2 changed files with 34 additions and 8 deletions
|
|
@ -143,6 +143,8 @@ proc closeEmitter*(em: var Emitter) =
|
||||||
var lineBegin = 0
|
var lineBegin = 0
|
||||||
var i = 0
|
var i = 0
|
||||||
while i <= em.tokens.high:
|
while i <= em.tokens.high:
|
||||||
|
when defined(debug):
|
||||||
|
echo "i-th token ", em.kinds[i], " ", em.tokens[i]
|
||||||
case em.kinds[i]
|
case em.kinds[i]
|
||||||
of ltBeginSection:
|
of ltBeginSection:
|
||||||
maxLhs = computeMax(em, lineBegin)
|
maxLhs = computeMax(em, lineBegin)
|
||||||
|
|
@ -219,11 +221,24 @@ proc wr(em: var Emitter; x: string; lt: LayoutToken) =
|
||||||
inc em.col, x.len
|
inc em.col, x.len
|
||||||
assert em.tokens.len == em.kinds.len
|
assert em.tokens.len == em.kinds.len
|
||||||
|
|
||||||
proc wrNewline(em: var Emitter) =
|
proc wrNewline(em: var Emitter; kind = ltCrucialNewline) =
|
||||||
em.tokens.add "\L"
|
em.tokens.add "\L"
|
||||||
em.kinds.add ltCrucialNewline
|
em.kinds.add kind
|
||||||
em.col = 0
|
em.col = 0
|
||||||
|
|
||||||
|
proc newlineWasSplitting*(em: var Emitter) =
|
||||||
|
if em.kinds.len >= 3 and em.kinds[^3] == ltCrucialNewline:
|
||||||
|
em.kinds[^3] = ltSplittingNewline
|
||||||
|
|
||||||
|
#[
|
||||||
|
Splitting newlines can occur:
|
||||||
|
- after commas, semicolon, '[', '('.
|
||||||
|
- after binary operators, '='.
|
||||||
|
- after ':' type
|
||||||
|
|
||||||
|
We only need parser support for the "after type" case.
|
||||||
|
]#
|
||||||
|
|
||||||
proc wrSpaces(em: var Emitter; spaces: int) =
|
proc wrSpaces(em: var Emitter; spaces: int) =
|
||||||
if spaces > 0:
|
if spaces > 0:
|
||||||
wr(em, strutils.repeat(' ', spaces), ltSpaces)
|
wr(em, strutils.repeat(' ', spaces), ltSpaces)
|
||||||
|
|
@ -261,7 +276,7 @@ const
|
||||||
tkBracketRi, tkCurlyDotRi,
|
tkBracketRi, tkCurlyDotRi,
|
||||||
tkCurlyRi}
|
tkCurlyRi}
|
||||||
|
|
||||||
splitters = openPars + {tkComma, tkSemicolon}
|
splitters = openPars + {tkComma, tkSemicolon} # do not add 'tkColon' here!
|
||||||
oprSet = {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs,
|
oprSet = {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs,
|
||||||
tkIsnot, tkNot, tkOf, tkAs, tkDotDot, tkAnd, tkOr, tkXor}
|
tkIsnot, tkNot, tkOf, tkAs, tkDotDot, tkAnd, tkOr, tkXor}
|
||||||
|
|
||||||
|
|
@ -366,12 +381,14 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
|
||||||
em.fixedUntil = em.tokens.high
|
em.fixedUntil = em.tokens.high
|
||||||
|
|
||||||
elif tok.indent >= 0:
|
elif tok.indent >= 0:
|
||||||
|
var newlineKind = ltCrucialNewline
|
||||||
if em.keepIndents > 0:
|
if em.keepIndents > 0:
|
||||||
em.indentLevel = tok.indent
|
em.indentLevel = tok.indent
|
||||||
elif (em.lastTok in (splitters + oprSet) and tok.tokType notin closedPars):
|
elif (em.lastTok in (splitters + oprSet) and tok.tokType notin closedPars):
|
||||||
# aka: we are in an expression context:
|
# aka: we are in an expression context:
|
||||||
let alignment = max(tok.indent - em.indentStack[^1], 0)
|
let alignment = max(tok.indent - em.indentStack[^1], 0)
|
||||||
em.indentLevel = alignment + em.indentStack.high * em.indWidth
|
em.indentLevel = alignment + em.indentStack.high * em.indWidth
|
||||||
|
newlineKind = ltSplittingNewline
|
||||||
else:
|
else:
|
||||||
if tok.indent > em.indentStack[^1]:
|
if tok.indent > em.indentStack[^1]:
|
||||||
em.indentStack.add tok.indent
|
em.indentStack.add tok.indent
|
||||||
|
|
@ -391,7 +408,7 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
|
||||||
]#
|
]#
|
||||||
# remove trailing whitespace:
|
# remove trailing whitespace:
|
||||||
removeSpaces em
|
removeSpaces em
|
||||||
wrNewline em
|
wrNewline em, newlineKind
|
||||||
for i in 2..tok.line - em.lastLineNumber: wrNewline(em)
|
for i in 2..tok.line - em.lastLineNumber: wrNewline(em)
|
||||||
wrSpaces em, em.indentLevel
|
wrSpaces em, em.indentLevel
|
||||||
em.fixedUntil = em.tokens.high
|
em.fixedUntil = em.tokens.high
|
||||||
|
|
|
||||||
|
|
@ -147,10 +147,17 @@ template withInd(p, body: untyped) =
|
||||||
body
|
body
|
||||||
p.currInd = oldInd
|
p.currInd = oldInd
|
||||||
|
|
||||||
|
template newlineWasSplitting(p: var TParser) =
|
||||||
|
when defined(nimpretty):
|
||||||
|
layouter.newlineWasSplitting(p.em)
|
||||||
|
|
||||||
template realInd(p): bool = p.tok.indent > p.currInd
|
template realInd(p): bool = p.tok.indent > p.currInd
|
||||||
template sameInd(p): bool = p.tok.indent == p.currInd
|
template sameInd(p): bool = p.tok.indent == p.currInd
|
||||||
template sameOrNoInd(p): bool = p.tok.indent == p.currInd or p.tok.indent < 0
|
template sameOrNoInd(p): bool = p.tok.indent == p.currInd or p.tok.indent < 0
|
||||||
|
|
||||||
|
proc validInd(p: var TParser): bool {.inline.} =
|
||||||
|
result = p.tok.indent < 0 or p.tok.indent > p.currInd
|
||||||
|
|
||||||
proc rawSkipComment(p: var TParser, node: PNode) =
|
proc rawSkipComment(p: var TParser, node: PNode) =
|
||||||
if p.tok.tokType == tkComment:
|
if p.tok.tokType == tkComment:
|
||||||
if node != nil:
|
if node != nil:
|
||||||
|
|
@ -367,6 +374,7 @@ proc colonOrEquals(p: var TParser, a: PNode): PNode =
|
||||||
if p.tok.tokType == tkColon:
|
if p.tok.tokType == tkColon:
|
||||||
result = newNodeP(nkExprColonExpr, p)
|
result = newNodeP(nkExprColonExpr, p)
|
||||||
getTok(p)
|
getTok(p)
|
||||||
|
newlineWasSplitting(p)
|
||||||
#optInd(p, result)
|
#optInd(p, result)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
addSon(result, parseExpr(p))
|
addSon(result, parseExpr(p))
|
||||||
|
|
@ -1295,6 +1303,7 @@ proc binaryNot(p: var TParser; a: PNode): PNode =
|
||||||
|
|
||||||
proc parseTypeDesc(p: var TParser): PNode =
|
proc parseTypeDesc(p: var TParser): PNode =
|
||||||
#| typeDesc = simpleExpr ('not' expr)?
|
#| typeDesc = simpleExpr ('not' expr)?
|
||||||
|
newlineWasSplitting(p)
|
||||||
result = simpleExpr(p, pmTypeDesc)
|
result = simpleExpr(p, pmTypeDesc)
|
||||||
result = binaryNot(p, result)
|
result = binaryNot(p, result)
|
||||||
|
|
||||||
|
|
@ -1510,6 +1519,7 @@ proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode =
|
||||||
elif p.tok.indent >= 0 and p.tok.indent <= p.currInd or not isExprStart(p):
|
elif p.tok.indent >= 0 and p.tok.indent <= p.currInd or not isExprStart(p):
|
||||||
# NL terminates:
|
# NL terminates:
|
||||||
addSon(result, p.emptyNode)
|
addSon(result, p.emptyNode)
|
||||||
|
# nimpretty here!
|
||||||
else:
|
else:
|
||||||
var e = parseExpr(p)
|
var e = parseExpr(p)
|
||||||
e = postExprBlocks(p, e)
|
e = postExprBlocks(p, e)
|
||||||
|
|
@ -1722,9 +1732,6 @@ proc parsePattern(p: var TParser): PNode =
|
||||||
result = parseStmt(p)
|
result = parseStmt(p)
|
||||||
eat(p, tkCurlyRi)
|
eat(p, tkCurlyRi)
|
||||||
|
|
||||||
proc validInd(p: var TParser): bool =
|
|
||||||
result = p.tok.indent < 0 or p.tok.indent > p.currInd
|
|
||||||
|
|
||||||
proc parseRoutine(p: var TParser, kind: TNodeKind): PNode =
|
proc parseRoutine(p: var TParser, kind: TNodeKind): PNode =
|
||||||
#| indAndComment = (IND{>} COMMENT)? | COMMENT?
|
#| indAndComment = (IND{>} COMMENT)? | COMMENT?
|
||||||
#| routine = optInd identVis pattern? genericParamList?
|
#| routine = optInd identVis pattern? genericParamList?
|
||||||
|
|
@ -1809,7 +1816,7 @@ proc parseEnum(p: var TParser): PNode =
|
||||||
symPragma = newNodeP(nkPragmaExpr, p)
|
symPragma = newNodeP(nkPragmaExpr, p)
|
||||||
addSon(symPragma, a)
|
addSon(symPragma, a)
|
||||||
addSon(symPragma, pragma)
|
addSon(symPragma, pragma)
|
||||||
|
# nimpretty support here
|
||||||
if p.tok.indent >= 0 and p.tok.indent <= p.currInd:
|
if p.tok.indent >= 0 and p.tok.indent <= p.currInd:
|
||||||
add(result, symPragma)
|
add(result, symPragma)
|
||||||
break
|
break
|
||||||
|
|
@ -2219,6 +2226,7 @@ proc parseStmt(p: var TParser): PNode =
|
||||||
#| stmt = (IND{>} complexOrSimpleStmt^+(IND{=} / ';') DED)
|
#| stmt = (IND{>} complexOrSimpleStmt^+(IND{=} / ';') DED)
|
||||||
#| / simpleStmt ^+ ';'
|
#| / simpleStmt ^+ ';'
|
||||||
if p.tok.indent > p.currInd:
|
if p.tok.indent > p.currInd:
|
||||||
|
# nimpretty support here
|
||||||
result = newNodeP(nkStmtList, p)
|
result = newNodeP(nkStmtList, p)
|
||||||
withInd(p):
|
withInd(p):
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -2295,6 +2303,7 @@ proc parseTopLevelStmt(p: var TParser): PNode =
|
||||||
result = p.emptyNode
|
result = p.emptyNode
|
||||||
# progress guaranteed
|
# progress guaranteed
|
||||||
while true:
|
while true:
|
||||||
|
# nimpretty support here
|
||||||
if p.tok.indent != 0:
|
if p.tok.indent != 0:
|
||||||
if p.firstTok and p.tok.indent < 0: discard
|
if p.firstTok and p.tok.indent < 0: discard
|
||||||
elif p.tok.tokType != tkSemiColon:
|
elif p.tok.tokType != tkSemiColon:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue