Skip to content

Commit

Permalink
Prefer infix operator at end of line
Browse files Browse the repository at this point in the history
If the second argument of an infix doesn't fit on the current line but
fits on a new line, prefer a newline before the argument over partially
formatting it on the same line as the operator.

This gives a preference to having the operator alone on the end of the
line and nicely lines up parenthesized expressions in general.
  • Loading branch information
arnetheduck committed Feb 5, 2024
1 parent 255dac4 commit 1a7f575
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 46 deletions.
5 changes: 2 additions & 3 deletions src/astcmp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ proc parseString2(
closeParser(p)

proc similarKinds(ak, bk: TNodeKind): bool =
ak == bk or (ak in {nkElseExpr, nkElse} and bk in {nkElseExpr, nkElse}) or (
ak in {nkElifExpr, nkElifBranch} and bk in {nkElifExpr, nkElifBranch}
)
ak == bk or (ak in {nkElseExpr, nkElse} and bk in {nkElseExpr, nkElse}) or
(ak in {nkElifExpr, nkElifBranch} and bk in {nkElifExpr, nkElifBranch})

proc equivalent*(a, b: PNode): Outcome =
if not similarKinds(a.kind, b.kind):
Expand Down
15 changes: 6 additions & 9 deletions src/phlexer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,8 @@ proc getNumber(L: var Lexer, result: var Token) =
else:
lexMessageLitNum(L, "invalid number suffix: '$1'", errPos)
# Is there still a literalish char awaiting? Then it's an error!
if L.buf[postPos] in literalishChars or (
L.buf[postPos] == '.' and L.buf[postPos + 1] in {'0' .. '9'}
):
if L.buf[postPos] in literalishChars or
(L.buf[postPos] == '.' and L.buf[postPos + 1] in {'0' .. '9'}):
lexMessageLitNum(L, "invalid number: '$1'", startpos)

if result.tokType != tkCustomLit:
Expand Down Expand Up @@ -1172,9 +1171,8 @@ proc getSymbol(L: var Lexer, tok: var Token) =

h = !$h
tok.ident = L.cache.getIdent(cast[cstring](addr(L.buf[L.bufpos])), pos - L.bufpos, h)
if (tok.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or (
tok.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)
):
if (tok.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
(tok.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)):
tok.tokType = tkSymbol
else:
tok.tokType = TokType(tok.ident.id + ord(tkSymbol))
Expand Down Expand Up @@ -1604,9 +1602,8 @@ proc rawGetTok*(L: var Lexer, tok: var Token) =
"invalid token: no whitespace between number and identifier"
)
of '-':
if L.buf[L.bufpos + 1] in {'0' .. '9'} and (
L.bufpos - 1 == 0 or L.buf[L.bufpos - 1] in UnaryMinusWhitelist
):
if L.buf[L.bufpos + 1] in {'0' .. '9'} and
(L.bufpos - 1 == 0 or L.buf[L.bufpos - 1] in UnaryMinusWhitelist):
# x)-23 # binary minus
# ,-23 # unary minus
# \n-78 # unary minus? Yes.
Expand Down
10 changes: 4 additions & 6 deletions src/phlineinfos.nim
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,12 @@ type

proc computeNotesVerbosity(): array[0 .. 3, TNoteKinds] =
result[3] =
{low(TNoteKind) .. high(TNoteKind)} - {
warnObservableStores, warnResultUsed, warnAnyEnumConv, warnBareExcept
}
{low(TNoteKind) .. high(TNoteKind)} -
{warnObservableStores, warnResultUsed, warnAnyEnumConv, warnBareExcept}

result[2] =
result[3] - {
hintStackTrace, hintExtendedContext, hintDeclaredLoc, hintProcessingStmt
}
result[3] -
{hintStackTrace, hintExtendedContext, hintDeclaredLoc, hintProcessingStmt}

result[1] =
result[2] - {
Expand Down
7 changes: 3 additions & 4 deletions src/phmsgs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ proc quit(conf: ConfigRef, msg: TMsgKind) {.gcsafe.} =
"""
No stack traceback available
To create a stacktrace, rerun compilation with './koch temp $1 <file>', see $2 for details""" %
[conf.command, "intern.html#debugging-the-compiler".createDocLink],
[conf.command, "intern.html#debugging-the-compiler".createDocLink],
conf.unitSep,
)

