buffer_mapping.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. """
  2. The BufferMapping contains all the buffers for a command line interface, and it
  3. keeps track of which buffer gets the focus.
  4. """
  5. from __future__ import unicode_literals
  6. from .enums import DEFAULT_BUFFER, SEARCH_BUFFER, SYSTEM_BUFFER, DUMMY_BUFFER
  7. from .buffer import Buffer, AcceptAction
  8. from .history import InMemoryHistory
  9. import six
  10. __all__ = (
  11. 'BufferMapping',
  12. )
  13. class BufferMapping(dict):
  14. """
  15. Dictionary that maps the name of the buffers to the
  16. :class:`~prompt_toolkit.buffer.Buffer` instances.
  17. This mapping also keeps track of which buffer currently has the focus.
  18. (Some methods receive a 'cli' parameter. This is useful for applications
  19. where this `BufferMapping` is shared between several applications.)
  20. """
  21. def __init__(self, buffers=None, initial=DEFAULT_BUFFER):
  22. assert buffers is None or isinstance(buffers, dict)
  23. # Start with an empty dict.
  24. super(BufferMapping, self).__init__()
  25. # Add default buffers.
  26. self.update({
  27. # For the 'search' and 'system' buffers, 'returnable' is False, in
  28. # order to block normal Enter/ControlC behaviour.
  29. DEFAULT_BUFFER: Buffer(accept_action=AcceptAction.RETURN_DOCUMENT),
  30. SEARCH_BUFFER: Buffer(history=InMemoryHistory(), accept_action=AcceptAction.IGNORE),
  31. SYSTEM_BUFFER: Buffer(history=InMemoryHistory(), accept_action=AcceptAction.IGNORE),
  32. DUMMY_BUFFER: Buffer(read_only=True),
  33. })
  34. # Add received buffers.
  35. if buffers is not None:
  36. self.update(buffers)
  37. # Focus stack.
  38. self.focus_stack = [initial or DEFAULT_BUFFER]
  39. def current(self, cli):
  40. """
  41. The active :class:`.Buffer`.
  42. """
  43. return self[self.focus_stack[-1]]
  44. def current_name(self, cli):
  45. """
  46. The name of the active :class:`.Buffer`.
  47. """
  48. return self.focus_stack[-1]
  49. def previous(self, cli):
  50. """
  51. Return the previously focussed :class:`.Buffer` or `None`.
  52. """
  53. if len(self.focus_stack) > 1:
  54. try:
  55. return self[self.focus_stack[-2]]
  56. except KeyError:
  57. pass
  58. def focus(self, cli, buffer_name):
  59. """
  60. Focus the buffer with the given name.
  61. """
  62. assert isinstance(buffer_name, six.text_type)
  63. self.focus_stack = [buffer_name]
  64. def push_focus(self, cli, buffer_name):
  65. """
  66. Push buffer on the focus stack.
  67. """
  68. assert isinstance(buffer_name, six.text_type)
  69. self.focus_stack.append(buffer_name)
  70. def pop_focus(self, cli):
  71. """
  72. Pop buffer from the focus stack.
  73. """
  74. if len(self.focus_stack) > 1:
  75. self.focus_stack.pop()
  76. else:
  77. raise IndexError('Cannot pop last item from the focus stack.')