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