Expand All @@ -498,9 +498,8 @@ proc handleError(

quit(conf, msg)

if msg >= errMin and msg <= errMax or (
msg in warnMin .. hintMax and msg in conf.warningAsErrors and not ignoreMsg
):
if msg >= errMin and msg <= errMax or
(msg in warnMin .. hintMax and msg in conf.warningAsErrors and not ignoreMsg):
inc(conf.errorCounter)

conf.exitcode = 1'i8
Expand Down
5 changes: 2 additions & 3 deletions src/phoptions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -771,9 +771,8 @@ proc isDefined*(conf: ConfigRef, symbol: string): bool =
result = CPU[conf.target.targetCPU].bit == 64
of "nimrawsetjmp":
result =
conf.target.targetOS in {
osSolaris, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osMacosx
}
conf.target.targetOS in
{osSolaris, osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osMacosx}
else:
discard

Expand Down
37 changes: 23 additions & 14 deletions src/phrenderer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,8 @@ proc isSimple(n: PNode, allowExported = false, allowInfix = false): bool =
# determines how long the subtree will likely be, the second
# phase appends to a buffer that will be the output.
proc isKeyword*(i: PIdent): bool =
if (i.id >= ord(tokKeywordLow) - ord(tkSymbol)) and (
i.id <= ord(tokKeywordHigh) - ord(tkSymbol)
):
if (i.id >= ord(tokKeywordLow) - ord(tkSymbol)) and
(i.id <= ord(tokKeywordHigh) - ord(tkSymbol)):
result = true

proc initSrcGen(g: var TSrcGen, config: ConfigRef) =
Expand Down Expand Up @@ -412,9 +411,8 @@ proc litAux(g: TOutput, n: PNode, x: BiggestInt, size: int): string =
proc skip(t: PType): PType =
result = t
while result != nil and
result.kind in {
tyGenericInst, tyRange, tyVar, tyLent, tyDistinct, tyOrdinal, tyAlias, tySink
}
result.kind in
{tyGenericInst, tyRange, tyVar, tyLent, tyDistinct, tyOrdinal, tyAlias, tySink}
:
result = lastSon(result)

Expand Down Expand Up @@ -1302,9 +1300,8 @@ proc gident(g: var TOutput, n: PNode) =
var s = atom(g, n)
if s.len > 0 and s[0] in phlexer.SymChars:
if n.kind == nkIdent:
if (n.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or (
n.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)
):
if (n.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
(n.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)):
t = tkSymbol
else:
t = TokType(n.ident.id + ord(tkSymbol))
Expand Down Expand Up @@ -1358,7 +1355,11 @@ proc gsubOptNL(g: var TOutput, n: PNode, indentNL = IndentWidth, flags: SubFlags
isStackedCall(n, false)
)
ind = condIndent(g, nl or g.pendingNL >= 0 or n.prefix.len > 0, indentNL)

flags =
if ind > 0:
{sfNoIndent} + flags
else:
flags
if nl:
optNL(g)
gsub(g, n, flags = flags)
Expand Down Expand Up @@ -1746,10 +1747,18 @@ proc gsub(g: var TOutput, n: PNode, flags: SubFlags, extra: int) =

gsub(g, n[0], flags = flags) # binary operator

doAssert n.len == 3

# `fitsNL` governs a preference to fit an argument fully on a new line over
# leaving parts of it on the same line as the operator.
# This increases the probability that the line will end with an operator and
# not a `(` or some other nlsub-selected line-breaking token
let
overflows =
n.len == 3 and overflows(g, nlsub(g, n[2])) and not infixHasParens(n, 2)
indent = overflows and sfNoIndent notin flags and not hasIndent(n[2])
sublen = lsub(g, n[2])
nsublen = nlsub(g, n[2])
overflows = n.len == 3 and overflows(g, nsublen) and not infixHasParens(n, 2)
fitsNL = overflows(g, sublen) and fits(g, sublen + g.indent)
indent = sfNoIndent notin flags and (fitsNL or overflows and not hasIndent(n[2]))
wid = flagIndent(flags)
flags =
if indent:
Expand All @@ -1761,7 +1770,7 @@ proc gsub(g: var TOutput, n: PNode, flags: SubFlags, extra: int) =

if indent:
indentNL(g, wid)
elif overflows:
elif overflows or fitsNL:
optNL(g)
elif spaces:
optSpace(g)
Expand Down
18 changes: 12 additions & 6 deletions tests/after/exprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,13 @@ if aaaaaaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbb and cccccccccccccccccccccccc
ddddddddddddddddd and fffffffffffffffff:
discard

if (aaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbbbbbbb) or (
ccccccccccccccccccccccccccc and ddddddddddddddddddddd
):
if (aaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbbbbbbb) or
(ccccccccccccccccccccccccccc and ddddddddddddddddddddd):
discard
elif aaaaaaaaa and (
bbbbbbbbbb or
cccccccccccc and (
dddddddddddddddd or eeeeeeeeeeeeeee or fffffffffffffff or gggggggggggggg
)
cccccccccccc and
(dddddddddddddddd or eeeeeeeeeeeeeee or fffffffffffffff or gggggggggggggg)
):
discard

Expand Down Expand Up @@ -164,3 +162,11 @@ let xxxxxxxxx = block:
let yyyyyyyyyy = aaaaaaaaaaaaaaaaaaaaaaaaa.ffffffffffffff(
aaaaaaaaa, bbbbbbbbbbbbbbbbbb, cccccccccccccccccccc
)

discard
aaaaaaaaa and (
aaaaaaaaaaaaaaaaaaaaaaaa and (
aaaaaaaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbb and
(cccccccccccccccccccccc and ddddddddddddddddddd)
)
)
40 changes: 40 additions & 0 deletions tests/after/exprs.nim.nph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1845,3 +1845,43 @@ sons:
ident: "bbbbbbbbbbbbbbbbbb"
- kind: "nkIdent"
ident: "cccccccccccccccccccc"
- kind: "nkDiscardStmt"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "aaaaaaaaa"
- kind: "nkPar"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "aaaaaaaaaaaaaaaaaaaaaaaa"
- kind: "nkPar"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "aaaaaaaaaaaaaaaaaaaaa"
- kind: "nkIdent"
ident: "bbbbbbbbbbbbbbbbbbbbbbb"
- kind: "nkPar"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "cccccccccccccccccccccc"
- kind: "nkIdent"
ident: "ddddddddddddddddddd"
4 changes: 3 additions & 1 deletion tests/before/exprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,6 @@ let xxxxxxxxx = block:
f()
v

let yyyyyyyyyy = aaaaaaaaaaaaaaaaaaaaaaaaa.ffffffffffffff(aaaaaaaaa, bbbbbbbbbbbbbbbbbb, cccccccccccccccccccc)
let yyyyyyyyyy = aaaaaaaaaaaaaaaaaaaaaaaaa.ffffffffffffff(aaaaaaaaa, bbbbbbbbbbbbbbbbbb, cccccccccccccccccccc)

discard aaaaaaaaa and (aaaaaaaaaaaaaaaaaaaaaaaa and (aaaaaaaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbb and (cccccccccccccccccccccc and ddddddddddddddddddd)))
40 changes: 40 additions & 0 deletions tests/before/exprs.nim.nph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1845,3 +1845,43 @@ sons:
ident: "bbbbbbbbbbbbbbbbbb"
- kind: "nkIdent"
ident: "cccccccccccccccccccc"
- kind: "nkDiscardStmt"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "aaaaaaaaa"
- kind: "nkPar"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "aaaaaaaaaaaaaaaaaaaaaaaa"
- kind: "nkPar"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "aaaaaaaaaaaaaaaaaaaaa"
- kind: "nkIdent"
ident: "bbbbbbbbbbbbbbbbbbbbbbb"
- kind: "nkPar"
sons:
- kind: "nkInfix"
sons:
- kind: "nkIdent"
ident: "and"
- kind: "nkIdent"
ident: "cccccccccccccccccccccc"
- kind: "nkIdent"
ident: "ddddddddddddddddddd"

0 comments on commit 1a7f575

Please sign in to comment.