дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
fix(vim): only shadow leader keys, not operators a mapping starts with (#2360)
Цей коміт міститься в:
1 джерело
44d871caee
коміт
7c80b68787
2 files changed
+23
-6
No files matched your search
@@ -173,6 +173,21 @@ describe("Vim engine", () => {
|
||||
d();
|
||||
});
|
||||
|
||||
it.each([
|
||||
["nmap dx <Action>(GotoFile)", ["d", "w"], "two\nthree"],
|
||||
["nmap cs <Action>(GotoFile)", ["c", "w"], " two\nthree"],
|
||||
["nnoremap yz yy", ["y", "y", "p"], "one two\none two\nthree"],
|
||||
])("keeps built-in operators a mapping starts with (%s)", async (rc, keys, doc) => {
|
||||
const view = makeView();
|
||||
const cm = getCM(view)!;
|
||||
applyRcCommands(parseVimrc(rc).commands);
|
||||
for (const k of keys) Vim.handleKey(cm as never, k, "user");
|
||||
await tick();
|
||||
expect(view.state.doc.toString()).toBe(doc);
|
||||
applyRcCommands([]);
|
||||
view.destroy();
|
||||
});
|
||||
|
||||
it("restores the built-in key the leader shadowed once the rc stops using it (#2337)", async () => {
|
||||
const view = makeView();
|
||||
const cm = getCM(view)!;
|
||||
|
||||
@@ -327,10 +327,10 @@ const LEADER_BUILTIN_DEFAULTS: Record<string, Record<string, unknown>> = {
|
||||
};
|
||||
|
||||
/** Built-ins unmapped to make room for a user mapping's first key, by key. */
|
||||
const shadowedBuiltins = new Map<string, Record<string, unknown> | null>();
|
||||
const shadowedBuiltins = new Map<string, Record<string, unknown>>();
|
||||
|
||||
function firstKey(lhs: string): string {
|
||||
return /^<[CSMA]-*\w+>|^./i.exec(lhs)?.[0] ?? lhs;
|
||||
return /^<[^<>]+>|^./.exec(lhs)?.[0] ?? lhs;
|
||||
}
|
||||
|
||||
/** Applies rc commands (replacing earlier rc mappings). Returns problems to report. */
|
||||
@@ -342,17 +342,19 @@ export function applyRcCommands(commands: readonly RcCommand[]): string[] {
|
||||
// one's first keys collide with. Restoring first keeps mapclear's
|
||||
// user/default boundary honest — it assumes the default region never shrank.
|
||||
for (const [key, entry] of shadowedBuiltins) {
|
||||
if (entry) Vim._mapCommand(entry as never);
|
||||
Vim._mapCommand(entry as never);
|
||||
shadowedBuiltins.delete(key);
|
||||
}
|
||||
|
||||
for (const c of commands) {
|
||||
if (c.kind !== "map" && c.kind !== "mapEx") continue;
|
||||
const key = firstKey(c.lhs);
|
||||
// Only the single-key motions a leader reuses: unmapping an operator or prefix
|
||||
// (`d`, `c`, `y`, `<C-d>`…) would break every command built on it.
|
||||
const builtin = LEADER_BUILTIN_DEFAULTS[key];
|
||||
if (!builtin || shadowedBuiltins.has(key)) continue;
|
||||
// The builtins this shadows are context-less; `undefined` matches them.
|
||||
if (!shadowedBuiltins.has(key) && Vim.unmap(key, undefined as unknown as string)) {
|
||||
shadowedBuiltins.set(key, LEADER_BUILTIN_DEFAULTS[key] ?? null);
|
||||
}
|
||||
if (Vim.unmap(key, undefined as unknown as string)) shadowedBuiltins.set(key, builtin);
|
||||
}
|
||||
for (const c of commands) {
|
||||
try {
|
||||
|
||||
Reference in new issue
Заблокувати користувача