Files
str/src/vm/output.ts

97 lines
2.8 KiB
TypeScript

import {StrRVal} from "./commands/command.js";
import {Awaitable} from "../util/types.js";
import childProcess from "node:child_process";
import fs from "node:fs";
import {tempFile} from "../util/fs.js";
export const getSubjectDisplay = (sub: StrRVal): string => {
let annotated = '\n┌───────────────\n'
if ( sub.term === 'string' ) {
const lines = sub.value.split('\n')
const padLength = `${lines.length}`.length // heh
annotated += lines
.map((line, idx) => '│ ' + idx.toString().padStart(padLength, ' ') + ' │' + line)
.join('\n')
}
if ( sub.term === 'int' ) {
annotated += `${sub.value}`
}
if ( sub.term === 'destructured' ) {
const padLength = `${sub.value.length}`.length
annotated += sub.value
.map((el, idx) => '│ ' + idx.toString().padStart(padLength, ' ') + ' │'
+ el.value.split('\n').map((line, lineIdx) => lineIdx ? (`${''.padStart(padLength, ' ')}${line}`) : line).join('\n'))
.join('\n│ ' + ''.padStart(padLength, ' ') + ' ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈\n')
}
annotated += '\n├───────────────'
annotated += `\n│ :: ${sub.term}`
annotated += '\n└───────────────'
return annotated
}
export type Display = {
showSubject(sub: StrRVal): Awaitable<unknown>
showRaw(str: string): Awaitable<unknown>
}
export class ConsoleDisplay implements Display {
showSubject(sub: StrRVal) {
console.log(getSubjectDisplay(sub))
}
showRaw(str: string) {
console.log(str)
}
}
export class NullDisplay implements Display {
showSubject() {}
showRaw() {}
}
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
}
}
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,
}