3
from userinteractor import UserInteractor, UserOption
7
def __init__(self, char, action, help, default=False):
10
self.default = default
14
Option('n', 'shelve', 'shelve this change for the moment.',
16
Option('y', 'keep', 'keep this change in your tree.'),
17
Option('d', 'done', 'done, skip to the end.'),
18
Option('i', 'invert', 'invert the current selection of all hunks.'),
19
Option('s', 'status', 'show status of hunks.'),
20
Option('q', 'quit', 'quit')
24
Option('y', 'continue', 'proceed to shelve selected changes.',
26
Option('r', 'restart', 'restart the hunk selection loop.'),
27
Option('s', 'status', 'show status of hunks.'),
28
Option('i', 'invert', 'invert the current selection of all hunks.'),
29
Option('q', 'quit', 'quit')
8
32
def __init__(self, patches):
9
self.standard_options = [
10
UserOption('y', self._selected, self.strings['select_desc'],
12
UserOption('n', self._unselected, self.strings['unselect_desc']),
13
UserOption('d', UserInteractor.FINISH, 'done, skip to the end.'),
14
UserOption('i', self._invert,
15
'invert the current selection status of all hunks.'),
16
UserOption('s', self._status,
17
'show selection status of all hunks.'),
18
UserOption('q', UserInteractor.QUIT, 'quit')
22
UserOption('y', UserInteractor.FINISH, self.strings['finish_desc'],
24
UserOption('r', UserInteractor.RESTART,
25
'restart the hunk selection loop.'),
26
UserOption('s', self._status,
27
'show selection status of all hunks.'),
28
UserOption('i', self._invert,
29
'invert the current selection status of all hunks.'),
30
UserOption('q', UserInteractor.QUIT, 'quit')
33
33
self.patches = patches
34
34
self.total_hunks = 0
36
self.interactor = UserInteractor()
37
self.interactor.set_item_callback(self._hunk_callback)
38
self.interactor.set_start_callback(self._start_callback)
39
self.interactor.set_end_callback(self._end_callback)
41
35
for patch in patches:
42
36
for hunk in patch.hunks:
43
# everything's selected by default
37
# everything's shelved by default
44
38
hunk.selected = True
45
39
self.total_hunks += 1
46
# we need a back pointer in the callbacks
48
self.interactor.add_item(hunk)
50
# Called at the start of the main loop
51
def _start_callback(self):
52
self.last_printed = -1
53
self.interactor.set_prompt(self.strings['prompt'])
54
self.interactor.set_options(self.standard_options)
56
# Called at the end of the item loop, return False to indicate that the
57
# interaction isn't finished and the confirmation prompt should be displayed
58
def _end_callback(self):
60
self.interactor.set_prompt(self.strings['end_prompt'])
61
self.interactor.set_options(self.end_options)
64
# Called once for each hunk
65
def _hunk_callback(self, hunk, count):
66
if self.last_printed != count:
67
print hunk.patch.get_header(), hunk
68
self.last_printed = count
71
self.interactor.get_option('y').default = True
72
self.interactor.get_option('n').default = False
74
self.interactor.get_option('y').default = False
75
self.interactor.get_option('n').default = True
77
# The user chooses to (un)shelve a hunk
78
def _selected(self, hunk):
82
# The user chooses to keep a hunk
83
def _unselected(self, hunk):
87
# The user chooses to invert the selection
88
def _invert(self, hunk):
41
def __get_option(self, char):
42
for opt in self.standard_options:
45
raise Exception('Option "%s" not found!' % char)
47
def __select_loop(self):
89
49
for patch in self.patches:
90
for hunk in patch.hunks:
91
if hunk.__dict__.has_key('selected'):
92
hunk.selected = not hunk.selected
52
while i < len(patch.hunks):
55
print patch.get_header(), hunk
59
prompt = 'Keep this change? (%d of %d)' \
60
% (j, self.total_hunks)
63
self.__get_option('n').default = True
64
self.__get_option('y').default = False
66
self.__get_option('n').default = False
67
self.__get_option('y').default = True
69
action = self.__ask_user(prompt, self.standard_options)
73
elif action == 'shelve':
94
74
hunk.selected = True
98
# The user wants to see the status
99
def _status(self, hunk=None):
101
for patch in self.patches:
102
print ' %s' % patch.oldname
105
for hunk in patch.hunks:
111
print ' ', self.strings['status_selected'] % selected
112
print ' ', self.strings['status_unselected'] % unselected
115
# Tell the interactor we're not done with this item
75
elif action == 'done':
77
elif action == 'invert':
78
self.__invert_selection()
81
elif action == 'status':
84
elif action == 'quit':
119
91
if self.total_hunks == 0:
122
if not self.interactor.interact():
123
# False from interact means they quit
96
if not self.__select_loop():
101
prompt = "Shelve these changes, or restart?"
102
action = self.__ask_user(prompt, self.end_options)
104
if action == 'continue':
107
elif action == 'quit':
109
elif action == 'status':
111
elif action == 'invert':
112
self.__invert_selection()
113
elif action == 'restart':
126
117
for patch in self.patches:
139
130
return self.patches
141
class ShelveHunkSelector(HunkSelector):
142
def __init__(self, patches):
144
self.strings['status_selected'] = '%d hunks to be shelved'
145
self.strings['status_unselected'] = '%d hunks to be kept'
146
self.strings['select_desc'] = 'shelve this change.'
147
self.strings['unselect_desc'] = 'keep this change in your tree.'
148
self.strings['finish_desc'] = 'shelve selected changes.'
149
self.strings['prompt'] = 'Shelve this change? (%(count)d of %(total)d)'
150
self.strings['end_prompt'] = 'Shelve these changes?'
151
HunkSelector.__init__(self, patches)
153
class UnshelveHunkSelector(HunkSelector):
154
def __init__(self, patches):
156
self.strings['status_selected'] = '%d hunks to be unshelved'
157
self.strings['status_unselected'] = '%d hunks left on shelf'
158
self.strings['select_desc'] = 'unshelve this change.'
159
self.strings['unselect_desc'] = 'leave this change on the shelf.'
160
self.strings['finish_desc'] = 'unshelve selected changes.'
161
self.strings['prompt'] = 'Unshelve this change? ' \
162
'(%(count)d of %(total)d)'
163
self.strings['end_prompt'] = 'Unshelve these changes?'
164
HunkSelector.__init__(self, patches)
132
def __invert_selection(self):
133
for patch in self.patches:
134
for hunk in patch.hunks:
135
if hunk.__dict__.has_key('selected'):
136
hunk.selected = not hunk.selected
140
def __show_status(self):
142
for patch in self.patches:
143
print ' %s' % patch.oldname
146
for hunk in patch.hunks:
152
print ' %d hunks to be shelved' % shelve
153
print ' %d hunks to be kept' % keep
156
if sys.platform == "win32":
159
return msvcrt.getche()
164
fd = sys.stdin.fileno()
165
settings = termios.tcgetattr(fd)
168
ch = sys.stdin.read(1)
170
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
173
def __ask_user(self, prompt, options):
175
sys.stdout.write(prompt)
176
sys.stdout.write(' [')
180
sys.stdout.write(opt.char)
181
sys.stdout.write('?] (%s): ' % default.char)
183
response = self.__getchar()
185
# default, which we see as newline, is 'n'
186
if response in ['\n', '\r', '\r\n']:
187
response = default.char
189
print response # because echo is off
192
if opt.char == response:
196
print ' %s - %s' % (opt.char, opt.help)