xmyshell 0.2.12__tar.gz → 0.2.14__tar.gz

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 (29) hide show
  1. {xmyshell-0.2.12/xmyshell.egg-info → xmyshell-0.2.14}/PKG-INFO +1 -1
  2. {xmyshell-0.2.12 → xmyshell-0.2.14}/pyproject.toml +1 -1
  3. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/completer.py +4 -1
  4. xmyshell-0.2.14/xmyshell/injection.py +42 -0
  5. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/kernel.py +19 -8
  6. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/main.py +12 -3
  7. {xmyshell-0.2.12 → xmyshell-0.2.14/xmyshell.egg-info}/PKG-INFO +1 -1
  8. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell.egg-info/SOURCES.txt +1 -0
  9. {xmyshell-0.2.12 → xmyshell-0.2.14}/LICENSE +0 -0
  10. {xmyshell-0.2.12 → xmyshell-0.2.14}/README.md +0 -0
  11. {xmyshell-0.2.12 → xmyshell-0.2.14}/setup.cfg +0 -0
  12. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/__init__.py +0 -0
  13. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/__main__.py +0 -0
  14. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/data/commands.json +0 -0
  15. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/environment.py +0 -0
  16. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/init.py +0 -0
  17. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/keybindings.py +0 -0
  18. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/lexer.py +0 -0
  19. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/meta.py +0 -0
  20. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/stubs/__init__.py +0 -0
  21. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/stubs/__init__.pyi +0 -0
  22. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/stubs/py.typed +0 -0
  23. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/themes.py +0 -0
  24. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/update.py +0 -0
  25. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell/utils.py +0 -0
  26. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell.egg-info/dependency_links.txt +0 -0
  27. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell.egg-info/entry_points.txt +0 -0
  28. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell.egg-info/requires.txt +0 -0
  29. {xmyshell-0.2.12 → xmyshell-0.2.14}/xmyshell.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xmyshell
3
- Version: 0.2.12
3
+ Version: 0.2.14
4
4
  Summary: XmyShell is a shell-like tool built on top of prompt_toolkit which provides a persistent Python runtime.
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xmyshell"
3
- version = "0.2.12"
3
+ version = "0.2.14"
4
4
  description = "XmyShell is a shell-like tool built on top of prompt_toolkit which provides a persistent Python runtime."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -158,7 +158,10 @@ class ShellCompleter(Completer):
158
158
  in_string = in_string or last.startswith('"') or last.startswith("'")
159
159
  last = last.lstrip('"\'')
160
160
  if last == '~': return # don't remove this
161
- path = os.path.expanduser(last)
161
+ try:
162
+ path = os.path.expanduser(shlex.split(last)[0])
163
+ except (ValueError, IndexError):
164
+ path = os.path.expanduser(last)
162
165
  dirname = os.path.dirname(path) or "."
163
166
  prefix = os.path.basename(path).strip('"\'')
164
167
 
@@ -0,0 +1,42 @@
1
+ from prompt_toolkit.buffer import _only_one_at_a_time, CompletionState
2
+ from prompt_toolkit.application import get_app
3
+
4
+
5
+ def _new_text_and_position(self: CompletionState):
6
+
7
+ def new_text_and_position() -> tuple[str, int]:
8
+ """Injected by XmyShell."""
9
+ if self.complete_index is None:
10
+ return self.original_document.text, self.original_document.cursor_position
11
+ else:
12
+ original_text_before_cursor = self.original_document.text_before_cursor
13
+ original_text_after_cursor = self.original_document.text_after_cursor
14
+
15
+ c = self.completions[self.complete_index]
16
+ c.text = c.text.rstrip() # injected
17
+ if c.start_position == 0:
18
+ before = original_text_before_cursor
19
+ else:
20
+ before = original_text_before_cursor[: c.start_position]
21
+
22
+ new_text = before + c.text + original_text_after_cursor
23
+ new_cursor_position = len(before) + len(c.text)
24
+ return new_text, new_cursor_position
25
+ return new_text_and_position
26
+
27
+
28
+ def inject() -> None:
29
+ buffer = get_app().current_buffer
30
+
31
+ async_completer = buffer._create_completer_coroutine()
32
+
33
+ @_only_one_at_a_time
34
+ async def _async_completer(*args, **kwargs) -> None:
35
+ """Injected by XmyShell."""
36
+ await async_completer(*args, **kwargs)
37
+ if buffer.complete_state:
38
+ buffer.complete_state.new_text_and_position = \
39
+ _new_text_and_position(buffer.complete_state)
40
+ buffer.complete_state.go_to_index(0)
41
+
42
+ buffer._async_completer = _async_completer
@@ -2,6 +2,7 @@ from collections.abc import Generator, Sequence
2
2
  from contextlib import contextmanager
