euporie 2.8.4__py3-none-any.whl → 2.8.6__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.
- euporie/console/_commands.py +143 -0
- euporie/console/_settings.py +58 -0
- euporie/console/app.py +25 -71
- euporie/console/tabs/console.py +58 -62
- euporie/core/__init__.py +1 -1
- euporie/core/__main__.py +28 -11
- euporie/core/_settings.py +109 -0
- euporie/core/app/__init__.py +3 -0
- euporie/core/app/_commands.py +95 -0
- euporie/core/app/_settings.py +457 -0
- euporie/core/{app.py → app/app.py} +212 -576
- euporie/core/app/base.py +51 -0
- euporie/core/{current.py → app/current.py} +13 -4
- euporie/core/app/cursor.py +35 -0
- euporie/core/app/dummy.py +12 -0
- euporie/core/app/launch.py +28 -0
- euporie/core/bars/__init__.py +11 -0
- euporie/core/bars/command.py +205 -0
- euporie/core/bars/menu.py +258 -0
- euporie/core/{widgets → bars}/search.py +20 -16
- euporie/core/{widgets → bars}/status.py +6 -23
- euporie/core/clipboard.py +19 -80
- euporie/core/comm/base.py +8 -6
- euporie/core/comm/ipywidgets.py +16 -7
- euporie/core/comm/registry.py +2 -1
- euporie/core/commands.py +10 -20
- euporie/core/completion.py +3 -2
- euporie/core/config.py +368 -341
- euporie/core/convert/__init__.py +0 -30
- euporie/core/convert/datum.py +116 -53
- euporie/core/convert/formats/__init__.py +31 -0
- euporie/core/convert/formats/ansi.py +9 -23
- euporie/core/convert/formats/common.py +11 -23
- euporie/core/convert/formats/html.py +45 -40
- euporie/core/convert/formats/pil.py +1 -1
- euporie/core/convert/formats/png.py +3 -5
- euporie/core/convert/formats/sixel.py +3 -3
- euporie/core/convert/registry.py +4 -6
- euporie/core/convert/utils.py +41 -4
- euporie/core/diagnostics.py +2 -2
- euporie/core/filters.py +98 -40
- euporie/core/format.py +2 -3
- euporie/core/ft/ansi.py +1 -1
- euporie/core/ft/html.py +12 -21
- euporie/core/ft/table.py +1 -3
- euporie/core/ft/utils.py +4 -1
- euporie/core/graphics.py +386 -133
- euporie/core/history.py +2 -2
- euporie/core/inspection.py +3 -2
- euporie/core/io.py +207 -28
- euporie/core/kernel/__init__.py +1 -0
- euporie/core/{kernel.py → kernel/client.py} +45 -108
- euporie/core/kernel/manager.py +114 -0
- euporie/core/key_binding/bindings/__init__.py +1 -8
- euporie/core/key_binding/bindings/basic.py +47 -7
- euporie/core/key_binding/bindings/completion.py +3 -8
- euporie/core/key_binding/bindings/micro.py +1 -6
- euporie/core/key_binding/bindings/mouse.py +2 -2
- euporie/core/key_binding/bindings/terminal.py +193 -0
- euporie/core/key_binding/key_processor.py +43 -2
- euporie/core/key_binding/registry.py +2 -0
- euporie/core/key_binding/utils.py +22 -2
- euporie/core/keys.py +7156 -93
- euporie/core/layout/cache.py +3 -3
- euporie/core/layout/containers.py +48 -4
- euporie/core/layout/decor.py +2 -2
- euporie/core/layout/mouse.py +1 -1
- euporie/core/layout/print.py +2 -1
- euporie/core/layout/scroll.py +39 -34
- euporie/core/log.py +76 -64
- euporie/core/lsp.py +118 -24
- euporie/core/margins.py +1 -1
- euporie/core/path.py +62 -13
- euporie/core/renderer.py +58 -17
- euporie/core/style.py +57 -39
- euporie/core/suggest.py +103 -85
- euporie/core/tabs/__init__.py +32 -0
- euporie/core/tabs/_settings.py +113 -0
- euporie/core/tabs/base.py +80 -470
- euporie/core/tabs/kernel.py +419 -0
- euporie/core/tabs/notebook.py +24 -101
- euporie/core/utils.py +92 -15
- euporie/core/validation.py +1 -1
- euporie/core/widgets/_settings.py +188 -0
- euporie/core/widgets/cell.py +19 -50
- euporie/core/widgets/cell_outputs.py +25 -36
- euporie/core/widgets/decor.py +11 -41
- euporie/core/widgets/dialog.py +62 -27
- euporie/core/widgets/display.py +12 -15
- euporie/core/widgets/file_browser.py +2 -23
- euporie/core/widgets/forms.py +8 -5
- euporie/core/widgets/inputs.py +13 -70
- euporie/core/widgets/layout.py +2 -1
- euporie/core/widgets/logo.py +49 -0
- euporie/core/widgets/menu.py +10 -8
- euporie/core/widgets/pager.py +6 -10
- euporie/core/widgets/palette.py +6 -6
- euporie/hub/app.py +52 -35
- euporie/notebook/_commands.py +24 -0
- euporie/notebook/_settings.py +107 -0
- euporie/notebook/app.py +49 -171
- euporie/notebook/filters.py +1 -1
- euporie/notebook/tabs/__init__.py +46 -7
- euporie/notebook/tabs/_commands.py +714 -0
- euporie/notebook/tabs/_settings.py +32 -0
- euporie/notebook/tabs/display.py +4 -4
- euporie/notebook/tabs/edit.py +11 -44
- euporie/notebook/tabs/json.py +5 -5
- euporie/notebook/tabs/log.py +1 -18
- euporie/notebook/tabs/notebook.py +11 -660
- euporie/notebook/widgets/_commands.py +11 -0
- euporie/notebook/widgets/_settings.py +19 -0
- euporie/notebook/widgets/side_bar.py +14 -34
- euporie/preview/_settings.py +104 -0
- euporie/preview/app.py +6 -31
- euporie/preview/tabs/notebook.py +6 -72
- euporie/web/__init__.py +1 -0
- euporie/web/tabs/__init__.py +14 -0
- euporie/web/tabs/web.py +11 -6
- euporie/web/widgets/__init__.py +1 -0
- euporie/web/widgets/webview.py +5 -15
- {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/METADATA +10 -8
- euporie-2.8.6.dist-info/RECORD +175 -0
- {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/WHEEL +1 -1
- {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/entry_points.txt +2 -2
- {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/licenses/LICENSE +1 -1
- euporie/core/launch.py +0 -64
- euporie/core/terminal.py +0 -522
- euporie-2.8.4.dist-info/RECORD +0 -147
- {euporie-2.8.4.data → euporie-2.8.6.data}/data/share/applications/euporie-console.desktop +0 -0
- {euporie-2.8.4.data → euporie-2.8.6.data}/data/share/applications/euporie-notebook.desktop +0 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
"""Define commands for widgets."""
|
2
|
+
|
3
|
+
from euporie.core.commands import add_cmd
|
4
|
+
|
5
|
+
|
6
|
+
@add_cmd()
|
7
|
+
def _toggle_side_bar_pane() -> None:
|
8
|
+
"""Open or close the current side-bar pane."""
|
9
|
+
from euporie.notebook.current import get_app
|
10
|
+
|
11
|
+
get_app().side_bar.toggle_pane()
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"""Define settings for the notebook app widgets."""
|
2
|
+
|
3
|
+
from euporie.core.config import add_setting
|
4
|
+
|
5
|
+
add_setting(
|
6
|
+
name="show_side_bar",
|
7
|
+
group="euporie.notebook.widgets.side_bar",
|
8
|
+
flags=["--show-side-bar"],
|
9
|
+
type_=bool,
|
10
|
+
title="side-bar",
|
11
|
+
help_="Show the side-bar",
|
12
|
+
default=False,
|
13
|
+
schema={
|
14
|
+
"type": "boolean",
|
15
|
+
},
|
16
|
+
description="""
|
17
|
+
Whether the side-bar should be shown at the side of the screen.
|
18
|
+
""",
|
19
|
+
)
|
@@ -16,14 +16,12 @@ from prompt_toolkit.layout.containers import (
|
|
16
16
|
)
|
17
17
|
from prompt_toolkit.layout.controls import FormattedTextControl
|
18
18
|
|
19
|
-
from euporie.core.commands import add_cmd
|
20
|
-
from euporie.core.config import add_setting
|
21
19
|
from euporie.core.key_binding.registry import register_bindings
|
22
20
|
from euporie.core.layout.decor import Line
|
23
21
|
from euporie.core.widgets.forms import ToggleButton, ToggleButtons
|
24
22
|
|
25
23
|
if TYPE_CHECKING:
|
26
|
-
from
|
24
|
+
from collections.abc import Sequence
|
27
25
|
|
28
26
|
from prompt_toolkit.layout.containers import AnyContainer
|
29
27
|
|
@@ -39,13 +37,22 @@ class SideBarButtons(ToggleButtons):
|
|
39
37
|
else:
|
40
38
|
return "class:side_bar,buttons,separator"
|
41
39
|
|
40
|
+
def _get_sep_char(self, i: int) -> str:
|
41
|
+
if self.index in {i, i - 1}:
|
42
|
+
return "▄"
|
43
|
+
return ""
|
44
|
+
|
42
45
|
def load_container(self) -> AnyContainer:
|
43
46
|
"""Load the widget's container."""
|
44
47
|
self.buttons: list[ToggleButton] = []
|
45
48
|
children: list[AnyContainer] = []
|
46
49
|
for i, (label, selected) in enumerate(zip(self.labels, self.mask)):
|
47
50
|
children.append(
|
48
|
-
Window(
|
51
|
+
Window(
|
52
|
+
char=partial(self._get_sep_char, i),
|
53
|
+
height=1,
|
54
|
+
style=partial(self._get_sep_style, i),
|
55
|
+
)
|
49
56
|
)
|
50
57
|
button = ToggleButton(
|
51
58
|
text=label,
|
@@ -60,7 +67,7 @@ class SideBarButtons(ToggleButtons):
|
|
60
67
|
children.extend(
|
61
68
|
[
|
62
69
|
Window(
|
63
|
-
char=
|
70
|
+
char=partial(self._get_sep_char, i),
|
64
71
|
height=1,
|
65
72
|
style=partial(self._get_sep_style, len(self.options)),
|
66
73
|
),
|
@@ -85,7 +92,7 @@ class SideBar:
|
|
85
92
|
panels: Sequence[AnyContainer],
|
86
93
|
) -> None:
|
87
94
|
"""Initialize a new side-bar object."""
|
88
|
-
from euporie.core.current import get_app
|
95
|
+
from euporie.core.app.current import get_app
|
89
96
|
|
90
97
|
self.side_bar_buttons = SideBarButtons(
|
91
98
|
options=list(icons),
|
@@ -158,7 +165,7 @@ class SideBar:
|
|
158
165
|
],
|
159
166
|
style="class:side_bar",
|
160
167
|
),
|
161
|
-
filter=get_app().config.
|
168
|
+
filter=get_app().config.filters.show_side_bar,
|
162
169
|
)
|
163
170
|
|
164
171
|
def toggle_pane(self) -> None:
|
@@ -172,33 +179,6 @@ class SideBar:
|
|
172
179
|
"""Return the side_bar's main container."""
|
173
180
|
return self.container
|
174
181
|
|
175
|
-
# ################################### Settings ####################################
|
176
|
-
|
177
|
-
add_setting(
|
178
|
-
name="show_side_bar",
|
179
|
-
flags=["--show-side-bar"],
|
180
|
-
type_=bool,
|
181
|
-
title="side-bar",
|
182
|
-
help_="Show the side-bar",
|
183
|
-
default=False,
|
184
|
-
schema={
|
185
|
-
"type": "boolean",
|
186
|
-
},
|
187
|
-
description="""
|
188
|
-
Whether the side-bar should be shown at the side of the screen.
|
189
|
-
""",
|
190
|
-
)
|
191
|
-
|
192
|
-
# ################################### Commands ####################################
|
193
|
-
|
194
|
-
@staticmethod
|
195
|
-
@add_cmd()
|
196
|
-
def _toggle_side_bar_pane() -> None:
|
197
|
-
"""Open or close the current side-bar pane."""
|
198
|
-
from euporie.notebook.current import get_app
|
199
|
-
|
200
|
-
get_app().side_bar.toggle_pane()
|
201
|
-
|
202
182
|
# ################################# Key Bindings ##################################
|
203
183
|
|
204
184
|
register_bindings(
|
@@ -0,0 +1,104 @@
|
|
1
|
+
"""Define settings for the preview app."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import logging
|
6
|
+
|
7
|
+
from upath import UPath
|
8
|
+
|
9
|
+
from euporie.core.config import add_setting
|
10
|
+
|
11
|
+
log = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
add_setting(
|
15
|
+
name="output_file",
|
16
|
+
group="euporie.preview.app",
|
17
|
+
flags=["--output-file"],
|
18
|
+
nargs="?",
|
19
|
+
default="-",
|
20
|
+
const="-",
|
21
|
+
type_=UPath,
|
22
|
+
help_="Output path when previewing file",
|
23
|
+
description="""
|
24
|
+
When set to a file path, the formatted output will be written to the
|
25
|
+
given path. If no value is given (or the default "-" is passed) output
|
26
|
+
will be printed to standard output.
|
27
|
+
""",
|
28
|
+
)
|
29
|
+
|
30
|
+
add_setting(
|
31
|
+
name="page",
|
32
|
+
group="euporie.preview.app",
|
33
|
+
flags=["--page"],
|
34
|
+
type_=bool,
|
35
|
+
help_="Pass output to pager",
|
36
|
+
default=False,
|
37
|
+
description="""
|
38
|
+
Whether to pipe output to the system pager when previewing a notebook.
|
39
|
+
""",
|
40
|
+
)
|
41
|
+
|
42
|
+
|
43
|
+
add_setting(
|
44
|
+
name="run",
|
45
|
+
group="euporie.preview.app",
|
46
|
+
flags=["--run"],
|
47
|
+
type_=bool,
|
48
|
+
help_="Run the notebook files when loaded",
|
49
|
+
default=False,
|
50
|
+
description="""
|
51
|
+
If set, notebooks will be run automatically when opened, or if previewing a
|
52
|
+
file, the notebooks will be run before being output.
|
53
|
+
""",
|
54
|
+
)
|
55
|
+
|
56
|
+
add_setting(
|
57
|
+
name="save",
|
58
|
+
group="euporie.preview.app",
|
59
|
+
flags=["--save"],
|
60
|
+
type_=bool,
|
61
|
+
help_="Save the notebook after running it",
|
62
|
+
default=False,
|
63
|
+
description="""
|
64
|
+
If set, notebooks will be saved after they have been run. This setting only
|
65
|
+
has any affect if the :option:`run` setting is active.
|
66
|
+
""",
|
67
|
+
)
|
68
|
+
|
69
|
+
add_setting(
|
70
|
+
name="show_filenames",
|
71
|
+
group="euporie.preview.app",
|
72
|
+
flags=["--show-filenames"],
|
73
|
+
type_=bool,
|
74
|
+
help_="Show the notebook filenames when previewing multiple notebooks",
|
75
|
+
default=False,
|
76
|
+
description="""
|
77
|
+
If set, the notebook filenames will be printed above each notebook's output
|
78
|
+
when multiple notebooks are being previewed.
|
79
|
+
""",
|
80
|
+
)
|
81
|
+
|
82
|
+
add_setting(
|
83
|
+
name="cell_start",
|
84
|
+
group="euporie.preview.app",
|
85
|
+
flags=["--cell-start"],
|
86
|
+
type_=int,
|
87
|
+
help_="The first cell to include in the preview",
|
88
|
+
default=None,
|
89
|
+
description="""
|
90
|
+
When set, only cells after the given cell index will be shown.
|
91
|
+
""",
|
92
|
+
)
|
93
|
+
|
94
|
+
add_setting(
|
95
|
+
name="cell_stop",
|
96
|
+
group="euporie.preview.app",
|
97
|
+
flags=["--cell-stop"],
|
98
|
+
type_=int,
|
99
|
+
help_="The last cell to include in the preview",
|
100
|
+
default=None,
|
101
|
+
description="""
|
102
|
+
When set, only cells before the given cell index will be shown.
|
103
|
+
""",
|
104
|
+
)
|
euporie/preview/app.py
CHANGED
@@ -12,10 +12,9 @@ from typing import TYPE_CHECKING, cast
|
|
12
12
|
from prompt_toolkit.layout.containers import DynamicContainer, FloatContainer, Window
|
13
13
|
from prompt_toolkit.output.defaults import create_output
|
14
14
|
from prompt_toolkit.output.vt100 import Vt100_Output
|
15
|
-
from upath import UPath
|
16
15
|
|
17
|
-
from euporie.core.app import BaseApp
|
18
|
-
from euporie.core.
|
16
|
+
from euporie.core.app.app import BaseApp
|
17
|
+
from euporie.core.app.current import get_app
|
19
18
|
from euporie.core.io import PseudoTTY
|
20
19
|
from euporie.core.key_binding.registry import register_bindings
|
21
20
|
from euporie.preview.tabs.notebook import PreviewNotebook
|
@@ -55,6 +54,7 @@ class PreviewApp(BaseApp):
|
|
55
54
|
kwargs.setdefault("max_render_postpone_time", 0)
|
56
55
|
kwargs.setdefault("min_redraw_interval", 0)
|
57
56
|
kwargs.setdefault("extend_renderer_height", True)
|
57
|
+
kwargs.setdefault("enable_page_navigation_bindings", False)
|
58
58
|
# Adjust options if we are paging output
|
59
59
|
if self.config.page:
|
60
60
|
kwargs.setdefault("set_title", False)
|
@@ -126,7 +126,7 @@ class PreviewApp(BaseApp):
|
|
126
126
|
# Use a temporary file as display output if we are going to page the output
|
127
127
|
from tempfile import TemporaryFile
|
128
128
|
|
129
|
-
output_file = TemporaryFile("w+")
|
129
|
+
output_file = TemporaryFile("w+") # noqa: SIM115
|
130
130
|
# Make this file look like a tty so we get colorful output
|
131
131
|
output_file = cast("TextIO", PseudoTTY(output_file, isatty=True))
|
132
132
|
|
@@ -192,33 +192,8 @@ class PreviewApp(BaseApp):
|
|
192
192
|
def _update_invalidate_events(self) -> None:
|
193
193
|
"""Do nothing, as we don't need invalidation events for the preview app."""
|
194
194
|
|
195
|
-
#
|
196
|
-
|
197
|
-
add_setting(
|
198
|
-
name="output_file",
|
199
|
-
flags=["--output-file"],
|
200
|
-
nargs="?",
|
201
|
-
default="-",
|
202
|
-
const="-",
|
203
|
-
type_=UPath,
|
204
|
-
help_="Output path when previewing file",
|
205
|
-
description="""
|
206
|
-
When set to a file path, the formatted output will be written to the
|
207
|
-
given path. If no value is given (or the default "-" is passed) output
|
208
|
-
will be printed to standard output.
|
209
|
-
""",
|
210
|
-
)
|
211
|
-
|
212
|
-
add_setting(
|
213
|
-
name="page",
|
214
|
-
flags=["--page"],
|
215
|
-
type_=bool,
|
216
|
-
help_="Pass output to pager",
|
217
|
-
default=False,
|
218
|
-
description="""
|
219
|
-
Whether to pipe output to the system pager when previewing a notebook.
|
220
|
-
""",
|
221
|
-
)
|
195
|
+
# def load_key_bindings(self) -> None:
|
196
|
+
# """Do no load any additional key-bindings for the preview app."""
|
222
197
|
|
223
198
|
# ################################# Key Bindings ##################################
|
224
199
|
|
euporie/preview/tabs/notebook.py
CHANGED
@@ -11,7 +11,6 @@ from prompt_toolkit.layout.containers import (
|
|
11
11
|
)
|
12
12
|
from prompt_toolkit.layout.dimension import Dimension
|
13
13
|
|
14
|
-
from euporie.core.config import add_setting
|
15
14
|
from euporie.core.layout.containers import VSplit, Window
|
16
15
|
from euporie.core.layout.print import PrintingContainer
|
17
16
|
from euporie.core.tabs.notebook import BaseNotebook
|
@@ -26,9 +25,9 @@ if TYPE_CHECKING:
|
|
26
25
|
from prompt_toolkit.formatted_text.base import StyleAndTextTuples
|
27
26
|
from prompt_toolkit.layout.containers import AnyContainer
|
28
27
|
|
29
|
-
from euporie.core.app import BaseApp
|
28
|
+
from euporie.core.app.app import BaseApp
|
30
29
|
from euporie.core.comm.base import Comm
|
31
|
-
from euporie.core.kernel import Kernel
|
30
|
+
from euporie.core.kernel.client import Kernel
|
32
31
|
|
33
32
|
log = logging.getLogger(__name__)
|
34
33
|
|
@@ -36,8 +35,6 @@ log = logging.getLogger(__name__)
|
|
36
35
|
class PreviewNotebook(BaseNotebook):
|
37
36
|
"""A notebook tab which renders cells sequentially."""
|
38
37
|
|
39
|
-
bg_init = False
|
40
|
-
|
41
38
|
def __init__(
|
42
39
|
self,
|
43
40
|
app: BaseApp,
|
@@ -132,7 +129,7 @@ class PreviewNotebook(BaseNotebook):
|
|
132
129
|
):
|
133
130
|
self.print_title()
|
134
131
|
|
135
|
-
if not self.json
|
132
|
+
if not self.json.get("cells", []):
|
136
133
|
log.error("No cells")
|
137
134
|
self.app.print_text([("", "(No cells to display)\n")])
|
138
135
|
self.app.close_tab(self)
|
@@ -165,13 +162,12 @@ class PreviewNotebook(BaseNotebook):
|
|
165
162
|
|
166
163
|
def load_container(self) -> AnyContainer:
|
167
164
|
"""Load the notebook's main container."""
|
165
|
+
no_expand = ~self.app.config.filters.expand
|
168
166
|
return PrintingContainer(
|
169
167
|
[
|
170
168
|
VSplit(
|
171
169
|
[
|
172
|
-
ConditionalContainer(
|
173
|
-
Window(), filter=~self.app.config.filter("expand")
|
174
|
-
),
|
170
|
+
ConditionalContainer(Window(), filter=no_expand),
|
175
171
|
Box(
|
176
172
|
body=DynamicContainer(lambda: self.cell),
|
177
173
|
padding=0,
|
@@ -179,70 +175,8 @@ class PreviewNotebook(BaseNotebook):
|
|
179
175
|
preferred=self.app.config.max_notebook_width
|
180
176
|
),
|
181
177
|
),
|
182
|
-
ConditionalContainer(
|
183
|
-
Window(), filter=~self.app.config.filter("expand")
|
184
|
-
),
|
178
|
+
ConditionalContainer(Window(), filter=no_expand),
|
185
179
|
]
|
186
180
|
)
|
187
181
|
]
|
188
182
|
)
|
189
|
-
|
190
|
-
# ################################### Settings ####################################
|
191
|
-
|
192
|
-
add_setting(
|
193
|
-
name="run",
|
194
|
-
flags=["--run"],
|
195
|
-
type_=bool,
|
196
|
-
help_="Run the notebook files when loaded",
|
197
|
-
default=False,
|
198
|
-
description="""
|
199
|
-
If set, notebooks will be run automatically when opened, or if previewing a
|
200
|
-
file, the notebooks will be run before being output.
|
201
|
-
""",
|
202
|
-
)
|
203
|
-
|
204
|
-
add_setting(
|
205
|
-
name="save",
|
206
|
-
flags=["--save"],
|
207
|
-
type_=bool,
|
208
|
-
help_="Save the notebook after running it",
|
209
|
-
default=False,
|
210
|
-
description="""
|
211
|
-
If set, notebooks will be saved after they have been run. This setting only
|
212
|
-
has any affect if the :option:`run` setting is active.
|
213
|
-
""",
|
214
|
-
)
|
215
|
-
|
216
|
-
add_setting(
|
217
|
-
name="show_filenames",
|
218
|
-
flags=["--show-filenames"],
|
219
|
-
type_=bool,
|
220
|
-
help_="Show the notebook filenames when previewing multiple notebooks",
|
221
|
-
default=False,
|
222
|
-
description="""
|
223
|
-
If set, the notebook filenames will be printed above each notebook's output
|
224
|
-
when multiple notebooks are being previewed.
|
225
|
-
""",
|
226
|
-
)
|
227
|
-
|
228
|
-
add_setting(
|
229
|
-
name="cell_start",
|
230
|
-
flags=["--cell-start"],
|
231
|
-
type_=int,
|
232
|
-
help_="The first cell to include in the preview",
|
233
|
-
default=None,
|
234
|
-
description="""
|
235
|
-
When set, only cells after the given cell index will be shown.
|
236
|
-
""",
|
237
|
-
)
|
238
|
-
|
239
|
-
add_setting(
|
240
|
-
name="cell_stop",
|
241
|
-
flags=["--cell-stop"],
|
242
|
-
type_=int,
|
243
|
-
help_="The last cell to include in the preview",
|
244
|
-
default=None,
|
245
|
-
description="""
|
246
|
-
When set, only cells before the given cell index will be shown.
|
247
|
-
""",
|
248
|
-
)
|
euporie/web/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"""A euporie web viewer component."""
|
@@ -0,0 +1,14 @@
|
|
1
|
+
"""Tabs for use in euporie notebook editor."""
|
2
|
+
|
3
|
+
from euporie.core.tabs import _TAB_REGISTRY, TabRegistryEntry
|
4
|
+
|
5
|
+
_TAB_REGISTRY.extend(
|
6
|
+
[
|
7
|
+
TabRegistryEntry(
|
8
|
+
path="euporie.web.tabs.web:WebTab",
|
9
|
+
name="Web Viewer",
|
10
|
+
mime_types={"text/html", "text/markdown"},
|
11
|
+
weight=2,
|
12
|
+
),
|
13
|
+
]
|
14
|
+
)
|
euporie/web/tabs/web.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
+
import asyncio
|
5
6
|
import logging
|
6
7
|
from typing import TYPE_CHECKING
|
7
8
|
|
@@ -10,13 +11,12 @@ from prompt_toolkit.layout.containers import HSplit, VSplit
|
|
10
11
|
from prompt_toolkit.layout.dimension import Dimension
|
11
12
|
from upath import UPath
|
12
13
|
|
14
|
+
from euporie.core.app.current import get_app
|
13
15
|
from euporie.core.convert.mime import get_mime
|
14
|
-
from euporie.core.current import get_app
|
15
16
|
from euporie.core.data_structures import DiBool
|
16
17
|
from euporie.core.layout.decor import FocusedStyle
|
17
18
|
from euporie.core.margins import MarginContainer, ScrollbarMargin
|
18
19
|
from euporie.core.tabs.base import Tab
|
19
|
-
from euporie.core.utils import run_in_thread_with_context
|
20
20
|
from euporie.core.widgets.display import DisplayWindow
|
21
21
|
from euporie.core.widgets.forms import Button, Text
|
22
22
|
from euporie.web.widgets.webview import WebViewControl
|
@@ -27,8 +27,8 @@ if TYPE_CHECKING:
|
|
27
27
|
|
28
28
|
from prompt_toolkit.layout.containers import AnyContainer
|
29
29
|
|
30
|
-
from euporie.core.app import BaseApp
|
31
|
-
from euporie.core.
|
30
|
+
from euporie.core.app.app import BaseApp
|
31
|
+
from euporie.core.bars.status import StatusBarFields
|
32
32
|
|
33
33
|
log = logging.getLogger(__name__)
|
34
34
|
|
@@ -45,14 +45,19 @@ class WebTab(Tab):
|
|
45
45
|
super().__init__(app, path)
|
46
46
|
self.status: Callable[[], StatusBarFields] | None = None
|
47
47
|
|
48
|
+
# self.container = self.load_container()
|
49
|
+
|
48
50
|
def _load() -> None:
|
51
|
+
old_container = self.container
|
49
52
|
self.container = self.load_container()
|
53
|
+
if self.app.layout.has_focus(old_container):
|
54
|
+
self.focus()
|
55
|
+
self.app.invalidate()
|
50
56
|
|
51
|
-
|
57
|
+
self._load_task = app.create_background_task(asyncio.to_thread(_load))
|
52
58
|
|
53
59
|
def focus(self) -> None:
|
54
60
|
"""Focus the webview when this tab is focused."""
|
55
|
-
super().focus()
|
56
61
|
self.app.layout.focus(self.webview)
|
57
62
|
|
58
63
|
@property
|
@@ -0,0 +1 @@
|
|
1
|
+
"""Contain widgets used in the web viewer."""
|
euporie/web/widgets/webview.py
CHANGED
@@ -17,10 +17,10 @@ from prompt_toolkit.mouse_events import MouseButton, MouseEvent, MouseEventType
|
|
17
17
|
from prompt_toolkit.utils import Event
|
18
18
|
from upath import UPath
|
19
19
|
|
20
|
+
from euporie.core.app.current import get_app
|
20
21
|
from euporie.core.commands import add_cmd
|
21
22
|
from euporie.core.convert.datum import Datum, get_loop
|
22
23
|
from euporie.core.convert.mime import get_format
|
23
|
-
from euporie.core.current import get_app
|
24
24
|
from euporie.core.ft.html import HTML, Node
|
25
25
|
from euporie.core.ft.utils import fragment_list_width, paste
|
26
26
|
from euporie.core.graphics import GraphicProcessor
|
@@ -31,9 +31,10 @@ from euporie.core.key_binding.registry import (
|
|
31
31
|
from euporie.core.path import parse_path
|
32
32
|
|
33
33
|
if TYPE_CHECKING:
|
34
|
+
from collections.abc import Iterable
|
34
35
|
from concurrent.futures._base import Future
|
35
36
|
from pathlib import Path
|
36
|
-
from typing import Any, Callable
|
37
|
+
from typing import Any, Callable
|
37
38
|
|
38
39
|
from prompt_toolkit.formatted_text.base import AnyFormattedText, StyleAndTextTuples
|
39
40
|
from prompt_toolkit.key_binding.key_bindings import (
|
@@ -102,9 +103,6 @@ class WebViewControl(UIControl):
|
|
102
103
|
self._dom_cache: FastDictCache[tuple[Path], HTML] = FastDictCache(
|
103
104
|
get_value=self.get_dom, size=100
|
104
105
|
)
|
105
|
-
self._line_cache: FastDictCache[
|
106
|
-
tuple[HTML, int, int], list[StyleAndTextTuples]
|
107
|
-
] = FastDictCache(get_value=self.get_lines, size=100_000)
|
108
106
|
self._content_cache: FastDictCache = FastDictCache(self.get_content, size=1_000)
|
109
107
|
|
110
108
|
self.load_url(url)
|
@@ -134,16 +132,14 @@ class WebViewControl(UIControl):
|
|
134
132
|
if changed:
|
135
133
|
self.on_cursor_position_changed.fire()
|
136
134
|
|
137
|
-
def get_dom(self, url: Path
|
135
|
+
def get_dom(self, url: Path) -> HTML:
|
138
136
|
"""Load a HTML page as renderable formatted text."""
|
139
137
|
markup = str(
|
140
138
|
Datum(
|
141
139
|
data=url.read_text(),
|
142
140
|
format=(format_ := get_format(url, default="html")),
|
143
141
|
path=url,
|
144
|
-
).convert(
|
145
|
-
to="html",
|
146
|
-
)
|
142
|
+
).convert(to="html")
|
147
143
|
)
|
148
144
|
return HTML(
|
149
145
|
markup=markup,
|
@@ -174,12 +170,6 @@ class WebViewControl(UIControl):
|
|
174
170
|
return dom.title
|
175
171
|
return ""
|
176
172
|
|
177
|
-
def get_lines(
|
178
|
-
self, dom: HTML, width: int, height: int, assets_loaded: bool = False
|
179
|
-
) -> list[StyleAndTextTuples]:
|
180
|
-
"""Render a HTML page as lines of formatted text."""
|
181
|
-
return list(split_lines(dom.render(width, height)))
|
182
|
-
|
183
173
|
def load_url(self, url: str | Path, **kwargs: Any) -> None:
|
184
174
|
"""Load a new URL."""
|
185
175
|
save_to_history = kwargs.get("save_to_history", True)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: euporie
|
3
|
-
Version: 2.8.
|
3
|
+
Version: 2.8.6
|
4
4
|
Summary: Euporie is a suite of terminal applications for interacting with Jupyter kernels
|
5
5
|
Project-URL: Documentation, https://euporie.readthedocs.io/en/latest
|
6
6
|
Project-URL: Issues, https://github.com/joouha/euporie/issues
|
@@ -13,15 +13,15 @@ Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: Environment :: Console
|
14
14
|
Classifier: Framework :: Jupyter
|
15
15
|
Classifier: Programming Language :: Python
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
17
16
|
Classifier: Programming Language :: Python :: 3.9
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
20
21
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
21
22
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
22
23
|
Classifier: Topic :: Scientific/Engineering
|
23
|
-
Requires-Python: >=3.
|
24
|
-
Requires-Dist: aenum<=3.1.12,~=3.1
|
24
|
+
Requires-Python: >=3.9
|
25
25
|
Requires-Dist: fastjsonschema~=2.15
|
26
26
|
Requires-Dist: flatlatex~=0.15
|
27
27
|
Requires-Dist: fsspec[http]>=2022.12.0
|
@@ -37,12 +37,12 @@ Requires-Dist: platformdirs~=3.5
|
|
37
37
|
Requires-Dist: prompt-toolkit~=3.0.36
|
38
38
|
Requires-Dist: pygments~=2.11
|
39
39
|
Requires-Dist: pyperclip~=1.8
|
40
|
-
Requires-Dist: sixelcrop~=0.1.
|
40
|
+
Requires-Dist: sixelcrop~=0.1.9
|
41
41
|
Requires-Dist: timg~=1.1.6
|
42
42
|
Requires-Dist: typing-extensions~=4.5
|
43
43
|
Requires-Dist: universal-pathlib~=0.2.1
|
44
44
|
Provides-Extra: hub
|
45
|
-
Requires-Dist: asyncssh~=2.
|
45
|
+
Requires-Dist: asyncssh~=2.18; extra == 'hub'
|
46
46
|
Description-Content-Type: text/x-rst
|
47
47
|
|
48
48
|
|logo|
|
@@ -85,10 +85,12 @@ If you're working with Jupyter notebooks in a terminal only environment, like an
|
|
85
85
|
Install
|
86
86
|
*******
|
87
87
|
|
88
|
-
You can install euporie with `pipx <https://pipxproject.github.io/>`_
|
88
|
+
You can install euporie with `uv <https://docs.astral.sh/uv/>`_ (recommended), or with `pipx <https://pipxproject.github.io/>`_ or ``pip``):
|
89
89
|
|
90
90
|
.. code-block:: console
|
91
91
|
|
92
|
+
$ uv tool install euporie
|
93
|
+
$ # OR
|
92
94
|
$ pipx install euporie
|
93
95
|
$ # OR
|
94
96
|
$ python -m pip install --user euporie
|