Setup basic terminal output for Deno
This commit is contained in:
parent
e3083b1743
commit
f238b162f6
@ -1,2 +1,15 @@
|
||||
export enum Ansi {
|
||||
function escape(suffix: string): string {
|
||||
return `\x1b[${suffix}`;
|
||||
}
|
||||
|
||||
function moveCursor(row: number, col: number): string {
|
||||
return escape(`${row};${col}H`);
|
||||
}
|
||||
|
||||
export const Ansi = {
|
||||
ClearScreen: escape('2J'),
|
||||
ResetCursor: escape('H'),
|
||||
moveCursor,
|
||||
};
|
||||
|
||||
export default Ansi;
|
||||
|
@ -1,6 +1,60 @@
|
||||
export class Editor {
|
||||
import { Ansi } from './ansi.ts';
|
||||
import { importForRuntime } from './runtime.ts';
|
||||
import { ctrl_key } from './strings.ts';
|
||||
|
||||
class Buffer {
|
||||
#b = '';
|
||||
|
||||
constructor() {
|
||||
}
|
||||
public processKeyPress(): void {
|
||||
|
||||
append(s: string): void {
|
||||
this.#b += s;
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.#b = '';
|
||||
}
|
||||
|
||||
getBuffer(): string {
|
||||
return this.#b;
|
||||
}
|
||||
}
|
||||
|
||||
export class Editor {
|
||||
#buffer: Buffer;
|
||||
constructor() {
|
||||
this.#buffer = new Buffer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what to do based on input
|
||||
* @param input - the decoded chunk of stdin
|
||||
*/
|
||||
public processKeyPress(input: string): boolean {
|
||||
switch (input) {
|
||||
case ctrl_key('q'):
|
||||
this.clearScreen();
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the screen and write out the buffer
|
||||
*/
|
||||
public async refreshScreen(): Promise<void> {
|
||||
const { write } = await importForRuntime('terminal_io');
|
||||
|
||||
this.clearScreen();
|
||||
await write(this.#buffer.getBuffer());
|
||||
this.#buffer.clear();
|
||||
}
|
||||
|
||||
private clearScreen(): void {
|
||||
this.#buffer.append(Ansi.ClearScreen);
|
||||
this.#buffer.append(Ansi.ResetCursor);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { importForRuntime } from "./runtime";
|
||||
import { ctrl_key, is_control } from "./strings";
|
||||
import { importForRuntime } from './runtime.ts';
|
||||
import { Editor } from './editor.ts';
|
||||
|
||||
export * from './runtime.ts';
|
||||
export * from './strings.ts';
|
||||
@ -8,31 +8,28 @@ export type { ITestBase } from './test_base.ts';
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
export function readKey(chunk): string {
|
||||
const char = String(decoder.decode(chunk))
|
||||
|
||||
return char;
|
||||
}
|
||||
|
||||
export async function main() {
|
||||
const { inputLoop, init } = await importForRuntime('mod.ts');
|
||||
|
||||
// Set up handlers to enable/disable raw mode for each runtime
|
||||
await init();
|
||||
|
||||
// Create the editor itself
|
||||
const editor = new Editor();
|
||||
|
||||
// The main event loop
|
||||
for await (const chunk of inputLoop()) {
|
||||
const char = readKey(chunk);
|
||||
const char = String(decoder.decode(chunk));
|
||||
|
||||
if (char === ctrl_key('q')) {
|
||||
// Clear the screen for output
|
||||
await editor.refreshScreen();
|
||||
|
||||
// Process input
|
||||
const shouldLoop = editor.processKeyPress(char);
|
||||
|
||||
if (!shouldLoop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_control(char)) {
|
||||
console.log(char.codePointAt(0) + '\r');
|
||||
} else {
|
||||
console.log(`${char} ('${char.codePointAt(0)}')\r`);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* The main entrypoint when using Deno as the runtime
|
||||
*/
|
||||
import { getTermios } from "../common/mod.ts";
|
||||
import { getTermios } from '../common/mod.ts';
|
||||
|
||||
export * from './terminal_io.ts';
|
||||
|
||||
|
@ -6,3 +6,11 @@ export async function* inputLoop() {
|
||||
yield chunk;
|
||||
}
|
||||
}
|
||||
|
||||
export async function write(s: string): Promise<void> {
|
||||
const buffer = new TextEncoder().encode(s);
|
||||
|
||||
const stdout = Deno.stdout.writable.getWriter();
|
||||
await stdout.write(buffer);
|
||||
stdout.releaseLock();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user