xmyshell 0.1.3__tar.gz → 0.2.0__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 (26) hide show
  1. {xmyshell-0.1.3/xmyshell.egg-info → xmyshell-0.2.0}/PKG-INFO +19 -1
  2. {xmyshell-0.1.3 → xmyshell-0.2.0}/README.md +18 -0
  3. {xmyshell-0.1.3 → xmyshell-0.2.0}/pyproject.toml +1 -1
  4. xmyshell-0.2.0/xmyshell/__main__.py +20 -0
  5. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/completer.py +2 -2
  6. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/data/commands.json +1 -1
  7. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/environment.py +8 -1
  8. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/kernel.py +40 -16
  9. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/meta.py +13 -4
  10. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/update.py +5 -3
  11. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/utils.py +5 -0
  12. {xmyshell-0.1.3 → xmyshell-0.2.0/xmyshell.egg-info}/PKG-INFO +19 -1
  13. xmyshell-0.1.3/xmyshell/__main__.py +0 -12
  14. {xmyshell-0.1.3 → xmyshell-0.2.0}/LICENSE +0 -0
  15. {xmyshell-0.1.3 → xmyshell-0.2.0}/setup.cfg +0 -0
  16. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/__init__.py +0 -0
  17. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/init.py +0 -0
  18. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/keybindings.py +0 -0
  19. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/lexer.py +0 -0
  20. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/main.py +0 -0
  21. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell/themes.py +0 -0
  22. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell.egg-info/SOURCES.txt +0 -0
  23. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell.egg-info/dependency_links.txt +0 -0
  24. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell.egg-info/entry_points.txt +0 -0
  25. {xmyshell-0.1.3 → xmyshell-0.2.0}/xmyshell.egg-info/requires.txt +0 -0
  26. {xmyshell-0.1.3 → xmyshell-0.2.0}/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.1.3
3
+ Version: 0.2.0
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
@@ -112,6 +112,11 @@ or
112
112
  ❯ update 0.1.3
113
113
  ```
114
114
 
115
+ - Alias
116
+ ```
117
+ ❯ alias ll='ls -lh'
118
+ ```
119
+
115
120
  - Syntax highlighting via `prompt_toolkit`
116
121
  - Powerful auto-completion, history search, and automatic bracket/quote pairing
117
122
  - Startup configuration: `~/.xmyshell/config.py` loaded at launch
@@ -131,6 +136,13 @@ Returns the parent directory of a path.
131
136
  - `basename(path)`
132
137
  Returns the final component of a path.
133
138
 
139
+ - `cat(file)`
140
+ Shortcut for `open(file).read()`.
141
+
142
+ - `alias(altname, target)`
143
+ Same as the command.
144
+
145
+
134
146
  ### Reserved global varibles
135
147
  - `exit_code`
136
148
  The exit code of the last command.
@@ -138,6 +150,12 @@ The exit code of the last command.
138
150
  - `exec_duration`
139
151
  The duration which last command took.
140
152
 
153
+ - `HOME_DIR`
154
+ The home directory, similar to `~`.
155
+
156
+ - `PROFILE`
157
+ The path of config file.
158
+
141
159
  ### Keyboard Shortcuts
142
160
  - `↑↓` -> Navigate through command history.
143
161
  - `→` -> Apply selected history entry to the prompt.
@@ -102,6 +102,11 @@ or
102
102
  ❯ update 0.1.3
103
103
  ```
104
104
 
105
+ - Alias
106
+ ```
107
+ ❯ alias ll='ls -lh'
108
+ ```
109
+
105
110
  - Syntax highlighting via `prompt_toolkit`
106
111
  - Powerful auto-completion, history search, and automatic bracket/quote pairing
107
112
  - Startup configuration: `~/.xmyshell/config.py` loaded at launch
@@ -121,6 +126,13 @@ Returns the parent directory of a path.
121
126
  - `basename(path)`
122
127
  Returns the final component of a path.
123
128
 
129
+ - `cat(file)`
130
+ Shortcut for `open(file).read()`.
131
+
132
+ - `alias(altname, target)`
133
+ Same as the command.
134
+
135
+
124
136
  ### Reserved global varibles
125
137
  - `exit_code`
126
138
  The exit code of the last command.
