euporie 2.8.1__py3-none-any.whl → 2.8.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. euporie/console/_commands.py +143 -0
  2. euporie/console/_settings.py +58 -0
  3. euporie/console/app.py +25 -71
  4. euporie/console/tabs/console.py +267 -147
  5. euporie/core/__init__.py +1 -9
  6. euporie/core/__main__.py +31 -5
  7. euporie/core/_settings.py +104 -0
  8. euporie/core/app/__init__.py +3 -0
  9. euporie/core/app/_commands.py +70 -0
  10. euporie/core/app/_settings.py +427 -0
  11. euporie/core/{app.py → app/app.py} +214 -572
  12. euporie/core/app/base.py +51 -0
  13. euporie/core/{current.py → app/current.py} +13 -4
  14. euporie/core/app/cursor.py +35 -0
  15. euporie/core/app/dummy.py +12 -0
  16. euporie/core/app/launch.py +28 -0
  17. euporie/core/bars/__init__.py +11 -0
  18. euporie/core/bars/command.py +182 -0
  19. euporie/core/bars/menu.py +258 -0
  20. euporie/core/{widgets → bars}/search.py +154 -57
  21. euporie/core/{widgets → bars}/status.py +9 -26
  22. euporie/core/clipboard.py +19 -80
  23. euporie/core/comm/base.py +8 -6
  24. euporie/core/comm/ipywidgets.py +21 -12
  25. euporie/core/comm/registry.py +2 -1
  26. euporie/core/commands.py +11 -5
  27. euporie/core/completion.py +3 -2
  28. euporie/core/config.py +368 -341
  29. euporie/core/convert/__init__.py +0 -30
  30. euporie/core/convert/datum.py +131 -60
  31. euporie/core/convert/formats/__init__.py +31 -0
  32. euporie/core/convert/formats/ansi.py +46 -30
  33. euporie/core/convert/formats/common.py +11 -23
  34. euporie/core/convert/formats/html.py +45 -40
  35. euporie/core/convert/formats/pil.py +1 -1
  36. euporie/core/convert/formats/png.py +3 -5
  37. euporie/core/convert/formats/sixel.py +3 -3
  38. euporie/core/convert/registry.py +11 -8
  39. euporie/core/convert/utils.py +50 -23
  40. euporie/core/diagnostics.py +2 -2
  41. euporie/core/filters.py +72 -82
  42. euporie/core/format.py +13 -2
  43. euporie/core/ft/ansi.py +1 -1
  44. euporie/core/ft/html.py +36 -36
  45. euporie/core/ft/table.py +1 -3
  46. euporie/core/ft/utils.py +4 -1
  47. euporie/core/graphics.py +216 -124
  48. euporie/core/history.py +2 -2
  49. euporie/core/inspection.py +3 -2
  50. euporie/core/io.py +207 -28
  51. euporie/core/kernel/__init__.py +1 -0
  52. euporie/core/{kernel.py → kernel/client.py} +100 -139
  53. euporie/core/kernel/manager.py +114 -0
  54. euporie/core/key_binding/bindings/__init__.py +2 -8
  55. euporie/core/key_binding/bindings/basic.py +47 -7
  56. euporie/core/key_binding/bindings/completion.py +3 -8
  57. euporie/core/key_binding/bindings/micro.py +5 -7
  58. euporie/core/key_binding/bindings/mouse.py +26 -24
  59. euporie/core/key_binding/bindings/terminal.py +193 -0
  60. euporie/core/key_binding/bindings/vi.py +46 -0
  61. euporie/core/key_binding/key_processor.py +43 -2
  62. euporie/core/key_binding/registry.py +2 -0
  63. euporie/core/key_binding/utils.py +22 -2
  64. euporie/core/keys.py +7156 -93
  65. euporie/core/layout/cache.py +35 -25
  66. euporie/core/layout/containers.py +280 -74
  67. euporie/core/layout/decor.py +5 -5
  68. euporie/core/layout/mouse.py +1 -1
  69. euporie/core/layout/print.py +16 -3
  70. euporie/core/layout/scroll.py +26 -28
  71. euporie/core/log.py +75 -60
  72. euporie/core/lsp.py +118 -24
  73. euporie/core/margins.py +60 -31
  74. euporie/core/path.py +2 -1
  75. euporie/core/renderer.py +58 -17
  76. euporie/core/style.py +60 -40
  77. euporie/core/suggest.py +103 -85
  78. euporie/core/tabs/__init__.py +34 -0
  79. euporie/core/tabs/_settings.py +113 -0
  80. euporie/core/tabs/base.py +11 -435
  81. euporie/core/tabs/kernel.py +420 -0
  82. euporie/core/tabs/notebook.py +20 -54
  83. euporie/core/utils.py +98 -6
  84. euporie/core/validation.py +1 -1
  85. euporie/core/widgets/_settings.py +188 -0
  86. euporie/core/widgets/cell.py +90 -158
  87. euporie/core/widgets/cell_outputs.py +25 -36
  88. euporie/core/widgets/decor.py +11 -41
  89. euporie/core/widgets/dialog.py +55 -44
  90. euporie/core/widgets/display.py +27 -24
  91. euporie/core/widgets/file_browser.py +5 -26
  92. euporie/core/widgets/forms.py +16 -12
  93. euporie/core/widgets/inputs.py +37 -81
  94. euporie/core/widgets/layout.py +7 -6
  95. euporie/core/widgets/logo.py +49 -0
  96. euporie/core/widgets/menu.py +13 -11
  97. euporie/core/widgets/pager.py +8 -11
  98. euporie/core/widgets/palette.py +6 -6
  99. euporie/hub/app.py +52 -31
  100. euporie/notebook/_commands.py +24 -0
  101. euporie/notebook/_settings.py +107 -0
  102. euporie/notebook/app.py +109 -210
  103. euporie/notebook/filters.py +1 -1
  104. euporie/notebook/tabs/__init__.py +46 -7
  105. euporie/notebook/tabs/_commands.py +714 -0
  106. euporie/notebook/tabs/_settings.py +32 -0
  107. euporie/notebook/tabs/display.py +2 -2
  108. euporie/notebook/tabs/edit.py +12 -7
  109. euporie/notebook/tabs/json.py +3 -3
  110. euporie/notebook/tabs/log.py +1 -18
  111. euporie/notebook/tabs/notebook.py +21 -674
  112. euporie/notebook/widgets/_commands.py +11 -0
  113. euporie/notebook/widgets/_settings.py +19 -0
  114. euporie/notebook/widgets/side_bar.py +14 -34
  115. euporie/preview/_settings.py +104 -0
  116. euporie/preview/app.py +8 -30
  117. euporie/preview/tabs/notebook.py +15 -86
  118. euporie/web/tabs/web.py +4 -6
  119. euporie/web/widgets/webview.py +5 -12
  120. {euporie-2.8.1.dist-info → euporie-2.8.5.dist-info}/METADATA +11 -15
  121. euporie-2.8.5.dist-info/RECORD +172 -0
  122. {euporie-2.8.1.dist-info → euporie-2.8.5.dist-info}/WHEEL +1 -1
  123. {euporie-2.8.1.dist-info → euporie-2.8.5.dist-info}/entry_points.txt +2 -2
  124. {euporie-2.8.1.dist-info → euporie-2.8.5.dist-info}/licenses/LICENSE +1 -1
  125. euporie/core/launch.py +0 -59
  126. euporie/core/terminal.py +0 -527
  127. euporie-2.8.1.dist-info/RECORD +0 -146
  128. {euporie-2.8.1.data → euporie-2.8.5.data}/data/share/applications/euporie-console.desktop +0 -0
  129. {euporie-2.8.1.data → euporie-2.8.5.data}/data/share/applications/euporie-notebook.desktop +0 -0
