diff --git a/docs/guide/extensibility/plugins/input_handlers/code/Input Handlers.sublime-commands b/docs/guide/extensibility/plugins/input_handlers/code/Input Handlers.sublime-commands index 712f149f..9db9cc27 100644 --- a/docs/guide/extensibility/plugins/input_handlers/code/Input Handlers.sublime-commands +++ b/docs/guide/extensibility/plugins/input_handlers/code/Input Handlers.sublime-commands @@ -2,4 +2,5 @@ { "caption": "Simple Command", "command": "simple" }, { "caption": "Insert Html Entity", "command": "insert_html_entity" }, { "caption": "Multiply", "command": "multiply" }, + { "caption": "Accumulate", "command": "accumulate" }, ] diff --git a/docs/guide/extensibility/plugins/input_handlers/code/accumulate.py b/docs/guide/extensibility/plugins/input_handlers/code/accumulate.py new file mode 100644 index 00000000..12915355 --- /dev/null +++ b/docs/guide/extensibility/plugins/input_handlers/code/accumulate.py @@ -0,0 +1,51 @@ +import sublime_plugin + + +class ItemsInputHandler(sublime_plugin.ListInputHandler): + def __init__(self, choices, accumulated=None, selected_index=0): + self.choices = choices + self.accumulated = accumulated or [] + self.selected_index = selected_index + + self.alt_pressed = False + self.selected = None + + def want_event(self): + # Declare that we want to receive the `event` argument. + return True + + def validate(self, _value, _event): + # We must override this method because we define `want_event`. + # https://github.com/sublimehq/sublime_text/issues/6258 + return True + + def list_items(self): + # Each selectable item represents + # all accumulated items plus the new item as a list. + return ( + [(item, self.accumulated + [item]) for item in self.choices], + self.selected_index, + ) + + def confirm(self, value, event): + # Record that the alt key was pressed when confirming + # so that we can return a follow-up input handler + # in `next_input`. + self.alt_pressed = event["modifier_keys"].get("alt", False) + self.selected = value + + def next_input(self, _args): + if self.alt_pressed: + selected_index = self.choices.index(self.selected[-1]) + return ItemsInputHandler(self.choices, self.selected, selected_index) + return None + + +class AccumulateCommand(sublime_plugin.WindowCommand): + def input(self, args): + if "items" not in args: + choices = "a b c d e".split(" ") + return ItemsInputHandler(choices=choices) + + def run(self, items): + self.window.run_command('insert', {'characters': " ".join(items)}) diff --git a/docs/guide/extensibility/plugins/input_handlers/images/accumulate.mp4 b/docs/guide/extensibility/plugins/input_handlers/images/accumulate.mp4 new file mode 100644 index 00000000..7dae8296 --- /dev/null +++ b/docs/guide/extensibility/plugins/input_handlers/images/accumulate.mp4 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:369c64b5371943e299f4d4e6efed8775fa4c7e89dba75e1fb0747ad4b5daadab +size 293113 diff --git a/docs/guide/extensibility/plugins/input_handlers/index.md b/docs/guide/extensibility/plugins/input_handlers/index.md index ba316b22..1aa6b15a 100644 --- a/docs/guide/extensibility/plugins/input_handlers/index.md +++ b/docs/guide/extensibility/plugins/input_handlers/index.md @@ -319,11 +319,107 @@ Try for yourself! ::: +### Accumulating Inputs from a List + +It is also possible to accumulate multiple inputs dynamically. +We can achieve this +by using lists as the values +of our ListInputHandler's `list_items` return value. + +To allow the user to signal that they want to select more values, +we define the `want_event` method and `return True` from it. +This tells Sublime Text to add an [`event` argument][Event] +to the `validate` and `confirm` methods, +which we use to determine +if a certain modifier key was held +and whether to return another input handler +in the `next_input` method. + +:::tip +Due to [a bug in the plugin API][core-6258], +we need to define *both* methods, +`validate` and `confirm`, +and have them accept this additional `event` argument, +even when we don't need them. +::: + +<<< ./code/accumulate.py {13-15,25-28,34-35,38-40,47-48} + +Here is what it looks like in action: + +