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