Files
str/src/vm/output.ts

76 lines
1.8 KiB
TypeScript
Raw Normal View History

import {StrRVal} from "./commands/command.js";
import {Awaitable} from "../util/types.js";
2026-02-21 19:20:22 -06:00
import childProcess from "node:child_process";
import fs from "node:fs";
import crypto from "node:crypto";
export const getSubjectDisplay = (sub: StrRVal): string => {
if ( sub.term === 'string' ) {
return sub.value
}
if ( sub.term === 'int' ) {
return String(sub.term)
}
return JSON.stringify(sub.value, null, '\t') // fixme
}
export type Display = {
showSubject(sub: StrRVal): Awaitable<unknown>
}
export class ConsoleDisplay implements Display {
showSubject(sub: StrRVal) {
console.log(`\n---------------\n${getSubjectDisplay(sub)}\n---------------\n`)
}
}
export class NullDisplay implements Display {
showSubject() {}
}
export type Clipboard = {
read(): Awaitable<string>
overwrite(sub: string): Awaitable<unknown>
}
export class FakeClipboard {
private val = ''
read() {
return this.val
}
overwrite(sub: string) {
this.val = sub
}
}
2026-02-21 19:20:22 -06:00
const tempFile = () => `/tmp/str-${crypto.randomBytes(4).readUInt32LE(0)}.txt`
export class WlClipboard {
async read(): Promise<string> {
const tmp = tempFile()
fs.writeFileSync(tmp, '')
const proc = childProcess.spawn('sh', ['-c', `wl-paste > "${tmp}"`])
await new Promise<void>(res => {
proc.on('close', () => res())
})
return fs.readFileSync(tmp).toString('utf-8')
}
async overwrite(sub: string): Promise<void> {
const tmp = tempFile()
fs.writeFileSync(tmp, sub)
const proc = childProcess.spawn('sh', ['-c', `wl-copy < "${tmp}"`], { stdio: 'inherit' })
await new Promise<void>(res => {
proc.on('close', () => res())
})
}
}
export type OutputManager = {
display: Display,
clipboard: Clipboard,
}