mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-31 03:41:51 +00:00
fix(tui): stop hijacking j/k in model search
This commit is contained in:
@@ -124,6 +124,34 @@ describe("SearchableSelectList", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps model-search rows within width when filtering by m", () => {
|
||||
const items = [
|
||||
{ value: "minimax-cn/MiniMax-M2", label: "minimax-cn/MiniMax-M2", description: "MiniMax M2" },
|
||||
{
|
||||
value: "minimax-cn/MiniMax-M2.1",
|
||||
label: "minimax-cn/MiniMax-M2.1",
|
||||
description: "MiniMax M2.1",
|
||||
},
|
||||
{
|
||||
value: "mistral/codestral-latest",
|
||||
label: "mistral/codestral-latest",
|
||||
description: "Codestral",
|
||||
},
|
||||
{
|
||||
value: "mistral/devstral-medium-latest",
|
||||
label: "mistral/devstral-medium-latest",
|
||||
description: "Devstral Medium",
|
||||
},
|
||||
];
|
||||
const list = new SearchableSelectList(items, 9, ansiHighlightTheme);
|
||||
typeInput(list, "m");
|
||||
|
||||
const width = 209;
|
||||
for (const line of list.render(width)) {
|
||||
expect(visibleWidth(line)).toBeLessThanOrEqual(width);
|
||||
}
|
||||
});
|
||||
|
||||
it("ignores ANSI escape codes in search matching", () => {
|
||||
const items = [
|
||||
{ value: "styled", label: "\u001b[32mopenai/gpt-4\u001b[0m", description: "Styled label" },
|
||||
@@ -266,6 +294,24 @@ describe("SearchableSelectList", () => {
|
||||
expect(list.getSelectedItem()?.value).toBe("anthropic/claude-3-sonnet");
|
||||
});
|
||||
|
||||
it("types j and k into search input instead of intercepting as vim navigation", () => {
|
||||
const items = [
|
||||
{ value: "alpha", label: "alpha" },
|
||||
{ value: "kilo", label: "kilo" },
|
||||
{ value: "juliet", label: "juliet" },
|
||||
];
|
||||
|
||||
const jList = new SearchableSelectList(items, 5, mockTheme);
|
||||
jList.handleInput("j");
|
||||
expect(jList.getSelectedItem()?.value).toBe("juliet");
|
||||
expect(stripAnsi(jList.render(80)[0] ?? "")).toContain("j");
|
||||
|
||||
const kList = new SearchableSelectList(items, 5, mockTheme);
|
||||
kList.handleInput("k");
|
||||
expect(kList.getSelectedItem()?.value).toBe("kilo");
|
||||
expect(stripAnsi(kList.render(80)[0] ?? "")).toContain("k");
|
||||
});
|
||||
|
||||
it("calls onSelect when enter is pressed", () => {
|
||||
const list = new SearchableSelectList(testItems, 5, mockTheme);
|
||||
let selectedValue: string | undefined;
|
||||
|
||||
@@ -330,24 +330,14 @@ export class SearchableSelectList implements Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const allowVimNav = !this.searchInput.getValue().trim();
|
||||
|
||||
// Navigation keys
|
||||
if (
|
||||
matchesKey(keyData, "up") ||
|
||||
matchesKey(keyData, "ctrl+p") ||
|
||||
(allowVimNav && keyData === "k")
|
||||
) {
|
||||
if (matchesKey(keyData, "up") || matchesKey(keyData, "ctrl+p")) {
|
||||
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
|
||||
this.notifySelectionChange();
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
matchesKey(keyData, "down") ||
|
||||
matchesKey(keyData, "ctrl+n") ||
|
||||
(allowVimNav && keyData === "j")
|
||||
) {
|
||||
if (matchesKey(keyData, "down") || matchesKey(keyData, "ctrl+n")) {
|
||||
this.selectedIndex = Math.min(this.filteredItems.length - 1, this.selectedIndex + 1);
|
||||
this.notifySelectionChange();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user