myrtui 0.5.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 (109) hide show
  1. myrtui-0.5.0/.gitignore +30 -0
  2. myrtui-0.5.0/CONTRIBUTING.md +82 -0
  3. myrtui-0.5.0/LICENSE +21 -0
  4. myrtui-0.5.0/PKG-INFO +187 -0
  5. myrtui-0.5.0/README.md +145 -0
  6. myrtui-0.5.0/README.zh-CN.md +136 -0
  7. myrtui-0.5.0/docs/ARCHITECTURE.md +102 -0
  8. myrtui-0.5.0/docs/USAGE.md +344 -0
  9. myrtui-0.5.0/docs/USAGE.zh-CN.md +594 -0
  10. myrtui-0.5.0/myrtui/__init__.py +3 -0
  11. myrtui-0.5.0/myrtui/cli.py +522 -0
  12. myrtui-0.5.0/myrtui/client/__init__.py +1 -0
  13. myrtui-0.5.0/myrtui/client/app.py +3068 -0
  14. myrtui-0.5.0/myrtui/client/cells.py +31 -0
  15. myrtui-0.5.0/myrtui/client/clipboard.py +238 -0
  16. myrtui-0.5.0/myrtui/client/context_menu.py +98 -0
  17. myrtui-0.5.0/myrtui/client/docpage.py +808 -0
  18. myrtui-0.5.0/myrtui/client/file_tree.py +440 -0
  19. myrtui-0.5.0/myrtui/client/git_panel.py +345 -0
  20. myrtui-0.5.0/myrtui/client/graphics.py +251 -0
  21. myrtui-0.5.0/myrtui/client/htmlexport_data/KATEX_VERSION +1 -0
  22. myrtui-0.5.0/myrtui/client/htmlexport_data/auto-render.min.js +1 -0
  23. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  24. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  25. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  26. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  27. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  28. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Main-Bold.woff2 +0 -0
  29. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  30. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Main-Italic.woff2 +0 -0
  31. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Main-Regular.woff2 +0 -0
  32. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  33. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Math-Italic.woff2 +0 -0
  34. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  35. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  36. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  37. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Script-Regular.woff2 +0 -0
  38. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  39. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  40. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  41. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  42. myrtui-0.5.0/myrtui/client/htmlexport_data/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  43. myrtui-0.5.0/myrtui/client/htmlexport_data/katex.min.css +1 -0
  44. myrtui-0.5.0/myrtui/client/htmlexport_data/katex.min.js +1 -0
  45. myrtui-0.5.0/myrtui/client/imageprep.py +233 -0
  46. myrtui-0.5.0/myrtui/client/imagepreview.py +414 -0
  47. myrtui-0.5.0/myrtui/client/katex.py +222 -0
  48. myrtui-0.5.0/myrtui/client/mathimg.py +1053 -0
  49. myrtui-0.5.0/myrtui/client/mathrender.py +554 -0
  50. myrtui-0.5.0/myrtui/client/mathtext.py +249 -0
  51. myrtui-0.5.0/myrtui/client/mdpreview.py +709 -0
  52. myrtui-0.5.0/myrtui/client/pageview.py +291 -0
  53. myrtui-0.5.0/myrtui/client/pane_widget.py +415 -0
  54. myrtui-0.5.0/myrtui/client/separators.py +119 -0
  55. myrtui-0.5.0/myrtui/client/shortcuts.py +165 -0
  56. myrtui-0.5.0/myrtui/client/sidebar.py +183 -0
  57. myrtui-0.5.0/myrtui/client/topbar.py +157 -0
  58. myrtui-0.5.0/myrtui/fileview.py +175 -0
  59. myrtui-0.5.0/myrtui/gitlog.py +184 -0
  60. myrtui-0.5.0/myrtui/gitstat.py +193 -0
  61. myrtui-0.5.0/myrtui/i18n.py +148 -0
  62. myrtui-0.5.0/myrtui/instances.py +418 -0
  63. myrtui-0.5.0/myrtui/layout_state.py +138 -0
  64. myrtui-0.5.0/myrtui/locales/__init__.py +4 -0
  65. myrtui-0.5.0/myrtui/locales/en.py +231 -0
  66. myrtui-0.5.0/myrtui/locales/zh_CN.py +228 -0
  67. myrtui-0.5.0/myrtui/mouse.py +199 -0
  68. myrtui-0.5.0/myrtui/pane_commands.py +264 -0
  69. myrtui-0.5.0/myrtui/tmux_backend.py +465 -0
  70. myrtui-0.5.0/pyproject.toml +96 -0
  71. myrtui-0.5.0/scripts/affected_tests.py +245 -0
  72. myrtui-0.5.0/scripts/bench_event_loop.py +194 -0
  73. myrtui-0.5.0/scripts/demo.tape +67 -0
  74. myrtui-0.5.0/scripts/install.sh +365 -0
  75. myrtui-0.5.0/scripts/spike_paged_preview.py +108 -0
  76. myrtui-0.5.0/scripts/spike_preview_bitmap.py +146 -0
  77. myrtui-0.5.0/scripts/spike_sixel.py +235 -0
  78. myrtui-0.5.0/tests/README.md +304 -0
  79. myrtui-0.5.0/tests/conftest.py +109 -0
  80. myrtui-0.5.0/tests/test_affected_tests.py +94 -0
  81. myrtui-0.5.0/tests/test_b0b1.py +388 -0
  82. myrtui-0.5.0/tests/test_docs_policy.py +213 -0
  83. myrtui-0.5.0/tests/test_i18n.py +315 -0
  84. myrtui-0.5.0/tests/test_imagepreview.py +378 -0
  85. myrtui-0.5.0/tests/test_install_script.py +109 -0
  86. myrtui-0.5.0/tests/test_instances.py +609 -0
  87. myrtui-0.5.0/tests/test_mouse.py +898 -0
  88. myrtui-0.5.0/tests/test_p0.py +304 -0
  89. myrtui-0.5.0/tests/test_p1.py +837 -0
  90. myrtui-0.5.0/tests/test_p2.py +484 -0
  91. myrtui-0.5.0/tests/test_p3.py +1000 -0
  92. myrtui-0.5.0/tests/test_refresh_dir.py +252 -0
  93. myrtui-0.5.0/tests/test_v10.py +387 -0
  94. myrtui-0.5.0/tests/test_v11.py +808 -0
  95. myrtui-0.5.0/tests/test_v13.py +480 -0
  96. myrtui-0.5.0/tests/test_v14.py +394 -0
  97. myrtui-0.5.0/tests/test_v15.py +278 -0
  98. myrtui-0.5.0/tests/test_v18.py +296 -0
  99. myrtui-0.5.0/tests/test_v20.py +537 -0
  100. myrtui-0.5.0/tests/test_v22.py +351 -0
  101. myrtui-0.5.0/tests/test_v28.py +607 -0
  102. myrtui-0.5.0/tests/test_v29.py +229 -0
  103. myrtui-0.5.0/tests/test_v31.py +329 -0
  104. myrtui-0.5.0/tests/test_v34.py +214 -0
  105. myrtui-0.5.0/tests/test_v35.py +722 -0
  106. myrtui-0.5.0/tests/test_v36.py +708 -0
  107. myrtui-0.5.0/tests/test_v37.py +949 -0
  108. myrtui-0.5.0/tests/test_v37_1.py +621 -0
  109. myrtui-0.5.0/tests/test_v37_2.py +671 -0
