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')
6
32
def __init__(self, patches):
7
self.standard_options = [
8
UserOption('y', self.shelve, 'shelve this change.', default=True),
9
UserOption('n', self.keep, 'keep this change in your tree.'),
10
UserOption('d', UserInteractor.FINISH, 'done, skip to the end.'),
11
UserOption('i', self.invert,
12
'invert the current selection status of all hunks.'),
13
UserOption('s', self.status, 'show selection status of all hunks.'),
14
UserOption('q', UserInteractor.QUIT, 'quit')
18
UserOption('y', UserInteractor.FINISH,
19
'shelve selected changes.', default=True),
20
UserOption('r', UserInteractor.RESTART,
21
'restart the hunk selection loop.'),
22
UserOption('s', self.status, 'show selection status of all hunks.'),
23
UserOption('i', self.invert,
24
'invert the current selection status of all hunks.'),
25
UserOption('q', UserInteractor.QUIT, 'quit')
28
33
self.patches = patches
29
34
self.total_hunks = 0
31
self.last_printed = -1
32
self.interactor = UserInteractor()
33
self.interactor.set_item_callback(self.hunk_callback)
34
self.interactor.set_start_callback(self.start_callback)
35
self.interactor.set_end_callback(self.end_callback)
37
35
for patch in patches:
38
36
for hunk in patch.hunks:
39
37
# everything's shelved by default
40
38
hunk.selected = True
41
39
self.total_hunks += 1
42
# we need a back pointer in the callbacks
44
self.interactor.add_item(hunk)
46
# Called at the start of the main loop
47
def start_callback(self):
48
self.interactor.set_prompt('Shelve this change? ' \
49
'(%(count)d of %(total)d)')
50
self.interactor.set_options(self.standard_options)
52
# Called at the end of the item loop, return False to indicate that the
53
# interaction isn't finished and the confirmation prompt should be displayed
54
def end_callback(self):
56
self.interactor.set_prompt("Shelve these changes?")
57
self.interactor.set_options(self.end_options)
60
# Called once for each hunk
61
def hunk_callback(self, hunk, count):
62
if self.last_printed != count:
63
print hunk.patch.get_header(), hunk
64
self.last_printed = count
67
self.interactor.get_option('y').default = True
68
self.interactor.get_option('n').default = False
70
self.interactor.get_option('y').default = False
71
self.interactor.get_option('n').default = True
73
# The user chooses to shelve a hunk
74
def shelve(self, hunk):
78
# The user chooses to keep a hunk
83
# The user chooses to invert the selection
84
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):
49
for patch in self.patches:
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':
75
elif action == 'done':
77
elif action == 'invert':
78
self.__invert_selection()
81
elif action == 'status':
84
elif action == 'quit':
91
if self.total_hunks == 0:
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':
117
for patch in self.patches:
119
for hunk in patch.hunks:
125
for patch in self.patches:
132
def __invert_selection(self):
85
133
for patch in self.patches:
86
134
for hunk in patch.hunks:
87
135
if hunk.__dict__.has_key('selected'):
88
136
hunk.selected = not hunk.selected
90
138
hunk.selected = True
94
# The user wants to see the status
95
def status(self, hunk=None):
140
def __show_status(self):
97
142
for patch in self.patches:
98
143
print ' %s' % patch.oldname
108
153
print ' %d hunks to be kept' % keep
111
# Tell the interactor we're not done with this item
115
if self.total_hunks == 0:
118
if not self.interactor.interact():
119
# False from interact means they quit
122
for patch in self.patches:
124
for hunk in patch.hunks:
130
for patch in self.patches:
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)