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
euporie/core/ft/html.py CHANGED
@@ -15,7 +15,6 @@ from math import ceil
15
15
  from operator import eq, ge, gt, le, lt
16
16
  from typing import TYPE_CHECKING, NamedTuple, cast, overload
17
17
 
18
- from flatlatex.data import subscript, superscript
19
18
  from fsspec.core import url_to_fs
20
19
  from prompt_toolkit.application.current import get_app_session
21
20
  from prompt_toolkit.data_structures import Size
@@ -28,6 +27,7 @@ from prompt_toolkit.layout.dimension import Dimension
28
27
  from prompt_toolkit.utils import Event
29
28
  from upath import UPath
30
29
 
30
+ from euporie.core.app.current import get_app
31
31
  from euporie.core.border import (
32
32
  DiLineStyle,
33
33
  DoubleLine,
@@ -51,7 +51,6 @@ from euporie.core.border import (
51
51
  )
52
52
  from euporie.core.convert.datum import Datum, get_loop
53
53
  from euporie.core.convert.mime import get_format
54
- from euporie.core.current import get_app
55
54
  from euporie.core.data_structures import DiBool, DiInt, DiStr
56
55
  from euporie.core.ft.table import Cell, Table, compute_padding
57
56
  from euporie.core.ft.utils import (
@@ -74,6 +73,16 @@ from euporie.core.ft.utils import (
74
73
  valign,
75
74
  )
76
75
 
76
+ sub_trans = str.maketrans(
77
+ "0123456789+-=()aeijoruvxβγρφχ",
78
+ "₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎ₐₑᵢⱼₒᵣᵤᵥₓᵦᵧᵨᵩᵪ",
79
+ )
80
+
81
+ sup_trans = str.maketrans(
82
+ "0123456789+-=()abcdefghijklmnoprstuvwxyzABDEGHIJKLMNOPRTUVWαβγδ∊θιΦφχ",
83
+ "⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖʳˢᵗᵘᵛʷˣʸᶻᴬᴮᴰᴱᴳᴴᴵᴶᴷᴸᴹᴺᴼᴾᴿᵀᵁⱽᵂᵅᵝᵞᵟᵋᶿᶥᶲᵠᵡ",
84
+ )
85
+
77
86
 
78
87
  class CssSelector(NamedTuple):
79
88
  """A named tuple to hold CSS selector data."""
@@ -93,8 +102,9 @@ class CssSelector(NamedTuple):
93
102
 
94
103
 
95
104
  if TYPE_CHECKING:
105
+ from collections.abc import Generator, Iterator
96
106
  from pathlib import Path
97
- from typing import Any, Callable, Generator, Iterator
107
+ from typing import Any, Callable
98
108
 
99
109
  from fsspec.spec import AbstractFileSystem
100
110
  from prompt_toolkit.filters.base import Filter
@@ -343,6 +353,7 @@ _HERITABLE_PROPS = {
343
353
  "text_transform",
344
354
  "text_decoration",
345
355
  "text_align",
356
+ "vertical_align",
346
357
  "visibility",
347
358
  "white_space",
348
359
  "list_style_type",
@@ -585,8 +596,8 @@ def css_dimension(
585
596
 
586
597
  # Get cell pixel dimensions
587
598
  app = get_app()
588
- if hasattr(app, "term_info"):
589
- cell_px, cell_py = get_app().term_info.cell_size_px
599
+ if hasattr(app, "cell_size_px"):
600
+ cell_px, cell_py = get_app().cell_size_px
590
601
  else:
591
602
  cell_px, cell_py = 10, 20
592
603
 
@@ -1139,8 +1150,7 @@ class Theme(Mapping):
1139
1150
  and parent_theme["flex_direction"].startswith("col")
1140
1151
  )
1141
1152
  )
1142
- or (parent_theme is not None and parent_theme.d_grid)
1143
- )
1153
+ ) or (parent_theme is not None and parent_theme.d_grid)
1144
1154
 
1145
1155
  @cached_property
1146
1156
  def d_inline(self) -> bool:
@@ -1761,18 +1771,19 @@ class Theme(Mapping):
1761
1771
 
1762
1772
  async def text_transform(self, value: str) -> str:
1763
1773
  """Return a function which transforms text."""
1764
- if "uppercase" in self.theme["text_transform"]:
1774
+ transform = self.theme["text_transform"]
1775
+ if "uppercase" in transform:
1765
1776
  return value.upper()
1766
- elif "lowercase" in self.theme["text_transform"]:
1777
+ elif "lowercase" in transform:
1767
1778
  return value.lower()
1768
- elif "capitalize" in self.theme["text_transform"]:
1779
+ elif "capitalize" in transform:
1769
1780
  return value.capitalize()
1770
- elif "sub" in self.theme["vertical_align"]:
1771
- return "".join(subscript.get(c, c) for c in value)
1772
- elif "super" in self.theme["vertical_align"]:
1773
- return "".join(superscript.get(c, c) for c in value)
1774
- elif "latex" in self.theme["text_transform"]:
1781
+ elif "latex" in transform:
1775
1782
  return await Datum(value, "latex").convert_async("ansi")
1783
+ if "sub" in self.theme["vertical_align"]:
1784
+ return value.translate(sub_trans)
1785
+ elif "super" in self.theme["vertical_align"]:
1786
+ return value.translate(sup_trans)
1776
1787
  return value
1777
1788
 
1778
1789
  @cached_property
