##// END OF EJS Templates
grep: move match and diff logic to new module...
Yuya Nishihara -
r46288:de6f2afc default
parent child Browse files
Show More
@@ -0,0 +1,71 b''
1 # grep.py - logic for history walk and grep
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
7
8 from __future__ import absolute_import
9
10 import difflib
11
12 from . import pycompat
13
14
15 def matchlines(body, regexp):
16 begin = 0
17 linenum = 0
18 while begin < len(body):
19 match = regexp.search(body, begin)
20 if not match:
21 break
22 mstart, mend = match.span()
23 linenum += body.count(b'\n', begin, mstart) + 1
24 lstart = body.rfind(b'\n', begin, mstart) + 1 or begin
25 begin = body.find(b'\n', mend) + 1 or len(body) + 1
26 lend = begin - 1
27 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
28
29
30 class linestate(object):
31 def __init__(self, line, linenum, colstart, colend):
32 self.line = line
33 self.linenum = linenum
34 self.colstart = colstart
35 self.colend = colend
36
37 def __hash__(self):
38 return hash(self.line)
39
40 def __eq__(self, other):
41 return self.line == other.line
42
43 def findpos(self, regexp):
44 """Iterate all (start, end) indices of matches"""
45 yield self.colstart, self.colend
46 p = self.colend
47 while p < len(self.line):
48 m = regexp.search(self.line, p)
49 if not m:
50 break
51 if m.end() == p:
52 p += 1
53 else:
54 yield m.span()
55 p = m.end()
56
57
58 def difflinestates(a, b):
59 sm = difflib.SequenceMatcher(None, a, b)
60 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
61 if tag == 'insert':
62 for i in pycompat.xrange(blo, bhi):
63 yield (b'+', b[i])
64 elif tag == 'delete':
65 for i in pycompat.xrange(alo, ahi):
66 yield (b'-', a[i])
67 elif tag == 'replace':
68 for i in pycompat.xrange(alo, ahi):
69 yield (b'-', a[i])
70 for i in pycompat.xrange(blo, bhi):
71 yield (b'+', b[i])
@@ -7,7 +7,6 b''
7 7
8 8 from __future__ import absolute_import
9 9
10 import difflib
11 10 import errno
12 11 import os
13 12 import re
@@ -41,6 +40,7 b' from . import ('
41 40 filemerge,
42 41 formatter,
43 42 graphmod,
43 grep as grepmod,
44 44 hbisect,
45 45 help,
46 46 hg,
@@ -3399,48 +3399,6 b' def grep(ui, repo, pattern, *pats, **opt'
3399 3399 sep = eol = b'\0'
3400 3400
3401 3401 getfile = util.lrucachefunc(repo.file)
3402
3403 def matchlines(body, regexp):
3404 begin = 0
3405 linenum = 0
3406 while begin < len(body):
3407 match = regexp.search(body, begin)
3408 if not match:
3409 break
3410 mstart, mend = match.span()
3411 linenum += body.count(b'\n', begin, mstart) + 1
3412 lstart = body.rfind(b'\n', begin, mstart) + 1 or begin
3413 begin = body.find(b'\n', mend) + 1 or len(body) + 1
3414 lend = begin - 1
3415 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3416
3417 class linestate(object):
3418 def __init__(self, line, linenum, colstart, colend):
3419 self.line = line
3420 self.linenum = linenum
3421 self.colstart = colstart
3422 self.colend = colend
3423
3424 def __hash__(self):
3425 return hash(self.line)
3426
3427 def __eq__(self, other):
3428 return self.line == other.line
3429
3430 def findpos(self, regexp):
3431 """Iterate all (start, end) indices of matches"""
3432 yield self.colstart, self.colend
3433 p = self.colend
3434 while p < len(self.line):
3435 m = regexp.search(self.line, p)
3436 if not m:
3437 break
3438 if m.end() == p:
3439 p += 1
3440 else:
3441 yield m.span()
3442 p = m.end()
3443
3444 3402 matches = {}
3445 3403 copies = {}
3446 3404
@@ -3450,25 +3408,10 b' def grep(ui, repo, pattern, *pats, **opt'
3450 3408 if body is None:
3451 3409 return
3452 3410
3453 for lnum, cstart, cend, line in matchlines(body, regexp):
3454 s = linestate(line, lnum, cstart, cend)
3411 for lnum, cstart, cend, line in grepmod.matchlines(body, regexp):
3412 s = grepmod.linestate(line, lnum, cstart, cend)
3455 3413 m.append(s)
3456 3414
3457 def difflinestates(a, b):
3458 sm = difflib.SequenceMatcher(None, a, b)
3459 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3460 if tag == 'insert':
3461 for i in pycompat.xrange(blo, bhi):
3462 yield (b'+', b[i])
3463 elif tag == 'delete':
3464 for i in pycompat.xrange(alo, ahi):
3465 yield (b'-', a[i])
3466 elif tag == 'replace':
3467 for i in pycompat.xrange(alo, ahi):
3468 yield (b'-', a[i])
3469 for i in pycompat.xrange(blo, bhi):
3470 yield (b'+', b[i])
3471
3472 3415 uipathfn = scmutil.getuipathfn(repo)
3473 3416
3474 3417 def display(fm, fn, ctx, pstates, states):
@@ -3493,7 +3436,7 b' def grep(ui, repo, pattern, *pats, **opt'
3493 3436
3494 3437 fieldnamemap = {b'linenumber': b'lineno'}
3495 3438 if diff:
3496 iter = difflinestates(pstates, states)
3439 iter = grepmod.difflinestates(pstates, states)
3497 3440 else:
3498 3441 iter = [(b'', l) for l in states]
3499 3442 for change, l in iter:
General Comments 0
You need to be logged in to leave comments. Login now