@@ -0,0 +1,143 @@
1
+ """Contains commands for the console."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from prompt_toolkit.filters.app import (
8
+ buffer_has_focus,
9
+ has_selection,
10
+ )
11
+
12
+ from euporie.core.commands import add_cmd
13
+ from euporie.core.filters import (
14
+ buffer_is_code,
15
+ buffer_is_empty,
16
+ kernel_tab_has_focus,
17
+ )
18
+ from euporie.core.tabs.kernel import KernelTab
19
+
20
+ if TYPE_CHECKING:
21
+ from prompt_toolkit.key_binding.key_processor import KeyPressEvent
22
+
23
+
24
+ @add_cmd()
25
+ async def _convert_to_notebook() -> None:
26
+ """Convert the current console session to a notebook."""
27
+ from prompt_toolkit.application.run_in_terminal import in_terminal
28
+
29
+ from euporie.console.app import get_app
30
+ from euporie.console.tabs.console import Console
31
+ from euporie.notebook.app import NotebookApp
32
+
33
+ app = get_app()
34
+ NotebookApp.config = app.config
35
+ NotebookApp.load_settings()
36
+ NotebookApp.config.__init__(app="notebook") # type: ignore [misc]
37
+ nb_app = NotebookApp()
38
+ # Use same event loop
39
+ nb_app.loop = app.loop
40
+ for tab in app.tabs:
41
+ if isinstance(tab, Console):
42
+ from euporie.notebook.tabs.notebook import Notebook
43
+
44
+ nb = Notebook(
45
+ app=nb_app,
46
+ path=tab.path,
47
+ kernel=tab.kernel,
48
+ comms=tab.comms,
49
+ json=tab.json,
50
+ )
51
+ # Set the history to the console's history
52
+ nb.history = tab.history
53
+ # Add the current input
54
+ nb.add(len(nb.json["cells"]) + 1, source=tab.input_box.buffer.text)
55
+ # Add the new notebook to the notebook app
56
+ nb_app.tabs.append(nb)
57
+ # Tell notebook that the kernel has already started
58
+ nb.kernel_started()
59
+
60
+ async with in_terminal():
61
+ await nb_app.run_async()
62
+
63
+ app.exit()
64
+
65
+
66
+ @add_cmd()
67
+ def _accept_input() -> None:
68
+ """Accept the current console input."""
69
+ from euporie.console.app import get_app
70
+
71
+ buffer = get_app().current_buffer
72
+ if buffer:
73
+ buffer.validate_and_handle()
74
+
75
+
76
+ @add_cmd(
77
+ filter=buffer_is_code & buffer_has_focus & ~has_selection & ~buffer_is_empty,
78
+ )
79
+ def _clear_input() -> None:
80
+ """Clear the console input."""
81
+ from euporie.console.app import get_app
82
+
83
+ buffer = get_app().current_buffer
84
+ buffer.reset()
85
+
86
+
87
+ @add_cmd(
88
+ filter=buffer_is_code & buffer_has_focus,
89
+ )
90
+ def _run_input() -> None:
91
+ """Run the console input."""
92
+ from euporie.console.app import get_app
93
+ from euporie.console.tabs.console import Console
94
+
95
+ if isinstance(console := get_app().tab, Console):
96
+ console.run()
97
+
98
+
99
+ @add_cmd(
100
+ name="cc-interrupt-kernel",
101
+ hidden=True,
102
+ filter=buffer_is_code & buffer_is_empty,
103
+ )
104
+ @add_cmd(filter=kernel_tab_has_focus)
105
+ def _interrupt_kernel() -> None:
106
+ """Interrupt the notebook's kernel."""
107
+ from euporie.console.app import get_app
108
+
109
+ if isinstance(kt := get_app().tab, KernelTab):
110
+ kt.interrupt_kernel()
111
+
112
+
113
+ @add_cmd(filter=kernel_tab_has_focus)
114
+ def _restart_kernel() -> None:
115
+ """Restart the notebook's kernel."""
116
+ from euporie.console.app import get_app
117
+
118
+ if isinstance(kt := get_app().tab, KernelTab):
119
+ kt.restart_kernel()
120
+
121
+
122
+ @add_cmd(
123
+ filter=buffer_is_code & buffer_is_empty,
124
+ hidden=True,
125
+ description="Signals the end of the input, causing the console to exit.",
126
+ )
127
+ def _end_of_file(event: KeyPressEvent) -> None:
128
+ """Exit when Control-D has been pressed."""
129
+ event.app.exit(exception=EOFError)
130
+
131
+
132
+ @add_cmd()
133
+ def _clear_screen() -> None:
134
+ """Clear the screen and the previous output."""
135
+ from euporie.console.app import get_app
136
+ from euporie.console.tabs.console import Console
137
+
138
+ app = get_app()
139
+ app.renderer.clear()
140
+
141
+ if isinstance(console := app.tab, Console):
142
+ console.reset()
143
+ app.layout.focus(console.input_box)
@@ -0,0 +1,58 @@
1
+ """Settings for the console app."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from upath import UPath
8
+
9
+ from euporie.core.config import add_setting
10
+
11
+ if TYPE_CHECKING:
12
+ from typing import TypeVar
13
+
14
+ _AppResult = TypeVar("_AppResult")
15
+
16
+ add_setting(
17
+ name="mouse_support",
18
+ group="euporie.console.app",
19
+ flags=["--mouse-support"],
20
+ type_=bool,
21
+ help_="Enable or disable mouse support",
22
+ default=None,
23
+ description="""
24
+ When set to True, mouse support is enabled. When set to False, mouse
25
+ support is disabled.
26
+ """,
27
+ )
28
+ add_setting(
29
+ name="max_stored_outputs",
30
+ group="euporie.console.app",
31
+ flags=["--max-stored-outputs"],
32
+ type_=int,
33
+ help_="The number of inputs / outputs to store in an in-memory notebook",
34
+ default=100,
35
+ schema={
36
+ "minimum": 0,
37
+ },
38
+ description="""
39
+ Defines the maximum number of executed "cells" to store in case the console
40
+ session is saved to a file or converted into a notebook.
41
+ """,
42
+ )
43
+
44
+ add_setting(
45
+ name="connection_file",
46
+ group="euporie.console.app",
47
+ flags=["--connection-file", "--kernel-connection-file"],
48
+ type_=UPath,
49
+ help_="Attempt to connect to an existing kernel using a JSON connection info file",
50
+ default=None,
51
+ description="""
52
+ If the file does not exist, kernel connection information will be written
53
+ to the file path provided.
54
+
55
+ If the file exists, kernel connection info will be read from the file,
56
+ allowing euporie to connect to existing kernels.
57
+ """,
58
+ )
euporie/console/app.py CHANGED
@@ -6,7 +6,6 @@ import logging
6
6
  from typing import TYPE_CHECKING, cast
7
7
 
8
8
  from prompt_toolkit.application.current import get_app as ptk_get_app
9
- from prompt_toolkit.application.run_in_terminal import in_terminal
10
9
  from prompt_toolkit.filters.app import (
11
10
  has_completions,
12
11
  is_done,
@@ -15,6 +14,7 @@ from prompt_toolkit.filters.app import (
15
14
  )
16
15
  from prompt_toolkit.layout.containers import (
17
16
  ConditionalContainer,
17
+ Float,
18
18
  FloatContainer,
19
19
  HSplit,
20
20
  VSplit,
@@ -23,10 +23,11 @@ from prompt_toolkit.layout.containers import (
23
23
  from prompt_toolkit.layout.dimension import Dimension
24
24
 
25
25
  from euporie.console.tabs.console import Console
26
- from euporie.core import __logo__
27
- from euporie.core.app import BaseApp
28
- from euporie.core.commands import add_cmd
29
- from euporie.core.config import add_setting
26
+ from euporie.core.app.app import BaseApp
27
+ from euporie.core.bars.command import CommandBar
28
+ from euporie.core.bars.menu import ToolbarCompletionsMenu
29
+ from euporie.core.bars.search import SearchBar
30
+ from euporie.core.bars.status import StatusBar
30
31
  from euporie.core.filters import has_dialog
31
32
  from euporie.core.layout.mouse import DisableMouseOnScroll
32
33
  from euporie.core.widgets.dialog import (
@@ -36,14 +37,15 @@ from euporie.core.widgets.dialog import (
36
37
  SelectKernelDialog,
37
38
  ShortcutsDialog,
38
39
  )
40
+ from euporie.core.widgets.logo import Logo
39
41
  from euporie.core.widgets.pager import Pager
40
42
  from euporie.core.widgets.palette import CommandPalette
41
- from euporie.core.widgets.search import SearchBar
42
- from euporie.core.widgets.status import StatusBar
43
43
 
44
44
  if TYPE_CHECKING:
45
45
  from typing import Any, TypeVar
46
46
 
47
+ from prompt_toolkit.application.application import Application
48
+
47
49
  _AppResult = TypeVar("_AppResult")
48
50
 
49
51
  log = logging.getLogger(__name__)
@@ -63,7 +65,6 @@ class ConsoleApp(BaseApp):
63
65
  """