@@ -2771,7 +2782,7 @@ _BROWSER_CSS: CssSelectors = {
2771
2782
  "text_transform": "latex",
2772
2783
  "display": "inline-block",
2773
2784
  "vertical_align": "top",
2774
- # "margin_right": "1em",
2785
+ "white_space": "pre",
2775
2786
  },
2776
2787
  (
2777
2788
  (
@@ -2881,7 +2892,7 @@ class Node:
2881
2892
  s += ">"
2882
2893
  if self.contents:
2883
2894
  for child in self.contents:
2884
- s += f"\n{dd} {child._outer_html(d+1, attrs=attrs)}"
2895
+ s += f"\n{dd} {child._outer_html(d + 1, attrs=attrs)}"
2885
2896
  s += f"\n{dd}{dd}"
2886
2897
  s += f"</{self.name}>"
2887
2898
  else:
@@ -3252,15 +3263,6 @@ class CustomHTMLParser(HTMLParser):
3252
3263
  Node(dom=self.dom, name="::text", text=data, parent=self.curr, attrs=[])
3253
3264
  )
3254
3265
 
3255
- # def handle_endtag(self, tag: str) -> None:
3256
- # """Handle end tags: close the currently opened element."""
3257
- # if tag == self.curr.name:
3258
- # self.curr.closed = True
3259
- # if self.curr.parent:
3260
- # self.curr = self.curr.parent
3261
- # else:
3262
- # self.autoclose()
3263
-
3264
3266
  def handle_endtag(self, tag: str) -> None:
3265
3267
  """Handle end tags: close the currently opened element."""
3266
3268
  if tag != self.curr.name:
@@ -3274,7 +3276,6 @@ def parse_style_sheet(css_str: str, dom: HTML, condition: Filter = always) -> No
3274
3276
  """Collect all CSS styles from style tags."""
3275
3277
  dom_css = dom.css
3276
3278
  # Remove whitespace and newlines
3277
- # css_str = css_str.strip().replace("\n", "")
3278
3279
  css_str = re.sub(r"\s*\n\s*", " ", css_str)
3279
3280
  # Remove comments
3280
3281
  css_str = re.sub(r"\/\*[^\*]+\*\/", "", css_str)
@@ -4275,7 +4276,7 @@ class HTML:
4275
4276
 
4276
4277
  # Render text representation
4277
4278
  ft: StyleAndTextTuples = await self.render_node_content(
4278
- element, left, fill, align_content
4279
+ element, left=0, fill=False, align_content=False
4279
4280
  )
4280
4281
 
4281
4282
  # Render graphic representation
@@ -4307,14 +4308,12 @@ class HTML:
4307
4308
  @overload
4308
4309
  async def _render_image(
4309
4310
  self, data: bytes, format_: str, theme: Theme, path: Path | None = None
4310
- ) -> StyleAndTextTuples:
4311
- ...
4311
+ ) -> StyleAndTextTuples: ...
4312
4312
 
4313
4313
  @overload
4314
4314
  async def _render_image(
4315
4315
  self, data: str, format_: str, theme: Theme, path: Path | None = None
4316
- ) -> StyleAndTextTuples:
4317
- ...
4316
+ ) -> StyleAndTextTuples: ...
4318
4317
 
4319
4318
  async def _render_image(self, data, format_, theme, path=None):
4320
4319
  """Render an image and prepare graphic representation."""
@@ -4983,15 +4982,16 @@ if __name__ == "__main__":
4983
4982
  from prompt_toolkit.shortcuts.utils import print_formatted_text
4984
4983
  from prompt_toolkit.styles.style import Style
4985
4984
 
4986
- from euporie.core.app import BaseApp
4985
+ from euporie.core.app.dummy import DummyApp
4987
4986
  from euporie.core.path import parse_path
4988
4987
  from euporie.core.style import HTML_STYLE
4989
4988
 
4990
4989
  path = parse_path(sys.argv[1])
4991
4990
 
4992
- with create_app_session(
4993
- input=BaseApp.load_input(), output=BaseApp.load_output()
4994
- ), set_app(BaseApp()):
4991
+ with (
4992
+ create_app_session(input=DummyApp.load_input(), output=DummyApp.load_output()),
4993
+ set_app(DummyApp()),
4994
+ ):
4995
4995
  print_formatted_text(
4996
4996
  HTML(
4997
4997
  path.read_text(),
euporie/core/ft/table.py CHANGED
@@ -36,11 +36,9 @@ from euporie.core.ft.utils import (
36
36
  )
37
37
 
38
38
  if TYPE_CHECKING:
39
+ from collections.abc import Iterable, Iterator, Sequence
39
40
  from typing import (
40
41
  Any,
41
- Iterable,
42
- Iterator,
43
- Sequence,
44
42
  TypeVar,
45
43
  )
46
44
 
euporie/core/ft/utils.py CHANGED
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import re
6
6
  from enum import Enum
7
- from typing import Iterable, cast
7
+ from typing import TYPE_CHECKING, cast
8
8
 
9
9
  from prompt_toolkit.formatted_text.base import OneStyleAndTextTuple, StyleAndTextTuples
10
10
  from prompt_toolkit.formatted_text.utils import (
@@ -20,6 +20,9 @@ from pygments.util import ClassNotFound
20
20
  from euporie.core.border import GridStyle, ThinGrid
21
21
  from euporie.core.data_structures import DiBool, DiInt, DiStr
22
22
 
23
+ if TYPE_CHECKING:
24
+ from collections.abc import Iterable
25
+
23
26
  _ZERO_WIDTH_FRAGMENTS = ("[ZeroWidthEscape]", "[ReverseOverwrite]")
24
27
 
25
28