mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-23 07:08:16 +00:00
feat(redis): add command history navigation with arrow keys
- Press ↑ to recall previous command, ↓ for next command (terminal-like behavior) - Press ↓ at end of history to clear input - Use readonly instead of disabled to maintain cursor focus and blink state - Semi-transparent visual feedback during command execution
This commit is contained in:
@@ -82,6 +82,7 @@ const commandText = ref("");
|
||||
const commandRunning = ref(false);
|
||||
const commandDb = ref(props.db);
|
||||
const commandHistory = ref<RedisCommandHistoryEntry[]>([]);
|
||||
const commandHistoryIndex = ref(-1);
|
||||
const activeSidePanel = ref<RedisSidePanel>("detail");
|
||||
const showCreateKeyDialog = ref(false);
|
||||
const creatingKey = ref(false);
|
||||
@@ -692,6 +693,7 @@ async function executeCommand() {
|
||||
if (isRedisClearScreenCommand(command)) {
|
||||
commandHistory.value = [];
|
||||
commandText.value = "";
|
||||
commandHistoryIndex.value = -1;
|
||||
scrollCommandTerminalToEnd();
|
||||
return;
|
||||
}
|
||||
@@ -705,15 +707,18 @@ async function executeCommand() {
|
||||
error: true,
|
||||
});
|
||||
commandText.value = "";
|
||||
commandHistoryIndex.value = -1;
|
||||
return;
|
||||
}
|
||||
if (safety === "confirm") {
|
||||
pendingDanger.value = { kind: "command", command };
|
||||
showDangerConfirm.value = true;
|
||||
commandText.value = "";
|
||||
commandHistoryIndex.value = -1;
|
||||
return;
|
||||
}
|
||||
commandText.value = "";
|
||||
commandHistoryIndex.value = -1;
|
||||
await runRedisCommand(command);
|
||||
}
|
||||
|
||||
@@ -840,6 +845,39 @@ function onCommandAreaClick() {
|
||||
}
|
||||
}
|
||||
|
||||
function onCommandInputKeydown(event: KeyboardEvent) {
|
||||
// 上下键切换历史命令
|
||||
if (event.key === "ArrowUp") {
|
||||
event.preventDefault();
|
||||
if (commandHistory.value.length === 0) return;
|
||||
|
||||
if (commandHistoryIndex.value === -1) {
|
||||
// 首次按上键,从最后一条开始
|
||||
commandHistoryIndex.value = commandHistory.value.length - 1;
|
||||
} else if (commandHistoryIndex.value > 0) {
|
||||
// 继续往前
|
||||
commandHistoryIndex.value--;
|
||||
}
|
||||
commandText.value = commandHistory.value[commandHistoryIndex.value].command;
|
||||
} else if (event.key === "ArrowDown") {
|
||||
event.preventDefault();
|
||||
if (commandHistoryIndex.value === -1) return;
|
||||
|
||||
if (commandHistoryIndex.value < commandHistory.value.length - 1) {
|
||||
// 往后
|
||||
commandHistoryIndex.value++;
|
||||
commandText.value = commandHistory.value[commandHistoryIndex.value].command;
|
||||
} else {
|
||||
// 到达末尾,清空输入
|
||||
commandHistoryIndex.value = -1;
|
||||
commandText.value = "";
|
||||
}
|
||||
} else if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
executeCommand();
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
resumeRedisBrowserBackgroundWork();
|
||||
void loadKeys();
|
||||
@@ -1009,11 +1047,12 @@ defineExpose({ focusSearch });
|
||||
v-model="commandText"
|
||||
data-redis-command-input
|
||||
class="dbx-editor-font-family min-w-0 flex-1 border-0 bg-transparent p-0 text-[13px] text-slate-200 caret-[#d7ba7d] outline-none placeholder:text-slate-500"
|
||||
:disabled="commandRunning"
|
||||
:class="{ 'opacity-50': commandRunning }"
|
||||
:readonly="commandRunning"
|
||||
autocomplete="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false"
|
||||
@keydown.enter.prevent="executeCommand"
|
||||
@keydown="onCommandInputKeydown"
|
||||
/>
|
||||
<Loader2 v-if="commandRunning" class="h-3.5 w-3.5 shrink-0 animate-spin text-slate-500" />
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user