3
3
  import os
4
4
  import sys
5
+ import re
5
6
  import runpy
6
7
  import subprocess
7
8
  import signal
@@ -322,21 +323,31 @@ def xmyshell(cmd_line: str) -> int:
322
323
  try:
323
324
  target_dir = os.path.expanduser(target_dir)
324
325
  # only works on Windows
325
- if os.name == "nt" and target_dir.startswith("/"):
326
- import re
327
-
326
+ if os.name == "nt":
328
327
  if target_dir.startswith("/"):
329
- m = re.match(r"^/([a-zA-Z])/", target_dir)
328
+ m = re.match(r"^/([a-zA-Z])(/.*)?$", target_dir)
330
329
  if m:
331
330
  drive = m.group(1).upper()
332
- target_dir = drive + ":/" + target_dir[3:]
333
- os.chdir(target_dir)
331
+ rest = m.group(2) or ""
332
+ target_dir = drive + ":" + rest
333
+ target_dir = target_dir.replace("\\", "/")
334
+ _splited = shlex.split(target_dir)
335
+ if len(_splited) > 1:
336
+ pyerror("too many arguments")
337
+ return -1
338
+ os.chdir(_splited[0])
334
339
  return 0
335
340
  except FileNotFoundError:
336
- pyerror(f"file not found: '{target_dir}'")
341
+ pyerror(f"file not found: {target_dir!r}")
337
342
  return -1
338
343
  except NotADirectoryError:
339
- pyerror(f"not a directory: '{target_dir}'")
344
+ pyerror(f"not a directory: {target_dir!r}")
345
+ return -1
346
+ except PermissionError:
347
+ pyerror(f"permission denied: {target_dir!r}")
348
+ return -1
349
+ except (OSError, ValueError):
350
+ pyerror(f"wrong path format: {target_dir!r}")
340
351
  return -1
341
352
 
342
353
  case "source":
@@ -1,18 +1,26 @@
1
1
  from time import time_ns
2
+
2
3
  _start_time = time_ns()
3
4
 
5
+
4
6
  import os
5
- from prompt_toolkit import HTML, PromptSession
7
+ from prompt_toolkit.application import get_app
6
8
  from prompt_toolkit.styles import Style
9
+ from prompt_toolkit import HTML, PromptSession
7
10
  from prompt_toolkit.history import FileHistory
8
11
  from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
9
12
  from .meta import WELCOME_MESSAGE
10
13
  from .environment import namespace
11
- from .keybindings import bindings, on_cursor_position_changed, on_text_changed, clean_buffer
14
+ from .keybindings import (
15
+ bindings,
16
+ on_cursor_position_changed,
17
+ on_text_changed,
18
+ clean_buffer,
19
+ )
12
20
  from .init import xmyshell_init
13
21
  from .kernel import pyeval, xmyshell
14
22
  from .lexer import XmyShellLexer
15
-
23
+ from .injection import inject
16
24
 
17
25
  def xmyshell_main() -> None:
18
26
  xmyshell_init()
@@ -41,6 +49,7 @@ def xmyshell_main() -> None:
41
49
  completer=namespace["shell_completer"],
42
50
  placeholder=HTML(namespace["prompt_placeholder"]),
43
51
  style=Style.from_dict(namespace["prompt_style"]),
52
+ pre_run=inject,
44
53
  )
45
54
  start_time = time_ns()
46
55
  namespace["exit_code"] = xmyshell(cmd_line)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xmyshell
3
- Version: 0.2.12
3
+ Version: 0.2.14
4
4
  Summary: XmyShell is a shell-like tool built on top of prompt_toolkit which provides a persistent Python runtime.
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
@@ -6,6 +6,7 @@ xmyshell/__main__.py
6
6
  xmyshell/completer.py
7
7
  xmyshell/environment.py
8
8
  xmyshell/init.py
9
+ xmyshell/injection.py
9
10
  xmyshell/kernel.py
10
11
  xmyshell/keybindings.py
11
12
  xmyshell/lexer.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes