Implement methods to get current console size
This commit is contained in:
parent
9cca55b101
commit
d99656de66
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Wrap the runtime-specific hook into stdin
|
||||
*/
|
||||
import { ITerminalIO } from '../common/mod.ts';
|
||||
import { ITerminalIO, ITerminalSize } from '../common/mod.ts';
|
||||
|
||||
export async function* inputLoop() {
|
||||
for await (const chunk of Bun.stdin.stream()) {
|
||||
@ -15,8 +15,20 @@ export async function write(s: string): Promise<void> {
|
||||
await Bun.write(Bun.stdout, buffer);
|
||||
}
|
||||
|
||||
export function getSize(): ITerminalSize {
|
||||
// @TODO implement
|
||||
// Check for tput
|
||||
// If has tput, use it to get terminal size
|
||||
// If not, try FFI fallback
|
||||
// Otherwise, return 80x25 as a last resort
|
||||
const fallback: ITerminalSize = { rows: 25, cols: 80 };
|
||||
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const BunTerminalIO: ITerminalIO = {
|
||||
inputLoop,
|
||||
getSize,
|
||||
write,
|
||||
};
|
||||
|
||||
|
@ -1,15 +1,13 @@
|
||||
function escape(suffix: string): string {
|
||||
return `\x1b[${suffix}`;
|
||||
}
|
||||
|
||||
function moveCursor(row: number, col: number): string {
|
||||
return escape(`${row};${col}H`);
|
||||
function esc(pieces: TemplateStringsArray): string {
|
||||
return '\x1b[' + pieces[0];
|
||||
}
|
||||
|
||||
export const Ansi = {
|
||||
ClearScreen: escape('2J'),
|
||||
ResetCursor: escape('H'),
|
||||
moveCursor,
|
||||
ClearScreen: esc`2J`,
|
||||
ResetCursor: esc`H`,
|
||||
moveCursor: function moveCursor(row: number, col: number): string {
|
||||
return `\x1b${row};${col}H`;
|
||||
},
|
||||
};
|
||||
|
||||
export default Ansi;
|
||||
|
@ -12,6 +12,10 @@ class Buffer {
|
||||
this.#b += s;
|
||||
}
|
||||
|
||||
appendLine(s: string): void {
|
||||
this.#b += s + '\r\n';
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.#b = '';
|
||||
}
|
||||
@ -49,10 +53,18 @@ export class Editor {
|
||||
const { write } = await importForRuntime('terminal_io');
|
||||
|
||||
this.clearScreen();
|
||||
this.drawRows();
|
||||
|
||||
await write(this.#buffer.getBuffer());
|
||||
this.#buffer.clear();
|
||||
}
|
||||
|
||||
private drawRows(): void {
|
||||
for (let y = 0; y <= 24; y++) {
|
||||
this.#buffer.appendLine('~');
|
||||
}
|
||||
}
|
||||
|
||||
private clearScreen(): void {
|
||||
this.#buffer.append(Ansi.ClearScreen);
|
||||
this.#buffer.append(Ansi.ResetCursor);
|
||||
|
@ -1,41 +1,3 @@
|
||||
import { importForRuntime } from './runtime.ts';
|
||||
import { Editor } from './editor.ts';
|
||||
import { getTermios } from './termios.ts';
|
||||
|
||||
export * from './runtime.ts';
|
||||
export * from './strings.ts';
|
||||
export type * from './types.ts';
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
export async function main() {
|
||||
const { inputLoop, onExit } = await importForRuntime('mod.ts');
|
||||
|
||||
// Setup raw mode, and tear down on error or normal exit
|
||||
const t = await getTermios();
|
||||
t.enableRawMode();
|
||||
onExit(() => {
|
||||
console.info('Exit handler called, disabling raw mode');
|
||||
t.disableRawMode();
|
||||
});
|
||||
|
||||
// Create the editor itself
|
||||
const editor = new Editor();
|
||||
|
||||
// The main event loop
|
||||
for await (const chunk of inputLoop()) {
|
||||
const char = String(decoder.decode(chunk));
|
||||
|
||||
// Clear the screen for output
|
||||
await editor.refreshScreen();
|
||||
|
||||
// Process input
|
||||
const shouldLoop = editor.processKeyPress(char);
|
||||
|
||||
if (!shouldLoop) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -37,6 +37,11 @@ export interface IFFI {
|
||||
getPointer(ta: any): unknown;
|
||||
}
|
||||
|
||||
export interface ITerminalSize {
|
||||
rows: number;
|
||||
cols: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime-specific IO streams
|
||||
*/
|
||||
@ -46,6 +51,11 @@ export interface ITerminalIO {
|
||||
*/
|
||||
inputLoop(): AsyncGenerator<Uint8Array, void, unknown>;
|
||||
|
||||
/**
|
||||
* Get the size of the terminal
|
||||
*/
|
||||
getSize(): ITerminalSize;
|
||||
|
||||
/**
|
||||
* Pipe a string to stdout
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ITerminalIO } from '../common/types.ts';
|
||||
import { ITerminalIO, ITerminalSize } from '../common/types.ts';
|
||||
|
||||
/**
|
||||
* Wrap the runtime-specific hook into stdin
|
||||
@ -17,8 +17,18 @@ export async function write(s: string): Promise<void> {
|
||||
stdout.releaseLock();
|
||||
}
|
||||
|
||||
export function getSize(): ITerminalSize {
|
||||
const size: { rows: number; columns: number } = Deno.consoleSize();
|
||||
|
||||
return {
|
||||
rows: size.rows,
|
||||
cols: size.columns,
|
||||
};
|
||||
}
|
||||
|
||||
const DenoTerminalIO: ITerminalIO = {
|
||||
inputLoop,
|
||||
getSize,
|
||||
write,
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,43 @@
|
||||
/**
|
||||
* The starting point for running scroll
|
||||
*/
|
||||
import { main } from './common/mod.ts';
|
||||
import { importForRuntime } from './common/mod.ts';
|
||||
import { getTermios } from './common/termios.ts';
|
||||
import { Editor } from './common/editor.ts';
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
export async function main() {
|
||||
const { inputLoop, onExit } = await importForRuntime('mod.ts');
|
||||
|
||||
// Setup raw mode, and tear down on error or normal exit
|
||||
const t = await getTermios();
|
||||
t.enableRawMode();
|
||||
onExit(() => {
|
||||
console.info('Exit handler called, disabling raw mode');
|
||||
t.disableRawMode();
|
||||
});
|
||||
|
||||
// Create the editor itself
|
||||
const editor = new Editor();
|
||||
|
||||
// The main event loop
|
||||
for await (const chunk of inputLoop()) {
|
||||
const char = String(decoder.decode(chunk));
|
||||
|
||||
// Clear the screen for output
|
||||
await editor.refreshScreen();
|
||||
|
||||
// Process input
|
||||
const shouldLoop = editor.processKeyPress(char);
|
||||
|
||||
if (!shouldLoop) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the event loop
|
||||
|
Loading…
Reference in New Issue
Block a user