euporie 2.8.5__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.
Files changed (38) hide show
  1. euporie/core/__init__.py +1 -1
  2. euporie/core/__main__.py +2 -2
  3. euporie/core/_settings.py +7 -2
  4. euporie/core/app/_commands.py +26 -1
  5. euporie/core/app/_settings.py +34 -4
  6. euporie/core/app/app.py +18 -11
  7. euporie/core/bars/command.py +44 -21
  8. euporie/core/commands.py +0 -16
  9. euporie/core/filters.py +32 -9
  10. euporie/core/format.py +2 -3
  11. euporie/core/graphics.py +191 -31
  12. euporie/core/layout/scroll.py +35 -33
  13. euporie/core/log.py +1 -4
  14. euporie/core/path.py +61 -13
  15. euporie/core/tabs/__init__.py +2 -4
  16. euporie/core/tabs/base.py +73 -7
  17. euporie/core/tabs/kernel.py +2 -3
  18. euporie/core/tabs/notebook.py +14 -54
  19. euporie/core/utils.py +1 -18
  20. euporie/core/widgets/cell.py +1 -1
  21. euporie/core/widgets/dialog.py +32 -3
  22. euporie/core/widgets/display.py +2 -2
  23. euporie/core/widgets/menu.py +1 -1
  24. euporie/notebook/tabs/display.py +2 -2
  25. euporie/notebook/tabs/edit.py +8 -43
  26. euporie/notebook/tabs/json.py +2 -2
  27. euporie/web/__init__.py +1 -0
  28. euporie/web/tabs/__init__.py +14 -0
  29. euporie/web/tabs/web.py +10 -4
  30. euporie/web/widgets/__init__.py +1 -0
  31. euporie/web/widgets/webview.py +2 -4
  32. {euporie-2.8.5.dist-info → euporie-2.8.6.dist-info}/METADATA +4 -2
  33. {euporie-2.8.5.dist-info → euporie-2.8.6.dist-info}/RECORD +38 -35
  34. {euporie-2.8.5.data → euporie-2.8.6.data}/data/share/applications/euporie-console.desktop +0 -0
  35. {euporie-2.8.5.data → euporie-2.8.6.data}/data/share/applications/euporie-notebook.desktop +0 -0
  36. {euporie-2.8.5.dist-info → euporie-2.8.6.dist-info}/WHEEL +0 -0
  37. {euporie-2.8.5.dist-info → euporie-2.8.6.dist-info}/entry_points.txt +0 -0
  38. {euporie-2.8.5.dist-info → euporie-2.8.6.dist-info}/licenses/LICENSE +0 -0
