feat(app): add tab close keybind (#11780)

This commit is contained in:
Rahul A Mistry
2026-02-02 18:20:06 +05:30
committed by GitHub
parent 34c58af796
commit 3408f1a6ae
3 changed files with 22 additions and 3 deletions

View File

@@ -3,11 +3,12 @@ import type { JSX } from "solid-js"
import { createSortable } from "@thisbeyond/solid-dnd" import { createSortable } from "@thisbeyond/solid-dnd"
import { FileIcon } from "@opencode-ai/ui/file-icon" import { FileIcon } from "@opencode-ai/ui/file-icon"
import { IconButton } from "@opencode-ai/ui/icon-button" import { IconButton } from "@opencode-ai/ui/icon-button"
import { Tooltip } from "@opencode-ai/ui/tooltip" import { TooltipKeybind } from "@opencode-ai/ui/tooltip"
import { Tabs } from "@opencode-ai/ui/tabs" import { Tabs } from "@opencode-ai/ui/tabs"
import { getFilename } from "@opencode-ai/util/path" import { getFilename } from "@opencode-ai/util/path"
import { useFile } from "@/context/file" import { useFile } from "@/context/file"
import { useLanguage } from "@/context/language" import { useLanguage } from "@/context/language"
import { useCommand } from "@/context/command"
export function FileVisual(props: { path: string; active?: boolean }): JSX.Element { export function FileVisual(props: { path: string; active?: boolean }): JSX.Element {
return ( return (
@@ -27,6 +28,7 @@ export function FileVisual(props: { path: string; active?: boolean }): JSX.Eleme
export function SortableTab(props: { tab: string; onTabClose: (tab: string) => void }): JSX.Element { export function SortableTab(props: { tab: string; onTabClose: (tab: string) => void }): JSX.Element {
const file = useFile() const file = useFile()
const language = useLanguage() const language = useLanguage()
const command = useCommand()
const sortable = createSortable(props.tab) const sortable = createSortable(props.tab)
const path = createMemo(() => file.pathFromTab(props.tab)) const path = createMemo(() => file.pathFromTab(props.tab))
return ( return (
@@ -36,7 +38,11 @@ export function SortableTab(props: { tab: string; onTabClose: (tab: string) => v
<Tabs.Trigger <Tabs.Trigger
value={props.tab} value={props.tab}
closeButton={ closeButton={
<Tooltip value={language.t("common.closeTab")} placement="bottom"> <TooltipKeybind
title={language.t("common.closeTab")}
keybind={command.keybind("tab.close")}
placement="bottom"
>
<IconButton <IconButton
icon="close-small" icon="close-small"
variant="ghost" variant="ghost"
@@ -44,7 +50,7 @@ export function SortableTab(props: { tab: string; onTabClose: (tab: string) => v
onClick={() => props.onTabClose(props.tab)} onClick={() => props.onTabClose(props.tab)}
aria-label={language.t("common.closeTab")} aria-label={language.t("common.closeTab")}
/> />
</Tooltip> </TooltipKeybind>
} }
hideCloseButton hideCloseButton
onMiddleClick={() => props.onTabClose(props.tab)} onMiddleClick={() => props.onTabClose(props.tab)}

View File

@@ -45,6 +45,7 @@ export const dict = {
"command.session.new": "New session", "command.session.new": "New session",
"command.file.open": "Open file", "command.file.open": "Open file",
"command.file.open.description": "Search files and commands", "command.file.open.description": "Search files and commands",
"command.tab.close": "Close tab",
"command.context.addSelection": "Add selection to context", "command.context.addSelection": "Add selection to context",
"command.context.addSelection.description": "Add selected lines from the current file", "command.context.addSelection.description": "Add selected lines from the current file",
"command.terminal.toggle": "Toggle terminal", "command.terminal.toggle": "Toggle terminal",

View File

@@ -689,6 +689,18 @@ export default function Page() {
slash: "open", slash: "open",
onSelect: () => dialog.show(() => <DialogSelectFile onOpenFile={() => showAllFiles()} />), onSelect: () => dialog.show(() => <DialogSelectFile onOpenFile={() => showAllFiles()} />),
}, },
{
id: "tab.close",
title: language.t("command.tab.close"),
category: language.t("command.category.file"),
keybind: "mod+w",
disabled: !tabs().active(),
onSelect: () => {
const active = tabs().active()
if (!active) return
tabs().close(active)
},
},
{ {
id: "context.addSelection", id: "context.addSelection",
title: language.t("command.context.addSelection"), title: language.t("command.context.addSelection"),