Skip to content

Commit 61ec5b2

Browse files
committed
fix flushing, --replace, improve --count
1 parent e5dd663 commit 61ec5b2

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

tools/nimgrep.nim

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ type
103103
TOption = enum
104104
optFind, optReplace, optPeg, optRegex, optRecursive, optConfirm, optStdin,
105105
optWord, optIgnoreCase, optIgnoreStyle, optVerbose, optFilenames,
106-
optRex, optFollow, optLimitChars, optFit
106+
optRex, optFollow, optCount, optLimitChars, optFit
107107
TOptions = set[TOption]
108108
TConfirmEnum = enum
109109
ceAbort, ceYes, ceAll, ceNo, ceNone
@@ -162,7 +162,6 @@ var
162162
options: TOptions = {optRegex}
163163
walkOpt {.threadvar.}: WalkOpt
164164
searchOpt {.threadvar.}: SearchOpt
165-
justCount = false
166165
sortTime = false
167166
sortTimeOrder = SortOrder.Ascending
168167
useWriteStyled = true
@@ -171,7 +170,7 @@ var
171170
linesAfter = 0
172171
linesContext = 0
173172
newLine = false
174-
gVar = (matches: 0, errors: 0, reallyReplace: false)
173+
gVar = (matches: 0, errors: 0, reallyReplace: true)
175174
# gVar - variables that can change during search/replace
176175
nWorkers = 0 # run in single thread by default
177176
searchRequestsChan: Channel[Trequest]
@@ -474,7 +473,11 @@ proc printSubLinesBefore(filename: string, beforeMatch: string, lineBeg: int,
474473

475474
proc getSubLinesAfter(buf: string, mi: MatchInfo): string =
476475
let last = afterPattern(buf, mi.last+1, 1+linesAfter)
477-
result = substr(buf, mi.last+1, last)
476+
let skipByte = # workaround posix: suppress extra line at the end of file
477+
if (last == buf.len-1 and buf.len >= 2 and
478+
buf[^1] == '\l' and buf[^2] != '\c'): 1
479+
else: 0
480+
result = substr(buf, mi.last+1, last - skipByte)
478481

479482
proc printOverflow(filename: string, line: int, curCol: var Column) =
480483
if curCol.overflowMatches > 0:
@@ -494,11 +497,7 @@ proc printSubLinesAfter(filename: string, afterMatch: string, matchLineEnd: int,
494497
# complete the line after the match itself
495498
newLn(curCol)
496499
printOverflow(filename, matchLineEnd, curCol)
497-
#let skipLine = # workaround posix line ending at the end of file
498-
# if last == s.len-1 and s.len >= 2 and s[^1] == '\l' and s[^2] != '\c': 1
499-
# else: 0 TODO:
500-
let skipLine = 0
501-
for i in 1 ..< sLines.len - skipLine:
500+
for i in 1 ..< sLines.len:
502501
lineHeader(filename, matchLineEnd + i, isMatch = false, curCol)
503502
sLines[i].printCropped(curCol, fromLeft = false)
504503
newLn(curCol)
@@ -552,6 +551,7 @@ proc printReplacement(filename: string, buf: string, mi: MatchInfo,
552551
printMatch(fileName, miFixLines, curCol)
553552
printSubLinesAfter(fileName, getSubLinesAfter(buf, miFixLines),
554553
miFixLines.lineEnd, curCol)
554+
if linesAfter + linesBefore >= 2 and not newLine: stdout.write("\n")
555555
stdout.flushFile()
556556

557557
proc replace1match(filename: string, buf: string, mi: MatchInfo, i: int,
@@ -608,14 +608,14 @@ proc printOutput(filename: string, output: Output, curCol: var Column) =
608608
printSubLinesBefore(filename, output.pre, output.match.lineBeg,
609609
curCol, reserveChars(output.match))
610610
printMatch(filename, output.match, curCol)
611-
#flush: TODO
612611
of BlockNextMatch:
613612
printBetweenMatches(filename, output.pre, output.match.lineBeg,
614613
curCol, reserveChars(output.match))
615614
printMatch(filename, output.match, curCol)
616615
of BlockEnd:
617616
printSubLinesAfter(filename, output.blockEnding, output.firstLine, curCol)
618-
if linesAfter + linesBefore >= 2 and not newLine: stdout.write("\n")
617+
if linesAfter + linesBefore >= 2 and not newLine and
618+
optFilenames notin options: stdout.write("\n")
619619

620620
iterator searchFile(pattern: Pattern; filename: string;
621621
buffer: string): Output =
@@ -784,14 +784,14 @@ iterator processFile(searchOptC: SearchOptComp[Pattern], filename: string,
784784
var cnt = 0
785785
for output in searchFile(searchOptC.pattern, filename, buffer):
786786
found = true
787-
if not justCount:
787+
if optCount notin options:
788788
yield output
789789
else:
790790
if output.kind in {BlockFirstMatch, BlockNextMatch}:
791791
inc(cnt)
792-
if justCount and cnt > 0:
792+
if optCount in options and cnt > 0:
793793
yield Output(kind: JustCount, matches: cnt)
794-
if yieldContents and found and not justCount:
794+
if yieldContents and found and optCount notin options:
795795
yield Output(kind: FileContents, buffer: buffer)
796796

797797
proc hasRightFileName(path: string, walkOptC: WalkOptComp[Pattern]): bool =
@@ -925,13 +925,18 @@ template processFileResult(pattern: Pattern; filename: string,
925925
showFilename
926926
if optReplace notin options:
927927
var curCol: Column
928+
var toFlush: bool
928929
for output in fileResult:
929930
updateCounters(output)
931+
toFlush = true
930932
if output.kind notin {Rejected, OpenError, JustCount} and not oneline:
931933
showFilename
932934
if output.kind == JustCount and oneline:
933935
printFile(filename & ":")
934936
printOutput(filename, output, curCol)
937+
if nWorkers == 0 and output.kind in {BlockFirstMatch, BlockNextMatch}:
938+
stdout.flushFile() # flush immediately in single thread mode
939+
if toFlush: stdout.flushFile()
935940
else:
936941
var buffer = ""
937942
var matches: FileResult
@@ -1116,7 +1121,7 @@ for kind, key, val in getopt():
11161121
of "only": searchOpt.checkBin = biOnly
11171122
else: reportError("unknown value for --bin")
11181123
of "text", "t": searchOpt.checkBin = biNo
1119-
of "count": justCount = true
1124+
of "count": incl(options, optCount)
11201125
of "sorttime", "sort-time", "s":
11211126
sortTime = true
11221127
case normalize(val)
@@ -1172,6 +1177,7 @@ for kind, key, val in getopt():
11721177
of cmdEnd: assert(false) # cannot happen
11731178

11741179
checkOptions({optFind, optReplace}, "find", "replace")
1180+
checkOptions({optCount, optReplace}, "count", "replace")
11751181
checkOptions({optPeg, optRegex}, "peg", "re")
11761182
checkOptions({optIgnoreCase, optIgnoreStyle}, "ignore_case", "ignore_style")
11771183
checkOptions({optFilenames, optReplace}, "filenames", "replace")

0 commit comments

Comments
 (0)