mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-07 04:14:19 +00:00
nimpretty: more features
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
|
||||
## Layouter for nimpretty. Still primitive but useful.
|
||||
## TODO
|
||||
## - Fix 'echo ()' vs 'echo()' difference!
|
||||
## - Make indentations consistent.
|
||||
## - Align 'if' and 'case' expressions properly.
|
||||
|
||||
@@ -31,6 +30,7 @@ type
|
||||
lastTok: TTokType
|
||||
inquote: bool
|
||||
col, lastLineNumber, lineSpan, indentLevel: int
|
||||
doIndentMore*: int
|
||||
content: string
|
||||
fixedUntil: int # marks where we must not go in the content
|
||||
altSplitPos: array[SplitKind, int] # alternative split positions
|
||||
@@ -77,6 +77,8 @@ template rememberSplit(kind) =
|
||||
if goodCol(em.col):
|
||||
em.altSplitPos[kind] = em.content.len
|
||||
|
||||
template moreIndent(em): int = (if em.doIndentMore > 0: 4 else: 2)
|
||||
|
||||
proc softLinebreak(em: var Emitter, lit: string) =
|
||||
# XXX Use an algorithm that is outlined here:
|
||||
# https://llvm.org/devmtg/2013-04/jasper-slides.pdf
|
||||
@@ -85,12 +87,12 @@ proc softLinebreak(em: var Emitter, lit: string) =
|
||||
if em.lastTok in splitters:
|
||||
wr("\L")
|
||||
em.col = 0
|
||||
for i in 1..em.indentLevel+2: wr(" ")
|
||||
for i in 1..em.indentLevel+moreIndent(em): wr(" ")
|
||||
else:
|
||||
# search backwards for a good split position:
|
||||
for a in em.altSplitPos:
|
||||
if a > em.fixedUntil:
|
||||
let ws = "\L" & repeat(' ',em.indentLevel+2)
|
||||
let ws = "\L" & repeat(' ',em.indentLevel+moreIndent(em))
|
||||
em.col = em.content.len - a
|
||||
em.content.insert(ws, a)
|
||||
break
|
||||
@@ -155,15 +157,19 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
|
||||
wr(TokTypeToStr[tok.tokType])
|
||||
wr(" ")
|
||||
rememberSplit(splitComma)
|
||||
of tkParLe, tkParRi, tkBracketLe,
|
||||
tkBracketRi, tkCurlyLe, tkCurlyRi,
|
||||
tkBracketDotLe, tkBracketDotRi,
|
||||
tkCurlyDotLe, tkCurlyDotRi,
|
||||
tkParDotLe, tkParDotRi,
|
||||
tkColonColon, tkDot, tkBracketLeColon:
|
||||
of tkParDotLe, tkParLe, tkBracketDotLe, tkBracketLe,
|
||||
tkCurlyLe, tkCurlyDotLe, tkBracketLeColon:
|
||||
if tok.strongSpaceA > 0 and not em.endsInWhite:
|
||||
wr(" ")
|
||||
wr(TokTypeToStr[tok.tokType])
|
||||
rememberSplit(splitParLe)
|
||||
of tkParRi,
|
||||
tkBracketRi, tkCurlyRi,
|
||||
tkBracketDotRi,
|
||||
tkCurlyDotRi,
|
||||
tkParDotRi,
|
||||
tkColonColon, tkDot:
|
||||
wr(TokTypeToStr[tok.tokType])
|
||||
if tok.tokType in splitters:
|
||||
rememberSplit(splitParLe)
|
||||
of tkEquals:
|
||||
if not em.endsInWhite: wr(" ")
|
||||
wr(TokTypeToStr[tok.tokType])
|
||||
@@ -206,3 +212,13 @@ proc starWasExportMarker*(em: var Emitter) =
|
||||
setLen(em.content, em.content.len-3)
|
||||
em.content.add("*")
|
||||
dec em.col, 2
|
||||
|
||||
proc commaWasSemicolon*(em: var Emitter) =
|
||||
if em.content.endsWith(", "):
|
||||
setLen(em.content, em.content.len-2)
|
||||
em.content.add("; ")
|
||||
|
||||
proc curlyRiWasPragma*(em: var Emitter) =
|
||||
if em.content.endsWith("}"):
|
||||
setLen(em.content, em.content.len-1)
|
||||
em.content.add(".}")
|
||||
|
||||
@@ -408,6 +408,8 @@ proc exprColonEqExpr(p: var TParser): PNode =
|
||||
|
||||
proc exprList(p: var TParser, endTok: TTokType, result: PNode) =
|
||||
#| exprList = expr ^+ comma
|
||||
when defined(nimpretty2):
|
||||
inc p.em.doIndentMore
|
||||
getTok(p)
|
||||
optInd(p, result)
|
||||
# progress guaranteed
|
||||
@@ -417,6 +419,8 @@ proc exprList(p: var TParser, endTok: TTokType, result: PNode) =
|
||||
if p.tok.tokType != tkComma: break
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
when defined(nimpretty2):
|
||||
dec p.em.doIndentMore
|
||||
|
||||
proc exprColonEqExprListAux(p: var TParser, endTok: TTokType, result: PNode) =
|
||||
assert(endTok in {tkCurlyRi, tkCurlyDotRi, tkBracketRi, tkParRi})
|
||||
@@ -837,7 +841,11 @@ proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode =
|
||||
result = parseOperators(p, result, limit, mode)
|
||||
|
||||
proc simpleExpr(p: var TParser, mode = pmNormal): PNode =
|
||||
when defined(nimpretty2):
|
||||
inc p.em.doIndentMore
|
||||
result = simpleExprAux(p, -1, mode)
|
||||
when defined(nimpretty2):
|
||||
dec p.em.doIndentMore
|
||||
|
||||
proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode =
|
||||
#| condExpr = expr colcom expr optInd
|
||||
@@ -912,8 +920,12 @@ proc parsePragma(p: var TParser): PNode =
|
||||
getTok(p)
|
||||
skipComment(p, a)
|
||||
optPar(p)
|
||||
if p.tok.tokType in {tkCurlyDotRi, tkCurlyRi}: getTok(p)
|
||||
else: parMessage(p, "expected '.}'")
|
||||
if p.tok.tokType in {tkCurlyDotRi, tkCurlyRi}:
|
||||
when defined(nimpretty2):
|
||||
curlyRiWasPragma(p.em)
|
||||
getTok(p)
|
||||
else:
|
||||
parMessage(p, "expected '.}'")
|
||||
dec p.inPragma
|
||||
|
||||
proc identVis(p: var TParser; allowDot=false): PNode =
|
||||
@@ -1000,6 +1012,8 @@ proc parseTuple(p: var TParser, indentAllowed = false): PNode =
|
||||
var a = parseIdentColonEquals(p, {})
|
||||
addSon(result, a)
|
||||
if p.tok.tokType notin {tkComma, tkSemiColon}: break
|
||||
when defined(nimpretty2):
|
||||
commaWasSemicolon(p.em)
|
||||
getTok(p)
|
||||
skipComment(p, a)
|
||||
optPar(p)
|
||||
@@ -1034,6 +1048,8 @@ proc parseParamList(p: var TParser, retColon = true): PNode =
|
||||
var a: PNode
|
||||
result = newNodeP(nkFormalParams, p)
|
||||
addSon(result, p.emptyNode) # return type
|
||||
when defined(nimpretty2):
|
||||
inc p.em.doIndentMore
|
||||
let hasParLe = p.tok.tokType == tkParLe and p.tok.indent < 0
|
||||
if hasParLe:
|
||||
getTok(p)
|
||||
@@ -1053,6 +1069,8 @@ proc parseParamList(p: var TParser, retColon = true): PNode =
|
||||
break
|
||||
addSon(result, a)
|
||||
if p.tok.tokType notin {tkComma, tkSemiColon}: break
|
||||
when defined(nimpretty2):
|
||||
commaWasSemicolon(p.em)
|
||||
getTok(p)
|
||||
skipComment(p, a)
|
||||
optPar(p)
|
||||
@@ -1066,6 +1084,8 @@ proc parseParamList(p: var TParser, retColon = true): PNode =
|
||||
elif not retColon and not hasParle:
|
||||
# Mark as "not there" in order to mark for deprecation in the semantic pass:
|
||||
result = p.emptyNode
|
||||
when defined(nimpretty2):
|
||||
dec p.em.doIndentMore
|
||||
|
||||
proc optPragmas(p: var TParser): PNode =
|
||||
if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)):
|
||||
@@ -1668,6 +1688,8 @@ proc parseGenericParamList(p: var TParser): PNode =
|
||||
var a = parseGenericParam(p)
|
||||
addSon(result, a)
|
||||
if p.tok.tokType notin {tkComma, tkSemiColon}: break
|
||||
when defined(nimpretty2):
|
||||
commaWasSemicolon(p.em)
|
||||
getTok(p)
|
||||
skipComment(p, a)
|
||||
optPar(p)
|
||||
|
||||
Reference in New Issue
Block a user