@@ -0,0 +1,30 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+ .venv-ci/
11
+ .venv-release/
12
+ .uv/
13
+ uv.lock
14
+
15
+ # Tooling caches
16
+ .mypy_cache/
17
+ .ruff_cache/
18
+ .pytest_cache/
19
+ .coverage
20
+ htmlcov/
21
+
22
+ # 内部设计/验收记录:独立 git 仓,嵌套在本目录下,只推内网 Gitea(myrtui-docs)。
23
+ # 必须保持未跟踪——一旦被 `git add` 进去会变成 gitlink(mode 160000),
24
+ # 公开仓里就会出现一个打不开的 submodule 指针(tests/test_docs_policy.py 守着)。
25
+ docs-internal/
26
+
27
+ # Editors / OS
28
+ .DS_Store
29
+ .idea/
30
+ .vscode/
@@ -0,0 +1,82 @@
1
+ # Contributing
2
+
3
+ Thanks for taking a look. This is a small, opinionated project; the notes below
4
+ are what you need to run it, test it, and not fight its conventions.
5
+
6
+ **If you are an AI agent, read [AGENTS.md](AGENTS.md) first** — it is the
7
+ short form of everything below, plus the hard rules.
8
+
9
+ ## Language policy
10
+
11
+ - **Code comments and docstrings are in Chinese** by project convention. This
12
+ is deliberate: the maintainer thinks and iterates in Chinese, and a partial
13
+ English translation would rot into "stale English + live Chinese".
14
+ - **User-facing text is English**: this file, `README.md`, `docs/`, code that
15
+ is printed to the terminal, and (eventually) the TUI itself.
16
+ - **New commit messages use English subjects.** History before the public
17
+ release is Chinese and is not being rewritten.
18
+ - Issues and pull requests in **English or Chinese** are both welcome.
19
+
20
+ ## Development setup
21
+
22
+ ```sh
23
+ git clone https://github.com/YidingPing/myrtui
24
+ cd myrtui
25
+ python -m venv .venv && . .venv/bin/activate
26
+ pip install -e ".[dev]"
27
+ ```
28
+
29
+ `tmux >= 3.1` must be on `PATH`; the test suite starts real, isolated tmux
30
+ servers (each with its own socket name) and cleans them up.
31
+
32
+ ## Tests
33
+
34
+ ```sh
35
+ python -m pytest -n 4 # ~1 minute on 8 cores
36
+ python -m pytest tests/test_v22.py -q # a single area
37
+ ```
38
+
39
+ - The suite is parallel-safe: sockets carry a uuid, project roots come from
40
+ `tmp_path`, and each instance gets its own data directory.
41
+ - Do **not** point tests at `$TMPDIR` as a project root; see the note in
42
+ `tests/conftest.py` for why that is pathologically slow.
43
+ - Tests that need a real terminal feature (Sixel, `termtex`, Chrome) are
44
+ skipped or simulated; real-tool smoke tests are manual only.
45
+ - `tests/README.md` documents the fragile spots (shell-readiness races, stdout
46
+ capture inside Textual, etc.) — read the relevant section before debugging a
47
+ flaky case.
48
+
49
+ ## Documentation boundaries
50
+
51
+ `docs/` is public and ships inside the PyPI sdist. It may contain only the
52
+ files listed in `docs/README.md`; `tests/test_docs_policy.py` enforces that
53
+ list, forbids private network addresses and blocks internal document names
54
+ (`*-PLAN.md`, `*-ACCEPTANCE.md`, …) anywhere in the tree.
55
+
56
+ Design plans, acceptance records and release playbooks live in `docs-internal/`
57
+ at the repository root: a nested git repository with its own history, excluded
58
+ by `.gitignore` and never published. A fresh clone does not contain it. If you
59
+ need that context, open an issue — do not add such files here.
60
+
61
+ ## Style
62
+
63
+ - Python ≥ 3.10, `from __future__ import annotations`, type hints on public
64
+ functions.
65
+ - No new runtime dependencies without a strong reason: the runtime is
66
+ Python + tmux, plus optional external tools (`micro`, `ov`, `termtex`,
67
+ `poppler`, Chrome) that must always degrade gracefully.
68
+ - Comments explain *why* (constraints, measured behaviour, past bugs), not
69
+ *what*. Several files carry long header comments recording exactly that —
70
+ keep the habit.
71
+
72
+ ## Release (maintainers)
73
+
74
+ 1. Bump the version in **two** places: `pyproject.toml` and
75
+ `myrtui/__init__.py`.
76
+ 2. Push `main`; CI must be green.
77
+ 3. `git tag v<version> && git push origin v<version>` — `release.yml` then runs
78
+ the macOS verification, builds wheel + sdist, publishes to PyPI via Trusted
79
+ Publishing, and creates the GitHub Release.
80
+
81
+ Publishing requires `pypi` as the Trusted Publisher environment in the repo
82
+ settings; see the header of `.github/workflows/release.yml`.
myrtui-0.5.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yiding Ping
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
myrtui-0.5.0/PKG-INFO ADDED
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.5
2
+ Name: myrtui
3
+ Version: 0.5.0
4
+ Summary: Lightweight per-project terminal workspace: file tree + git log + up to 4 real tmux panes, in Textual
5
+ Project-URL: Homepage, https://github.com/YidingPing/myrtui
6
+ Project-URL: Repository, https://github.com/YidingPing/myrtui
7
+ Project-URL: Issues, https://github.com/YidingPing/myrtui/issues
8
+ Project-URL: Changelog, https://github.com/YidingPing/myrtui/releases
9
+ Project-URL: Documentation, https://github.com/YidingPing/myrtui/blob/main/docs/USAGE.md
10
+ Author: Yiding Ping
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: multiplexer,terminal,textual,tmux,tui,workspace
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: MacOS
19
+ Classifier: Operating System :: POSIX :: Linux
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
26
+ Classifier: Topic :: Software Development :: User Interfaces
27
+ Classifier: Topic :: Terminals :: Terminal Emulators/X Terminals
28
+ Requires-Python: >=3.10
29
+ Requires-Dist: mdit-py-plugins>=0.4
30
+ Requires-Dist: pillow>=10.3; python_version >= '3.12'
31
+ Requires-Dist: platformdirs
32
+ Requires-Dist: textual-image<0.16,>=0.14; python_version >= '3.12'
33
+ Requires-Dist: textual<9,>=8
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest-xdist>=3; extra == 'dev'
36
+ Requires-Dist: pytest>=8; extra == 'dev'
37
+ Requires-Dist: tomli>=2; (python_version < '3.11') and extra == 'dev'
38
+ Provides-Extra: graphics
39
+ Requires-Dist: pillow>=10.3; extra == 'graphics'
40
+ Requires-Dist: textual-image<0.16,>=0.14; extra == 'graphics'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # myrtui
44
+
45
+ **English** | [简体中文](README.zh-CN.md)
46
+
47
+ [![PyPI](https://img.shields.io/pypi/v/myrtui)](https://pypi.org/project/myrtui/)
48
+ [![Python](https://img.shields.io/pypi/pyversions/myrtui)](https://pypi.org/project/myrtui/)
49
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
50
+ ![Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey)
51
+
52
+ A **project-scoped terminal workspace**: a file tree and git log on the left,
53
+ up to four real shell panes on the right — one session per project, restored
54
+ where you left it.
55
+
56
+ > It is **not** a tmux replacement. myrtui drives tmux (via a per-project
57
+ > socket) and adds the things tmux deliberately leaves out.
58
+
59
+ <!-- Record it with: vhs scripts/demo.tape -> docs/demo.gif, then uncomment. -->
60
+ <!-- ![demo](docs/demo.gif) -->
61
+
62
+ ## Why not just tmux
63
+
64
+ | | tmux / zellij | tmuxinator / sesh | myrtui |
65
+ |---|---|---|---|
66
+ | One session per project, named and isolated automatically | manual | needs a config file | `cd project && myrtui` |
67
+ | File tree + git history next to your shells | — | — | Yes |
68
+ | Layout ratios remembered per project | — | re-edit config | Yes |
69
+ | Open / preview Markdown, images, LaTeX | — | — | Yes |
70
+ | Detach / re-attach, shells survive | Yes | Yes | Yes |
71
+
72
+ ## Features
73
+
74
+ - **One directory = one instance.** Session identity is derived from the
75
+ realpath, so two projects never collide; running `myrtui` again attaches to
76
+ the same session with your panes, layout and scrollback intact.
77
+ - **Up to 4 real tmux panes** with mouse support: click to focus, wheel to
78
+ scroll, drag splitters to resize (ratios persisted per project).
79
+ - **File tree with git status colours** (VS Code conventions), lazy-loaded,
80
+ context menu for open / preview / copy path.
81
+ - **Git history panel** — repo-wide or per file, hover a commit for details.
82
+ - **Markdown preview** with GFM, `$math$` via `termtex`, optional full-page
83
+ LaTeX typesetting through KaTeX on a sepia page (`v`).
84
+ - **Image preview** with Sixel / Kitty graphics where the terminal supports it.
85
+ - **Selection and clipboard** that actually work inside a TUI: drag to select,
86
+ release to copy (OSC 52 + native clipboard commands).
87
+
88
+ ## Install
89
+
90
+ Requires `tmux >= 3.1` and Python `>= 3.10` (macOS and Linux; Windows is not
91
+ supported — `fcntl` and no native tmux).
92
+
93
+ ```sh
94
+ brew install tmux # Linux: sudo apt install tmux
95
+ pipx install myrtui
96
+ myrtui --version
97
+ ```
98
+
99
+ Or use the installer that also checks dependencies and offers the optional
100
+ tools (`micro`, `ov`, `termtex`):
101
+
102
+ ```sh
103
+ curl -fsSL https://raw.githubusercontent.com/YidingPing/myrtui/main/scripts/install.sh | sh
104
+ ```
105
+
106
+ Upgrade with `pipx upgrade myrtui`. Annotations: Python ≥ 3.12 automatically
107
+ pulls the bitmap extras (`textual-image` + `Pillow`); on 3.10/3.11 previews fall
108
+ back to text, everything else works.
109
+
110
+ ## Usage
111
+
112
+ ```sh
113
+ cd some-project
114
+ myrtui # first run creates the session, later runs attach
115
+ ```
116
+
117
+ - `myrtui ls` — list live instances (add `--all` for dead leftovers, `--json`);
118
+ - `myrtui attach [target]` — target = index, hash prefix, or path;
119
+ - `myrtui stop [target]` — cooperative shutdown (never kills panes);
120
+ - `myrtui --root /path/to/other/project` — work on a second project without
121
+ `cd`; `--shell` and `--scrollback` set the pane shell / history limit.
122
+
123
+ ## Keys (Ctrl-a prefix)
124
+
125
+ | Key | Action |
126
+ |---|---|
127
+ | `Ctrl-a d` | detach — quit the UI, keep every shell running |
128
+ | `Ctrl-a k` | kill the session (asks first) |
129
+ | `Ctrl-a t` / `w` | open / close a pane (up to 4) |
130
+ | `Ctrl-a 1..4` | focus pane N |
131
+ | `Ctrl-a r` | re-open a dead pane |
132
+ | `Ctrl-a b` | collapse / expand the sidebar |
133
+ | `Ctrl-a s` / `g` | focus the file tree / git history |
134
+ | `Ctrl-a c` / `v` | copy selection / paste |
135
+
136
+ Everything else goes straight to the inner shell. `Esc` returns from the
137
+ sidebar to the active pane; `Ctrl-a ?` (or hovering `?` in the top bar) shows
138
+ the full cheat sheet. Full tables: [docs/USAGE.md](docs/USAGE.md#key-bindings).
139
+
140
+ ## Configuration
141
+
142
+ <details>
143
+ <summary>Environment variables</summary>
144
+
145
+ | Variable | Meaning |
146
+ |---|---|
147
+ | `MYRTUI_LANG` | UI language: `en` (default) / `zh_CN`; `--lang` overrides it for one run |
148
+ | `MYRTUI_EDITOR` | editor for "Open" (falls back to `$EDITOR` / `$VISUAL` / `micro` → `vim` → `vi`) |
149
+ | `MYRTUI_IDLE_INTERVAL` | idle capture interval in seconds (default `0.15`, range `0.05–5.0`); raise it for background instances |
150
+ | `MYRTUI_COPY_ON_SELECT` | auto-copy on drag release (default `1`; `0` keeps the selection for `Ctrl-a c`) |
151
+ | `MYRTUI_DRAG_SELECT` | `always` (default) = drag always selects; `app` = when the pane program requested mouse, drag is forwarded to it |
152
+ | `MYRTUI_GRAPHICS` | bitmap protocol: `auto` (default) / `sixel` / `tgp` / `unicode` / `off` |
153
+ | `MYRTUI_PAGE_THEME` | LaTeX page theme: `sepia` (default) / `paper` / `gray` / `white` / `dim` / `dark` |
154
+ | `MYRTUI_MATH_BACKEND` | math backend for Markdown preview: `auto` (default) / `plain` / `termtex` |
155
+ | `MYRTUI_CELL_PX` | override the terminal cell size (`10x20`) when it is not reported |
156
+ | `MYRTUI_CHROME` | Chrome/Chromium binary for the LaTeX page view |
157
+ | `MYRTUI_PDFTOCAIRO` | PDF → PNG converter (`pdftocairo` preferred, then `pdftoppm`) |
158
+ | `MYRTUI_LOOP_DEBUG` / `MYRTUI_MOUSE_DEBUG` | write timing / mouse event diagnostics to stderr or a temp log |
159
+
160
+ </details>
161
+
162
+ ## Limitations
163
+
164
+ - **macOS / Linux only** — Windows has no native tmux and `cli.py` needs `fcntl`.
165
+ - **Clicks inside panes are delayed by 50–150 ms** — dragging always belongs to
166
+ selection, so a click is injected on release (use `MYRTUI_DRAG_SELECT=app` to
167
+ give drag back to the program).
168
+ - **No bitmap inside panes** — images render in the preview layer only.
169
+ - **Soft-wrapped lines copy with extra newlines** (capture works line by line).
170
+ - **Echo latency ~150 ms when idle** — tmux capture is polled; typing raises the
171
+ rate to ~30 ms.
172
+
173
+ ## Docs & contributing
174
+
175
+ - [docs/USAGE.md](docs/USAGE.md) — the full manual (keys, previews, splitters,
176
+ instance management, all environment variables). Also available in
177
+ [Chinese](docs/USAGE.zh-CN.md).
178
+ - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — module map and design decisions.
179
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — how to run tests, plus the language policy.
180
+
181
+ Code comments and docstrings are written in Chinese by project convention;
182
+ user-facing text (this README, the UI, `docs/`) is available in English.
183
+ Issues and pull requests in either language are welcome.
184
+
185
+ ## License
186
+
187
+ MIT — see [LICENSE](LICENSE).
myrtui-0.5.0/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # myrtui
2
+
3
+ **English** | [简体中文](README.zh-CN.md)
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/myrtui)](https://pypi.org/project/myrtui/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/myrtui)](https://pypi.org/project/myrtui/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
8
+ ![Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey)
9
+
10
+ A **project-scoped terminal workspace**: a file tree and git log on the left,
11
+ up to four real shell panes on the right — one session per project, restored
12
+ where you left it.
13
+
14
+ > It is **not** a tmux replacement. myrtui drives tmux (via a per-project
15
+ > socket) and adds the things tmux deliberately leaves out.
16
+
17
+ <!-- Record it with: vhs scripts/demo.tape -> docs/demo.gif, then uncomment. -->
18
+ <!-- ![demo](docs/demo.gif) -->
19
+
20
+ ## Why not just tmux
21
+
22
+ | | tmux / zellij | tmuxinator / sesh | myrtui |
23
+ |---|---|---|---|
24
+ | One session per project, named and isolated automatically | manual | needs a config file | `cd project && myrtui` |
25
+ | File tree + git history next to your shells | — | — | Yes |
26
+ | Layout ratios remembered per project | — | re-edit config | Yes |
27
+ | Open / preview Markdown, images, LaTeX | — | — | Yes |
28
+ | Detach / re-attach, shells survive | Yes | Yes | Yes |
29
+
30
+ ## Features
31
+
32
+ - **One directory = one instance.** Session identity is derived from the
33
+ realpath, so two projects never collide; running `myrtui` again attaches to
34
+ the same session with your panes, layout and scrollback intact.
35
+ - **Up to 4 real tmux panes** with mouse support: click to focus, wheel to
36
+ scroll, drag splitters to resize (ratios persisted per project).
37
+ - **File tree with git status colours** (VS Code conventions), lazy-loaded,
38
+ context menu for open / preview / copy path.
39
+ - **Git history panel** — repo-wide or per file, hover a commit for details.
40
+ - **Markdown preview** with GFM, `$math$` via `termtex`, optional full-page
41
+ LaTeX typesetting through KaTeX on a sepia page (`v`).
42
+ - **Image preview** with Sixel / Kitty graphics where the terminal supports it.
43
+ - **Selection and clipboard** that actually work inside a TUI: drag to select,
44
+ release to copy (OSC 52 + native clipboard commands).
45
+
46
+ ## Install
47
+
48
+ Requires `tmux >= 3.1` and Python `>= 3.10` (macOS and Linux; Windows is not
49
+ supported — `fcntl` and no native tmux).
50
+
51
+ ```sh
52
+ brew install tmux # Linux: sudo apt install tmux
53
+ pipx install myrtui
54
+ myrtui --version
55
+ ```
56
+
57
+ Or use the installer that also checks dependencies and offers the optional
58
+ tools (`micro`, `ov`, `termtex`):
59
+
60
+ ```sh
61
+ curl -fsSL https://raw.githubusercontent.com/YidingPing/myrtui/main/scripts/install.sh | sh
62
+ ```
63
+
64
+ Upgrade with `pipx upgrade myrtui`. Annotations: Python ≥ 3.12 automatically
65
+ pulls the bitmap extras (`textual-image` + `Pillow`); on 3.10/3.11 previews fall
66
+ back to text, everything else works.
67
+
68
+ ## Usage
69
+
70
+ ```sh
71
+ cd some-project
72
+ myrtui # first run creates the session, later runs attach
73
+ ```
74
+
75
+ - `myrtui ls` — list live instances (add `--all` for dead leftovers, `--json`);
76
+ - `myrtui attach [target]` — target = index, hash prefix, or path;
77
+ - `myrtui stop [target]` — cooperative shutdown (never kills panes);
78
+ - `myrtui --root /path/to/other/project` — work on a second project without
79
+ `cd`; `--shell` and `--scrollback` set the pane shell / history limit.
80
+
81
+ ## Keys (Ctrl-a prefix)
82
+
83
+ | Key | Action |
84
+ |---|---|
85
+ | `Ctrl-a d` | detach — quit the UI, keep every shell running |
86
+ | `Ctrl-a k` | kill the session (asks first) |
87
+ | `Ctrl-a t` / `w` | open / close a pane (up to 4) |
88
+ | `Ctrl-a 1..4` | focus pane N |
89
+ | `Ctrl-a r` | re-open a dead pane |
90
+ | `Ctrl-a b` | collapse / expand the sidebar |
91
+ | `Ctrl-a s` / `g` | focus the file tree / git history |
92
+ | `Ctrl-a c` / `v` | copy selection / paste |
93
+
94
+ Everything else goes straight to the inner shell. `Esc` returns from the
95
+ sidebar to the active pane; `Ctrl-a ?` (or hovering `?` in the top bar) shows
96
+ the full cheat sheet. Full tables: [docs/USAGE.md](docs/USAGE.md#key-bindings).
97
+
98
+ ## Configuration
99
+
100
+ <details>
101
+ <summary>Environment variables</summary>
102
+
103
+ | Variable | Meaning |
104
+ |---|---|
105
+ | `MYRTUI_LANG` | UI language: `en` (default) / `zh_CN`; `--lang` overrides it for one run |
106
+ | `MYRTUI_EDITOR` | editor for "Open" (falls back to `$EDITOR` / `$VISUAL` / `micro` → `vim` → `vi`) |
107
+ | `MYRTUI_IDLE_INTERVAL` | idle capture interval in seconds (default `0.15`, range `0.05–5.0`); raise it for background instances |
108
+ | `MYRTUI_COPY_ON_SELECT` | auto-copy on drag release (default `1`; `0` keeps the selection for `Ctrl-a c`) |
109
+ | `MYRTUI_DRAG_SELECT` | `always` (default) = drag always selects; `app` = when the pane program requested mouse, drag is forwarded to it |
110
+ | `MYRTUI_GRAPHICS` | bitmap protocol: `auto` (default) / `sixel` / `tgp` / `unicode` / `off` |
111
+ | `MYRTUI_PAGE_THEME` | LaTeX page theme: `sepia` (default) / `paper` / `gray` / `white` / `dim` / `dark` |
112
+ | `MYRTUI_MATH_BACKEND` | math backend for Markdown preview: `auto` (default) / `plain` / `termtex` |
113
+ | `MYRTUI_CELL_PX` | override the terminal cell size (`10x20`) when it is not reported |
114
+ | `MYRTUI_CHROME` | Chrome/Chromium binary for the LaTeX page view |
115
+ | `MYRTUI_PDFTOCAIRO` | PDF → PNG converter (`pdftocairo` preferred, then `pdftoppm`) |
116
+ | `MYRTUI_LOOP_DEBUG` / `MYRTUI_MOUSE_DEBUG` | write timing / mouse event diagnostics to stderr or a temp log |
117
+
118
+ </details>
119
+
120
+ ## Limitations
121
+
122
+ - **macOS / Linux only** — Windows has no native tmux and `cli.py` needs `fcntl`.
123
+ - **Clicks inside panes are delayed by 50–150 ms** — dragging always belongs to
124
+ selection, so a click is injected on release (use `MYRTUI_DRAG_SELECT=app` to
125
+ give drag back to the program).
126
+ - **No bitmap inside panes** — images render in the preview layer only.
127
+ - **Soft-wrapped lines copy with extra newlines** (capture works line by line).
128
+ - **Echo latency ~150 ms when idle** — tmux capture is polled; typing raises the
129
+ rate to ~30 ms.
130
+
131
+ ## Docs & contributing
132
+
133
+ - [docs/USAGE.md](docs/USAGE.md) — the full manual (keys, previews, splitters,
134
+ instance management, all environment variables). Also available in
135
+ [Chinese](docs/USAGE.zh-CN.md).
136
+ - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — module map and design decisions.
137
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — how to run tests, plus the language policy.
138
+
139
+ Code comments and docstrings are written in Chinese by project convention;
140
+ user-facing text (this README, the UI, `docs/`) is available in English.
141
+ Issues and pull requests in either language are welcome.
142
+
143
+ ## License
144
+
145
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,136 @@
1
+ # myrtui
2
+
3
+ [English](README.md) | **简体中文**
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/myrtui)](https://pypi.org/project/myrtui/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/myrtui)](https://pypi.org/project/myrtui/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
8
+ ![Platforms](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey)
9
+
10
+ **面向单个项目的终端工作台**:左侧文件树 + Git 历史,右侧最多 4 个真实 shell
11
+ pane。一个项目一个会话,退出再进来还是原来的布局。
12
+
13
+ > 它不是 tmux 的替代品——底层就是 tmux(每个项目一个独立 socket)。
14
+ > myrtui 补的是 tmux 故意不做的那些事。
15
+
16
+ <!-- 录制方式:vhs scripts/demo.tape -> docs/demo.gif,录完取消下面这行注释。 -->
17
+ <!-- ![demo](docs/demo.gif) -->
18
+
19
+ ## 为什么不用 tmux 自己分屏
20
+
21
+ | | tmux / zellij | tmuxinator / sesh | myrtui |
22
+ |---|---|---|---|
23
+ | 一项目一会话,自动命名与隔离 | 手工 | 要写配置文件 | `cd 项目 && myrtui` |
24
+ | 文件树 + Git 历史与 shell 同屏 | — | — | 有 |
25
+ | 每个项目记住分隔线比例 | — | 每次改配置 | 有 |
26
+ | 打开 / 预览 Markdown、图片、LaTeX | — | — | 有 |
27
+ | detach / attach,shell 继续存活 | 有 | 有 | 有 |
28
+
29
+ ## 特性
30
+
31
+ - **一个目录 = 一个实例**:身份由真实路径派生,两个项目互不干扰;再次运行
32
+ 同一目录即 attach 回原会话,pane、布局、滚动历史都在。
33
+ - **最多 4 个真实 tmux pane**,鼠标可用:点击聚焦、滚轮翻历史、拖动分隔线
34
+ 调比例(比例按项目落盘记住)。
35
+ - **文件树带 Git 状态配色**(VS Code 习惯),懒加载;右键菜单可打开 / 预览 /
36
+ 复制路径。
37
+ - **Git 历史面板**:仓库级或按文件,鼠标停留 1 秒看提交详情。
38
+ - **Markdown 预览**:GFM、`$公式$` 走 `termtex`,可选 `v` 用 KaTeX 分页排版
39
+ (米黄纸底)。
40
+ - **图片预览**:终端支持 Sixel / Kitty 时按可视区等比显示。
41
+ - **选区与剪贴板**在 TUI 里真的能用:拖拽选字,松手即复制(OSC 52 + 系统命令)。
42
+
43
+ ## 安装
44
+
45
+ 需要 `tmux >= 3.1` 与 Python `>= 3.10`(macOS / Linux;不支持 Windows——
46
+ `fcntl` 依赖,且 tmux 无原生 Windows 版)。
47
+
48
+ ```sh
49
+ brew install tmux # Linux: sudo apt install tmux
50
+ pipx install myrtui
51
+ myrtui --version
52
+ ```
53
+
54
+ 也可以交给脚本(额外检查依赖、逐项询问可选组件):
55
+
56
+ ```sh
57
+ curl -fsSL https://raw.githubusercontent.com/YidingPing/myrtui/main/scripts/install.sh | sh
58
+ ```
59
+
60
+ 升级用 `pipx upgrade myrtui`。Python ≥ 3.12 会自动带上位图依赖(`textual-image`
61
+ + `Pillow`);3.10/3.11 上预览回落为文本,其余功能不受影响。
62
+
63
+ ## 使用
64
+
65
+ ```sh
66
+ cd some-project
67
+ myrtui # 首次运行创建会话,之后都是 attach
68
+ ```
69
+
70
+ - `myrtui ls` —— 列出存活实例(`--all` 含 dead 残留,`--json` 机器可读);
71
+ - `myrtui attach [目标]` —— 目标 = 序号 / hash 前缀 / 项目路径;
72
+ - `myrtui stop [目标]` —— 协作式退场(不 kill pane);
73
+ - `myrtui --root /path/to/other` —— 不 `cd` 也能开另一个项目的实例;
74
+ `--shell` / `--scrollback` 设置 pane 的 shell 与历史深度。
75
+
76
+ ## 键位(Ctrl-a 前缀)
77
+
78
+ | 键 | 作用 |
79
+ |---|---|
80
+ | `Ctrl-a d` | detach:前端退出,所有 shell 继续运行 |
81
+ | `Ctrl-a k` | 结束会话(先确认) |
82
+ | `Ctrl-a t` / `w` | 新建 / 关闭 pane(最多 4 个) |
83
+ | `Ctrl-a 1..4` | 切换焦点 pane |
84
+ | `Ctrl-a r` | 重开已退出的 pane |
85
+ | `Ctrl-a b` | 折叠 / 展开侧栏 |
86
+ | `Ctrl-a s` / `g` | 聚焦文件树 / Git 历史 |
87
+ | `Ctrl-a c` / `v` | 复制选区 / 粘贴 |
88
+
89
+ 其余按键直接透传给内层 shell。`Esc` 从侧栏回到 pane;`Ctrl-a ?`(或鼠标悬停
90
+ 顶栏的 `?`)显示完整快捷键浮层。全表见[使用手册](docs/USAGE.zh-CN.md)。
91
+
92
+ ## 配置
93
+
94
+ <details>
95
+ <summary>环境变量</summary>
96
+
97
+ | 变量 | 作用 |
98
+ |---|---|
99
+ | `MYRTUI_LANG` | 界面语言:`en`(默认)/ `zh_CN`;`--lang` 可单次覆盖 |
100
+ | `MYRTUI_EDITOR` | 「打开」用的编辑器(否则 `$EDITOR` / `$VISUAL` / `micro` → `vim` → `vi`) |
101
+ | `MYRTUI_IDLE_INTERVAL` | 空闲抓屏间隔,秒(默认 `0.15`,夹取 `0.05–5.0`);后台实例可调大 |
102
+ | `MYRTUI_COPY_ON_SELECT` | 拖拽松手自动复制(默认 `1`;`0` 时用 `Ctrl-a c` 手动复制) |
103
+ | `MYRTUI_DRAG_SELECT` | `always`(默认)= 拖拽永远选字;`app` = 程序请求鼠标时把拖拽还给它 |
104
+ | `MYRTUI_GRAPHICS` | 位图协议:`auto`(默认)/ `sixel` / `tgp` / `unicode` / `off` |
105
+ | `MYRTUI_PAGE_THEME` | `v` 排版页面配色:`sepia`(默认)/ `paper` / `gray` / `white` / `dim` / `dark` |
106
+ | `MYRTUI_MATH_BACKEND` | Markdown 公式后端:`auto`(默认)/ `plain` / `termtex` |
107
+ | `MYRTUI_CELL_PX` | 终端不回报单元格像素尺寸时手动指定(`10x20`) |
108
+ | `MYRTUI_CHROME` | `v` 排版用的 Chrome/Chromium |
109
+ | `MYRTUI_PDFTOCAIRO` | PDF → PNG 转换器(优先 `pdftocairo`,其次 `pdftoppm`) |
110
+ | `MYRTUI_LOOP_DEBUG` / `MYRTUI_MOUSE_DEBUG` | 排障:事件循环延迟 / 鼠标事件写日志 |
111
+
112
+ </details>
113
+
114
+ ## 已知限制
115
+
116
+ - **仅 macOS / Linux**:Windows 没有原生 tmux,`cli.py` 也依赖 `fcntl`。
117
+ - **pane 内点击延迟 50–150 ms**:拖拽永远归选字,所以点击在松手时才注入
118
+ (`MYRTUI_DRAG_SELECT=app` 可把拖拽还给程序)。
119
+ - **pane 内没有位图**:图片只在预览层显示。
120
+ - **软折行复制会多出换行**:抓屏是按行来的。
121
+ - **空闲回显约 150 ms**:抓屏是轮询的,输入后会临时提频到 ~30 ms。
122
+
123
+ ## 文档与贡献
124
+
125
+ - [使用手册(中文)](docs/USAGE.zh-CN.md) —— 完整键位、预览、分隔线、实例管理、
126
+ 全部环境变量。
127
+ - [docs/USAGE.md](docs/USAGE.md) —— 同一份手册的英文版。
128
+ - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) —— 模块划分与设计取舍。
129
+ - [CONTRIBUTING.md](CONTRIBUTING.md) —— 如何跑测试,以及注释语言政策。
130
+
131
+ 按项目约定,**代码注释与 docstring 用中文**;面向用户的文本(README、界面、
132
+ `docs/`)提供英文。Issue 与 PR 中英文都欢迎。
133
+
134
+ ## 许可证
135
+
136
+ MIT —— 见 [LICENSE](LICENSE)。