1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#!/usr/bin/python
from userinteractor import UserInteractor, UserOption
class HunkSelector:
def __init__(self, patches):
self.standard_options = [
UserOption('n', self.shelve, 'shelve this change for the moment.',
default=True),
UserOption('y', self.keep, 'keep this change in your tree.'),
UserOption('d', UserInteractor.FINISH, 'done, skip to the end.'),
UserOption('i', self.invert,
'invert the current selection of all hunks.'),
UserOption('s', self.status, 'show status of hunks.'),
UserOption('q', UserInteractor.QUIT, 'quit')
]
self.end_options = [
UserOption('y', UserInteractor.FINISH,
'proceed to shelve selected changes.', default=True),
UserOption('r', UserInteractor.RESTART,
'restart the hunk selection loop.'),
UserOption('s', self.status, 'show status of hunks.'),
UserOption('i', self.invert,
'invert the current selection of all hunks.'),
UserOption('q', UserInteractor.QUIT, 'quit')
]
self.patches = patches
self.total_hunks = 0
self.last_printed = -1
self.interactor = UserInteractor()
self.interactor.set_prompt('Keep this change? (%(count)d of %(total)d)')
self.interactor.set_item_callback(self.hunk_callback)
self.interactor.set_start_callback(self.start_callback)
self.interactor.set_end_callback(self.end_callback)
for patch in patches:
for hunk in patch.hunks:
# everything's shelved by default
hunk.selected = True
self.total_hunks += 1
# we need a back pointer in the callbacks
hunk.patch = patch
self.interactor.add_item(hunk)
# Called at the start of the main loop
def start_callback(self):
self.interactor.set_options(self.standard_options)
# Called at the end of the item loop, return False to indicate that the
# interaction isn't finished and the confirmation prompt should be displayed
def end_callback(self):
self.status()
self.interactor.set_prompt("Shelve these changes, or restart?")
self.interactor.set_options(self.end_options)
return False
# Called once for each hunk
def hunk_callback(self, hunk, count):
if self.last_printed != count:
print hunk.patch.get_header(), hunk
self.last_printed = count
if hunk.selected:
self.interactor.get_option('n').default = True
self.interactor.get_option('y').default = False
else:
self.interactor.get_option('n').default = False
self.interactor.get_option('y').default = True
# The user chooses to shelve a hunk
def shelve(self, hunk):
hunk.selected = True
return True
# The user chooses to keep a hunk
def keep(self, hunk):
hunk.selected = False
return True
# The user chooses to invert the selection
def invert(self, hunk):
for patch in self.patches:
for hunk in patch.hunks:
if hunk.__dict__.has_key('selected'):
hunk.selected = not hunk.selected
else:
hunk.selected = True
self.status()
return False
# The user wants to see the status
def status(self, hunk=None):
print '\nStatus:'
for patch in self.patches:
print ' %s' % patch.oldname
shelve = 0
keep = 0
for hunk in patch.hunks:
if hunk.selected:
shelve += 1
else:
keep += 1
print ' %d hunks to be shelved' % shelve
print ' %d hunks to be kept' % keep
print
# Tell the interactor we're not done with this item
return False
def select(self):
if self.total_hunks == 0:
return []
if not self.interactor.interact():
# False from interact means they quit
return []
for patch in self.patches:
tmp = []
for hunk in patch.hunks:
if hunk.selected:
tmp.append(hunk)
patch.hunks = tmp
tmp = []
for patch in self.patches:
if len(patch.hunks):
tmp.append(patch)
self.patches = tmp
return self.patches
|