64
66
 
65
67
  name = "console"
66
- log_stdout_level = "ERROR"
67
68
 
68
69
  def __init__(self, **kwargs: Any) -> None:
69
70
  """Create a new euporie text user interface application instance."""
@@ -72,16 +73,22 @@ class ConsoleApp(BaseApp):
72
73
  kwargs.setdefault("title", "euporie-console")
73
74
  kwargs.setdefault("full_screen", False)
74
75
  kwargs.setdefault("leave_graphics", True)
75
- kwargs.setdefault("mouse_support", self.config.filter("mouse_support"))
76
+ kwargs.setdefault("mouse_support", self.config.filters.mouse_support)
76
77
 
77
78
  # Initialize the application
78
79
  super().__init__(**kwargs)
79
80
 
80
- self.search_bar = SearchBar()
81
81
  self.bindings_to_load += ["euporie.console.app.ConsoleApp"]
82
82
 
83
83
  self.tabs = []
84
- self.pager = Pager()
84
+
85
+ def pre_run(self, app: Application | None = None) -> None:
86
+ """Continue loading the app."""
87
+ super().pre_run(app)
88
+ # Add a toolbar completion menu
89
+ self.menus["toolbar_completions"] = Float(
90
+ content=ToolbarCompletionsMenu(), ycursor=True, transparent=True
91
+ )
85
92
 
