~abentley/bzrtools/bzrtools.dev

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/python

from userinteractor import UserInteractor, UserOption

class HunkSelector:
    def __init__(self, patches):
        self.standard_options = [
            UserOption('n', self.shelve, 'shelve this change for the moment.',
                default=True),
            UserOption('y', self.keep, 'keep this change in your tree.'),
            UserOption('d', UserInteractor.FINISH, 'done, skip to the end.'),
            UserOption('i', self.invert,
                'invert the current selection of all hunks.'),
            UserOption('s', self.status, 'show status of hunks.'),
            UserOption('q', UserInteractor.QUIT, 'quit')
        ]

        self.end_options = [
            UserOption('y', UserInteractor.FINISH,
                'proceed to shelve selected changes.', default=True),
            UserOption('r', UserInteractor.RESTART,
                'restart the hunk selection loop.'),
            UserOption('s', self.status, 'show status of hunks.'),
            UserOption('i', self.invert,
                'invert the current selection of all hunks.'),
            UserOption('q', UserInteractor.QUIT, 'quit')
        ]

        self.patches = patches
        self.total_hunks = 0

        self.last_printed = -1
        self.interactor = UserInteractor()
        self.interactor.set_prompt('Keep this change? (%(count)d of %(total)d)')
        self.interactor.set_item_callback(self.hunk_callback)
        self.interactor.set_start_callback(self.start_callback)
        self.interactor.set_end_callback(self.end_callback)

        for patch in patches:
            for hunk in patch.hunks:
                # everything's shelved by default
                hunk.selected = True
                self.total_hunks += 1
                # we need a back pointer in the callbacks
                hunk.patch = patch
                self.interactor.add_item(hunk)

    # Called at the start of the main loop
    def start_callback(self):
        self.interactor.set_options(self.standard_options)

    # Called at the end of the item loop, return False to indicate that the
    # interaction isn't finished and the confirmation prompt should be displayed
    def end_callback(self):
        self.status()
        self.interactor.set_prompt("Shelve these changes, or restart?")
        self.interactor.set_options(self.end_options)
        return False

    # Called once for each hunk
    def hunk_callback(self, hunk, count):
        if self.last_printed != count:
            print hunk.patch.get_header(), hunk
            self.last_printed = count

        if hunk.selected:
            self.interactor.get_option('n').default = True
            self.interactor.get_option('y').default = False
        else:
            self.interactor.get_option('n').default = False
            self.interactor.get_option('y').default = True

    # The user chooses to shelve a hunk
    def shelve(self, hunk):
        hunk.selected = True
        return True

    # The user chooses to keep a hunk
    def keep(self, hunk):
        hunk.selected = False
        return True

    # The user chooses to invert the selection
    def invert(self, hunk):
        for patch in self.patches:
            for hunk in patch.hunks:
                if hunk.__dict__.has_key('selected'):
                    hunk.selected = not hunk.selected
                else:
                    hunk.selected = True
        self.status()
        return False

    # The user wants to see the status
    def status(self, hunk=None):
        print '\nStatus:'
        for patch in self.patches:
            print '  %s' % patch.oldname
            shelve = 0
            keep = 0
            for hunk in patch.hunks:
                if hunk.selected:
                    shelve += 1
                else:
                    keep += 1

            print '    %d hunks to be shelved' % shelve
            print '    %d hunks to be kept' % keep
            print

        # Tell the interactor we're not done with this item
        return False

    def select(self):
        if self.total_hunks == 0:
            return []

        if not self.interactor.interact():
            # False from interact means they quit
            return []

        for patch in self.patches:
            tmp = []
            for hunk in patch.hunks:
                if hunk.selected:
                    tmp.append(hunk)
            patch.hunks = tmp

        tmp = []
        for patch in self.patches:
            if len(patch.hunks):
                tmp.append(patch)
        self.patches = tmp

        return self.patches