all repos — fae @ efef0d1465612c170ec6b591a90f8a6563fbcd9a

A minuscule find and edit utility.

Implemented colored matches.
h3rald h3rald@h3rald.com
Sun, 24 May 2015 10:57:37 +0200
commit

efef0d1465612c170ec6b591a90f8a6563fbcd9a

parent

509fa6dc73769e092281b65d702e27982750d18a

2 files changed, 49 insertions(+), 10 deletions(-)

jump to
M .gitignore.gitignore

@@ -1,2 +1,2 @@

+nimcache far -nimcache/
M far.nimfar.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."