[PATCH 2 of 3] record: add an option to split hunks
Steve Losh
steve at stevelosh.com
Mon Jan 4 18:44:53 CST 2010
# HG changeset patch
# User Steve Losh <steve at stevelosh.com>
# Date 1262652127 18000
# Node ID 4c11455bab391bee9fc7ae8ad9182b46468923c4
# Parent 1fa39ad1ca75699329f538aae321fcdcfbb5dfda
record: add an option to split hunks
diff --git a/hgext/record.py b/hgext/record.py
--- a/hgext/record.py
+++ b/hgext/record.py
@@ -153,7 +153,13 @@
self.hunk = hunk
self.added, self.removed = countchanges(self.hunk)
- def write(self, fp):
+ def write(self, fp, numbered=False):
+ if numbered:
+ _b, _h, _a = self.before, self.hunk, self.after
+ nlen = len(str(len(self.hunk) + 1))
+ self.before = ["%s%s" % (' '*(nlen+2), l) for l in self.before]
+ self.hunk = ["%%%dd: %%s" % nlen % (n, l) for n, l in enumerate(self.hunk)]
+ self.after = ["%s%s" % (' '*(nlen+2), l) for l in self.after]
delta = len(self.before) + len(self.after)
if self.after and self.after[-1] == '\\ No newline at end of file\n':
delta -= 1
@@ -163,6 +169,8 @@
(self.fromline, fromlen, self.toline, tolen,
self.proc and (' ' + self.proc)))
fp.write(''.join(self.before + self.hunk + self.after))
+ if numbered:
+ self.before, self.hunk, self.after = _b, _h, _a
pretty = write
@@ -172,6 +180,11 @@
def __repr__(self):
return '<hunk %r@%d>' % (self.filename(), self.fromline)
+def split_hunk(h, n):
+ h1 = hunk(h.header, h.fromline, h.toline, h.proc, h.before, h.hunk[:n], [])
+ h2 = hunk(h.header, h.fromline + n, h.toline + n, h.proc, [], h.hunk[n:], h.after)
+ return (h1, h2)
+
def parsepatch(fp):
"""patch -> [] of hunks """
class parser(object):
@@ -267,10 +280,11 @@
resp_all = [None] # this two are changed from inside prompt,
resp_file = [None] # so can't be usual variables
applied = {} # 'filename' -> [] of chunks
- def prompt(query):
+ def prompt(query, at_hunk=False):
"""prompt query, and process base inputs
- y/n for the rest of file
+ - p to split the hunk (if at_hunk is True)
- y/n for the rest
- ? (help)
- q (quit)
@@ -287,6 +301,7 @@
all_choices = {
'yes': _('&Yes, record this change'),
'no': _('&No, skip this change'),
+ 'split': _('S&plit this hunk'),
'skip': _('&Skip remaining changes to this file'),
'file': _('Record remaining changes to this &file'),
'done': _('&Done, skip remaining changes and files'),
@@ -294,14 +309,17 @@
'quit': _('&Quit, recording no changes'),
'help': _('&?'),
}
- choices = (all_choices['yes'],
+ choices = [all_choices['yes'],
all_choices['no'],
all_choices['skip'],
all_choices['file'],
all_choices['done'],
all_choices['all'],
all_choices['quit'],
- all_choices['help'],)
+ all_choices['help'],]
+ if at_hunk:
+ choices.insert(2, all_choices['split'])
+ resps = _('[Ynpsfdaq?]')
r = ui.promptchoice("%s %s" % (query, resps), choices)
choice = [k for k in all_choices if all_choices[k] == choices[r]][0]
if choice == 'help':
@@ -309,9 +327,10 @@
c = doc.find(_('y - record this change'))
doc_lines = doc[c:].splitlines()
if not at_hunk:
- doc_lines = [l for l in doc_lines if not l.startswith('p - split')]
+ doc_lines = [l for l in doc_lines
+ if not l.strip().startswith('p - split')]
else:
- doc_lines = filter(
+ doc_lines = map(
lambda l: l.replace('(if you are currently at a hunk)', ''),
doc_lines
)
@@ -322,6 +341,8 @@
ret = True
elif choice == 'no':
ret = False
+ elif choice == 'split':
+ ret = 'split'
elif choice == 'skip':
ret = resp_file[0] = False
elif choice == 'file':
@@ -361,10 +382,26 @@
if resp_file[0] is None and resp_all[0] is None:
chunk.pretty(ui)
r = total == 1 and prompt(_('record this change to %r?') %
- chunk.filename()) \
+ chunk.filename(), at_hunk=True) \
or prompt(_('record change %d/%d to %r?') %
- (pos, total, chunk.filename()))
- if r:
+ (pos, total, chunk.filename()),
+ at_hunk=True)
+ if r == 'split':
+ chunk.pretty(ui, numbered=True)
+ ns = [int(n) for n in raw_input('line numbers? 0 ').split(' ') if n]
+ ns = sorted(list(set(ns)), reverse=True)
+ invalid_ns = map(str, filter(lambda n: n >= len(chunk.hunk) or n < 0, ns))
+ if invalid_ns:
+ ui.write(_('invalid line number: %s\n') % ' '.join(invalid_ns))
+ chunks.append(chunk)
+ continue
+ for n in ns:
+ h1, h2 = split_hunk(chunk, n)
+ chunks.append(h2)
+ chunk = h1
+ total += 1
+ chunks.append(chunk)
+ elif r:
if fixoffset:
chunk = copy.copy(chunk)
chunk.toline += fixoffset
diff --git a/tests/test-record.out b/tests/test-record.out
--- a/tests/test-record.out
+++ b/tests/test-record.out
@@ -184,7 +184,7 @@
9
10
+11
-record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, no EOL
+record this change to 'plain'? [Ynpsfdaq?] % modify end of plain file, no EOL
diff --git a/plain b/plain
1 hunks, 1 lines changed
examine changes to 'plain'? [Ynsfdaq?] @@ -9,3 +9,4 @@
@@ -193,7 +193,7 @@
11
+cf81a2760718a74d44c0c2eecb72f659e63a69c5
\ No newline at end of file
-record this change to 'plain'? [Ynsfdaq?] % modify end of plain file, add EOL
+record this change to 'plain'? [Ynpsfdaq?] % modify end of plain file, add EOL
diff --git a/plain b/plain
1 hunks, 2 lines changed
examine changes to 'plain'? [Ynsfdaq?] @@ -9,4 +9,4 @@
@@ -203,7 +203,7 @@
-cf81a2760718a74d44c0c2eecb72f659e63a69c5
\ No newline at end of file
+cf81a2760718a74d44c0c2eecb72f659e63a69c5
-record this change to 'plain'? [Ynsfdaq?] % modify beginning, trim end, record both
+record this change to 'plain'? [Ynpsfdaq?] % modify beginning, trim end, record both
diff --git a/plain b/plain
2 hunks, 4 lines changed
examine changes to 'plain'? [Ynsfdaq?] @@ -1,4 +1,4 @@
@@ -212,13 +212,13 @@
2
3
4
-record change 1/2 to 'plain'? [Ynsfdaq?] @@ -8,5 +8,3 @@
+record change 1/2 to 'plain'? [Ynpsfdaq?] @@ -8,5 +8,3 @@
8
9
10
-11
-cf81a2760718a74d44c0c2eecb72f659e63a69c5
-record change 2/2 to 'plain'? [Ynsfdaq?]
+record change 2/2 to 'plain'? [Ynpsfdaq?]
changeset: 11:d09ab1967dab
tag: tip
user: test
@@ -255,7 +255,7 @@
7
8
9
-record change 1/2 to 'plain'? [Ynsfdaq?] @@ -4,7 +1,7 @@
+record change 1/2 to 'plain'? [Ynpsfdaq?] @@ -4,7 +1,7 @@
4
5
6
@@ -264,7 +264,7 @@
9
-10
+10.new
-record change 2/2 to 'plain'? [Ynsfdaq?]
+record change 2/2 to 'plain'? [Ynpsfdaq?]
changeset: 12:44516c9708ae
tag: tip
user: test
@@ -291,7 +291,7 @@
4
5
6
-record this change to 'plain'? [Ynsfdaq?]
+record this change to 'plain'? [Ynpsfdaq?]
changeset: 13:3ebbace64a8d
tag: tip
user: test
@@ -323,7 +323,7 @@
7
8
9
-record change 1/2 to 'plain'? [Ynsfdaq?] @@ -1,7 +4,6 @@
+record change 1/2 to 'plain'? [Ynpsfdaq?] @@ -1,7 +4,6 @@
4
5
6
@@ -331,7 +331,7 @@
8
9
-10.new
-record change 2/2 to 'plain'? [Ynsfdaq?] % add to beginning, middle, end
+record change 2/2 to 'plain'? [Ynpsfdaq?] % add to beginning, middle, end
% record beginning, middle
diff --git a/plain b/plain
3 hunks, 7 lines changed
@@ -341,7 +341,7 @@
+3
4
5
-record change 1/3 to 'plain'? [Ynsfdaq?] @@ -1,6 +4,8 @@
+record change 1/3 to 'plain'? [Ynpsfdaq?] @@ -1,6 +4,8 @@
4
5
+5.new
@@ -350,14 +350,14 @@
7
8
9
-record change 2/3 to 'plain'? [Ynsfdaq?] @@ -3,4 +8,6 @@
+record change 2/3 to 'plain'? [Ynpsfdaq?] @@ -3,4 +8,6 @@
6
7
8
9
+10
+11
-record change 3/3 to 'plain'? [Ynsfdaq?]
+record change 3/3 to 'plain'? [Ynpsfdaq?]
changeset: 15:c1c639d8b268
tag: tip
user: test
@@ -388,7 +388,7 @@
9
+10
+11
-record this change to 'plain'? [Ynsfdaq?]
+record this change to 'plain'? [Ynpsfdaq?]
changeset: 16:80b74bbc7808
tag: tip
user: test
@@ -411,7 +411,7 @@
examine changes to 'subdir/a'? [Ynsfdaq?] @@ -1,1 +1,2 @@
a
+a
-record this change to 'subdir/a'? [Ynsfdaq?]
+record this change to 'subdir/a'? [Ynpsfdaq?]
changeset: 18:33ff5c4fb017
tag: tip
user: test
@@ -500,7 +500,7 @@
a
a
+a
-record this change to 'subdir/f1'? [Ynsfdaq?]
+record this change to 'subdir/f1'? [Ynpsfdaq?]
changeset: 22:a891589cb933
tag: tip
user: test
@@ -525,7 +525,7 @@
a
a
+b
-record this change to 'subdir/f1'? [Ynsfdaq?]
+record this change to 'subdir/f1'? [Ynpsfdaq?]
changeset: 23:befa0dae6201
tag: tip
user: test
@@ -551,7 +551,7 @@
a
b
+c
-record this change to 'subdir/f1'? [Ynsfdaq?]
+record this change to 'subdir/f1'? [Ynpsfdaq?]
changeset: 24:8fd83ff53ce6
tag: tip
user: test
@@ -577,7 +577,7 @@
b
c
+d
-record this change to 'subdir/f1'? [Ynsfdaq?]
+record this change to 'subdir/f1'? [Ynpsfdaq?]
changeset: 25:49b3838dc9e7
tag: tip
user: test
More information about the Mercurial-devel
mailing list