diff --git a/packages/opencode/src/cli/cmd/tui/component/error-component.tsx b/packages/opencode/src/cli/cmd/tui/component/error-component.tsx index c568e54e4262..b22163902ee0 100644 --- a/packages/opencode/src/cli/cmd/tui/component/error-component.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/error-component.tsx @@ -4,6 +4,7 @@ import { Clipboard } from "@tui/util/clipboard" import { createSignal } from "solid-js" import { Installation } from "@/installation" import { win32FlushInputBuffer } from "../win32" +import { getScrollAcceleration } from "../util/scroll" export function ErrorComponent(props: { error: Error @@ -82,7 +83,7 @@ export function ErrorComponent(props: { Exit - + {props.error.stack} {props.error.message} diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx index 3240afab326a..1c5ede4d728f 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx @@ -6,6 +6,8 @@ import { createMemo, createResource, createEffect, onMount, onCleanup, Index, Sh import { createStore } from "solid-js/store" import { useSDK } from "@tui/context/sdk" import { useSync } from "@tui/context/sync" +import { getScrollAcceleration } from "../../util/scroll" +import { useTuiConfig } from "../../context/tui-config" import { useTheme, selectedForeground } from "@tui/context/theme" import { SplitBorder } from "@tui/component/border" import { useCommandDialog } from "@tui/component/dialog-command" @@ -81,6 +83,7 @@ export function Autocomplete(props: { const { theme } = useTheme() const dimensions = useTerminalDimensions() const frecency = useFrecency() + const tuiConfig = useTuiConfig() const [store, setStore] = createStore({ index: 0, @@ -605,6 +608,7 @@ export function Autocomplete(props: { }) let scroll: ScrollBoxRenderable + const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig)) return ( timestamps() === "show") const contentWidth = createMemo(() => dimensions().width - (sidebarVisible() ? 42 : 0) - 4) - const scrollAcceleration = createMemo(() => { - const tui = tuiConfig - if (tui?.scroll_acceleration?.enabled) { - return new MacOSScrollAccel() - } - if (tui?.scroll_speed) { - return new CustomSpeedScroll(tui.scroll_speed) - } - - return new CustomSpeedScroll(3) - }) + const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig)) createEffect(() => { if (session()?.workspaceID) { diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx index a50cd96fc843..a0d9a54ea9e9 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx @@ -15,6 +15,7 @@ import { Keybind } from "@/util/keybind" import { Locale } from "@/util/locale" import { Global } from "@/global" import { useDialog } from "../../ui/dialog" +import { getScrollAcceleration } from "../../util/scroll" import { useTuiConfig } from "../../context/tui-config" type PermissionStage = "permission" | "always" | "reject" @@ -62,12 +63,14 @@ function EditBody(props: { request: PermissionRequest }) { }) const ft = createMemo(() => filetype(filepath())) + const scrollAcceleration = createMemo(() => getScrollAcceleration(config)) return ( sync.session.get(props.sessionID)) + const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig)) return ( @@ -23,6 +28,7 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) { > { title: string @@ -50,6 +53,10 @@ export type DialogSelectRef = { export function DialogSelect(props: DialogSelectProps) { const dialog = useDialog() const { theme } = useTheme() + const sync = useSync() + const tuiConfig = useTuiConfig() + const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig)) + const [store, setStore] = createStore({ selected: 0, filter: "", @@ -276,6 +283,7 @@ export function DialogSelect(props: DialogSelectProps) { paddingLeft={1} paddingRight={1} scrollbarOptions={{ visible: false }} + scrollAcceleration={scrollAcceleration()} ref={(r: ScrollBoxRenderable) => (scroll = r)} maxHeight={height()} > diff --git a/packages/opencode/src/cli/cmd/tui/util/scroll.ts b/packages/opencode/src/cli/cmd/tui/util/scroll.ts new file mode 100644 index 000000000000..601c7fa92d89 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/util/scroll.ts @@ -0,0 +1,23 @@ +import { MacOSScrollAccel, type ScrollAcceleration } from "@opentui/core" +import { TuiConfig } from "@/config/tui" + +export class CustomSpeedScroll implements ScrollAcceleration { + constructor(private speed: number) {} + + tick(_now?: number): number { + return this.speed + } + + reset(): void {} +} + +export function getScrollAcceleration(tuiConfig?: TuiConfig.Info): ScrollAcceleration { + if (tuiConfig?.scroll_acceleration?.enabled) { + return new MacOSScrollAccel() + } + if (tuiConfig?.scroll_speed) { + return new CustomSpeedScroll(tuiConfig.scroll_speed) + } + + return new CustomSpeedScroll(3) +}