dhleong / judo

A more elegant way to play in the MUD
19 stars 2 forks source link

MultiTrigger support + more buffer control from scripts #95

Closed dhleong closed 4 years ago

dhleong commented 4 years ago

What is a MultiTrigger?

A MultiTrigger is a stateful tool that contains multiple triggers and operates in batch on a collection of lines. As it exists currently, a MultiTrigger is mostly a convenience tool—the only type is range, which could be implemented by hand using existing scripting tools. We provide MultiTrigger, however, to simplify common use cases, like removing a block of output and sending it to a separate window, for example (see below).

To operate on multiple lines, MultiTriggers are typically stateful, meaning each time it sees a line of text it may do something different depending on what it has seen previously. A range, for example, does nothing until it sees its "start" line, after which every line it sees gets collected, until it finally sees its "end" line, at which point all the lines its collected get sent to your handler. You could implement this with some state and three separate triggers, but MultiTrigger makes it more intuitive to do, and also prevents you from accidentally capturing all output forever if your "end" pattern isn't quite right.

Example

In starmourn, you can fairly simply pull out the space map:

space_map = {'window': None,
             'width': 42 }

@multitrigger('space-map', 'range', [
    re.compile(r'^(Location: .+\(.+\))[ ]*$'),
    re.compile(r'^(-----+)[ ]*$'),
], 'color delete')
def extract_space_map(newMapLines):
    newMapLines.pop()

    if space_map['window'] is None:
        primary = judo.current.window
        window = vsplit(space_map['width'])
        space_map['window'] = window
        judo.current.window = primary

    space_map['window'].buffer.set(newMapLines)
Screen Shot 2019-12-30 at 10 06 24 AM