T M4.5: textDocument/prepareRename (backlog item 3)
Built on #25 + #26 (branched off main after both merged).
- src/prepare_rename.rs: parse the prepareRename union
null | Range | { range, placeholder } | { defaultBehavior } into
{ allowed, placeholder?, range? }. Store/Key/Shared keyed
(server, uri). 7 unit tests.
- src/lsp.rs: prepare_rename_store + accessor,
ResponseRoute::PrepareRename + absorb, request_prepare_rename;
capability rename.prepareSupport=true +
prepareSupportDefaultBehavior=1.
- src/lua_bindings.rs: _request_prepare_rename_raw,
pmacs.prepare_rename.{result,clear}.
- builtin/runtime/lsp.lua: pmacs.lsp.rename() gates on
caps.renameProvider.prepareProvider. When supported: prepareRename
round-trip first — null/not-allowed -> "cannot rename here", the
prompt never opens; otherwise the prompt opens pre-filled with the
server's placeholder (minibuffer `initial`). Servers without
prepare keep the unchanged L2 path (on_accept factored into a
shared local; no behavior change there).
- pmacs_fake_lsp.rs: `prepare`/`preprefuse` modes inject
renameProvider.prepareProvider + a prepareRename arm
({range,placeholder} or null). Default `rename` mode untouched so
m4_13 still exercises the no-prepare path.
- tests/m4_acceptance.rs: m4_22 (prompt waits for the async
prepare, placeholder pre-filled, rename applies), m4_23 (refusal:
prompt never opens, buffer untouched).
Gates: lib 1299/0, m4 78/0, m8_1 10/0, m8_9 26/0, m8_10 19/0,
m9_1 18/0, m5_8 5/0, m11_5 (--features crdt) 2/0; fmt + clippy
clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>