base.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. """
  2. Clipboard for command line interface.
  3. """
  4. from __future__ import annotations
  5. from abc import ABCMeta, abstractmethod
  6. from typing import Callable
  7. from prompt_toolkit.selection import SelectionType
  8. __all__ = [
  9. "Clipboard",
  10. "ClipboardData",
  11. "DummyClipboard",
  12. "DynamicClipboard",
  13. ]
  14. class ClipboardData:
  15. """
  16. Text on the clipboard.
  17. :param text: string
  18. :param type: :class:`~prompt_toolkit.selection.SelectionType`
  19. """
  20. def __init__(
  21. self, text: str = "", type: SelectionType = SelectionType.CHARACTERS
  22. ) -> None:
  23. self.text = text
  24. self.type = type
  25. class Clipboard(metaclass=ABCMeta):
  26. """
  27. Abstract baseclass for clipboards.
  28. (An implementation can be in memory, it can share the X11 or Windows
  29. keyboard, or can be persistent.)
  30. """
  31. @abstractmethod
  32. def set_data(self, data: ClipboardData) -> None:
  33. """
  34. Set data to the clipboard.
  35. :param data: :class:`~.ClipboardData` instance.
  36. """
  37. def set_text(self, text: str) -> None: # Not abstract.
  38. """
  39. Shortcut for setting plain text on clipboard.
  40. """
  41. self.set_data(ClipboardData(text))
  42. def rotate(self) -> None:
  43. """
  44. For Emacs mode, rotate the kill ring.
  45. """
  46. @abstractmethod
  47. def get_data(self) -> ClipboardData:
  48. """
  49. Return clipboard data.
  50. """
  51. class DummyClipboard(Clipboard):
  52. """
  53. Clipboard implementation that doesn't remember anything.
  54. """
  55. def set_data(self, data: ClipboardData) -> None:
  56. pass
  57. def set_text(self, text: str) -> None:
  58. pass
  59. def rotate(self) -> None:
  60. pass
  61. def get_data(self) -> ClipboardData:
  62. return ClipboardData()
  63. class DynamicClipboard(Clipboard):
  64. """
  65. Clipboard class that can dynamically returns any Clipboard.
  66. :param get_clipboard: Callable that returns a :class:`.Clipboard` instance.
  67. """
  68. def __init__(self, get_clipboard: Callable[[], Clipboard | None]) -> None:
  69. self.get_clipboard = get_clipboard
  70. def _clipboard(self) -> Clipboard:
  71. return self.get_clipboard() or DummyClipboard()
  72. def set_data(self, data: ClipboardData) -> None:
  73. self._clipboard().set_data(data)
  74. def set_text(self, text: str) -> None:
  75. self._clipboard().set_text(text)
  76. def rotate(self) -> None:
  77. self._clipboard().rotate()
  78. def get_data(self) -> ClipboardData:
  79. return self._clipboard().get_data()