From 7ad90f03f40907c6f65a4868516bcaae9d932fa8 Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 11:37:34 +0200 Subject: [PATCH 1/8] add: example of coordination among different input text areas --- examples/prompts/edit-mask.py | 132 ++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100755 examples/prompts/edit-mask.py diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py new file mode 100755 index 000000000..b11b3561a --- /dev/null +++ b/examples/prompts/edit-mask.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +from prompt_toolkit.application import Application +from prompt_toolkit.key_binding import KeyBindings +from prompt_toolkit.layout.containers import Float, FloatContainer, HSplit, Window +from prompt_toolkit.layout.controls import BufferControl, FormattedTextControl +from prompt_toolkit.layout.layout import Layout +from prompt_toolkit.layout.menus import CompletionsMenu, CompletionsMenuControl + +from prompt_toolkit.filters import Condition +from prompt_toolkit.completion import FuzzyWordCompleter +from prompt_toolkit.widgets import TextArea +from prompt_toolkit.layout.dimension import D +from prompt_toolkit.application.current import get_app + + +class EditMask: + def __init__(self, animals=None, colors=None, cities=None, names=None): + self.animal_completer = FuzzyWordCompleter(animals) + self.color_completer = FuzzyWordCompleter(colors) + self.city_completer = FuzzyWordCompleter(cities) + self.name_completer = FuzzyWordCompleter(names) + + self.finish_event = '' + + kb = KeyBindings() + + @Condition + def is_not_autocompleting(): + "Check if the completion menu is visible" + for vw in get_app().layout.visible_windows: + if type(vw.content) is CompletionsMenuControl: + return False + return True + + @kb.add("down", filter=is_not_autocompleting) + def _(event): + "Move to next item." + get_app().layout.focus_next() + + @kb.add("up", filter=is_not_autocompleting) + def _(event): + "Move to previous item." + get_app().layout.focus_previous() + + @kb.add("c-c") + def _(event): + "Quit application without saving." + self.finish_event = 'quit' + event.app.exit() + + @kb.add("c-s") + def _(event): + "Save and quit application." + self.finish_event = 'save' + event.app.exit() + + self.text_area = { + 'Animal': self.factory_area('Animal', prefix_min_width=15, completer=self.animal_completer), + 'Color': self.factory_area('Color', prefix_min_width=15, completer=self.color_completer), + 'City': self.factory_area('City', prefix_min_width=15, completer=self.city_completer), + 'Name': self.factory_area('Name', prefix_min_width=15, completer=self.name_completer), + 'Other info 1': self.factory_area('Other info 1', prefix_min_width=15), + 'Other info 2': self.factory_area('Other info 2', prefix_min_width=15), + } + + self.completion_menu = CompletionsMenu(max_height=16, scroll_offset=1) + + self.float_area = Float( + xcursor=True, + ycursor=True, + content=self.completion_menu, + ) + + self.body = FloatContainer( + content=HSplit( + [ + Window( + FormattedTextControl('Ctrl-S - Save and quit | Ctrl-C - Quit without save '), height=1, style="reverse" + ), + self.text_area['Animal'], + self.text_area['Color'], + self.text_area['City'], + self.text_area['Name'], + self.text_area['Other info 1'], + self.text_area['Other info 2'], + ] + ), + floats=[ + self.float_area, + ], + ) + + #self.application = Application(layout=Layout(self.body), key_bindings=kb, full_screen=True) + self.application = Application(layout=Layout(self.body), key_bindings=kb) + + def accept_text(self, buf): + get_app().layout.focus_next() + buf.complete_state = None + return True + + def factory_area(self, prefix, prefix_min_width=0, completer=None): + """Generate a text area component.""" + ta = TextArea( + multiline=False, + completer=completer, + width=D(preferred=40), + accept_handler=self.accept_text, + get_line_prefix=lambda lineno, wrap_count : prefix + (' ' * (prefix_min_width - len(prefix) - 2)) + ': ', + ) + ta.control.buffer.name = prefix + return ta + + def run(self): + self.application.run() + if self.finish_event == 'quit': + print('Quitting without saving') + elif self.finish_event == 'save': + for key in self.text_area: + print(key, ':', self.text_area[key].text) + + +def main(): + animals = ["alligator", "crocodile", "bird", "cat", "dog"] + colors = ["red", "yellow", "green", "blue", "pink"] + cities = ["Rome", "Paris", "Madrid", "Athene", "Lisbon"] + names = ["Tullio", "Frank", "Jodi", "Mark"] + editor = EditMask(animals=animals, colors=colors, cities=cities, names=names) + editor.run() + + +if __name__ == "__main__": + main() From f14226296c497ee56a807c6bc954be106d429819 Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 11:53:25 +0200 Subject: [PATCH 2/8] fix: missing space that irritate flake8 --- examples/prompts/edit-mask.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py index b11b3561a..214f039e5 100755 --- a/examples/prompts/edit-mask.py +++ b/examples/prompts/edit-mask.py @@ -90,7 +90,7 @@ def _(event): ], ) - #self.application = Application(layout=Layout(self.body), key_bindings=kb, full_screen=True) + # self.application = Application(layout=Layout(self.body), key_bindings=kb, full_screen=True) self.application = Application(layout=Layout(self.body), key_bindings=kb) def accept_text(self, buf): From fe1d7e8a0945f69948951a188b13a32cff2a0f3d Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 12:17:58 +0200 Subject: [PATCH 3/8] fix: some linting --- examples/prompts/edit-mask.py | 66 +++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py index 214f039e5..0879840ec 100755 --- a/examples/prompts/edit-mask.py +++ b/examples/prompts/edit-mask.py @@ -1,16 +1,15 @@ #!/usr/bin/env python from prompt_toolkit.application import Application -from prompt_toolkit.key_binding import KeyBindings +from prompt_toolkit.application.current import get_app +from prompt_toolkit.completion import FuzzyWordCompleter +from prompt_toolkit.filters import Condition +from prompt_toolkit.layout.controls import FormattedTextControl +from prompt_toolkit.layout.menus import CompletionsMenu, CompletionsMenuControl from prompt_toolkit.layout.containers import Float, FloatContainer, HSplit, Window -from prompt_toolkit.layout.controls import BufferControl, FormattedTextControl +from prompt_toolkit.layout.dimension import D +from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.layout.layout import Layout -from prompt_toolkit.layout.menus import CompletionsMenu, CompletionsMenuControl - -from prompt_toolkit.filters import Condition -from prompt_toolkit.completion import FuzzyWordCompleter from prompt_toolkit.widgets import TextArea -from prompt_toolkit.layout.dimension import D -from prompt_toolkit.application.current import get_app class EditMask: @@ -55,12 +54,34 @@ def _(event): event.app.exit() self.text_area = { - 'Animal': self.factory_area('Animal', prefix_min_width=15, completer=self.animal_completer), - 'Color': self.factory_area('Color', prefix_min_width=15, completer=self.color_completer), - 'City': self.factory_area('City', prefix_min_width=15, completer=self.city_completer), - 'Name': self.factory_area('Name', prefix_min_width=15, completer=self.name_completer), - 'Other info 1': self.factory_area('Other info 1', prefix_min_width=15), - 'Other info 2': self.factory_area('Other info 2', prefix_min_width=15), + 'Animal': self.factory_area( + 'Animal', + prefix_min_width=15, + completer=self.animal_completer + ), + 'Color': self.factory_area( + 'Color', + prefix_min_width=15, + completer=self.color_completer + ), + 'City': self.factory_area( + 'City', + prefix_min_width=15, + completer=self.city_completer + ), + 'Name': self.factory_area( + 'Name', + prefix_min_width=15, + completer=self.name_completer + ), + 'Other info 1': self.factory_area( + 'Other info 1', + prefix_min_width=15 + ), + 'Other info 2': self.factory_area( + 'Other info 2', + prefix_min_width=15 + ), } self.completion_menu = CompletionsMenu(max_height=16, scroll_offset=1) @@ -75,7 +96,9 @@ def _(event): content=HSplit( [ Window( - FormattedTextControl('Ctrl-S - Save and quit | Ctrl-C - Quit without save '), height=1, style="reverse" + FormattedTextControl('Ctrl-S - Save and quit | Ctrl-C - Quit without save'), + height=1, + style="reverse" ), self.text_area['Animal'], self.text_area['Color'], @@ -90,7 +113,11 @@ def _(event): ], ) - # self.application = Application(layout=Layout(self.body), key_bindings=kb, full_screen=True) + # self.application = Application( + # layout=Layout(self.body), + # key_bindings=kb, + # full_screen=True + # ) self.application = Application(layout=Layout(self.body), key_bindings=kb) def accept_text(self, buf): @@ -105,7 +132,8 @@ def factory_area(self, prefix, prefix_min_width=0, completer=None): completer=completer, width=D(preferred=40), accept_handler=self.accept_text, - get_line_prefix=lambda lineno, wrap_count : prefix + (' ' * (prefix_min_width - len(prefix) - 2)) + ': ', + get_line_prefix=lambda lineno, + wrap_count : prefix + (' ' * (prefix_min_width - len(prefix) - 2)) + ': ', ) ta.control.buffer.name = prefix return ta @@ -115,8 +143,8 @@ def run(self): if self.finish_event == 'quit': print('Quitting without saving') elif self.finish_event == 'save': - for key in self.text_area: - print(key, ':', self.text_area[key].text) + for key, item in self.text_area.items(): + print(key, ':', item.text) def main(): From 30207d4693452a9508c43c522396b003894f6505 Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 12:41:00 +0200 Subject: [PATCH 4/8] fix: sorting of imports --- examples/prompts/edit-mask.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py index 0879840ec..85a31571f 100755 --- a/examples/prompts/edit-mask.py +++ b/examples/prompts/edit-mask.py @@ -3,12 +3,16 @@ from prompt_toolkit.application.current import get_app from prompt_toolkit.completion import FuzzyWordCompleter from prompt_toolkit.filters import Condition +from prompt_toolkit.key_binding import KeyBindings +from prompt_toolkit.layout.containers import Float +from prompt_toolkit.layout.containers import FloatContainer +from prompt_toolkit.layout.containers import HSplit +from prompt_toolkit.layout.containers import Window from prompt_toolkit.layout.controls import FormattedTextControl -from prompt_toolkit.layout.menus import CompletionsMenu, CompletionsMenuControl -from prompt_toolkit.layout.containers import Float, FloatContainer, HSplit, Window from prompt_toolkit.layout.dimension import D -from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.layout.layout import Layout +from prompt_toolkit.layout.menus import CompletionsMenu +from prompt_toolkit.layout.menus import CompletionsMenuControl from prompt_toolkit.widgets import TextArea From 5433c357f0449f862308bba75e68c4b2de070211 Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 12:51:17 +0200 Subject: [PATCH 5/8] fix: applied isort --- examples/prompts/edit-mask.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py index 85a31571f..74cdb5a8b 100755 --- a/examples/prompts/edit-mask.py +++ b/examples/prompts/edit-mask.py @@ -4,15 +4,11 @@ from prompt_toolkit.completion import FuzzyWordCompleter from prompt_toolkit.filters import Condition from prompt_toolkit.key_binding import KeyBindings -from prompt_toolkit.layout.containers import Float -from prompt_toolkit.layout.containers import FloatContainer -from prompt_toolkit.layout.containers import HSplit -from prompt_toolkit.layout.containers import Window +from prompt_toolkit.layout.containers import Float, FloatContainer, HSplit, Window from prompt_toolkit.layout.controls import FormattedTextControl from prompt_toolkit.layout.dimension import D from prompt_toolkit.layout.layout import Layout -from prompt_toolkit.layout.menus import CompletionsMenu -from prompt_toolkit.layout.menus import CompletionsMenuControl +from prompt_toolkit.layout.menus import CompletionsMenu, CompletionsMenuControl from prompt_toolkit.widgets import TextArea From a244bd6570d0e43810deb0a85120ddacf9efcf58 Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 13:01:50 +0200 Subject: [PATCH 6/8] fix: reformatting with black --- examples/prompts/edit-mask.py | 71 +++++++++++++++-------------------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py index 74cdb5a8b..40538ac1b 100755 --- a/examples/prompts/edit-mask.py +++ b/examples/prompts/edit-mask.py @@ -19,7 +19,7 @@ def __init__(self, animals=None, colors=None, cities=None, names=None): self.city_completer = FuzzyWordCompleter(cities) self.name_completer = FuzzyWordCompleter(names) - self.finish_event = '' + self.finish_event = "" kb = KeyBindings() @@ -44,44 +44,30 @@ def _(event): @kb.add("c-c") def _(event): "Quit application without saving." - self.finish_event = 'quit' + self.finish_event = "quit" event.app.exit() @kb.add("c-s") def _(event): "Save and quit application." - self.finish_event = 'save' + self.finish_event = "save" event.app.exit() self.text_area = { - 'Animal': self.factory_area( - 'Animal', - prefix_min_width=15, - completer=self.animal_completer + "Animal": self.factory_area( + "Animal", prefix_min_width=15, completer=self.animal_completer ), - 'Color': self.factory_area( - 'Color', - prefix_min_width=15, - completer=self.color_completer + "Color": self.factory_area( + "Color", prefix_min_width=15, completer=self.color_completer ), - 'City': self.factory_area( - 'City', - prefix_min_width=15, - completer=self.city_completer + "City": self.factory_area( + "City", prefix_min_width=15, completer=self.city_completer ), - 'Name': self.factory_area( - 'Name', - prefix_min_width=15, - completer=self.name_completer - ), - 'Other info 1': self.factory_area( - 'Other info 1', - prefix_min_width=15 - ), - 'Other info 2': self.factory_area( - 'Other info 2', - prefix_min_width=15 + "Name": self.factory_area( + "Name", prefix_min_width=15, completer=self.name_completer ), + "Other info 1": self.factory_area("Other info 1", prefix_min_width=15), + "Other info 2": self.factory_area("Other info 2", prefix_min_width=15), } self.completion_menu = CompletionsMenu(max_height=16, scroll_offset=1) @@ -96,16 +82,18 @@ def _(event): content=HSplit( [ Window( - FormattedTextControl('Ctrl-S - Save and quit | Ctrl-C - Quit without save'), + FormattedTextControl( + "Ctrl-S - Save and quit | Ctrl-C - Quit without save" + ), height=1, - style="reverse" + style="reverse", ), - self.text_area['Animal'], - self.text_area['Color'], - self.text_area['City'], - self.text_area['Name'], - self.text_area['Other info 1'], - self.text_area['Other info 2'], + self.text_area["Animal"], + self.text_area["Color"], + self.text_area["City"], + self.text_area["Name"], + self.text_area["Other info 1"], + self.text_area["Other info 2"], ] ), floats=[ @@ -132,19 +120,20 @@ def factory_area(self, prefix, prefix_min_width=0, completer=None): completer=completer, width=D(preferred=40), accept_handler=self.accept_text, - get_line_prefix=lambda lineno, - wrap_count : prefix + (' ' * (prefix_min_width - len(prefix) - 2)) + ': ', + get_line_prefix=lambda lineno, wrap_count: prefix + + (" " * (prefix_min_width - len(prefix) - 2)) + + ": ", ) ta.control.buffer.name = prefix return ta def run(self): self.application.run() - if self.finish_event == 'quit': - print('Quitting without saving') - elif self.finish_event == 'save': + if self.finish_event == "quit": + print("Quitting without saving") + elif self.finish_event == "save": for key, item in self.text_area.items(): - print(key, ':', item.text) + print(key, ":", item.text) def main(): From 2b893ed1284b4932e6d8ad996ccfdf68a1683cf9 Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 13:15:28 +0200 Subject: [PATCH 7/8] fix: applied some typing --- examples/prompts/edit-mask.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py index 40538ac1b..ec9cdf090 100755 --- a/examples/prompts/edit-mask.py +++ b/examples/prompts/edit-mask.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +from typing import Any + from prompt_toolkit.application import Application from prompt_toolkit.application.current import get_app from prompt_toolkit.completion import FuzzyWordCompleter @@ -13,7 +15,7 @@ class EditMask: - def __init__(self, animals=None, colors=None, cities=None, names=None): + def __init__(self, animals:Any, colors:Any, cities:Any, names:Any) -> None: self.animal_completer = FuzzyWordCompleter(animals) self.color_completer = FuzzyWordCompleter(colors) self.city_completer = FuzzyWordCompleter(cities) @@ -24,7 +26,7 @@ def __init__(self, animals=None, colors=None, cities=None, names=None): kb = KeyBindings() @Condition - def is_not_autocompleting(): + def is_not_autocompleting() -> bool: "Check if the completion menu is visible" for vw in get_app().layout.visible_windows: if type(vw.content) is CompletionsMenuControl: @@ -32,23 +34,23 @@ def is_not_autocompleting(): return True @kb.add("down", filter=is_not_autocompleting) - def _(event): + def _(event) -> None: "Move to next item." get_app().layout.focus_next() @kb.add("up", filter=is_not_autocompleting) - def _(event): + def _(event) -> None: "Move to previous item." get_app().layout.focus_previous() @kb.add("c-c") - def _(event): + def _(event) -> None: "Quit application without saving." self.finish_event = "quit" event.app.exit() @kb.add("c-s") - def _(event): + def _(event) -> None: "Save and quit application." self.finish_event = "save" event.app.exit() @@ -113,7 +115,7 @@ def accept_text(self, buf): buf.complete_state = None return True - def factory_area(self, prefix, prefix_min_width=0, completer=None): + def factory_area(self, prefix:str, prefix_min_width:int=0, completer:Any=None) -> TextArea: """Generate a text area component.""" ta = TextArea( multiline=False, @@ -127,7 +129,7 @@ def factory_area(self, prefix, prefix_min_width=0, completer=None): ta.control.buffer.name = prefix return ta - def run(self): + def run(self) -> None: self.application.run() if self.finish_event == "quit": print("Quitting without saving") @@ -136,7 +138,7 @@ def run(self): print(key, ":", item.text) -def main(): +def main() -> None: animals = ["alligator", "crocodile", "bird", "cat", "dog"] colors = ["red", "yellow", "green", "blue", "pink"] cities = ["Rome", "Paris", "Madrid", "Athene", "Lisbon"] From 46ba41bc04d03037bc93cc3ff47f6cf49f8c86b2 Mon Sep 17 00:00:00 2001 From: Tullio Facchinetti Date: Fri, 14 Oct 2022 13:20:50 +0200 Subject: [PATCH 8/8] fix: rerun black --- examples/prompts/edit-mask.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/prompts/edit-mask.py b/examples/prompts/edit-mask.py index ec9cdf090..8f855a612 100755 --- a/examples/prompts/edit-mask.py +++ b/examples/prompts/edit-mask.py @@ -15,7 +15,7 @@ class EditMask: - def __init__(self, animals:Any, colors:Any, cities:Any, names:Any) -> None: + def __init__(self, animals: Any, colors: Any, cities: Any, names: Any) -> None: self.animal_completer = FuzzyWordCompleter(animals) self.color_completer = FuzzyWordCompleter(colors) self.city_completer = FuzzyWordCompleter(cities) @@ -115,7 +115,9 @@ def accept_text(self, buf): buf.complete_state = None return True - def factory_area(self, prefix:str, prefix_min_width:int=0, completer:Any=None) -> TextArea: + def factory_area( + self, prefix: str, prefix_min_width: int = 0, completer: Any = None + ) -> TextArea: """Generate a text area component.""" ta = TextArea( multiline=False,