1from __future__ import unicode_literals 2 3from .buffer import Buffer, AcceptAction 4from .buffer_mapping import BufferMapping 5from .clipboard import Clipboard, InMemoryClipboard 6from .enums import DEFAULT_BUFFER, EditingMode 7from .filters import CLIFilter, to_cli_filter 8from .key_binding.bindings.basic import load_basic_bindings 9from .key_binding.bindings.emacs import load_emacs_bindings 10from .key_binding.bindings.vi import load_vi_bindings 11from .key_binding.registry import BaseRegistry 12from .key_binding.defaults import load_key_bindings 13from .layout import Window 14from .layout.containers import Container 15from .layout.controls import BufferControl 16from .styles import DEFAULT_STYLE, Style 17import six 18 19__all__ = ( 20 'AbortAction', 21 'Application', 22) 23 24 25class AbortAction(object): 26 """ 27 Actions to take on an Exit or Abort exception. 28 """ 29 RETRY = 'retry' 30 RAISE_EXCEPTION = 'raise-exception' 31 RETURN_NONE = 'return-none' 32 33 _all = (RETRY, RAISE_EXCEPTION, RETURN_NONE) 34 35 36class Application(object): 37 """ 38 Application class to be passed to a 39 :class:`~prompt_toolkit.interface.CommandLineInterface`. 40 41 This contains all customizable logic that is not I/O dependent. 42 (So, what is independent of event loops, input and output.) 43 44 This way, such an :class:`.Application` can run easily on several 45 :class:`~prompt_toolkit.interface.CommandLineInterface` instances, each 46 with a different I/O backends. that runs for instance over telnet, SSH or 47 any other I/O backend. 48 49 :param layout: A :class:`~prompt_toolkit.layout.containers.Container` instance. 50 :param buffer: A :class:`~prompt_toolkit.buffer.Buffer` instance for the default buffer. 51 :param initial_focussed_buffer: Name of the buffer that is focussed during start-up. 52 :param key_bindings_registry: 53 :class:`~prompt_toolkit.key_binding.registry.BaseRegistry` instance for 54 the key bindings. 55 :param clipboard: :class:`~prompt_toolkit.clipboard.base.Clipboard` to use. 56 :param on_abort: What to do when Control-C is pressed. 57 :param on_exit: What to do when Control-D is pressed. 58 :param use_alternate_screen: When True, run the application on the alternate screen buffer. 59 :param get_title: Callable that returns the current title to be displayed in the terminal. 60 :param erase_when_done: (bool) Clear the application output when it finishes. 61 :param reverse_vi_search_direction: Normally, in Vi mode, a '/' searches 62 forward and a '?' searches backward. In readline mode, this is usually 63 reversed. 64 65 Filters: 66 67 :param mouse_support: (:class:`~prompt_toolkit.filters.CLIFilter` or 68 boolean). When True, enable mouse support. 69 :param paste_mode: :class:`~prompt_toolkit.filters.CLIFilter` or boolean. 70 :param ignore_case: :class:`~prompt_toolkit.filters.CLIFilter` or boolean. 71 :param editing_mode: :class:`~prompt_toolkit.enums.EditingMode`. 72 73 Callbacks (all of these should accept a 74 :class:`~prompt_toolkit.interface.CommandLineInterface` object as input.) 75 76 :param on_input_timeout: Called when there is no input for x seconds. 77 (Fired when any eventloop.onInputTimeout is fired.) 78 :param on_start: Called when reading input starts. 79 :param on_stop: Called when reading input ends. 80 :param on_reset: Called during reset. 81 :param on_buffer_changed: Called when the content of a buffer has been changed. 82 :param on_initialize: Called after the 83 :class:`~prompt_toolkit.interface.CommandLineInterface` initializes. 84 :param on_render: Called right after rendering. 85 :param on_invalidate: Called when the UI has been invalidated. 86 """ 87 def __init__(self, layout=None, buffer=None, buffers=None, 88 initial_focussed_buffer=DEFAULT_BUFFER, 89 style=None, 90 key_bindings_registry=None, clipboard=None, 91 on_abort=AbortAction.RAISE_EXCEPTION, on_exit=AbortAction.RAISE_EXCEPTION, 92 use_alternate_screen=False, mouse_support=False, 93 get_title=None, 94 95 paste_mode=False, ignore_case=False, editing_mode=EditingMode.EMACS, 96 erase_when_done=False, 97 reverse_vi_search_direction=False, 98 99 on_input_timeout=None, on_start=None, on_stop=None, 100 on_reset=None, on_initialize=None, on_buffer_changed=None, 101 on_render=None, on_invalidate=None): 102 103 paste_mode = to_cli_filter(paste_mode) 104 ignore_case = to_cli_filter(ignore_case) 105 mouse_support = to_cli_filter(mouse_support) 106 reverse_vi_search_direction = to_cli_filter(reverse_vi_search_direction) 107 108 assert layout is None or isinstance(layout, Container) 109 assert buffer is None or isinstance(buffer, Buffer) 110 assert buffers is None or isinstance(buffers, (dict, BufferMapping)) 111 assert key_bindings_registry is None or isinstance(key_bindings_registry, BaseRegistry) 112 assert clipboard is None or isinstance(clipboard, Clipboard) 113 assert on_abort in AbortAction._all 114 assert on_exit in AbortAction._all 115 assert isinstance(use_alternate_screen, bool) 116 assert get_title is None or callable(get_title) 117 assert isinstance(paste_mode, CLIFilter) 118 assert isinstance(ignore_case, CLIFilter) 119 assert isinstance(editing_mode, six.string_types) 120 assert on_input_timeout is None or callable(on_input_timeout) 121 assert style is None or isinstance(style, Style) 122 assert isinstance(erase_when_done, bool) 123 124 assert on_start is None or callable(on_start) 125 assert on_stop is None or callable(on_stop) 126 assert on_reset is None or callable(on_reset) 127 assert on_buffer_changed is None or callable(on_buffer_changed) 128 assert on_initialize is None or callable(on_initialize) 129 assert on_render is None or callable(on_render) 130 assert on_invalidate is None or callable(on_invalidate) 131 132 self.layout = layout or Window(BufferControl()) 133 134 # Make sure that the 'buffers' dictionary is a BufferMapping. 135 # NOTE: If no buffer is given, we create a default Buffer, with IGNORE as 136 # default accept_action. This is what makes sense for most users 137 # creating full screen applications. Doing nothing is the obvious 138 # default. Those creating a REPL would use the shortcuts module that 139 # passes in RETURN_DOCUMENT. 140 self.buffer = buffer or Buffer(accept_action=AcceptAction.IGNORE) 141 if not buffers or not isinstance(buffers, BufferMapping): 142 self.buffers = BufferMapping(buffers, initial=initial_focussed_buffer) 143 else: 144 self.buffers = buffers 145 146 if buffer: 147 self.buffers[DEFAULT_BUFFER] = buffer 148 149 self.initial_focussed_buffer = initial_focussed_buffer 150 151 self.style = style or DEFAULT_STYLE 152 153 if key_bindings_registry is None: 154 key_bindings_registry = load_key_bindings() 155 156 if get_title is None: 157 get_title = lambda: None 158 159 self.key_bindings_registry = key_bindings_registry 160 self.clipboard = clipboard or InMemoryClipboard() 161 self.on_abort = on_abort 162 self.on_exit = on_exit 163 self.use_alternate_screen = use_alternate_screen 164 self.mouse_support = mouse_support 165 self.get_title = get_title 166 167 self.paste_mode = paste_mode 168 self.ignore_case = ignore_case 169 self.editing_mode = editing_mode 170 self.erase_when_done = erase_when_done 171 self.reverse_vi_search_direction = reverse_vi_search_direction 172 173 def dummy_handler(cli): 174 " Dummy event handler. " 175 176 self.on_input_timeout = on_input_timeout or dummy_handler 177 self.on_start = on_start or dummy_handler 178 self.on_stop = on_stop or dummy_handler 179 self.on_reset = on_reset or dummy_handler 180 self.on_initialize = on_initialize or dummy_handler 181 self.on_buffer_changed = on_buffer_changed or dummy_handler 182 self.on_render = on_render or dummy_handler 183 self.on_invalidate = on_invalidate or dummy_handler 184 185 # List of 'extra' functions to execute before a CommandLineInterface.run. 186 # Note: It's important to keep this here, and not in the 187 # CommandLineInterface itself. shortcuts.run_application creates 188 # a new Application instance everytime. (Which is correct, it 189 # could be that we want to detach from one IO backend and attach 190 # the UI on a different backend.) But important is to keep as 191 # much state as possible between runs. 192 self.pre_run_callables = [] 193