feat(app): add tab close keybind (#11780)
This commit is contained in:
@@ -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)}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
Reference in New Issue
Block a user