Implemented colored matches.
h3rald h3rald@h3rald.com
Sun, 24 May 2015 10:57:37 +0200
2 files changed,
49 insertions(+),
10 deletions(-)
M
far.nim
→
far.nim
@@ -1,7 +1,9 @@
import slre, parseopt2, - os + os, + terminal, + strutils type StringBounds = array[0..1, int]@@ -12,20 +14,22 @@ filter: string
substitute: string directory: string -proc matchBounds(str, regex: string, offset=0): StringBounds = +system.addQuitProc(resetAttributes) + +proc matchBounds(str, regex: string, start = 0): StringBounds = var c = cast[ptr array[0..9,Capture]](alloc0(sizeof(array[0..9, Capture]))) + var str = str.substr(start).cstring let match = slre_match(("(" & regex & ")").cstring, str.cstring, str.len.cint, c, 10, 0) if match >= 0: - result = [(match-c[0].len+offset), match-1+offset] + result = [match-c[0].len+start, match-1+start] else: result = [-1, match] -proc matchBoundsRec(str, regex: string, offset = 0, matches: var seq[StringBounds]) = - let match = matchBounds(str, regex, offset) +proc matchBoundsRec(str, regex: string, start = 0, matches: var seq[StringBounds]) = + let match = matchBounds(str, regex, start) if match[0] >= 0: matches.add(match) - var off = offset+match[1] - matchBoundsRec(str.substr(off), regex, off, matches) + matchBoundsRec(str, regex, start+match[1]+1, matches) proc match(str, regex: string): bool = var c = cast[ptr array[0..9,Capture]](alloc0(sizeof(array[0..9, Capture])))@@ -41,6 +45,41 @@ elif s[i] == '\10':
inc result inc i +proc displayMatch(str: string, start, finish: int) = + let context_start = max(start-10, 0) + let context_finish = min(finish+10, str.len) + let match: string = str.substr(start, finish) + var context: string = str.substr(context_start, context_finish) + if context_start > 0: + context = "..." & context + if context_finish < str.len: + context = context & "..." + let match_context_start:int = strutils.find(context, match) + let match_context_finish:int = match_context_start+match.len + let line_n = $str.countLines(0, finish+1) + stdout.write(" ") + setForegroundColor(fgYellow, true) + for i in 0..line_n.len: + stdout.write(line_n[i]) + resetAttributes() + stdout.write(": ") + context = context.replace("\n", " ") + for i in 0..context.len: + if i == match_context_start: + setForegroundColor(fgYellow, true) + if i == match_context_finish: + resetAttributes() + stdout.write(context[i]) + stdout.write("\n") + +proc displayFile(str: string) = + stdout.write "[" + setForegroundColor(fgGreen, true) + for i in 0..str.len: + stdout.write(str[i]) + resetAttributes() + stdout.write "]:\n" + ### MAIN var options = FarOptions(regex: nil, recursive: false, filter: nil, substitute: nil, directory: ".")@@ -95,9 +134,9 @@ contents = f.readfile()
contentsLen = contents.len matchBoundsRec(contents, options.regex, 0, matches) if matches.len > 0: - echo "[", count, "] --> " & f + displayFile(f) for match in matches: - echo contents.countLines(0, match[1])+1, ": ", contents.substr(match[0], match[1]) + displayMatch(contents, match[0], match[1]) matches = newSeq[StringBounds](0) echo "=== End: ", count, " files processed."