[Refactor] Rename hooks/ to composables/ (#2437)

This commit is contained in:
Chenlei Hu
2025-02-05 15:05:56 -05:00
committed by GitHub
parent c6ef107111
commit 6525ae7cf4
41 changed files with 40 additions and 34 deletions

View File

@@ -0,0 +1,99 @@
import { FitAddon } from '@xterm/addon-fit'
import { Terminal } from '@xterm/xterm'
import '@xterm/xterm/css/xterm.css'
import { debounce } from 'lodash'
import { Ref, markRaw, onMounted, onUnmounted } from 'vue'
export function useTerminal(element: Ref<HTMLElement>) {
const fitAddon = new FitAddon()
const terminal = markRaw(
new Terminal({
convertEol: true
})
)
terminal.loadAddon(fitAddon)
terminal.attachCustomKeyEventHandler((event) => {
// Allow default browser copy/paste handling
if (
event.type === 'keydown' &&
(event.ctrlKey || event.metaKey) &&
((event.key === 'c' && terminal.hasSelection()) || event.key === 'v')
) {
// TODO: Deselect text after copy/paste; use IPC.
return false
}
return true
})
onMounted(async () => {
terminal.open(element.value)
})
onUnmounted(() => {
terminal.dispose()
})
return {
terminal,
useAutoSize({
root,
autoRows = true,
autoCols = true,
minCols = Number.NEGATIVE_INFINITY,
minRows = Number.NEGATIVE_INFINITY,
onResize
}: {
root: Ref<HTMLElement>
autoRows?: boolean
autoCols?: boolean
minCols?: number
minRows?: number
onResize?: () => void
}) {
const ensureValidRows = (rows: number | undefined) => {
if (rows == null || isNaN(rows)) {
return root.value?.clientHeight / 20
}
return rows
}
const ensureValidCols = (cols: number | undefined): number => {
if (cols == null || isNaN(cols)) {
// Sometimes this is NaN if so, estimate.
return root.value?.clientWidth / 8
}
return cols
}
const resize = () => {
const dims = fitAddon.proposeDimensions()
// Sometimes propose returns NaN, so we may need to estimate.
terminal.resize(
Math.max(
autoCols ? ensureValidCols(dims?.cols) : terminal.cols,
minCols
),
Math.max(
autoRows ? ensureValidRows(dims?.rows) : terminal.rows,
minRows
)
)
onResize?.()
}
const resizeObserver = new ResizeObserver(debounce(resize, 25))
onMounted(async () => {
resizeObserver.observe(root.value)
resize()
})
onUnmounted(() => {
resizeObserver.disconnect()
})
return { resize }
}
}
}

View File

@@ -0,0 +1,30 @@
import { SerializeAddon } from '@xterm/addon-serialize'
import { Terminal } from '@xterm/xterm'
import { markRaw, onMounted, onUnmounted } from 'vue'
export function useTerminalBuffer() {
const serializeAddon = new SerializeAddon()
const terminal = markRaw(new Terminal({ convertEol: true }))
const copyTo = (destinationTerminal: Terminal) => {
destinationTerminal.write(serializeAddon.serialize())
}
const write = (message: string) => terminal.write(message)
const serialize = () => serializeAddon.serialize()
onMounted(() => {
terminal.loadAddon(serializeAddon)
})
onUnmounted(() => {
terminal.dispose()
})
return {
copyTo,
serialize,
write
}
}

View File

@@ -0,0 +1,26 @@
import { markRaw } from 'vue'
import { useI18n } from 'vue-i18n'
import CommandTerminal from '@/components/bottomPanel/tabs/terminal/CommandTerminal.vue'
import LogsTerminal from '@/components/bottomPanel/tabs/terminal/LogsTerminal.vue'
import { BottomPanelExtension } from '@/types/extensionTypes'
export const useLogsTerminalTab = (): BottomPanelExtension => {
const { t } = useI18n()
return {
id: 'logs-terminal',
title: t('g.logs'),
component: markRaw(LogsTerminal),
type: 'vue'
}
}
export const useCommandTerminalTab = (): BottomPanelExtension => {
const { t } = useI18n()
return {
id: 'command-terminal',
title: t('g.terminal'),
component: markRaw(CommandTerminal),
type: 'vue'
}
}