0.1.18
by Michael Ellerman
Split out HunkSelector class. |
1 |
#!/usr/bin/python
|
2 |
||
0.3.5
by Aaron Bentley
Add colorizing to shelf |
3 |
import sys |
4 |
||
0.1.48
by Michael Ellerman
Move UserInteractor into a seperate file. |
5 |
from userinteractor import UserInteractor, UserOption |
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
6 |
import copy |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
7 |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
8 |
class HunkSelector: |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
9 |
strings = {} |
10 |
||
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
11 |
def __init__(self, patches): |
0.3.5
by Aaron Bentley
Add colorizing to shelf |
12 |
try: |
13 |
from colordiff import DiffWriter |
|
14 |
from terminal import has_ansi_colors |
|
15 |
if has_ansi_colors(): |
|
16 |
self.diff_stream = DiffWriter(sys.stdout) |
|
17 |
else: |
|
18 |
self.diff_stream = sys.stdout |
|
19 |
except ImportError: |
|
20 |
self.diff_stream = sys.stdout |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
21 |
self.standard_options = [ |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
22 |
UserOption('y', self._selected, self.strings['select_desc'], |
23 |
default=True), |
|
24 |
UserOption('n', self._unselected, self.strings['unselect_desc']), |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
25 |
UserOption('d', UserInteractor.FINISH, 'done, skip to the end.'), |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
26 |
UserOption('i', self._invert, |
0.1.49
by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully |
27 |
'invert the current selection status of all hunks.'), |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
28 |
UserOption('s', self._status, |
29 |
'show selection status of all hunks.'), |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
30 |
UserOption('q', UserInteractor.QUIT, 'quit') |
31 |
]
|
|
32 |
||
33 |
self.end_options = [ |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
34 |
UserOption('y', UserInteractor.FINISH, self.strings['finish_desc'], |
35 |
default=True), |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
36 |
UserOption('r', UserInteractor.RESTART, |
37 |
'restart the hunk selection loop.'), |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
38 |
UserOption('s', self._status, |
39 |
'show selection status of all hunks.'), |
|
40 |
UserOption('i', self._invert, |
|
0.1.49
by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully |
41 |
'invert the current selection status of all hunks.'), |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
42 |
UserOption('q', UserInteractor.QUIT, 'quit') |
43 |
]
|
|
44 |
||
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
45 |
self.patches = patches |
46 |
self.total_hunks = 0 |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
47 |
|
48 |
self.interactor = UserInteractor() |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
49 |
self.interactor.set_item_callback(self._hunk_callback) |
50 |
self.interactor.set_start_callback(self._start_callback) |
|
51 |
self.interactor.set_end_callback(self._end_callback) |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
52 |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
53 |
for patch in patches: |
54 |
for hunk in patch.hunks: |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
55 |
# everything's selected by default
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
56 |
hunk.selected = True |
57 |
self.total_hunks += 1 |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
58 |
# we need a back pointer in the callbacks
|
59 |
hunk.patch = patch |
|
60 |
self.interactor.add_item(hunk) |
|
61 |
||
62 |
# Called at the start of the main loop
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
63 |
def _start_callback(self): |
0.1.51
by Michael Ellerman
Restart after a done was broken, and we weren't resetting the print logic at |
64 |
self.last_printed = -1 |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
65 |
self.interactor.set_prompt(self.strings['prompt']) |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
66 |
self.interactor.set_options(self.standard_options) |
67 |
||
68 |
# Called at the end of the item loop, return False to indicate that the
|
|
69 |
# interaction isn't finished and the confirmation prompt should be displayed
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
70 |
def _end_callback(self): |
71 |
self._status() |
|
72 |
self.interactor.set_prompt(self.strings['end_prompt']) |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
73 |
self.interactor.set_options(self.end_options) |
74 |
return False |
|
75 |
||
76 |
# Called once for each hunk
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
77 |
def _hunk_callback(self, hunk, count): |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
78 |
if self.last_printed != count: |
0.3.5
by Aaron Bentley
Add colorizing to shelf |
79 |
self.diff_stream.write(str(hunk.patch.get_header())) |
80 |
self.diff_stream.write(str(hunk)) |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
81 |
self.last_printed = count |
82 |
||
83 |
if hunk.selected: |
|
0.1.49
by Michael Ellerman
Ask "shelve this change" instead of "keep this change", which is hopefully |
84 |
self.interactor.get_option('y').default = True |
85 |
self.interactor.get_option('n').default = False |
|
86 |
else: |
|
87 |
self.interactor.get_option('y').default = False |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
88 |
self.interactor.get_option('n').default = True |
89 |
||
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
90 |
# The user chooses to (un)shelve a hunk
|
91 |
def _selected(self, hunk): |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
92 |
hunk.selected = True |
93 |
return True |
|
94 |
||
95 |
# The user chooses to keep a hunk
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
96 |
def _unselected(self, hunk): |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
97 |
hunk.selected = False |
98 |
return True |
|
99 |
||
100 |
# The user chooses to invert the selection
|
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
101 |
def _invert(self, hunk): |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
102 |
for patch in self.patches: |
103 |
for hunk in patch.hunks: |
|
104 |
if hunk.__dict__.has_key('selected'): |
|
105 |
hunk.selected = not hunk.selected |
|
106 |
else: |
|
107 |
hunk.selected = True |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
108 |
self._status() |
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
109 |
return False |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
110 |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
111 |
# The user wants to see the status
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
112 |
def _status(self, hunk=None): |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
113 |
print '\nStatus:' |
114 |
for patch in self.patches: |
|
115 |
print ' %s' % patch.oldname |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
116 |
selected = 0 |
117 |
unselected = 0 |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
118 |
for hunk in patch.hunks: |
119 |
if hunk.selected: |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
120 |
selected += 1 |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
121 |
else: |
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
122 |
unselected += 1 |
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
123 |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
124 |
print ' ', self.strings['status_selected'] % selected |
125 |
print ' ', self.strings['status_unselected'] % unselected |
|
0.1.18
by Michael Ellerman
Split out HunkSelector class. |
126 |
print
|
127 |
||
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
128 |
# Tell the interactor we're not done with this item
|
129 |
return False |
|
130 |
||
131 |
def select(self): |
|
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
132 |
if self.total_hunks == 0 or not self.interactor.interact(): |
133 |
# False from interact means they chose to quit
|
|
134 |
return ([], []) |
|
135 |
||
136 |
# Go through each patch and collect all selected/unselected hunks
|
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
137 |
for patch in self.patches: |
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
138 |
patch.selected = [] |
139 |
patch.unselected = [] |
|
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
140 |
for hunk in patch.hunks: |
141 |
if hunk.selected: |
|
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
142 |
patch.selected.append(hunk) |
143 |
else: |
|
144 |
patch.unselected.append(hunk) |
|
145 |
||
146 |
# Now build two lists, one of selected patches the other unselected
|
|
147 |
selected_patches = [] |
|
148 |
unselected_patches = [] |
|
149 |
||
0.1.47
by Michael Ellerman
Refactored HunkSelector heavily to split out a UserInteractor class. |
150 |
for patch in self.patches: |
0.1.58
by Michael Ellerman
Unshelve --pick was broken, because we deleted the whole patch, even when only |
151 |
if len(patch.selected): |
152 |
tmp = copy.copy(patch) |
|
153 |
tmp.hunks = tmp.selected |
|
154 |
del tmp.selected |
|
155 |
del tmp.unselected |
|
156 |
selected_patches.append(tmp) |
|
157 |
||
158 |
if len(patch.unselected): |
|
159 |
tmp = copy.copy(patch) |
|
160 |
tmp.hunks = tmp.unselected |
|
161 |
del tmp.selected |
|
162 |
del tmp.unselected |
|
163 |
unselected_patches.append(tmp) |
|
164 |
||
165 |
return (selected_patches, unselected_patches) |
|
0.1.56
by Michael Ellerman
Make HunkSelector agnostic as to whether it's selecting for shelving or |
166 |
|
167 |
class ShelveHunkSelector(HunkSelector): |
|
168 |
def __init__(self, patches): |
|
169 |
self.strings = {} |
|
170 |
self.strings['status_selected'] = '%d hunks to be shelved' |
|
171 |
self.strings['status_unselected'] = '%d hunks to be kept' |
|
172 |
self.strings['select_desc'] = 'shelve this change.' |
|
173 |
self.strings['unselect_desc'] = 'keep this change in your tree.' |
|
174 |
self.strings['finish_desc'] = 'shelve selected changes.' |
|
175 |
self.strings['prompt'] = 'Shelve this change? (%(count)d of %(total)d)' |
|
176 |
self.strings['end_prompt'] = 'Shelve these changes?' |
|
177 |
HunkSelector.__init__(self, patches) |
|
178 |
||
179 |
class UnshelveHunkSelector(HunkSelector): |
|
180 |
def __init__(self, patches): |
|
181 |
self.strings = {} |
|
182 |
self.strings['status_selected'] = '%d hunks to be unshelved' |
|
183 |
self.strings['status_unselected'] = '%d hunks left on shelf' |
|
184 |
self.strings['select_desc'] = 'unshelve this change.' |
|
185 |
self.strings['unselect_desc'] = 'leave this change on the shelf.' |
|
186 |
self.strings['finish_desc'] = 'unshelve selected changes.' |
|
187 |
self.strings['prompt'] = 'Unshelve this change? ' \ |
|
188 |
'(%(count)d of %(total)d)' |
|
189 |
self.strings['end_prompt'] = 'Unshelve these changes?' |
|
190 |
HunkSelector.__init__(self, patches) |