hgoblet 0.2.1__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.
hgoblet/__init__.py ADDED
@@ -0,0 +1,10 @@
1
+ """hgoblet // a switchboard for MProcs-family terminal suites.
2
+
3
+ hgoblet discovers installed copies of MProcs, Fumuda-XY and Nanuska-GP,
4
+ remembers which one is active, and launches either a suite's basic terminal
5
+ (``mp`` / ``fxy`` / ``ngp``) or one of its launcher functions.
6
+ """
7
+
8
+ __version__ = "0.2.1"
9
+
10
+ __all__ = ["__version__"]
hgoblet/__main__.py ADDED
@@ -0,0 +1,6 @@
1
+ """Allow ``python -m hgoblet``."""
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(main())
hgoblet/catalog.py ADDED
@@ -0,0 +1,133 @@
1
+ """The three terminal suites hgoblet knows how to switch between.
2
+
3
+ Each suite is the same MProcs terminal family in a different language skin.
4
+ The short command is the canonical "basic MProcs terminal" for that suite:
5
+
6
+ fumuda -> fxy (default)
7
+ mprocs -> mp
8
+ nanuska -> ngp
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import unicodedata
14
+ from dataclasses import dataclass
15
+ from typing import Dict, Optional, Tuple
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class Suite:
20
+ """One installable MProcs-family terminal suite."""
21
+
22
+ key: str
23
+ name: str
24
+ package: str
25
+ distributions: Tuple[str, ...]
26
+ commands: Tuple[str, ...]
27
+ tagline: str
28
+ accent: str = "cyan"
29
+ default: bool = False
30
+
31
+ @property
32
+ def command(self) -> str:
33
+ """Canonical short command (fxy / mp / ngp)."""
34
+ return self.commands[0]
35
+
36
+ @property
37
+ def install_hint(self) -> str:
38
+ return "python3 -m pip install %s" % self.distributions[0]
39
+
40
+
41
+ SUITES: Tuple[Suite, ...] = (
42
+ Suite(
43
+ key="fumuda",
44
+ name="Fumuda-XY",
45
+ package="Fumuda_XY",
46
+ distributions=("Fumuda-XY", "Fumuda_XY"),
47
+ commands=(
48
+ "fxy",
49
+ "FXY",
50
+ "fumuda-xy",
51
+ "Fumuda-XY",
52
+ "ふむだXY",
53
+ "フムダXY",
54
+ ),
55
+ tagline="Japanese terminal suite",
56
+ accent="magenta",
57
+ default=True,
58
+ ),
59
+ Suite(
60
+ key="mprocs",
61
+ name="MProcs",
62
+ package="MProcs",
63
+ distributions=("MProcs", "mprocs"),
64
+ commands=("mp", "mprocs", "MProcs"),
65
+ tagline="original terminal suite",
66
+ accent="cyan",
67
+ ),
68
+ Suite(
69
+ key="nanuska",
70
+ name="Nanuska-GP",
71
+ package="Nanuska_GP",
72
+ distributions=("Nanuska-GP", "Nanuska_GP"),
73
+ commands=(
74
+ "ngp",
75
+ "NGP",
76
+ "nanuska-gp",
77
+ "nanuska",
78
+ "Nanuska-GP",
79
+ "нгп",
80
+ "НГП",
81
+ "нануска",
82
+ "Нануска-ГП",
83
+ ),
84
+ tagline="Russian terminal suite",
85
+ accent="green",
86
+ ),
87
+ )
88
+
89
+ SUITES_BY_KEY: Dict[str, Suite] = {suite.key: suite for suite in SUITES}
90
+
91
+ SUITE_ORDER: Tuple[str, ...] = tuple(suite.key for suite in SUITES)
92
+
93
+ DEFAULT_SUITE: str = next(suite.key for suite in SUITES if suite.default)
94
+
95
+
96
+ def _fold(value: object) -> str:
97
+ text = unicodedata.normalize("NFKC", str(value)).strip().casefold()
98
+ return text.replace("_", "-")
99
+
100
+
101
+ _ALIASES: Dict[str, str] = {}
102
+ for _suite in SUITES:
103
+ for _token in (_suite.key, _suite.name, _suite.package) + _suite.commands:
104
+ _ALIASES[_fold(_token)] = _suite.key
105
+
106
+ # Human-friendly spellings and the two names people actually type.
107
+ _ALIASES.update(
108
+ {
109
+ "fumuda": "fumuda",
110
+ "fumuda-xy": "fumuda",
111
+ "fumudaxy": "fumuda",
112
+ "fxy": "fumuda",
113
+ "mprocs": "mprocs",
114
+ "m-procs": "mprocs",
115
+ "mp": "mprocs",
116
+ "nanuska": "nanuska",
117
+ "nanuska-gp": "nanuska",
118
+ "nanuskagp": "nanuska",
119
+ "ngp": "nanuska",
120
+ }
121
+ )
122
+
123
+
124
+ def normalize_suite(value: object) -> Optional[str]:
125
+ """Return a canonical suite key for a user-supplied name/alias."""
126
+ if value is None:
127
+ return None
128
+ return _ALIASES.get(_fold(value))
129
+
130
+
131
+ def suite_for(value: object) -> Optional[Suite]:
132
+ key = normalize_suite(value)
133
+ return SUITES_BY_KEY.get(key) if key else None