1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# The rename: zellij → sl0ppij
**Goal:** a machine can have stock zellij and sl0ppij installed at the same time,
running at the same time, without sharing a single byte of state.
Today the fork still builds a binary called `zellij` and `~/bin/sl0ppij` is a
symlink to it — so on any machine with real zellij, sl0ppij would fight it over
`~/.config/zellij`, the socket dir, and `$ZELLIJ*`.
## Isolation checklist
A rename is "done" when all of these are disjoint from upstream:
| surface | upstream today | after |
|---|---|---|
| binary name | `zellij` | `sl0ppij` |
| config dir | `~/.config/zellij` | `~/.config/sl0ppij` |
| cache/data dir | `ProjectDirs("", "", "Zellij")` | `ProjectDirs("", "", "sl0ppij")` |
| system config | `/etc/zellij` | `/etc/sl0ppij` |
| socket dir | `$TMPDIR/zellij-$UID` | `$TMPDIR/sl0ppij-$UID` |
| log dir/file | `…/zellij-log/zellij.log` | `…/sl0ppij-log/sl0ppij.log` |
| env marker | `ZELLIJ=0` | see "env vars" below |
| session env | `ZELLIJ_SESSION_NAME`, `ZELLIJ_PANE_ID`, … | ditto |
| plugin URL scheme | `zellij:about` | `sl0ppij:about` (+ accept `zellij:`) |
| desktop/shell assets | `assets/zellij.desktop`, `zellij.rc` | renamed |
## Where the work actually is
Encouragingly small and centralised:
- **`zellij-utils/src/consts.rs`** — the whole path story. Lines to touch:
- `SYSTEM_DEFAULT_CONFIG_DIR` (`/etc/zellij`, and the Windows arm)
- `ZELLIJ_PROJ_DIR` — `ProjectDirs::from("", "", "Zellij")` / `("org", "Zellij Contributors", "Zellij")`
- `ZELLIJ_TMP_DIR` — `temp_dir().join(format!("zellij-{}", *UID))`
- `ZELLIJ_TMP_LOG_DIR` / `ZELLIJ_TMP_LOG_FILE` — `zellij-log`, `zellij.log`
- the non-unix arm's `tmp_dir.join("zellij")`
- **`zellij-utils/src/envs.rs`** — `ZELLIJ_ENV_KEY`, `SESSION_NAME_ENV_KEY`,
`SOCKET_DIR_ENV_KEY`.
- **`zellij-utils/src/cli.rs:57`** — clap `name = "zellij"` (drives every usage
string and `--help`).
- **`zellij-utils/src/input/plugins.rs:77`** — builtin plugin URL scheme.
- **`Cargo.toml`** — the root package `name = "zellij"` decides the binary name.
*Renaming the package is the loudest possible change against upstream.* See
"Strategy" below.
- **`assets/zellij.desktop`, `assets/zellij.rc`**, `wix/`, `.github/` packaging bits.
- **user-visible help strings** — `"zellij setup --check"`, `"zellij -l compact"`
etc. inside `default-plugins/status-bar` tips and `about`.
## Strategy: one seam, not a sed
Do **not** `sed -i s/zellij/sl0ppij/g` the tree. Every touched upstream line is a
rebase conflict forever, and there are ~3300 upstream commits of future rebases.
Instead:
1. **Introduce a single branding module** (`zellij-utils/src/branding.rs`) with
`pub const APP: &str = "sl0ppij";` plus derived consts (config dir name, tmp
prefix, log names, env prefix, plugin scheme).
2. **Point the ~15 sites above at it.** Each becomes a one-line diff that reads
`branding::APP` instead of a literal — small, stable, easy to re-apply.
3. **Keep the crate/package names as `zellij*`.** The *binary* name is set with
`[[bin]] name = "sl0ppij"` instead of renaming the package, so all the
intra-workspace `zellij-utils`/`zellij-tile` deps, plugin APIs and the
`0.45.0+sl0p1` version trick keep working untouched. Nothing user-facing says
"zellij" and nothing internal has to move.
4. **`ZELLIJ_EXECUTABLE_LOCATION` / self-exec**: the client re-execs itself to
spawn the server. Verify it resolves via `current_exe()` and not a hardcoded
`"zellij"` on `$PATH`, or a sl0ppij client will start a zellij server.
## Open decision: env vars
Renaming `ZELLIJ=0` → `SL0PPIJ=0` gives true isolation but breaks every third-party
thing that detects "am I in a multiplexer" (shell prompts, starship, direnv
snippets, nested-session guards, and possibly our own `pi-ext`).
Proposal: **export both.** `SL0PPIJ*` is authoritative and what our own code
reads; `ZELLIJ*` is exported too so the ecosystem keeps working, with a config
option `export_zellij_env_vars true|false` for people who want strict isolation.
Reading follows the same order (`SL0PPIJ_*` first, then `ZELLIJ_*`).
Needs a decision before implementation starts.
## Verification
The rename is testable, so it should have a test:
```bash
# no state overlap while both run
sl0ppij -s a & zellij -s b &
test -d ~/.config/sl0ppij && test -d ~/.config/zellij
ls $TMPDIR/sl0ppij-$UID $TMPDIR/zellij-$UID # both exist, disjoint
sl0ppij list-sessions # shows a, not b
zellij list-sessions # shows b, not a
```
Plus a unit test asserting no shipped default path contains the string `zellij`.
|