Compare commits

...
Author SHA1 Message Date
Cursor Agentand陈大猫 ded9857700 fix(terminal): migrate persisted autocompleteMaxSuggestions 8 to 50
Existing installs saved the old default into localStorage with no settings
UI, so raising DEFAULT alone left the popup capped at 8. Treat 8 as the
legacy sentinel while preserving intentional custom caps.

Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>
2026-08-07 08:49:32 +00:00
Cursor Agentand陈大猫 09e086e7f9 fix(terminal): raise autocomplete suggestion default beyond 8
Snippet keyword matches were truncated at autocompleteMaxSuggestions=8
before the floating list, so users with many matching scripts could not
scroll to the rest (fixes #2793).

Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>
2026-08-07 08:43:14 +00:00
6 changed files with 73 additions and 5 deletions

No files matched your search

@@ -27,7 +27,7 @@ export function resolveTerminalAutocompleteSettings(input: {
allowLineReplacement: false,
debounceMs: terminalSettings?.autocompleteDebounceMs ?? 100,
minChars: terminalSettings?.autocompleteMinChars ?? 1,
maxSuggestions: terminalSettings?.autocompleteMaxSuggestions ?? 8,
maxSuggestions: terminalSettings?.autocompleteMaxSuggestions ?? 50,
historyScope: terminalSettings?.autocompleteHistoryScope ?? "host",
shiftEnterNewlineEnabled: terminalSettings?.shiftEnterNewlineEnabled ?? true,
};
@@ -43,7 +43,7 @@ export function resolveTerminalAutocompleteSettings(input: {
allowLineReplacement: true,
debounceMs: terminalSettings.autocompleteDebounceMs ?? 100,
minChars: terminalSettings.autocompleteMinChars ?? 1,
maxSuggestions: terminalSettings.autocompleteMaxSuggestions ?? 8,
maxSuggestions: terminalSettings.autocompleteMaxSuggestions ?? 50,
historyScope: terminalSettings.autocompleteHistoryScope ?? "host",
shiftEnterNewlineEnabled: terminalSettings.shiftEnterNewlineEnabled ?? true,
};
@@ -66,7 +66,7 @@ export const DEFAULT_AUTOCOMPLETE_SETTINGS: AutocompleteSettings = {
allowLineReplacement: true,
debounceMs: 100,
minChars: 1,
maxSuggestions: 8,
maxSuggestions: 50,
fastTypingThresholdMs: 40,
shiftEnterNewlineEnabled: true,
historyScope: "host",
@@ -2,6 +2,7 @@ import test from "node:test";
import assert from "node:assert/strict";
import { getCompletions } from "./autocomplete/completionEngine";
import { DEFAULT_AUTOCOMPLETE_SETTINGS } from "./autocomplete/useTerminalAutocomplete";
import type { Snippet } from "../../domain/models";
const deploySnippet: Snippet = { id: "d", label: "deploy", command: "kubectl apply -f ." };
@@ -17,3 +18,27 @@ test("getCompletions does not surface snippets past the command position", async
const out = await getCompletions("git dep", { snippets: [deploySnippet] });
assert.equal(out.find((s) => s.source === "snippet"), undefined);
});
test("getCompletions returns more than 8 snippet matches when default maxSuggestions allows it", async () => {
const snippets: Snippet[] = Array.from({ length: 20 }, (_, i) => ({
id: `s${i}`,
label: `deploy-${String(i).padStart(2, "0")}`,
command: `echo deploy-${i}`,
}));
assert.ok(
DEFAULT_AUTOCOMPLETE_SETTINGS.maxSuggestions > 8,
`expected raised default maxSuggestions (>8), got ${DEFAULT_AUTOCOMPLETE_SETTINGS.maxSuggestions}`,
);
const out = await getCompletions("dep", {
snippets,
maxResults: DEFAULT_AUTOCOMPLETE_SETTINGS.maxSuggestions,
});
const snippetMatches = out.filter((s) => s.source === "snippet");
assert.ok(
snippetMatches.length > 8,
`expected more than 8 snippet matches for scrolling popup, got ${snippetMatches.length}`,
);
assert.equal(snippetMatches.length, 20);
});
@@ -71,4 +71,22 @@ test("defaults autocomplete history scope to host when unset", () => {
})?.historyScope,
"host",
);
});
});
test("falls back to raised maxSuggestions default when unset", () => {
assert.equal(
resolveTerminalAutocompleteSettings({
protocol: "ssh",
terminalSettings: {
autocompleteEnabled: true,
},
})?.maxSuggestions,
50,
);
assert.equal(
resolveTerminalAutocompleteSettings({
protocol: "serial",
})?.maxSuggestions,
50,
);
});
+8 -1
View File
@@ -396,9 +396,16 @@ export const normalizeTerminalSettings = (
? 'dom' as const
: mergedSettings.rendererType;
// Persisted installs wrote the old default (8) into localStorage with no UI
// to change it; bump that sentinel to the new default while keeping custom caps.
const autocompleteMaxSuggestions = mergedSettings.autocompleteMaxSuggestions === 8
? DEFAULT_TERMINAL_SETTINGS.autocompleteMaxSuggestions
: mergedSettings.autocompleteMaxSuggestions;
return {
...mergedSettings,
rendererType,
autocompleteMaxSuggestions,
hibernateHiddenTabsDelaySec: normalizeHibernateHiddenTabsDelaySec(
mergedSettings.hibernateHiddenTabsDelaySec,
),
@@ -517,7 +524,7 @@ const DEFAULT_TERMINAL_SETTINGS: TerminalSettings = {
autocompletePopupMenu: true, // Popup menu enabled by default
autocompleteDebounceMs: 100, // 100ms debounce
autocompleteMinChars: 1, // Start suggesting after 1 character
autocompleteMaxSuggestions: 8, // Show up to 8 suggestions
autocompleteMaxSuggestions: 50, // Show up to 50 suggestions (popup scrolls)
autocompleteHistoryScope: 'host', // Per-host history suggestions by default (#2595)
passwordPromptAssist: 'hint', // Historical sudo confirm-to-fill; picker is opt-in (#2156)
};
+18
View File
@@ -226,3 +226,21 @@ test("normalizeTerminalSettings prefers explicit middle-click behavior over lega
assert.equal(settings.middleClickBehavior, "context-menu");
assert.equal(settings.middleClickPaste, false);
});
test("normalizeTerminalSettings migrates legacy autocompleteMaxSuggestions default 8 to 50", () => {
assert.equal(
normalizeTerminalSettings({ autocompleteMaxSuggestions: 8 }).autocompleteMaxSuggestions,
50,
);
});
test("normalizeTerminalSettings preserves intentional custom autocompleteMaxSuggestions", () => {
assert.equal(
normalizeTerminalSettings({ autocompleteMaxSuggestions: 6 }).autocompleteMaxSuggestions,
6,
);
assert.equal(
normalizeTerminalSettings({ autocompleteMaxSuggestions: 20 }).autocompleteMaxSuggestions,
20,
);
});