euporie 2.8.0__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 -92
  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 +26 -37
  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 +9 -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.0.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.0.dist-info → euporie-2.8.5.dist-info}/WHEEL +1 -1
  123. {euporie-2.8.0.dist-info → euporie-2.8.5.dist-info}/entry_points.txt +2 -2
  124. {euporie-2.8.0.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.0.dist-info/RECORD +0 -146
  128. {euporie-2.8.0.data → euporie-2.8.5.data}/data/share/applications/euporie-console.desktop +0 -0
  129. {euporie-2.8.0.data → euporie-2.8.5.data}/data/share/applications/euporie-notebook.desktop +0 -0
euporie/hub/app.py CHANGED
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import logging
6
6
  from asyncio import get_event_loop
7
- from importlib.metadata import entry_points
8
7
  from typing import TYPE_CHECKING
9
8
 
10
9
  try:
@@ -18,16 +17,31 @@ except ModuleNotFoundError as err:
18
17
  from prompt_toolkit.contrib.ssh import PromptToolkitSSHSession
19
18
  from upath import UPath
20
19
 
21
- from euporie.core.app import BaseApp
20
+ from euporie.core.__main__ import available_apps
21
+ from euporie.core.app import APP_ALIASES
22
+ from euporie.core.app.base import ConfigurableApp
22
23
  from euporie.core.config import add_setting
23
- from euporie.core.log import setup_logs
24
24
 
25
25
  if TYPE_CHECKING:
26
- from typing import Awaitable
26
+ from collections.abc import Awaitable
27
+ from typing import Any, ClassVar
28
+
29
+ from euporie.core.app.app import BaseApp
27
30
 
28
31
  log = logging.getLogger(__name__)
29
32
 
30
33
 
34
+ def _euporie_hub_app_choices() -> list[str]:
35
+ """List known euporie-apps and their aliases."""
36
+ from euporie.core.__main__ import available_apps
37
+ from euporie.core.app import APP_ALIASES
38
+
39
+ return sorted(
40
+ {entry.name for entry in available_apps().values()} - {"launch", "hub"}
41
+ | APP_ALIASES.keys()
42
+ )
43
+
44
+
31
45
  class EuporieSSHServer(asyncssh.SSHServer): # type: ignore
32
46
  """Launch euporie hub, which serves a euporie app over SSH.
33
47
 
@@ -53,7 +67,7 @@ class EuporieSSHServer(asyncssh.SSHServer): # type: ignore
53
67
  return PromptToolkitSSHSession(self.app_cls.interact, enable_cpr=True) # type: ignore [call-arg]
54
68
 
55
69
 
56
- class HubApp(BaseApp):
70
+ class HubApp(ConfigurableApp):
57
71
  """Hub App.
58
72
 
59
73
  An app which runs as a multi-user SSH server.
@@ -62,25 +76,21 @@ class HubApp(BaseApp):
62
76
  """
63
77
 
64
78
  name = "hub"
65
-
66
- @classmethod
67
- def launch(cls) -> None:
68
- """Launch the HubApp SSH server."""
69
- # Default logging configuration
70
- setup_logs()
71
-
72
- # Configure some setting defaults
73
- cls.config.settings["log_file"].value = "-"
74
- cls.config.settings["log_level"].value = "info"
75
- cls.config.settings["log_config"].value = """
79
+ _config_defaults: ClassVar[dict[str, Any]] = {
80
+ "log_level_stdout": "info",
81
+ "log_config": """
76
82
  {
77
83
  "handlers": { "stdout": {"share_stream": false} },
78
84
  "loggers": { "asyncssh": { "handlers":["stdout"], "level": "DEBUG" } }
79
85
  }
80
- """
86
+ """,
87
+ }
81
88
 
82
- # Load the app's configuration
83
- cls.config.load(cls)
89
+ @classmethod
90
+ def launch(cls) -> None:
91
+ """Launch the HubApp SSH server."""
92
+ # Configure some setting defaults
93
+ super().launch()
84
94
 
85
95
  if not cls.config.auth:
86
96
  log.warning(
@@ -88,13 +98,16 @@ class HubApp(BaseApp):
88
98
  "meaning anyone can connect"
89
99
  )
90
100
 
101
+ # Detect selected app
102
+ chosen_app = cls.config.hub_app
103
+ chosen_app = APP_ALIASES.get(chosen_app, chosen_app)
104
+
91
105
  # Import the hubbed app
92
- if entry_point := {
93
- entry.name: entry for entry in entry_points()["euporie.apps"]
94
- }.get(cls.config.app):
95
- app_cls = entry_point.load()
106
+ apps = available_apps()
107
+ if entry := apps.get(chosen_app):
108
+ app_cls = entry.load()
96
109
  else:
97
- raise ValueError("Application `%s` not found", cls.config.app)
110
+ raise ModuleNotFoundError("Application `%s` not found", cls.config.app)
98
111
 
99
112
  # Run the HubApp in an SSH server
100
113
  loop = get_event_loop()
@@ -108,24 +121,28 @@ class HubApp(BaseApp):
108
121
  )
109
122
  )
110
123
  log.info("Running euporie hub on port %s", cls.config.port)
111
- loop.run_forever()
124
+ try:
125
+ loop.run_forever()
126
+ except KeyboardInterrupt:
127
+ log.info("Exiting euporie hub")
112
128
 
113
129
  # ################################### Settings ####################################
114
130
 
115
131
  add_setting(
116
- name="app",
117
- flags=["--app"],
118
- default="notebook",
132
+ name="hub_app",
133
+ group="euporie.hub.app",
134
+ flags=["hub_app"],
119
135
  type_=str,
120
- choices=["notebook", "console"],
121
- help_="App to run under euporie hub",
136
+ help_="The application to launch",
137
+ choices=_euporie_hub_app_choices,
122
138
  description="""
123
- Determine which euporie app should be launched under euporie hub.
139
+ The name of the application to launch.
124
140
  """,
125
141
  )
126
142
 
127
143
  add_setting(
128
144
  name="host",
145
+ group="euporie.hub.app",
129
146
  flags=["--host"],
130
147
  type_=str,
131
148
  help_="The host address to bind to",
@@ -137,6 +154,7 @@ class HubApp(BaseApp):
137
154
 
138
155
  add_setting(
139
156
  name="port",
157
+ group="euporie.hub.app",
140
158
  flags=["--port"],
141
159
  type_=int,
142
160
  help_="The port for the ssh server to use",
@@ -153,6 +171,7 @@ class HubApp(BaseApp):
153
171
 
154
172
  add_setting(
155
173
  name="host_keys",
174
+ group="euporie.hub.app",
156
175
  flags=["--host-keys"],
157
176
  nargs="*",
158
177
  type_=UPath,
@@ -172,6 +191,7 @@ class HubApp(BaseApp):
172
191
 
173
192
  add_setting(
174
193
  name="client_keys",
194
+ group="euporie.hub.app",
175
195
  flags=["--client-keys"],
176
196
  nargs="*",
177
197
  type_=UPath,
@@ -192,6 +212,7 @@ class HubApp(BaseApp):
192
212
 
193
213
  add_setting(
194
214
  name="auth",
215
+ group="euporie.hub.app",
195
216
  flags=["--auth"],
196
217
  type_=bool,
197
218
  help_="Allow unauthenticated access to euporie hub",
@@ -0,0 +1,24 @@
1
+ """Commands for the notebook app."""
2
+
3
+ from euporie.core.commands import add_cmd
4
+
5
+
6
+ @add_cmd(aliases=["n"])
7
+ def _new_notebook() -> None:
8
+ """Create a new file."""
9
+ from euporie.notebook.current import get_app
10
+ from euporie.notebook.tabs.notebook import Notebook
11
+
12
+ app = get_app()
13
+ app.add_tab(tab := Notebook(app, None))
14
+ tab.focus()
15
+
16
+
17
+ @add_cmd()
18
+ def _view_documentation() -> None:
19
+ """Open the documentation in a web-view tab."""
20
+ from upath import UPath
21
+
22
+ from euporie.core.app.current import get_app
23
+
24
+ get_app().open_file(UPath("https://euporie.readthedocs.io/"))
@@ -0,0 +1,107 @@
1
+ """Define settings for the notebook app."""
2
+
3
+ from euporie.core.config import add_setting
4
+ from euporie.notebook.enums import TabMode
5
+
6
+ add_setting(
7
+ name="tab_mode",
8
+ group="euporie.notebook.app",
9
+ flags=["--tab-mode"],
10
+ type_=str,
11
+ choices=[mode.value for mode in TabMode],
12
+ default="stack",
13
+ help_="The method used to display multiple tabs",
14
+ description="""
15
+ Determines how multiple tabs are displayed when more than one tab is open.
16
+ * ``stack`` displays one tab at a time with a tab-bar
17
+ * ``tile_horizontally`` displays tabs side-by-side
18
+ * ``tile_vertically`` displays tabs one-atop-the-next
19
+ """,
20
+ )
21
+
22
+ add_setting(
23
+ name="always_show_tab_bar",
24
+ group="euporie.notebook.app",
25
+ flags=["--always-show-tab-bar"],
26
+ type_=bool,
27
+ help_="Always show the tab bar",
28
+ default=False,
29
+ description="""
30
+ When set, the tab bar will always be shown - otherwise the tab bar is only
31
+ shown when multiple tabs are open.
32
+ """,
33
+ )
34
+
35
+ add_setting(
36
+ name="background_pattern",
37
+ group="euporie.notebook.app",
38
+ flags=["--background-pattern", "--bg-pattern"],
39
+ type_=int,
40
+ choices=list(range(6)),
41
+ help_="The background pattern to use",
42
+ default=2,
43
+ schema={
44
+ "minimum": 0,
45
+ "maximum": 5,
46
+ },
47
+ description="""
48
+ The background pattern to use when the notebook is narrower than the
49
+ available width. Zero mean no pattern is used.
50
+ """,
51
+ )
52
+
53
+ add_setting(
54
+ name="background_character",
55
+ group="euporie.notebook.app",
56
+ flags=["--background-character", "--bg-char"],
57
+ type_=str,
58
+ help_="Character for background pattern",
59
+ default="·",
60
+ schema={
61
+ "maxLength": 1,
62
+ },
63
+ description="""
64
+ The character to use when drawing the background pattern.
65
+
66
+ Recommended characters include: "·", "⬤", "╳", "╱", "╲", "░", "▒", "▓", "▞", "╬"
67
+ """, # ,
68
+ )
69
+
70
+ add_setting(
71
+ name="run_after_external_edit",
72
+ group="euporie.notebook.app",
73
+ flags=["--run-after-external-edit"],
74
+ type_=bool,
75
+ help_="Run cells after editing externally",
76
+ default=False,
77
+ description="""
78
+ Whether to execute a cell immediately after editing in `$EDITOR`.
79
+ """,
80
+ )
81
+
82
+ add_setting(
83
+ name="run",
84
+ group="euporie.notebook.app",
85
+ flags=["--run"],
86
+ type_=bool,
87
+ help_="Run the notebook files when loaded",
88
+ default=False,
89
+ description="""
90
+ If set, notebooks will be run automatically when opened, or if previewing a
91
+ file, the notebooks will be run before being output.
92
+ """,
93
+ )
94
+
95
+ add_setting(
96
+ name="show_top_bar",
97
+ group="euporie.notebook.app",
98
+ flags=["--show-top-bar"],
99
+ type_=bool,
100
+ title="top bar",
101
+ help_="Show the top bar",
102
+ default=True,
103
+ schema={"type": "boolean"},
104
+ description="""
105
+ Whether the top bar should be shown at the top of the screen.
106
+ """,
107
+ )