Просмотр исходного кода

feat(app): add ctrl/cmd+number keybinds to switch projects (#26280)

Brendan Allan 3 месяцев назад
Родитель
Сommit
3992e2a76b

+ 1 - 1
packages/app/src/components/dialog-select-file.tsx

@@ -107,7 +107,7 @@ function createCommandEntries(props: {
   const allowed = createMemo(() => {
     if (props.filesOnly()) return []
     return props.command.options.filter(
-      (option) => !option.disabled && !option.id.startsWith("suggested.") && option.id !== "file.open",
+      (option) => !option.disabled && !option.hidden && !option.id.startsWith("suggested.") && option.id !== "file.open",
     )
   })
 

+ 2 - 0
packages/app/src/components/settings-keybinds.tsx

@@ -123,11 +123,13 @@ function listFor(command: CommandContext, map: KeybindMap, palette: string) {
 
   for (const opt of command.catalog) {
     if (opt.id.startsWith("suggested.")) continue
+    if (opt.hidden) continue
     out.set(opt.id, { title: opt.title, group: groupFor(opt.id) })
   }
 
   for (const opt of command.options) {
     if (opt.id.startsWith("suggested.")) continue
+    if (opt.hidden) continue
     out.set(opt.id, { title: opt.title, group: groupFor(opt.id) })
   }
 

+ 10 - 7
packages/app/src/context/command.tsx

@@ -81,6 +81,7 @@ export interface CommandOption {
   slash?: string
   suggested?: boolean
   disabled?: boolean
+  hidden?: boolean
   onSelect?: (source?: "palette" | "keybind" | "slash") => void
   onHighlight?: () => (() => void) | void
 }
@@ -93,6 +94,7 @@ export type CommandCatalogItem = {
   category?: string
   keybind?: KeybindConfig
   slash?: string
+  hidden?: boolean
 }
 
 export type CommandRegistration = {
@@ -279,13 +281,14 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
       setCatalog(
         registered().reduce((acc, opt) => {
           const id = actionId(opt.id)
-          acc[id] = {
-            title: opt.title,
-            description: opt.description,
-            category: opt.category,
-            keybind: opt.keybind,
-            slash: opt.slash,
-          }
+          if (opt.title)
+            acc[id] = {
+              title: opt.title,
+              description: opt.description,
+              category: opt.category,
+              keybind: opt.keybind,
+              slash: opt.slash,
+            }
           return acc
         }, {} as CommandCatalog),
       )

+ 1 - 0
packages/app/src/i18n/en.ts

@@ -25,6 +25,7 @@ export const dict = {
   "command.project.open": "Open project",
   "command.project.previous": "Previous project",
   "command.project.next": "Next project",
+  "command.project.index": "Switch to project {{index}}",
   "command.provider.connect": "Connect provider",
   "command.server.switch": "Switch server",
   "command.settings.open": "Open settings",

+ 22 - 0
packages/app/src/pages/layout.tsx

@@ -960,6 +960,15 @@ export default function Layout(props: ParentProps) {
     void openProject(target.worktree)
   }
 
+  function navigateToProjectIndex(index: number) {
+    const projects = layout.projects.list()
+    const target = projects[index]
+    if (!target) return
+
+    globalSync.child(target.worktree)
+    void openProject(target.worktree)
+  }
+
   function navigateSessionByUnseen(offset: number) {
     const sessions = currentSessions()
     if (sessions.length === 0) return
@@ -1040,6 +1049,19 @@ export default function Layout(props: ParentProps) {
         keybind: "mod+alt+arrowdown",
         onSelect: () => navigateProjectByOffset(1),
       },
+      ...Array.from({ length: 9 }, (_, i) => {
+        const index = i
+        const number = index + 1
+        return {
+          id: `project.${number}`,
+          category: language.t("command.category.project"),
+          title: `Open Project {number}`,
+          keybind: `mod+${number}`,
+          disabled: layout.projects.list().length <= index,
+          hidden: true,
+          onSelect: () => navigateToProjectIndex(index),
+        }
+      }),
       {
         id: "provider.connect",
         title: language.t("command.provider.connect"),