@@ -33,7 +33,6 @@ from euporie.core.inspection import (
33
33
  from euporie.core.kernel.client import Kernel, MsgCallbacks
34
34
  from euporie.core.suggest import HistoryAutoSuggest
35
35
  from euporie.core.tabs.base import Tab
36
- from euporie.core.utils import run_in_thread_with_context
37
36
 
38
37
  if TYPE_CHECKING:
39
38
  from collections.abc import Sequence
@@ -97,8 +96,8 @@ class KernelTab(Tab, metaclass=ABCMeta):
97
96
 
98
97
  if self.bg_init:
99
98
  # Load kernel in a background thread
100
- run_in_thread_with_context(
101
- partial(
99
+ app.create_background_task(
100
+ asyncio.to_thread(
102
101
  self.init_kernel, kernel, comms, use_kernel_history, connection_file
103
102
  )
104
103
  )
@@ -275,18 +275,15 @@ class BaseNotebook(KernelTab, metaclass=ABCMeta):
275
275
  else:
276
276
  super().close(cb)
277
277
 
278
- def save(self, path: Path | None = None, cb: Callable | None = None) -> None:
278
+ def write_file(self, path: Path) -> None:
279
279
  """Write the notebook's JSON to the current notebook's file.
280
280
 
281
281
  Additionally save the widget state to the notebook metadata.
282
282
 
283
283
  Args:
284
- path: An optional new path at which to save the tab
285
- cb: A callback to run if after saving the notebook.
284
+ path: An path at which to save the file
286
285
 
287
286
  """
288
- if path is not None:
289
- self.path = path
290
287
  if self.app.config.save_widget_state:
291
288
  self.json.setdefault("metadata", {})["widgets"] = {
292
289
  "application/vnd.jupyter.widget-state+json": {
@@ -299,58 +296,21 @@ class BaseNotebook(KernelTab, metaclass=ABCMeta):
299
296
  },
300
297
  }
301
298
  }
302
- if self.path is None or isinstance(self.path, UntitledPath):
303
- if dialog := self.app.dialogs.get("save-as"):
304
- dialog.show(tab=self, cb=cb)
305
- else:
306
- log.debug("Saving notebook..")
307
- self.saving = True
308
- self.app.invalidate()
309
- # Ensure parent path exists
310
- parent = self.path.parent
311
- parent.mkdir(exist_ok=True, parents=True)
312
- # Save to a temp file, then replace the original
313
- temp_path = parent / f".{self.path.stem}.tmp{self.path.suffix}"
314
- log.debug("Using temporary file %s", temp_path.name)
299
+ with path.open("w") as open_file:
315
300
  try:
316
- open_file = temp_path.open("w")
317
- except NotImplementedError:
318
- get_cmd("save-as").run()
319
- else:
301
+ write_nb(nb=nbformat.from_dict(self.json), fp=open_file)
302
+ except AssertionError:
320
303
  try:
321
- try:
322
- write_nb(nb=nbformat.from_dict(self.json), fp=open_file)
323
- except AssertionError:
324
- try:
325
- # Jupytext requires a filename if we don't give it a format
326
- write_nb(nb=nbformat.from_dict(self.json), fp=temp_path)
327
- except Exception:
328
- # Jupytext requires a format if the path has no extension
329
- # We just use ipynb as the default format
330
- write_nb(
331
- nb=nbformat.from_dict(self.json),
332
- fp=open_file,
333
- fmt="ipynb",
334
- )
304
+ # Jupytext requires a filename if we don't give it a format
305
+ write_nb(nb=nbformat.from_dict(self.json), fp=path)
335
306
  except Exception:
336
- log.exception("An error occurred while saving the file")
337
- if dialog := self.app.dialogs.get("save-as"):
338
- dialog.show(tab=self, cb=cb)
339
- else:
340
- open_file.close()
341
- try:
342
- temp_path.rename(self.path)
343
- except Exception:
344
- if dialog := self.app.dialogs.get("save-as"):
345
- dialog.show(tab=self, cb=cb)
346
- else:
347
- self.dirty = False
348
- self.saving = False
349
- self.app.invalidate()
350
- log.debug("Notebook saved")
351
- # Run the callback
352
- if callable(cb):
353
- cb()
307
+ # Jupytext requires a format if the path has no extension
308
+ # We just use ipynb as the default format
309
+ write_nb(
310
+ nb=nbformat.from_dict(self.json),
311
+ fp=open_file,
312
+ fmt="ipynb",
313
+ )
354
314
 
355
315
  def run_cell(
356
316
  self,
euporie/core/utils.py CHANGED
@@ -2,11 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import contextvars
6
5
  from collections.abc import Sequence
7
6
  from functools import cache
8
7
  from itertools import chain
9
- from threading import Thread
10
8
  from typing import TYPE_CHECKING, TypeVar, overload
11
9
 
12
10
  from prompt_toolkit.mouse_events import MouseButton, MouseEventType
@@ -14,7 +12,7 @@ from prompt_toolkit.mouse_events import MouseButton, MouseEventType
14
12
  if TYPE_CHECKING:
15
13
  from collections.abc import Iterable
16
14
  from types import ModuleType
17
- from typing import Any, Callable
15
+ from typing import Callable
18
16
 
19
17
  from prompt_toolkit.key_binding.key_bindings import NotImplementedOrNone
20
18
  from prompt_toolkit.layout.mouse_handlers import MouseHandler
@@ -78,21 +76,6 @@ def on_click(func: Callable) -> MouseHandler:
78
76
  return _mouse_handler
79
77
 
80
78
 
81
- def run_in_thread_with_context(
82
- func: Callable, *args: Any, daemon: bool = True, **kwargs: Any
83
- ) -> None:
84
- """Run a function in an thread, but make sure it uses the same contextvars.
85
-
86
- This is required so that the function will see the right application.
87
- """
88
- Thread(
89
- target=contextvars.copy_context().run,
90
- args=(func, *args),
91
- kwargs=kwargs,
92
- daemon=daemon,
93
- ).start()
94
-
95
-
96
79
  @cache
97
80
  def root_module(name: str) -> ModuleType:
98
81
  """Find and load the root module of a given module name by traversing up the module hierarchy.
@@ -172,7 +172,7 @@ class Cell:
172
172
  # Now we generate the main container used to represent a kernel_tab cell
173
173
 
174
174
  source_hidden = Condition(
175
- lambda: weak_self.json["metadata"]
175
+ lambda: weak_self.json.get("metadata", {})
176
176
  .get("jupyter", {})
177
177
  .get("source_hidden", False)
178
178
  )
@@ -40,7 +40,7 @@ from euporie.core.border import (
40
40
  UpperRightHalfLine,
41
41
  )
42
42
  from euporie.core.commands import add_cmd
43
- from euporie.core.filters import tab_has_focus
43
+ from euporie.core.filters import tab_can_save
44
44
  from euporie.core.ft.utils import FormattedTextAlign, align, lex
45
45
  from euporie.core.key_binding.registry import register_bindings
46
46
  from euporie.core.layout.containers import HSplit, VSplit, Window
@@ -602,7 +602,7 @@ class SaveAsDialog(FileDialog):
602
602
  @staticmethod
603
603
  @add_cmd(
604
604
  menu_title="Save As…",
605
- filter=tab_has_focus,
605
+ filter=tab_can_save,
606
606
  )
607
607
  def _save_as() -> None:
608
608
  """Save the current file at a new location."""
@@ -834,7 +834,36 @@ class ErrorDialog(Dialog):
834
834
  def _copy_traceback() -> None:
835
835
  self.app.clipboard.set_data(ClipboardData(tb_text))
836
836
 
837
- self.buttons = {"Close": None, "Copy Traceback": _copy_traceback}
837
+ def _report() -> None:
838
+ import webbrowser
839
+ from importlib.metadata import metadata
840
+ from urllib.parse import urlencode, urlparse, urlunparse
841
+
842
+ data = metadata("euporie")
843
+ if issue_url := dict(
844
+ x.split(", ", 1) for x in data.json["project_url"]
845
+ ).get("Issues"):
846
+ parsed_url = urlparse(issue_url)
847
+ url = urlunparse(
848
+ parsed_url._replace(
849
+ path=f"{parsed_url.path.rstrip('/')}/new"
850
+ )._replace(
851
+ query=urlencode(
852
+ {
853
+ "title": f"Error: {exception!r}",
854
+ "body": "(Please describe what you did)\n\n"
855
+ f"## Traceback\n\n```python\n{tb_text}\n```\n",
856
+ }
857
+ )
858
+ )
859
+ )
860
+ webbrowser.open(url, new=2, autoraise=True)
861
+
862
+ self.buttons = {
863
+ "Report on GitHub": _report,
864
+ "Copy Traceback": _copy_traceback,
865
+ "Close": None,
866
+ }
838
867
 
839
868
 
840
869
  class UnsavedDialog(Dialog):
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import asyncio
5
6
  import logging
6
7
  from functools import partial
7
8
  from math import ceil
@@ -28,7 +29,6 @@ from euporie.core.key_binding.registry import (
28
29
  )
29
30
  from euporie.core.layout.containers import VSplit, Window
30
31
  from euporie.core.margins import MarginContainer, ScrollbarMargin
31
- from euporie.core.utils import run_in_thread_with_context
32
32
 
33
33
  if TYPE_CHECKING:
34
34
  from collections.abc import Iterable
@@ -217,7 +217,7 @@ class DisplayControl(UIControl):
217
217
  if not self.rendering:
218
218
  self.rendering = True
219
219
  if self.threaded:
220
- run_in_thread_with_context(_render)
220
+ get_app().create_background_task(asyncio.to_thread(_render))
221
221
  else:
222
222
  _render()
223
223
 
@@ -150,7 +150,7 @@ class MenuItem:
150
150
  """Create a menu item from a command."""
151
151
  return cls(
152
152
  formatted_text=command.menu_title,
153
- handler=command.menu_handler,
153
+ handler=command.run,
154
154
  shortcut=command.key_str,
155
155
  disabled=~command.filter,
156
156
  hidden=command.hidden,
@@ -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, ClassVar
7
8
 
@@ -12,7 +13,6 @@ from euporie.core.convert.datum import Datum
12
13
  from euporie.core.convert.mime import MIME_FORMATS, get_format
13
14
  from euporie.core.margins import MarginContainer, ScrollbarMargin
14
15
  from euporie.core.tabs.base import Tab
15
- from euporie.core.utils import run_in_thread_with_context
16
16
  from euporie.core.widgets.display import Display
17
17
 
18
18
  if TYPE_CHECKING:
@@ -44,7 +44,7 @@ class DisplayTab(Tab):
44
44
  self.app.layout.focus(self.container)
45
45
  self.app.invalidate()
46
46
 
47
- run_in_thread_with_context(_load)
47
+ app.create_background_task(asyncio.to_thread(_load))
48
48
 
49
49
  def __pt_status__(self) -> StatusBarFields | None:
50
50
  """Return a list of statusbar field values shown then this tab is active."""
@@ -154,46 +154,11 @@ class EditorTab(KernelTab):
154
154
  ),
155
155
  )
156
156
 
157
- def save(self, path: Path | None = None, cb: Callable | None = None) -> None:
158
- """Save the current file."""
159
- if path is not None:
160
- self.path = path
161
-
162
- if isinstance(self.path, UntitledPath):
163
- if dialog := self.app.dialogs.get("save-as"):
164
- dialog.show(tab=self, cb=cb)
165
- else:
166
- log.debug("Saving file...")
167
- self.saving = True
168
- self.app.invalidate()
169
- # Ensure parent path exists
170
- parent = self.path.parent
171
- parent.mkdir(exist_ok=True, parents=True)
172
- # Save to a temp file, then replace the original
173
- temp_path = parent / f".{self.path.stem}.tmp{self.path.suffix}"
174
- log.debug("Using temporary file %s", temp_path.name)
175
- try:
176
- open_file = temp_path.open("w")
177
- except NotImplementedError:
178
- if dialog := self.app.dialogs.get("save-as"):
179
- dialog.show(tab=self, cb=cb)
180
- else:
181
- try:
182
- open_file.write(self.input_box.buffer.text)
183
- except Exception:
184
- if dialog := self.app.dialogs.get("save-as"):
185
- dialog.show(tab=self, cb=cb)
186
- else:
187
- try:
188
- temp_path.rename(self.path)
189
- except Exception:
190
- if dialog := self.app.dialogs.get("save-as"):
191
- dialog.show(tab=self, cb=cb)
192
- else:
193
- self.dirty = False
194
- self.saving = False
195
- self.app.invalidate()
196
- log.debug("File saved")
197
- # Run the callback
198
- if callable(cb):
199
- cb()
157
+ def write_file(self, path: Path) -> None:
158
+ """Write the file's text data to a path.
159
+
160
+ Args:
161
+ path: An path at which to save the file
162
+
163
+ """
164
+ path.write_text(self.input_box.buffer.text)
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import asyncio
5
6
  import json
6
7
  import logging
7
8
  from typing import TYPE_CHECKING, ClassVar
@@ -10,7 +11,6 @@ from prompt_toolkit.layout.containers import VSplit
10
11
  from prompt_toolkit.layout.dimension import Dimension
11
12
 
12
13
  from euporie.core.tabs.base import Tab
13
- from euporie.core.utils import run_in_thread_with_context
14
14
  from euporie.core.widgets.tree import JsonView
15
15
 
16
16
  if TYPE_CHECKING:
@@ -43,7 +43,7 @@ class JsonTab(Tab):
43
43
  self.app.layout.focus(self.container)
44
44
  self.app.invalidate()
45
45
 
46
- run_in_thread_with_context(_load)
46
+ app.create_background_task(asyncio.to_thread(_load))
47
47
 
48
48
  def __pt_status__(self) -> StatusBarFields | None:
49
49
  """Return a list of statusbar field values shown then this tab is active."""
@@ -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
 
@@ -16,14 +17,13 @@ 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
23
23
 
24
24
  if TYPE_CHECKING:
25
25
  from pathlib import Path
26
- from typing import Any, Callable
26
+ from typing import Any, Callable, ClassVar
27
27
 
28
28
  from prompt_toolkit.layout.containers import AnyContainer
29
29
 
@@ -38,20 +38,26 @@ class WebTab(Tab):
38
38
 
39
39
  name = "Web Viewer"
40
40
  weight = 2
41
+ mime_types: ClassVar[set[str]] = {"text/html", "text/markdown"}
41
42
 
42
43
  def __init__(self, app: BaseApp, path: Path | None) -> None:
43
44
  """Call when the tab is created."""
44
45
  super().__init__(app, path)
45
46
  self.status: Callable[[], StatusBarFields] | None = None
46
47
 
48
+ # self.container = self.load_container()
49
+
47
50
  def _load() -> None:
51
+ old_container = self.container
48
52
  self.container = self.load_container()
53
+ if self.app.layout.has_focus(old_container):
54
+ self.focus()
55
+ self.app.invalidate()
49
56
 
50
- run_in_thread_with_context(_load)
57
+ self._load_task = app.create_background_task(asyncio.to_thread(_load))
51
58
 
52
59
  def focus(self) -> None:
53
60
  """Focus the webview when this tab is focused."""
54
- super().focus()
55
61
  self.app.layout.focus(self.webview)
56
62
 
57
63
  @property
@@ -0,0 +1 @@
1
+ """Contain widgets used in the web viewer."""
@@ -132,16 +132,14 @@ class WebViewControl(UIControl):
132
132
  if changed:
133
133
  self.on_cursor_position_changed.fire()
134
134
 
135
- def get_dom(self, url: Path, x: bool = False) -> HTML:
135
+ def get_dom(self, url: Path) -> HTML:
136
136
  """Load a HTML page as renderable formatted text."""
137
137
  markup = str(
138
138
  Datum(
139
139
  data=url.read_text(),
140
140
  format=(format_ := get_format(url, default="html")),
141
141
  path=url,
142
- ).convert(
143
- to="html",
144
- )
142
+ ).convert(to="html")
145
143
  )
146
144
  return HTML(
147
145
  markup=markup,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: euporie
3
- Version: 2.8.5
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
@@ -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/>`_ (recommended) or ``pip``:
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
@@ -6,28 +6,28 @@ euporie/console/app.py,sha256=cNYdKABGXpH6GMxIyE9OAn5uR-bnM2aSOa7FLcghTyA,5663
6
6
  euporie/console/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  euporie/console/tabs/__init__.py,sha256=Grm9EO1gnBO1o-k6Nqnlzo8XLIgFZSXNAdz49Vvh4zY,55
8
8
  euporie/console/tabs/console.py,sha256=370iUk9HKG0D8tTZ043b5XEF14bVDqe8XxrDf7PRxgw,31267
9
- euporie/core/__init__.py,sha256=MieVj9t7Kw-nlTylEe1fTf3ZvyVQqpBIc2TaNRVAZYo,313
10
- euporie/core/__main__.py,sha256=NshbuP78pqo7qx4P0_VVE_nqXa-rl76G4OFarworpm0,1292
11
- euporie/core/_settings.py,sha256=pjZZJmyBjVMjr2cH6w3ANAugqKXofCxBGVWRc1PZ7Lw,2873
9
+ euporie/core/__init__.py,sha256=pNVMlR2a7HBgedRtB5CsaSI19Keb-w_Ei-zrZ8BVBt4,313
10
+ euporie/core/__main__.py,sha256=QkRamWXgrPiRj7h4sYNhHNpVOUJuEpRuvZE-YLK1dUU,1255
11
+ euporie/core/_settings.py,sha256=JspB4eMUXry4r5g4Wzn4aV0FmzSVmWf1G96Jcr5bcDE,2937
12
12
  euporie/core/border.py,sha256=kJbpyxwJBtIRpFOpXhDtaCT1_oyVRjRiYKG4lXn3-iA,48507
13
13
  euporie/core/clipboard.py,sha256=A2LdeyWKWuG0rPy6QoefmBbRtOtpzz_R6FLwBfU5Dr4,2060
14
- euporie/core/commands.py,sha256=J7Unzj1cEcgP-3n_Frvgjd0CjjvHSb2YvegrzQQgx00,8518
14
+ euporie/core/commands.py,sha256=aGO9vKwcDiCP71NjOvKysKH6A99ewEhBzrejJ2V_TJk,7969
15
15
  euporie/core/completion.py,sha256=cy_eAusesqd4UV4Nl1bNPAEoQ0MDqGLVNmvQ2rClOmw,5516
16
16
  euporie/core/config.py,sha256=ngRZ8MRhDMiJEmQhPtfZb3Kf8Rfij4Rp7nTH0armch8,25137
17
17
  euporie/core/data_structures.py,sha256=eA54Cg305R1mVX6YGTRPIvTN4piEFKrltehif49l92o,1800
18
18
  euporie/core/diagnostics.py,sha256=KywmOqa1_Lfk5SsO1Fd0Vl801DvVKvAD4pOOpdLijAM,1680
19
- euporie/core/filters.py,sha256=8vnVkasT1pXbY4ObAJ0wfhjMSHLUjHzk_hbpfSwVZBs,9328
20
- euporie/core/format.py,sha256=oFlD3aX_uVeLhqxo2n-zaUBsiNKpWqhx6W-5arFY5C4,4154
21
- euporie/core/graphics.py,sha256=jFGWUAmoG0aPrZ0Jm5yz8W4ce6BcT0hDfklpFV8N_3U,36966
19
+ euporie/core/filters.py,sha256=3OEu0pnF8Soi9MsLcbAw46cQ6g8s7e-wQVb_usdkyHQ,9971
20
+ euporie/core/format.py,sha256=D8svQC9ZFO4rSkjtTIaRTfZ32KRgIN12KTjEeqM5Hag,4163
21
+ euporie/core/graphics.py,sha256=947_AUmgptPjew16pSyWM15-vuy3dcbdUMbmJs2TDUo,45268
22
22
  euporie/core/history.py,sha256=l-QxzSLbzws3fmrZEIrHVv8ucw0PuCYBOcMyAODMlP0,2558
23
23
  euporie/core/inspection.py,sha256=HG78a9LQ8vK_DGlSAbzzvvZ3npa2i1zuTprCrhT4H8I,2601
24
24
  euporie/core/io.py,sha256=VrTfRcU6B-hsFhrNcdG_oC6dR1Q9jCMTpL8PPBjhE3g,10981
25
25
  euporie/core/keys.py,sha256=Fhes_MnAjHd2x6fajzeM5VHF-XKYb0lEGDsvAURzwmM,411217
26
26
  euporie/core/lexers.py,sha256=AXNDYOR0BZf0sYj9o8YSb0oF4AGYZdKygwFIUKJ3XFM,1083
27
- euporie/core/log.py,sha256=-DDGwvBA22th5bX7tJcrLLyQTX-mGIyAqQB2wT1-5Yo,17293
27
+ euporie/core/log.py,sha256=XlwQDE8iK_K65tZFlywR-XO74geTTZOHsj7cwyrNf5g,17216
28
28
  euporie/core/lsp.py,sha256=bez_TPAfGXfVP_PbjbNH1woZIHTmrH2gvt3yV5E64o0,52952
29
29
  euporie/core/margins.py,sha256=mKnlUO1QaSMGqA_VsRfvpuvZrZyGLppm-zyniZnXPXk,24946
30
- euporie/core/path.py,sha256=ucQ9ijfqhIcY-SxgGl07a1qLK0rq10drZqfc-MRZI-k,2306
30
+ euporie/core/path.py,sha256=3Pa6hMS0sHWm5vC3kDooen1Rya-UFYVlJaxv2IcryQ0,3873
31
31
  euporie/core/processors.py,sha256=63vwLEuSdp5B_PuQ-zv--qtC05GTlbhXVojISzHUnIk,5478
32
32
  euporie/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  euporie/core/pygments.py,sha256=TE3VrZ-QKe4n6hmoYuNmt0l0XR6qmko7JvO5YHSt_rU,2588
@@ -35,19 +35,19 @@ euporie/core/reference.py,sha256=x8-7405xgTEcK7ImqikQtVAXXqFanz61UQ3mn7v_4-o,650
35
35
  euporie/core/renderer.py,sha256=JNqDP3y7NbM_y-JJZUNWy3qH4H3Et2hPRaM0YtLUTxM,18760
36
36
  euporie/core/style.py,sha256=CJUzs0s0sIiaxGL06kcBW8FzrS0yb4V_arQT6Da7dKU,34795
37
37
  euporie/core/suggest.py,sha256=2bDpp83j4cjIXYVc--XBUyKP0owP3z-ygK1qFGdkTHM,6094
38
- euporie/core/utils.py,sha256=t0otJYETOmMUPojAc6Ej26iBkclZSib2L3w9X9SkgTQ,6086
38
+ euporie/core/utils.py,sha256=ZfhvyLp5p9-FJg4AG9CywSf5UarPJtdfVZjeeTnEvgU,5611
39
39
  euporie/core/validation.py,sha256=xWWAk7uCzX5yU3qUOIyCv1eN-KfbnNdy1YLRJpHN_Cg,1187
40
40
  euporie/core/app/__init__.py,sha256=v5RgV1dRhKjWxojUE-hCNXRWIbEvYEYU7rL55fPaTno,88
41
- euporie/core/app/_commands.py,sha256=DXRP92hwVOwNaKXEJp4aVFdhaFhk12y3w_BMBtB0Otc,1685
42
- euporie/core/app/_settings.py,sha256=RgPE8bbBXv0BC7rwgNlL-xRzMfUEl20rbuVK6KBFu80,12132
43
- euporie/core/app/app.py,sha256=zjih0aPPhJ63jWaJTfh5s7lhnjsCnqLfkIITOQqcoHw,35404
41
+ euporie/core/app/_commands.py,sha256=8utEHyI1cm1GrxouthEVK5nvphrFdk-ntRdGnMQoPL4,2499
42
+ euporie/core/app/_settings.py,sha256=iHtUxVSkiuPOaDjW9dpg044HpgEV62XsqFIx1U3_bDQ,12797
43
+ euporie/core/app/app.py,sha256=SvXLMHCWfQHS43nuNR1hGSG-5v69JC8BvnNe9cvGqYU,35580
44
44
  euporie/core/app/base.py,sha256=an8aAKnLzSt1mr-JUY8QHAtpZ-RtCUIlNBR0oOsYn_E,1418
45
45
  euporie/core/app/current.py,sha256=u-5FXQUq9ikRxwb0fXI2_83uarPOMFLWRQ_7GDBQa5g,798
46
46
  euporie/core/app/cursor.py,sha256=O_zz7qw1Vn_OmsUI8jEwqPtYugKBGVLBtPhqu5ZboE4,1132
47
47
  euporie/core/app/dummy.py,sha256=hHCJUDwYOH1NmwVmtYz9SfGIgt57MjYoGGW5SrDnZw4,353
48
48
  euporie/core/app/launch.py,sha256=Uf16rnEc9VgH-skXiY252CsuV64c5A4OKOKEbpU9lpc,643
49
49
  euporie/core/bars/__init__.py,sha256=hZeIvEXxd3LPbwQND7G5VMV1x8Zn6kq3pDXQhkXA7_E,245
50
- euporie/core/bars/command.py,sha256=e-lgRBGkDNWbPHzvC-7JbGn1E9S2Tsllj-Uf_250E88,5989
50
+ euporie/core/bars/command.py,sha256=0GayANs6HH0L9oWfZXngllYFHazIRN5kp_WH-sScCxs,6870
51
51
  euporie/core/bars/menu.py,sha256=boFuIMYxWJ96bjqGGNGS19iZMoMGvXvF09RuihATnXk,9593
52
52
  euporie/core/bars/search.py,sha256=qTETqtWQXCGzOKN0IU4Nd662pUVZkOTn_0CKD2u6oEQ,12077
53
53
  euporie/core/bars/status.py,sha256=-00GMuatEXwUk86TmTJdJZ5nJKqhp1JjuwaTIgDw0LE,5082
@@ -104,26 +104,26 @@ euporie/core/layout/decor.py,sha256=aUJXdeDujk4hDG5uvEdF44sRBzTak12x1J5W7YQxfSk,
104
104
  euporie/core/layout/mouse.py,sha256=VgOzavrQoCpNcPozCVx-o8yhNBODvANHNaIMGBijKeA,5169
105
105
  euporie/core/layout/print.py,sha256=gAqApRCTh13A74Uda7NoPAYCksacUzDnj6M2ftPyVig,5185
106
106
  euporie/core/layout/screen.py,sha256=0xP9ZErMcw51nPgBbrm-DSQqFq5WNvsh9fw1amz2Z28,2224
107
- euporie/core/layout/scroll.py,sha256=WMKnaY6ECIqPAOl9xdpNMzUwZncOyNCsVqwxYPqWVZs,32897
108
- euporie/core/tabs/__init__.py,sha256=eZRQcRy4cQs4Cgd1YeF9Q0yN7wtb6qjy5hC2yS6-ccA,928
107
+ euporie/core/layout/scroll.py,sha256=kZabqEkubOv9tRbM0Ul11zfkls-an9bVn6kxT5imuiU,32886
108
+ euporie/core/tabs/__init__.py,sha256=hweWdELxTTipDRGHKuHuCBrRvfKQOoT2LtLkxD3TRF4,817
109
109
  euporie/core/tabs/_settings.py,sha256=0oSzDwRu_SzmqUDCHp9Sy2JhU4HMA2zSjWLjc07OqAY,3156
110
- euporie/core/tabs/base.py,sha256=cFfeH0I2GtQzC9ItZeu9Sn9OP01n4WzzlYVmyG-KH_c,5077
111
- euporie/core/tabs/kernel.py,sha256=upavHFs7VuVzg_MSBa2-Tt8pjH32nKgCf3AWUyyWqOk,15646
112
- euporie/core/tabs/notebook.py,sha256=VXPtDe5-LEqPdaGazg2unai5EOybvJuhmYcXVXTNohQ,17035
110
+ euporie/core/tabs/base.py,sha256=Vxh9dwBAxJyrATq-sc6BsaGKUac3U8TElOtFfbAlD88,7189
111
+ euporie/core/tabs/kernel.py,sha256=yKBCwPXr8f6qg48Rn6G0Tdrs4OM5K8vZiO3RlyTT3eI,15598
112
+ euporie/core/tabs/notebook.py,sha256=ARshfGgQVKuyjNYXtDA8VDS_Yr-JqyPIWeQ_iruZ9NI,15153
113
113
  euporie/core/widgets/__init__.py,sha256=ektso_Ea1-pZB04alUujQsa2r-kv8xAF0SmQOv_bvHQ,52
114
114
  euporie/core/widgets/_settings.py,sha256=ARwoXb80MCPRR4RHnDGcGMLQ9wvP5QZBikXLv7seVAY,4774
115
- euporie/core/widgets/cell.py,sha256=qjilhDW-l5DCUb6cZNUX9YGo8gkhq4WxTUxaUFFyW1c,33846
115
+ euporie/core/widgets/cell.py,sha256=KyycXyhxwqiGg8b8u3Nys_WsmG8lSxKjzePDjWboqNU,33854
116
116
  euporie/core/widgets/cell_outputs.py,sha256=iRPd3jPnMZVBq7Zg7OHIhlDGmsS0jkfru37xwp8Nll0,17008
117
117
  euporie/core/widgets/decor.py,sha256=_K3bSNpvAFdn5ZZyNFVjZPv6QV4fNIlNMdRpYjc4MU0,7895
118
- euporie/core/widgets/dialog.py,sha256=iQ6A4yr2pui-R91RbvMBErwacj-ppnRFdYTb02k9_KQ,33100
119
- euporie/core/widgets/display.py,sha256=JnfMg3z1KcE23AnuRZziAnWVYkIIuFSJqF64Abf3GWw,21575
118
+ euporie/core/widgets/dialog.py,sha256=tQkcTTWP-dil_WYrvy__sk-9cRBh7CWSMXkXCSlJ-rc,34199
119
+ euporie/core/widgets/display.py,sha256=Ht5INitUzG8-zY5jDbBNWarS_lgoH3559lJYS3OREtg,21557
120
120
  euporie/core/widgets/file_browser.py,sha256=jj8l5cpX7S6d1HlYXUg3TXdsvmhFneIOiotKpwCVgoQ,20050
121
121
  euporie/core/widgets/formatted_text_area.py,sha256=J7P_TNXPZKZkiBdjAVkPvkfRY1veXe4tzXU241k4b-Q,4037
122
122
  euporie/core/widgets/forms.py,sha256=kKrrkUh2aygJSuu_xAoA3z8Xh15M4U5W6F_lKg1Wc2I,85594
123
123
  euporie/core/widgets/inputs.py,sha256=As5VogmCy0ytMXMrVeth4K7Cu_fsN0K3WBDTjxOEwHw,20208
124
124
  euporie/core/widgets/layout.py,sha256=VVer3siFblvhG3IdsokQigjBNOasMJR-BzmnQYuU1LU,23538
125
125
  euporie/core/widgets/logo.py,sha256=VU9hSVAiguS5lI0EccQoPm8roAuQNgvFUO5IREvXWFo,1487
126
- euporie/core/widgets/menu.py,sha256=RExXL3-FSEQDAmKI7fDyF6B9wnQrm06gVEwOfvdwbWU,32880
126
+ euporie/core/widgets/menu.py,sha256=Ze_Hx04dkhmilkMsI7TdXMJmDvk28It_-8S3uvoar_M,32871
127
127
  euporie/core/widgets/pager.py,sha256=gEc68A_KSwttoXgI6d4JrXwRN4HsgTXxc0-i_QounjY,6413
128
128
  euporie/core/widgets/palette.py,sha256=gedT8628eMC9VgpGLNRQvmZbRWryJDMF-_7-bwb0rTg,10858
129
129
  euporie/core/widgets/tree.py,sha256=BG7QRsI2GzSJPReNQu9zWFjO0iy8TeJwrmCmP5dc2ek,3760
@@ -145,9 +145,9 @@ euporie/notebook/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
145
  euporie/notebook/tabs/__init__.py,sha256=JkFfg6tW3gbzRSUoC1lTeyDy_ZMHEfvknmvilW67UpA,1506
146
146
  euporie/notebook/tabs/_commands.py,sha256=wNPY84H_nWMO1fEwUuJ4oIK2wg4yfVmsA_y-ua3CZjM,19096
147
147
  euporie/notebook/tabs/_settings.py,sha256=-itfgWAk22SxA8ThdbVlHYfnv1PfYnvLTAKMjbJ90rs,766
148
- euporie/notebook/tabs/display.py,sha256=4xUrOmG8VrWtDBnpQpTopTr1aHFJ2icvWtxAaHSaeT8,2596
149
- euporie/notebook/tabs/edit.py,sha256=3gBjj-0nHRvT9iu9wByrtm-LwNP1aNNT4e_ZedcQnaA,6660
150
- euporie/notebook/tabs/json.py,sha256=ublrtQsrFBOSoLDurQQay9Ist5_9sf3FL8hSIwCx2_E,2192
148
+ euporie/notebook/tabs/display.py,sha256=SSRdbHPs34Wuu49WHnmJWmqT-lGiggB7Gf3_uvSFBHA,2572
149
+ euporie/notebook/tabs/edit.py,sha256=Djzlcf6pLEo-zMpcOBVU_Cd-dkgiBd70b24iGg0Tqk0,5081
150
+ euporie/notebook/tabs/json.py,sha256=mLm769FI9CueTgT2DpuzLB0Uhi2HnUUOZNIJ_xIVCI0,2168
151
151
  euporie/notebook/tabs/log.py,sha256=jKgsvkCNdQJ-6PzbG1tbRK-pR8DazPoemARHkOfH7fU,3062
152
152
  euporie/notebook/tabs/notebook.py,sha256=JtyPtyHckJlxU-aDwRIlk1IHNbFzEFQ6JrHn1UWtdAs,24072
153
153
  euporie/notebook/widgets/__init__.py,sha256=74tOl0bYuWkaKT-4pgD5zmdiIkoFYx8uGj4SxcLHLtQ,48
@@ -161,12 +161,15 @@ euporie/preview/app.py,sha256=jmmlrvkKN8ZK1277VGxbAc2ejZaXWj7FDN4loNl_dd0,7623
161
161
  euporie/preview/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
162
  euporie/preview/tabs/__init__.py,sha256=rY6DfQ-8qRo_AiICCD-zTyhJBnuMjawWDd8tRxR6q58,43
163
163
  euporie/preview/tabs/notebook.py,sha256=vbLKKssAB235xKWLgUNoaSBTjt0DbCcoJZjdCz3QaZM,6406
164
- euporie/web/tabs/web.py,sha256=pJ9AB9BnncYBSbj0SreMbKWGb2GfOz65jYzdcl4eDZc,5154
165
- euporie/web/widgets/webview.py,sha256=4LohRnbBNDK1603GcDYBASL6FyzPzQTfBW637IbXAvs,20414
166
- euporie-2.8.5.data/data/share/applications/euporie-console.desktop,sha256=DI08G0Dl2s5asM6afWUfkKvO5YmcBm-pWQZzUHiNnqc,153
167
- euporie-2.8.5.data/data/share/applications/euporie-notebook.desktop,sha256=RtpJzvizTDuOp0BLa2bLgVHx11LG6L7PL-oF-wHTsgU,155
168
- euporie-2.8.5.dist-info/METADATA,sha256=kOnH8_69FjDw0CuMKvU1RwveX4sWXQV6oBPcMvznY50,6430
169
- euporie-2.8.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
170
- euporie-2.8.5.dist-info/entry_points.txt,sha256=d53wF7X_94DSfKmr0Rq4MqWsSkDUko2TfCKpWUQ8ViA,790
171
- euporie-2.8.5.dist-info/licenses/LICENSE,sha256=qk66SWkX4TkJwDMw8-KC3KMkOScd_LTl-nQdlM-vjQM,1079
172
- euporie-2.8.5.dist-info/RECORD,,
164
+ euporie/web/__init__.py,sha256=wE-4WBbzcpWVu5YisLrUhYOn3ZlBK2YZryjc1r96qrY,38
165
+ euporie/web/tabs/__init__.py,sha256=0DbkceML8N_qefZFZB7CJQw_FX0gkuNdabQoEu0zV9E,340
166
+ euporie/web/tabs/web.py,sha256=Jnr4edvZLvwMgDCe3XrdR4Pi6yK0XmC2iWoc-vlEKI8,5415
167
+ euporie/web/widgets/__init__.py,sha256=xIxCPl9KiisYgsX-V1LvDT6BETZRF3nC-ZsP8DP7nOY,46
168
+ euporie/web/widgets/webview.py,sha256=nLfkKhxmOXcyqy1GjczVR_i4vvq5j65tB32DFmCeJ1s,20366
169
+ euporie-2.8.6.data/data/share/applications/euporie-console.desktop,sha256=DI08G0Dl2s5asM6afWUfkKvO5YmcBm-pWQZzUHiNnqc,153
170
+ euporie-2.8.6.data/data/share/applications/euporie-notebook.desktop,sha256=RtpJzvizTDuOp0BLa2bLgVHx11LG6L7PL-oF-wHTsgU,155
171
+ euporie-2.8.6.dist-info/METADATA,sha256=PYlbl9WoDEJy9nBW26IbDPqZLchL-BeXXmBj8Xd9RAQ,6515
172
+ euporie-2.8.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
173
+ euporie-2.8.6.dist-info/entry_points.txt,sha256=d53wF7X_94DSfKmr0Rq4MqWsSkDUko2TfCKpWUQ8ViA,790
174
+ euporie-2.8.6.dist-info/licenses/LICENSE,sha256=qk66SWkX4TkJwDMw8-KC3KMkOScd_LTl-nQdlM-vjQM,1079
175
+ euporie-2.8.6.dist-info/RECORD,,