Source

er-main / er / keystate.py

Full commit


from collections import namedtuple


NormalCommand = namedtuple('NormalCommand', 'command repeat range')


no_range_commands = set(['CUT'])
range_commands = set(['YANK', 'CHANGE'])
ranges = {
    'w': 'WORD',
    'iw': 'IWORD',
}


class NormalCommandParser(object):
    """
    Parse normal mode commands
    """

    def __init__(self, keys):
        self.keys = keys
        self.reset()

    def reset(self):
        self.command = None
        self.repeat = []
        self.range = []

    def parse(self, s):
        self.reset()
        return self.push(s)

    def push(self, s):
        for c in s:
            if not self.command:
                if c.isdigit():
                    self.repeat.append(c)
                else:
                    self.command = c
            else:
                self.range.append(c)

        r = None

        com = self.keys.get(self.command)

        if com is not None:

            if self.repeat:
                rep = int(''.join(self.repeat))
            else:
                rep = None

            if self.range:
                ran = ''.join(self.range)
                if ran == self.command:
                    ran = 'LINE'
                else:
                    ran = ranges.get(ran)

            else:
                ran = None

            if com in no_range_commands:
                r = (com, rep, None)
            elif ran:
                r = (com, rep, ran)


        if r is not None:
            self.reset()
            return r