86
93
  def _get_reserved_height(self) -> Dimension:
87
94
  if has_dialog():
@@ -95,9 +102,9 @@ class ConsoleApp(BaseApp):
95
102
  """Return a container with all opened tabs."""
96
103
  self.tabs = [Console(self)]
97
104
 
98
- assert self.pager is not None
99
- assert self.search_bar is not None
100
- assert self.tab is not None
105
+ self.command_bar = CommandBar()
106
+ self.search_bar = SearchBar()
107
+ self.pager = Pager()
101
108
 
102
109
  self.dialogs["command-palette"] = CommandPalette(self)
103
110
  self.dialogs["about"] = AboutDialog(self)
@@ -110,7 +117,7 @@ class ConsoleApp(BaseApp):
110
117
  DisableMouseOnScroll(
111
118
  HSplit(
112
119
  [
113
- self.tab,
120
+ self.tabs[0],
114
121
  ConditionalContainer(
115
122
  HSplit(
116
123
  [
@@ -120,17 +127,12 @@ class ConsoleApp(BaseApp):
120
127
  style="class:default",
121
128
  ),
122
129
  self.pager,
123
- self.search_bar,
124
130
  ConditionalContainer(
125
131
  VSplit(
126
132
  [
127
- Window(
128
- char=f" {__logo__} ",
129
- height=1,
130
- width=3,
131
- style="class:menu,logo",
132
- dont_extend_width=True,
133
- ),
133
+ Logo(),
134
+ self.command_bar,
135
+ self.search_bar,
134
136
  StatusBar(),
135
137
  ]
136
138
  ),
@@ -165,54 +167,6 @@ class ConsoleApp(BaseApp):
165
167
  else:
166
168
  super().exit()
167
169
 
168
- # ################################### Commands ####################################
169
-
170
- @staticmethod
171
- @add_cmd()
172
- async def _convert_to_notebook() -> None:
173
- """Convert the current console session to a notebook."""
174
- from euporie.notebook.app import NotebookApp
175
- from euporie.notebook.tabs.notebook import Notebook
176
-
177
- app = get_app()
178
- nb_app = NotebookApp()
179
- for tab in app.tabs:
180
- if isinstance(tab, Console):
181
- nb = Notebook(
182
- app=nb_app,
183
- path=tab.path,
184
- kernel=tab.kernel,
185
- comms=tab.comms,
186
- json=tab.json,
187
- )
188
- # Set the history to the console's history
189
- nb.history = tab.history
190
- # Add the current input
191
- nb.add(len(nb.json["cells"]) + 1, source=tab.input_box.buffer.text)
192
- # Add the new notebook to the notebook app
193
- nb_app.tabs.append(nb)
194
- # Tell notebook that the kernel has already started
195
- nb.kernel_started()
196
-
197
- async with in_terminal():
198
- await nb_app.run_async()
199
-
200
- app.exit()
201
-
202
- # ################################### Settings ####################################
203
-
204
- add_setting(
205
- name="mouse_support",
206
- flags=["--mouse-support"],
207
- type_=bool,
208
- help_="Enable or disable mouse support",
209
- default=None,
210
- description="""
211
- When set to True, mouse support is enabled. When set to False, mouse
212
- support is disabled.
213
- """,
214
- )
215
-
216
170
  # ################################# Key Bindings ##################################
217
171
 
218
172
  # register_bindings({"euporie.console.app.ConsoleApp": {}})