[refactoring] nimpretty

This commit is contained in:
Araq 2019-07-18 11:00:29 +02:00
commit 5b7273b4f8
2 changed files with 31 additions and 17 deletions

View file

@ -32,7 +32,7 @@ type
ltTab, ltTab,
ltOptionalNewline, ## optional newline introduced by nimpretty ltOptionalNewline, ## optional newline introduced by nimpretty
ltComment, ltLit, ltKeyword, ltExportMarker, ltIdent, ltComment, ltLit, ltKeyword, ltExportMarker, ltIdent,
ltOther, ltOpr, ltOther, ltOpr, ltSomeParLe, ltSomeParRi,
ltBeginSection, ltEndSection ltBeginSection, ltEndSection
Emitter* = object Emitter* = object
@ -142,7 +142,7 @@ proc optionalIsGood(em: var Emitter; pos, currentLen: int): bool =
result = true result = true
elif em.tokens[p+1].len < ourIndent: elif em.tokens[p+1].len < ourIndent:
result = isLongEnough(lineLen, pos, p) result = isLongEnough(lineLen, pos, p)
elif em.kinds[pos+1] == ltOther: # note: pos+1, not p+1 elif em.kinds[pos+1] in {ltOther, ltSomeParLe, ltSomeParRi}: # note: pos+1, not p+1
result = false result = false
else: else:
result = isLongEnough(lineLen, pos, p) result = isLongEnough(lineLen, pos, p)
@ -153,13 +153,21 @@ proc lenOfNextTokens(em: Emitter; pos: int): int =
if em.kinds[pos+i] in {ltCrucialNewline, ltSplittingNewline, ltOptionalNewline}: break if em.kinds[pos+i] in {ltCrucialNewline, ltSplittingNewline, ltOptionalNewline}: break
inc result, em.tokens[pos+i].len inc result, em.tokens[pos+i].len
proc lacksGuidingInd(em: Emitter; pos: int): bool =
result = true
proc closeEmitter*(em: var Emitter) = proc closeEmitter*(em: var Emitter) =
template defaultCase() =
content.add em.tokens[i]
inc lineLen, em.tokens[i].len
let outFile = em.config.absOutFile let outFile = em.config.absOutFile
var content = newStringOfCap(16_000) var content = newStringOfCap(16_000)
var maxLhs = 0 var maxLhs = 0
var lineLen = 0 var lineLen = 0
var lineBegin = 0 var lineBegin = 0
var openPars = 0
var i = 0 var i = 0
while i <= em.tokens.high: while i <= em.tokens.high:
when defined(debug): when defined(debug):
@ -203,6 +211,9 @@ proc closeEmitter*(em: var Emitter) =
content.add "\L" content.add "\L"
content.add em.tokens[i] content.add em.tokens[i]
lineLen = em.tokens[i].len lineLen = em.tokens[i].len
if false: # openPars == 0 or lacksGuidingInd(em, i):
content.add repeat(' ', em.indWidth*2)
lineLen += em.indWidth*2
lineBegin = i+1 lineBegin = i+1
if i+1 < em.kinds.len and em.kinds[i+1] == ltSpaces: if i+1 < em.kinds.len and em.kinds[i+1] == ltSpaces:
# inhibit extra spaces at the start of a new line # inhibit extra spaces at the start of a new line
@ -215,9 +226,15 @@ proc closeEmitter*(em: var Emitter) =
else: else:
inc lineLen, em.tokens[i].len inc lineLen, em.tokens[i].len
content.add em.tokens[i] content.add em.tokens[i]
of ltSomeParLe:
inc openPars
defaultCase()
of ltSomeParRi:
doAssert openPars > 0
dec openPars
defaultCase()
else: else:
content.add em.tokens[i] defaultCase()
inc lineLen, em.tokens[i].len
inc i inc i
if fileExists(outFile) and readFile(outFile.string) == content: if fileExists(outFile) and readFile(outFile.string) == content:
@ -292,7 +309,7 @@ const
tkCurlyLe} tkCurlyLe}
closedPars = {tkParRi, tkParDotRi, closedPars = {tkParRi, tkParDotRi,
tkBracketRi, tkCurlyDotRi, tkBracketRi, tkCurlyDotRi,
tkCurlyRi} tkCurlyRi, tkBracketDotRi}
splitters = openPars + {tkComma, tkSemiColon} # do not add 'tkColon' here! 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,
@ -416,7 +433,8 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
var newlineKind = ltCrucialNewline 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 - {tkBracketDotRi})):
# 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
@ -471,18 +489,14 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
wr(em, TokTypeToStr[tok.tokType], ltOther) wr(em, TokTypeToStr[tok.tokType], ltOther)
rememberSplit(splitComma) rememberSplit(splitComma)
wrSpace em wrSpace em
of tkParDotLe, tkParLe, tkBracketDotLe, tkBracketLe, of openPars:
tkCurlyLe, tkCurlyDotLe, tkBracketLeColon:
if tok.strongSpaceA > 0 and not em.endsInWhite and not em.wasExportMarker: if tok.strongSpaceA > 0 and not em.endsInWhite and not em.wasExportMarker:
wrSpace em wrSpace em
wr(em, TokTypeToStr[tok.tokType], ltOther) wr(em, TokTypeToStr[tok.tokType], ltSomeParLe)
rememberSplit(splitParLe) rememberSplit(splitParLe)
of tkParRi, of closedPars:
tkBracketRi, tkCurlyRi, wr(em, TokTypeToStr[tok.tokType], ltSomeParRi)
tkBracketDotRi, of tkColonColon:
tkCurlyDotRi,
tkParDotRi,
tkColonColon:
wr(em, TokTypeToStr[tok.tokType], ltOther) wr(em, TokTypeToStr[tok.tokType], ltOther)
of tkDot: of tkDot:
lastTokWasTerse = true lastTokWasTerse = true

View file

@ -25,7 +25,7 @@ const
Usage: Usage:
nimpretty [options] file.nim nimpretty [options] file.nim
Options: Options:
--output:file set the output file (default: overwrite the input file) --out:file set the output file (default: overwrite the input file)
--indent:N[=0] set the number of spaces that is used for indentation --indent:N[=0] set the number of spaces that is used for indentation
--indent:0 means autodetection (default behaviour) --indent:0 means autodetection (default behaviour)
--maxLineLen:N set the desired maximum line length (default: 80) --maxLineLen:N set the desired maximum line length (default: 80)
@ -79,7 +79,7 @@ proc main =
of "help", "h": writeHelp() of "help", "h": writeHelp()
of "version", "v": writeVersion() of "version", "v": writeVersion()
of "backup": backup = parseBool(val) of "backup": backup = parseBool(val)
of "output", "o": outfile = val of "output", "o", "out": outfile = val
of "indent": opt.indWidth = parseInt(val) of "indent": opt.indWidth = parseInt(val)
of "maxlinelen": opt.maxLineLen = parseInt(val) of "maxlinelen": opt.maxLineLen = parseInt(val)
else: writeHelp() else: writeHelp()