Co-authored-by: Aiden Cline <aidenpcline@gmail.com> Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Aarav Sareen <96787824+arvsrn@users.noreply.github.com> Co-authored-by: Brendan Allan <git@brendonovich.dev> Co-authored-by: James Long <longster@gmail.com> Co-authored-by: James Long <jlongster@users.noreply.github.com> Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Jay <53023+jayair@users.noreply.github.com> Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com> Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com> Co-authored-by: Dustin Deus <deusdustin@gmail.com> Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Co-authored-by: 冯基魁 <56265583+fengjikui@users.noreply.github.com> Co-authored-by: opencode <opencode@sst.dev> Co-authored-by: Frank <frank@anoma.ly> Co-authored-by: Aiden Cline <rekram1-node@users.noreply.github.com> Co-authored-by: Kit Langton <kit.langton@gmail.com> Co-authored-by: David Hill <1879069+iamdavidhill@users.noreply.github.com> Co-authored-by: usrnk1 <7547651+usrnk1@users.noreply.github.com> Co-authored-by: Victor Navarro <vn4varro@gmail.com> Co-authored-by: Dax Raad <d@ironbay.co> Co-authored-by: Dax <mail@thdxr.com> Co-authored-by: Nabs <nabil@instafork.com> Co-authored-by: Vladimir Glafirov <vglafirov@gitlab.com> Co-authored-by: AidenGeunGeun <eastlandwyvern@gmail.com> Co-authored-by: Mark <geraint0923@users.noreply.github.com> Co-authored-by: Jay <air@live.ca> Co-authored-by: BB84 <110078428+BB-84C@users.noreply.github.com>
83 lines
3.2 KiB
TypeScript
83 lines
3.2 KiB
TypeScript
import { useCommand, type CommandOption } from "@/context/command"
|
|
import { useLanguage } from "@/context/language"
|
|
import { useLocal, type ModelSelection } from "@/context/local"
|
|
import { useDialog } from "@opencode-ai/ui/context/dialog"
|
|
import { getCursorPosition, setCursorPosition } from "@/components/prompt-input/editor-dom"
|
|
import { useSessionLayout } from "./session-layout"
|
|
import { createSessionOwnership } from "./session-ownership"
|
|
|
|
const withCategory = (category: string) => {
|
|
return (option: Omit<CommandOption, "category">): CommandOption => ({
|
|
...option,
|
|
category,
|
|
})
|
|
}
|
|
|
|
export const useComposerCommands = (input: { model?: ModelSelection } = {}) => {
|
|
const command = useCommand()
|
|
const dialog = useDialog()
|
|
const language = useLanguage()
|
|
const local = useLocal()
|
|
const { sessionKey } = useSessionLayout()
|
|
const sessionOwnership = createSessionOwnership(sessionKey)
|
|
const model = input.model ?? local.model
|
|
const modelCommand = withCategory(language.t("command.category.model"))
|
|
const agentCommand = withCategory(language.t("command.category.agent"))
|
|
|
|
const chooseModel = async () => {
|
|
const owner = sessionOwnership.capture()
|
|
const editor = document.querySelector<HTMLElement>('[data-component="prompt-input"]')
|
|
const selection = window.getSelection()
|
|
const cursor =
|
|
editor && selection?.rangeCount && editor.contains(selection.anchorNode) ? getCursorPosition(editor) : null
|
|
const restoreComposer = () => {
|
|
// Kobalte restores focus during its teardown effect; defer past it so the
|
|
// composer keeps focus and the caret returns to where the user left it.
|
|
requestAnimationFrame(() => {
|
|
const editor = document.querySelector<HTMLElement>('[data-component="prompt-input"]')
|
|
if (!editor) return
|
|
editor.focus()
|
|
if (cursor !== null) setCursorPosition(editor, cursor)
|
|
})
|
|
}
|
|
const { DialogSelectModel } = await import("@/components/dialog-select-model")
|
|
owner.run(() => {
|
|
void dialog.show(() => <DialogSelectModel model={model} />, restoreComposer)
|
|
})
|
|
}
|
|
|
|
command.register("composer", () => [
|
|
modelCommand({
|
|
id: "model.choose",
|
|
title: language.t("command.model.choose"),
|
|
description: language.t("command.model.choose.description"),
|
|
keybind: "mod+'",
|
|
slash: "model",
|
|
onSelect: chooseModel,
|
|
}),
|
|
modelCommand({
|
|
id: "model.variant.cycle",
|
|
title: language.t("command.model.variant.cycle"),
|
|
description: language.t("command.model.variant.cycle.description"),
|
|
keybind: "shift+mod+d",
|
|
onSelect: () => model.variant.cycle(),
|
|
}),
|
|
agentCommand({
|
|
id: "agent.cycle",
|
|
title: language.t("command.agent.cycle"),
|
|
description: language.t("command.agent.cycle.description"),
|
|
keybind: "mod+.",
|
|
slash: "agent",
|
|
disabled: !local.agent.visible(),
|
|
onSelect: () => local.agent.move(1),
|
|
}),
|
|
agentCommand({
|
|
id: "agent.cycle.reverse",
|
|
title: language.t("command.agent.cycle.reverse"),
|
|
description: language.t("command.agent.cycle.reverse.description"),
|
|
keybind: "shift+mod+.",
|
|
disabled: !local.agent.visible(),
|
|
onSelect: () => local.agent.move(-1),
|
|
}),
|
|
])
|
|
}
|