@@ -128,6 +140,12 @@ The exit code of the last command.
128
140
  - `exec_duration`
129
141
  The duration which last command took.
130
142
 
143
+ - `HOME_DIR`
144
+ The home directory, similar to `~`.
145
+
146
+ - `PROFILE`
147
+ The path of config file.
148
+
131
149
  ### Keyboard Shortcuts
132
150
  - `↑↓` -> Navigate through command history.
133
151
  - `→` -> Apply selected history entry to the prompt.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xmyshell"
3
- version = "0.1.3"
3
+ version = "0.2.0"
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"
@@ -0,0 +1,20 @@
1
+ import subprocess
2
+ import sys
3
+
4
+
5
+ def main() -> None:
6
+ argv = sys.argv
7
+
8
+ if len(argv) == 1:
9
+ from .main import xmyshell_main
10
+ xmyshell_main()
11
+ elif argv[1] == "--update":
12
+ subprocess.run([sys.executable, "-m", "xmyshell.update"] + argv[2:])
13
+ elif argv[1] == "--version":
14
+ from .meta import WELCOME_MESSAGE
15
+ print(WELCOME_MESSAGE)
16
+ elif argv[1] == "--help":
17
+ from .meta import HELP_MESSAGE
18
+ print(HELP_MESSAGE)
19
+ else:
20
+ print(f"Error: cannot parse arguments '{' '.join(argv[1:])}'")
@@ -16,7 +16,7 @@ MAX_DISPLAY_LEN = 24
16
16
  MAX_META_LEN = 12
17
17
 
18
18
  BUILTINS = ("cd", "cp", "cat", "echo", "exit", "import", "ls", "print", "pyexec", "pwd", "source",
19
- "clear", "grep", "find", "from", "mkdir", "rm", "reload", "mv", "help")
19
+ "clear", "grep", "find", "from", "mkdir", "rm", "reload", "mv", "help", "alias", "update")
20
20
 
