Skip to content

Commit 090abcd

Browse files
ThomasK33claude
andcommitted
docs(repro): launch old Neovim via mise exec in paste-repro
Make reproducing #161 easy without changing your installed/active Neovim: - agent-repro.sh: add NVIM_VERSION (e.g. NVIM_VERSION=0.11.7), resolved through `mise exec neovim@<ver> -- nvim` — side-by-side and ephemeral, and resolves the managed tool directly so it isn't shadowed by other version managers on PATH. - README: document `mise exec neovim@<ver> -- nvim` for the interactive and pure-Neovim paths, with a note that mise installs side-by-side and never changes your default Neovim. Change-Id: Ia4140eb361c835b94151ec655c57ed90b37b9c36 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent cb225ef commit 090abcd

2 files changed

Lines changed: 55 additions & 24 deletions

File tree

fixtures/paste-repro/README.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,37 +69,43 @@ The observer is wired in as `terminal_cmd`, so pastes flow through the _real_ pl
6969

7070
## Reproduce it
7171

72-
The bug only appears on an affected Neovim. Install one with mise:
73-
74-
```bash
75-
mise install neovim@0.11.6 # affected (also 0.11.5, 0.12.1)
76-
```
72+
The bug only appears on an affected Neovim (`< 0.12.2`). You do **not** need to change your
73+
installed/active Neovim — `mise exec neovim@<ver> -- nvim …` runs an old build ephemerally. mise
74+
keeps versions side-by-side in its own cache and only switches the active one via `mise use`, so
75+
this never touches your default Neovim. (`mise exec neovim@<ver> -- nvim` resolves the managed tool
76+
directly, so it also isn't shadowed by other version managers on your `PATH`.) `agent-repro.sh`
77+
does this for you via `NVIM_VERSION`.
7778

7879
### A. Automated (agent-tty) — deterministic, no manual steps
7980

8081
From the repo root:
8182

8283
```bash
83-
NVIM_BIN="$HOME/.local/share/mise/installs/neovim/0.11.6/bin/nvim" \
84-
fixtures/paste-repro/agent-repro.sh
84+
NVIM_VERSION=0.11.7 fixtures/paste-repro/agent-repro.sh # affected: also 0.11.5/0.11.6/0.12.0/0.12.1
8585
```
8686

87-
Expected on 0.11.6:
87+
Expected on an affected version:
8888

8989
```
9090
default TOTAL ... start_markers=6 end_markers=6 => BUG (fragmented)
9191
with-workaround TOTAL ... start_markers=1 end_markers=1 => OK (single paste)
9292
```
9393

94-
Re-run with a 0.12.2 `NVIM_BIN` and both rows report `OK` — demonstrating the version fix.
94+
Re-run with `NVIM_VERSION=0.12.2` and both rows report `OK` — demonstrating the version fix.
9595
The script drives a real Neovim TUI in an isolated agent-tty session, auto-opens the plugin's
9696
Claude terminal (`PASTE_REPRO_AUTOOPEN=1`), pastes via bracketed paste, and reports segments.
97+
(`NVIM_VERSION` resolves the binary through mise without touching your active Neovim; pass an
98+
explicit `NVIM_BIN=/path/to/nvim` instead if you prefer.)
9799

98100
### B. Manual (interactive)
99101

102+
The `vv` alias calls bare `nvim` (subject to whatever's first on `PATH`), so launch Neovim directly
103+
through `mise exec` instead — it runs the managed build unambiguously:
104+
100105
```bash
101-
source fixtures/nvim-aliases.sh
102-
PATH="$HOME/.local/share/mise/installs/neovim/0.11.6/bin:$PATH" vv paste-repro
106+
cd fixtures && \
107+
NVIM_APPNAME=paste-repro XDG_CONFIG_HOME="$PWD" \
108+
mise exec neovim@0.11.7 -- nvim
103109
```
104110

105111
Then inside Neovim:
@@ -114,9 +120,9 @@ Then inside Neovim:
114120
### C. Pure-Neovim isolation (no plugin) — proves it's core, not the plugin
115121

116122
```bash
117-
NVIM=$HOME/.local/share/mise/installs/neovim/0.11.6/bin/nvim
118-
$NVIM --clean -c "terminal python3 $PWD/fixtures/paste-repro/observer.py /tmp/obs.log" -c startinsert
119-
# paste 100+ lines, then: grep TOTAL /tmp/obs.log -> start_markers=6 on 0.11.6, =1 on 0.12.2
123+
mise exec neovim@0.11.7 -- nvim --clean \
124+
-c "terminal python3 $PWD/fixtures/paste-repro/observer.py /tmp/obs.log" -c startinsert
125+
# paste 100+ lines, then: grep TOTAL /tmp/obs.log -> start_markers=6 on 0.11.7, =1 on 0.12.2
120126
```
121127

122128
## The workaround (and its edge cases)

fixtures/paste-repro/agent-repro.sh

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,43 @@
1414
#
1515
# Requirements: agent-tty, python3, and one or more Neovim builds.
1616
# The bug is version-dependent (fixed upstream by neovim/neovim#39152, in 0.12.2):
17-
# * Neovim 0.11.x / 0.12.1 -> reproduces (N segments)
18-
# * Neovim 0.12.2+ -> single segment
19-
# Install older builds with mise, e.g.: mise install neovim@0.11.6
17+
# * Neovim 0.11.x / 0.12.0 / 0.12.1 -> reproduces (N segments)
18+
# * Neovim 0.12.2+ -> single segment
2019
#
2120
# Usage:
22-
# ./agent-repro.sh # uses `nvim` on PATH, default + workaround
21+
# ./agent-repro.sh # uses `nvim` on PATH
22+
# NVIM_VERSION=0.11.7 ./agent-repro.sh # run an old Neovim via mise (recommended)
2323
# NVIM_BIN=/path/to/nvim ./agent-repro.sh
24-
# LINES=300 ./agent-repro.sh # bigger payload
24+
# LINES=300 ./agent-repro.sh # bigger payload
25+
#
26+
# NVIM_VERSION resolves the binary through mise. mise installs versions
27+
# side-by-side under its own cache, so this NEVER changes your active/default
28+
# Neovim (that only changes via `mise use`). To run one off without this script:
29+
# mise exec neovim@0.11.7 -- nvim ...
2530
set -uo pipefail
2631

2732
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
2833
FIX_DIR="$(dirname "$HERE")" # .../fixtures
29-
NVIM="${NVIM_BIN:-$(command -v nvim)}"
3034
LINES="${LINES:-120}"
3135
export _ZO_DOCTOR=0
3236

37+
# Resolve how to launch Neovim (used both verbatim and embedded in a `bash -lc`):
38+
# explicit NVIM_BIN > NVIM_VERSION (via `mise exec`, side-by-side/ephemeral) > `nvim` on PATH.
39+
# `mise exec neovim@X -- nvim` resolves the managed tool directly, so it is not affected by other
40+
# nvim managers on PATH and never changes your active Neovim.
41+
if [ -n "${NVIM_BIN:-}" ]; then
42+
NVIM="$NVIM_BIN"
43+
elif [ -n "${NVIM_VERSION:-}" ]; then
44+
command -v mise >/dev/null || {
45+
echo "ERROR: NVIM_VERSION set but mise not found on PATH"
46+
exit 1
47+
}
48+
mise install "neovim@$NVIM_VERSION" >/dev/null 2>&1 || true
49+
NVIM="mise exec neovim@$NVIM_VERSION -- nvim"
50+
else
51+
NVIM="nvim"
52+
fi
53+
3354
command -v agent-tty >/dev/null || {
3455
echo "ERROR: agent-tty not found on PATH"
3556
exit 1
@@ -38,8 +59,11 @@ command -v python3 >/dev/null || {
3859
echo "ERROR: python3 not found on PATH"
3960
exit 1
4061
}
41-
[ -x "$NVIM" ] || {
42-
echo "ERROR: nvim not found (set NVIM_BIN)"
62+
# $NVIM may be a path, "nvim", or "mise exec neovim@X -- nvim", so smoke-test it
63+
# (unquoted, to word-split the launcher) rather than checking for an executable file.
64+
# shellcheck disable=SC2086
65+
$NVIM --version >/dev/null 2>&1 || {
66+
echo "ERROR: could not run Neovim ('$NVIM'); set NVIM_BIN or NVIM_VERSION"
4367
exit 1
4468
}
4569

@@ -56,7 +80,8 @@ path, n = sys.argv[1], int(sys.argv[2])
5680
open(path, "w").write("\n".join("L%03d: the quick brown fox jumps over the lazy dog" % i for i in range(1, n+1)) + "\n")
5781
PY
5882
echo "Payload: $LINES lines, $(wc -c <"$PAYLOAD") bytes"
59-
echo "Neovim: $("$NVIM" --version | head -1)"
83+
# shellcheck disable=SC2086
84+
echo "Neovim: $($NVIM --version | head -1)"
6085
echo
6186

6287
run() { # run <apply_fix 0|1> <label>
@@ -66,7 +91,7 @@ run() { # run <apply_fix 0|1> <label>
6691
local a=(agent-tty --home "$AGENT_HOME")
6792
local sid
6893
sid="$("${a[@]}" create --json --cols 110 --rows 32 -- \
69-
bash -lc "cd '$FIX_DIR' && PASTE_OBSERVER_LOG='$log' APPLY_PASTE_FIX='$fix' PASTE_REPRO_AUTOOPEN=1 NVIM_APPNAME=paste-repro XDG_CONFIG_HOME='$FIX_DIR' '$NVIM' --clean -u '$FIX_DIR/paste-repro/init.lua'" |
94+
bash -lc "cd '$FIX_DIR' && PASTE_OBSERVER_LOG='$log' APPLY_PASTE_FIX='$fix' PASTE_REPRO_AUTOOPEN=1 NVIM_APPNAME=paste-repro XDG_CONFIG_HOME='$FIX_DIR' $NVIM --clean -u '$FIX_DIR/paste-repro/init.lua'" |
7095
python3 -c "import json,sys;print(json.load(sys.stdin)['result']['sessionId'])")"
7196
"${a[@]}" wait "$sid" --text 'OBSERVER READY' --timeout-ms 15000 --json >/dev/null 2>&1
7297
"${a[@]}" paste "$sid" "$(cat "$PAYLOAD")" --json >/dev/null 2>&1

0 commit comments

Comments
 (0)