21
21
  COMMON = (
22
22
  "python", "python3", "pip", "pip3", "git", "conda", "uv",
@@ -342,7 +342,7 @@ class ShellCompleter(Completer):
342
342
  parts = lstripped.split()
343
343
  if len(parts) >= 1:
344
344
  cmd = parts[0]
345
- if cmd in ("print", "pyexec"):
345
+ if cmd in ("print", "pyexec", "alias"):
346
346
  param_text = lstripped[len(cmd):].lstrip()
347
347
  yield from self._python_completion(param_text)
348
348
  return
@@ -1,5 +1,5 @@
1
1
  {
2
- "xmyshell": { "_global": ["--help", "--version"] },
2
+ "xmyshell": { "_global": ["--help", "--version", "--update"] },
3
3
  "git": {
4
4
  "_global": ["--help", "--version"],
5
5
  "add": {
@@ -5,11 +5,15 @@ import time
5
5
  from datetime import datetime
6
6
  from typing import Any
7
7
  from collections.abc import Mapping
8
- from .utils import XMYSHELL_MAGIC, getcwd, getlogin, HOME_DIR
8
+ from .utils import XMYSHELL_MAGIC, getcwd, getlogin, HOME_DIR, xmyshell_cat
9
9
 
10
10
  namespace: dict[str, Any] = {}
11
+ aliases: dict[str, str] = {}
11
12
  init_environ: dict[str, str] = dict(os.environ)
12
13
 
14
+ def xmyshell_alias(source: str, target: str) -> None:
15
+ aliases.update({source: target})
16
+
13
17
 
14
18
  _init_namespace: dict[str, Any] = {
15
19
  "_xmyshell_magic": XMYSHELL_MAGIC,
@@ -23,7 +27,10 @@ _init_namespace: dict[str, Any] = {
23
27
  "getcwd": getcwd,
24
28
  "dirname": os.path.dirname,
25
29
  "basename": os.path.basename,
30
+ "cat": xmyshell_cat,
31
+ "alias": xmyshell_alias,
26
32
  "HOME_DIR": HOME_DIR,
33
+ "PROFILE": f"{HOME_DIR}/.xmyshell/config.py",
27
34
  "exit_code": 0,
28
35
  "exec_duration": 0,
29
36
  "last_error": None,
@@ -1,8 +1,10 @@
1
+ from collections.abc import Generator, Sequence
1
2
  import os
2
3
  import sys
3
4
  import runpy
4
5
  import subprocess
5
- from .environment import namespace
6
+ import shlex
7
+ from .environment import namespace, aliases
6
8
  from .utils import pywarning, pyerror, getcwd
7
9
  from .meta import HELP_MESSAGE
8
10
 
@@ -52,6 +54,10 @@ def pyeval(cmd_line: str) -> str:
52
54
  if expr:
53
55
  try:
54
56
  val = eval(expr, dict(os.environ), namespace)
57
+ if not isinstance(
58
+ val, (str, bytes, bytearray, memoryview)
59
+ ) and isinstance(val, (Sequence, Generator)):
60
+ val = shlex.join(str(ele) for ele in val)
55
61
  result.append(str(val) if val is not None else '')
56
62
  except Exception as e:
57
63
  pywarning(f"An error occured when unfolding {expr!r}, using original string instead"
@@ -116,6 +122,20 @@ def xmyshell_raw_command(cmd_line: str) -> int | None:
116
122
  pyerror(f"{type(e).__name__}: {e}")
117
123
  return -1
118
124
 
125
+ case "alias":
126
+ code: str = cmd_line[len(command):].strip()
127
+ if not code:
128
+ pyerror("export: missing code")
129
+ return -1
130
+ try:
131
+ alias_source, alias_target = code.split('=', 1)
132
+ alias_source = alias_source.strip()
133
+ aliases[alias_source] = eval(alias_target, namespace, {})
134
+ return 0
135
+ except Exception as e:
136
+ pyerror(f"{type(e).__name__}: {e}")
137
+ return -1
138
+
119
139
  case "print":
120
140
  expr = cmd_line[len(command):].strip()
121
141
  if not expr:
@@ -139,6 +159,22 @@ def xmyshell_raw_command(cmd_line: str) -> int | None:
139
159
  [sys.executable, "-m", "xmyshell.update"]
140
160
  + (args[1:] if len(args) > 1 else [])
141
161
  )
162
+ return 0
163
+
164
+ case "help":
165
+ print(HELP_MESSAGE)
166
+ return 0
167
+
168
+ case "clear":
169
+ print("\033[2J\033[H", end="")
170
+ return 0
171
+
172
+ case "pwd":
173
+ print(getcwd())
174
+ return 0
175
+
176
+ case "exit":
177
+ sys.exit(0)
142
178
 
143
179
  if command.startswith("import") or command.startswith("from"):
144
180
  try:
@@ -225,6 +261,9 @@ def xmyshell(cmd_line: str) -> int:
225
261
  if not cmd_line:
226
262
  return 0
227
263
 
264
+ args = cmd_line.split()
265
+ args[0] = aliases.get(args[0], args[0])
266
+ cmd_line = " ".join(args)
228
267
  args = cmd_line.split()
229
268
  command = args[0]
230
269
 
@@ -252,14 +291,6 @@ def xmyshell(cmd_line: str) -> int:
252
291
  pyerror(f"not a directory: '{target_dir}'")
253
292
  return -1
254
293
 
255
- case "help":
256
- print(HELP_MESSAGE)
257
- return 0
258
-
259
- case "clear":
260
- print("\033[2J\033[H", end="")
261
- return 0
262
-
263
294
  case "source":
264
295
  if len(args) < 2:
265
296
  pyerror("source: missing script")
@@ -271,13 +302,6 @@ def xmyshell(cmd_line: str) -> int:
271
302
  pyerror(f"source error: {e}")
272
303
  return -1
273
304
 
274
- case "pwd":
275
- print(getcwd())
276
- return 0
277
-
278
- case "exit":
279
- sys.exit(0)
280
-
281
305
  if os.name == "nt":
282
306
  cmd_line = _fix_first_word(cmd_line)
283
307
  if target_var:
@@ -29,6 +29,7 @@ Built-in Commands:
29
29
  cd <dir> Change directory (supports {{expr}}).
30
30
  pwd Print working directory.
31
31
  clear Clear the terminal screen.
32
+ alias altname=<cmd> Create an alias command.
32
33
  exit Exit XmyShell.
33
34
 
34
35
  Inline Python:
@@ -44,10 +45,18 @@ IO:
44
45
  Example: print "\\n".join(str(i) for i in range(100)) |> grep 42
45
46
 
46
47
  Helper Functions:
47
- getlogin() - current username
48
- getcwd() - current working directory
49
- dirname(p) - parent directory of path
50
- basename(p) - final component of path
48
+ getlogin() - current username
49
+ getcwd() - current working directory
50
+ dirname(p) - parent directory of path
51
+ basename(p) - final component of path
52
+ cat(file) - Shortcut for open(file).read().
53
+ alias(altname, cmd) - Same as the command.
54
+
55
+ Built-in variables:
56
+ exit_code - The exit code of the last command.
57
+ exec_duration - The duration which last command took.
58
+ HOME_DIR - The home directory, similar to "~".
59
+ PROFILE - The path of config file.
51
60
 
52
61
  Keyboard Shortcuts:
53
62
  ↑↓ - Navigate through command history.
@@ -6,8 +6,6 @@ import subprocess
6
6
  def xmyshell_update(version: str | None = None) -> None:
7
7
  if os.name == "nt":
8
8
  subprocess.run("taskkill /F /IM xmyshell.exe", shell=True)
9
- else:
10
- subprocess.run(["pkill", "-f", "xmyshell"])
11
9
 
12
10
  time.sleep(1)
13
11
 
@@ -19,7 +17,11 @@ def xmyshell_update(version: str | None = None) -> None:
19
17
  "--upgrade",
20
18
  "xmyshell" + (f"=={version}" if version else ""),
21
19
  ]
22
- sys.exit(subprocess.run(install_args).returncode)
20
+ if os.name == "nt": print()
21
+ returncode = subprocess.run(install_args).returncode
22
+ if os.name == "nt":
23
+ print("Press <Enter> to continue ...", end="")
24
+ sys.exit(returncode)
23
25
 
24
26
  if __name__ == "__main__":
25
27
  version = sys.argv[1] if len(sys.argv) >= 2 else None
@@ -33,3 +33,8 @@ def getcwd() -> str:
33
33
  return os.getcwd()
34
34
 
35
35
  HOME_DIR = os.path.expanduser("~").replace('\\', '/')
36
+
37
+ def xmyshell_cat(file_path: str) -> str:
38
+ file_path = os.path.expanduser(file_path)
39
+ with open(file_path, "r") as f:
40
+ return f.read()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xmyshell
3
- Version: 0.1.3
3
+ Version: 0.2.0
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
@@ -112,6 +112,11 @@ or
112
112
  ❯ update 0.1.3
113
113
  ```
114
114
 
115
+ - Alias
116
+ ```
117
+ ❯ alias ll='ls -lh'
118
+ ```
119
+
115
120
  - Syntax highlighting via `prompt_toolkit`
116
121
  - Powerful auto-completion, history search, and automatic bracket/quote pairing
117
122
  - Startup configuration: `~/.xmyshell/config.py` loaded at launch
@@ -131,6 +136,13 @@ Returns the parent directory of a path.
131
136
  - `basename(path)`
132
137
  Returns the final component of a path.
133
138
 
139
+ - `cat(file)`
140
+ Shortcut for `open(file).read()`.
141
+
142
+ - `alias(altname, target)`
143
+ Same as the command.
144
+
145
+
134
146
  ### Reserved global varibles
135
147
  - `exit_code`
136
148
  The exit code of the last command.
@@ -138,6 +150,12 @@ The exit code of the last command.
138
150
  - `exec_duration`
139
151
  The duration which last command took.
140
152
 
153
+ - `HOME_DIR`
154
+ The home directory, similar to `~`.
155
+
156
+ - `PROFILE`
157
+ The path of config file.
158
+
141
159
  ### Keyboard Shortcuts
142
160
  - `↑↓` -> Navigate through command history.
143
161
  - `→` -> Apply selected history entry to the prompt.
@@ -1,12 +0,0 @@
1
- import sys
2
-
3
- def main() -> None:
4
- if "--version" in sys.argv:
5
- from .meta import WELCOME_MESSAGE
6
- print(WELCOME_MESSAGE)
7
- elif "--help" in sys.argv:
8
- from .meta import HELP_MESSAGE
9
- print(HELP_MESSAGE)
10
- else:
11
- from .main import xmyshell_main
12
- xmyshell_main()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes