Minor refactoring, build up the ansi escape codes to handle colors
This commit is contained in:
parent
30230520a0
commit
15496646d6
@ -18,13 +18,17 @@ const BunTerminalIO: ITerminal = {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get the size of the terminal window via ANSI codes
|
||||||
|
* @see https://viewsourcecode.org/snaptoken/kilo/03.rawInputAndOutput.html#window-size-the-hard-way
|
||||||
|
*/
|
||||||
getTerminalSize: async function getTerminalSize(): Promise<ITerminalSize> {
|
getTerminalSize: async function getTerminalSize(): Promise<ITerminalSize> {
|
||||||
const encoder = new TextEncoder();
|
|
||||||
|
|
||||||
// Tell the cursor to move to Row 999 and Column 999
|
// Tell the cursor to move to Row 999 and Column 999
|
||||||
// Since this command specifically doesn't go off the screen
|
// Since this command specifically doesn't go off the screen
|
||||||
// When we ask where the cursor is, we should get the size of the screen
|
// When we ask where the cursor is, we should get the size of the screen
|
||||||
await BunTerminalIO.writeStdout(Ansi.moveCursorForward(999) + Ansi.moveCursorDown(999));
|
await BunTerminalIO.writeStdout(
|
||||||
|
Ansi.moveCursorForward(999) + Ansi.moveCursorDown(999),
|
||||||
|
);
|
||||||
|
|
||||||
// Ask where the cursor is
|
// Ask where the cursor is
|
||||||
await BunTerminalIO.writeStdout(Ansi.GetCursorLocation);
|
await BunTerminalIO.writeStdout(Ansi.GetCursorLocation);
|
||||||
|
@ -6,7 +6,7 @@ import { Ansi, KeyCommand } from './ansi.ts';
|
|||||||
import { defaultTerminalSize, SCROLL_TAB_SIZE } from './config.ts';
|
import { defaultTerminalSize, SCROLL_TAB_SIZE } from './config.ts';
|
||||||
import { getTestRunner } from './runtime.ts';
|
import { getTestRunner } from './runtime.ts';
|
||||||
import { Position } from './types.ts';
|
import { Position } from './types.ts';
|
||||||
import * as Util from './fns.ts';
|
import * as Fn from './fns.ts';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
assertEquals,
|
assertEquals,
|
||||||
@ -22,7 +22,7 @@ const {
|
|||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
const testKeyMap = (codes: string[], expected: string) => {
|
const testKeyMap = (codes: string[], expected: string) => {
|
||||||
codes.forEach((code) => {
|
codes.forEach((code) => {
|
||||||
assertEquals(Util.readKey(encoder.encode(code)), expected);
|
assertEquals(Fn.readKey(encoder.encode(code)), expected);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ testSuite({
|
|||||||
assertEquals(row.byteIndexToCharIndex(0), 0);
|
assertEquals(row.byteIndexToCharIndex(0), 0);
|
||||||
|
|
||||||
// Return count on nonsense index
|
// Return count on nonsense index
|
||||||
assertEquals(Util.strlen(row.toString()), 10);
|
assertEquals(Fn.strlen(row.toString()), 10);
|
||||||
assertEquals(row.byteIndexToCharIndex(72), 10);
|
assertEquals(row.byteIndexToCharIndex(72), 10);
|
||||||
|
|
||||||
const row2 = Row.from('foobar');
|
const row2 = Row.from('foobar');
|
||||||
@ -224,121 +224,121 @@ testSuite({
|
|||||||
'fns': {
|
'fns': {
|
||||||
'arrayInsert() strings': () => {
|
'arrayInsert() strings': () => {
|
||||||
const a = ['😺', '😸', '😹'];
|
const a = ['😺', '😸', '😹'];
|
||||||
const b = Util.arrayInsert(a, 1, 'x');
|
const b = Fn.arrayInsert(a, 1, 'x');
|
||||||
const c = ['😺', 'x', '😸', '😹'];
|
const c = ['😺', 'x', '😸', '😹'];
|
||||||
assertEquals(b, c);
|
assertEquals(b, c);
|
||||||
|
|
||||||
const d = Util.arrayInsert(c, 17, 'y');
|
const d = Fn.arrayInsert(c, 17, 'y');
|
||||||
const e = ['😺', 'x', '😸', '😹', 'y'];
|
const e = ['😺', 'x', '😸', '😹', 'y'];
|
||||||
assertEquals(d, e);
|
assertEquals(d, e);
|
||||||
|
|
||||||
assertEquals(Util.arrayInsert([], 0, 'foo'), ['foo']);
|
assertEquals(Fn.arrayInsert([], 0, 'foo'), ['foo']);
|
||||||
},
|
},
|
||||||
'arrayInsert() numbers': () => {
|
'arrayInsert() numbers': () => {
|
||||||
const a = [1, 3, 5];
|
const a = [1, 3, 5];
|
||||||
const b = [1, 3, 4, 5];
|
const b = [1, 3, 4, 5];
|
||||||
assertEquals(Util.arrayInsert(a, 2, 4), b);
|
assertEquals(Fn.arrayInsert(a, 2, 4), b);
|
||||||
|
|
||||||
const c = [1, 2, 3, 4, 5];
|
const c = [1, 2, 3, 4, 5];
|
||||||
assertEquals(Util.arrayInsert(b, 1, 2), c);
|
assertEquals(Fn.arrayInsert(b, 1, 2), c);
|
||||||
},
|
},
|
||||||
'noop fn': () => {
|
'noop fn': () => {
|
||||||
assertExists(Util.noop);
|
assertExists(Fn.noop);
|
||||||
assertEquals(Util.noop(), undefined);
|
assertEquals(Fn.noop(), undefined);
|
||||||
},
|
},
|
||||||
'posSub()': () => {
|
'posSub()': () => {
|
||||||
assertEquals(Util.posSub(14, 15), 0);
|
assertEquals(Fn.posSub(14, 15), 0);
|
||||||
assertEquals(Util.posSub(15, 1), 14);
|
assertEquals(Fn.posSub(15, 1), 14);
|
||||||
},
|
},
|
||||||
'minSub()': () => {
|
'minSub()': () => {
|
||||||
assertEquals(Util.minSub(13, 25, -1), -1);
|
assertEquals(Fn.minSub(13, 25, -1), -1);
|
||||||
assertEquals(Util.minSub(25, 13, 0), 12);
|
assertEquals(Fn.minSub(25, 13, 0), 12);
|
||||||
},
|
},
|
||||||
'maxAdd()': () => {
|
'maxAdd()': () => {
|
||||||
assertEquals(Util.maxAdd(99, 99, 75), 75);
|
assertEquals(Fn.maxAdd(99, 99, 75), 75);
|
||||||
assertEquals(Util.maxAdd(25, 74, 101), 99);
|
assertEquals(Fn.maxAdd(25, 74, 101), 99);
|
||||||
},
|
},
|
||||||
'ord()': () => {
|
'ord()': () => {
|
||||||
// Invalid output
|
// Invalid output
|
||||||
assertEquals(Util.ord(''), 256);
|
assertEquals(Fn.ord(''), 256);
|
||||||
|
|
||||||
// Valid output
|
// Valid output
|
||||||
assertEquals(Util.ord('a'), 97);
|
assertEquals(Fn.ord('a'), 97);
|
||||||
},
|
},
|
||||||
'chars() properly splits strings into unicode characters': () => {
|
'strChars() properly splits strings into unicode characters': () => {
|
||||||
assertEquals(Util.chars('😺😸😹'), ['😺', '😸', '😹']);
|
assertEquals(Fn.strChars('😺😸😹'), ['😺', '😸', '😹']);
|
||||||
},
|
},
|
||||||
'ctrlKey()': () => {
|
'ctrlKey()': () => {
|
||||||
const ctrl_a = Util.ctrlKey('a');
|
const ctrl_a = Fn.ctrlKey('a');
|
||||||
assertTrue(Util.isControl(ctrl_a));
|
assertTrue(Fn.isControl(ctrl_a));
|
||||||
assertEquals(ctrl_a, String.fromCodePoint(0x01));
|
assertEquals(ctrl_a, String.fromCodePoint(0x01));
|
||||||
|
|
||||||
const invalid = Util.ctrlKey('😺');
|
const invalid = Fn.ctrlKey('😺');
|
||||||
assertFalse(Util.isControl(invalid));
|
assertFalse(Fn.isControl(invalid));
|
||||||
assertEquals(invalid, '😺');
|
assertEquals(invalid, '😺');
|
||||||
},
|
},
|
||||||
'isAscii()': () => {
|
'isAscii()': () => {
|
||||||
assertTrue(Util.isAscii('asjyverkjhsdf1928374'));
|
assertTrue(Fn.isAscii('asjyverkjhsdf1928374'));
|
||||||
assertFalse(Util.isAscii('😺acalskjsdf'));
|
assertFalse(Fn.isAscii('😺acalskjsdf'));
|
||||||
assertFalse(Util.isAscii('ab😺ac'));
|
assertFalse(Fn.isAscii('ab😺ac'));
|
||||||
},
|
},
|
||||||
'isControl()': () => {
|
'isControl()': () => {
|
||||||
assertFalse(Util.isControl('abc'));
|
assertFalse(Fn.isControl('abc'));
|
||||||
assertTrue(Util.isControl(String.fromCodePoint(0x01)));
|
assertTrue(Fn.isControl(String.fromCodePoint(0x01)));
|
||||||
assertFalse(Util.isControl('😺'));
|
assertFalse(Fn.isControl('😺'));
|
||||||
},
|
},
|
||||||
'strlen()': () => {
|
'strlen()': () => {
|
||||||
// Ascii length
|
// Ascii length
|
||||||
assertEquals(Util.strlen('abc'), 'abc'.length);
|
assertEquals(Fn.strlen('abc'), 'abc'.length);
|
||||||
|
|
||||||
// Get number of visible unicode characters
|
// Get number of visible unicode characters
|
||||||
assertEquals(Util.strlen('😺😸😹'), 3);
|
assertEquals(Fn.strlen('😺😸😹'), 3);
|
||||||
assertNotEquals('😺😸😹'.length, Util.strlen('😺😸😹'));
|
assertNotEquals('😺😸😹'.length, Fn.strlen('😺😸😹'));
|
||||||
|
|
||||||
// Skin tone modifier + base character
|
// Skin tone modifier + base character
|
||||||
assertEquals(Util.strlen('🤰🏼'), 2);
|
assertEquals(Fn.strlen('🤰🏼'), 2);
|
||||||
assertNotEquals('🤰🏼'.length, Util.strlen('🤰🏼'));
|
assertNotEquals('🤰🏼'.length, Fn.strlen('🤰🏼'));
|
||||||
|
|
||||||
// This has 4 sub-characters, and 3 zero-width-joiners
|
// This has 4 sub-characters, and 3 zero-width-joiners
|
||||||
assertEquals(Util.strlen('👨👩👧👦'), 7);
|
assertEquals(Fn.strlen('👨👩👧👦'), 7);
|
||||||
assertNotEquals('👨👩👧👦'.length, Util.strlen('👨👩👧👦'));
|
assertNotEquals('👨👩👧👦'.length, Fn.strlen('👨👩👧👦'));
|
||||||
},
|
},
|
||||||
'truncate()': () => {
|
'truncate()': () => {
|
||||||
assertEquals(Util.truncate('😺😸😹', 1), '😺');
|
assertEquals(Fn.truncate('😺😸😹', 1), '😺');
|
||||||
assertEquals(Util.truncate('😺😸😹', 5), '😺😸😹');
|
assertEquals(Fn.truncate('😺😸😹', 5), '😺😸😹');
|
||||||
assertEquals(Util.truncate('👨👩👧👦', 5), '👨👩👧');
|
assertEquals(Fn.truncate('👨👩👧👦', 5), '👨👩👧');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'readKey()': {
|
'readKey()': {
|
||||||
'empty input': () => {
|
'empty input': () => {
|
||||||
assertEquals(Util.readKey(new Uint8Array(0)), '');
|
assertEquals(Fn.readKey(new Uint8Array(0)), '');
|
||||||
},
|
},
|
||||||
'passthrough': () => {
|
'passthrough': () => {
|
||||||
// Ignore unhandled escape sequences
|
// Ignore unhandled escape sequences
|
||||||
assertEquals(Util.readKey(encoder.encode('\x1b[]')), '\x1b[]');
|
assertEquals(Fn.readKey(encoder.encode('\x1b[]')), '\x1b[]');
|
||||||
|
|
||||||
// Pass explicitly mapped values right through
|
// Pass explicitly mapped values right through
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Util.readKey(encoder.encode(KeyCommand.ArrowUp)),
|
Fn.readKey(encoder.encode(KeyCommand.ArrowUp)),
|
||||||
KeyCommand.ArrowUp,
|
KeyCommand.ArrowUp,
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Util.readKey(encoder.encode(KeyCommand.Home)),
|
Fn.readKey(encoder.encode(KeyCommand.Home)),
|
||||||
KeyCommand.Home,
|
KeyCommand.Home,
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Util.readKey(encoder.encode(KeyCommand.Delete)),
|
Fn.readKey(encoder.encode(KeyCommand.Delete)),
|
||||||
KeyCommand.Delete,
|
KeyCommand.Delete,
|
||||||
);
|
);
|
||||||
|
|
||||||
// And pass through whatever else
|
// And pass through whatever else
|
||||||
assertEquals(Util.readKey(encoder.encode('foobaz')), 'foobaz');
|
assertEquals(Fn.readKey(encoder.encode('foobaz')), 'foobaz');
|
||||||
},
|
},
|
||||||
|
|
||||||
'Esc': () => testKeyMap(['\x1b', Util.ctrlKey('l')], KeyCommand.Escape),
|
'Esc': () => testKeyMap(['\x1b', Fn.ctrlKey('l')], KeyCommand.Escape),
|
||||||
'Backspace': () =>
|
'Backspace': () =>
|
||||||
testKeyMap(
|
testKeyMap(
|
||||||
[Util.ctrlKey('h'), '\x7f'],
|
[Fn.ctrlKey('h'), '\x7f'],
|
||||||
KeyCommand.Backspace,
|
KeyCommand.Backspace,
|
||||||
),
|
),
|
||||||
'Home': () =>
|
'Home': () =>
|
||||||
|
@ -24,24 +24,112 @@ export enum KeyCommand {
|
|||||||
End = 'LineEnd',
|
End = 'LineEnd',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Ansi = {
|
/**
|
||||||
ClearLine: ANSI_PREFIX + 'K',
|
* Values for Basic ANSI colors and formatting
|
||||||
ClearScreen: ANSI_PREFIX + '2J',
|
*/
|
||||||
ResetCursor: ANSI_PREFIX + 'H',
|
export enum AnsiColor {
|
||||||
HideCursor: ANSI_PREFIX + '?25l',
|
TypeRGB = 2,
|
||||||
ShowCursor: ANSI_PREFIX + '?25h',
|
Type256 = 5,
|
||||||
GetCursorLocation: ANSI_PREFIX + '6n',
|
|
||||||
InvertColor: ANSI_PREFIX + '7m',
|
Invert = 7,
|
||||||
ResetFormatting: ANSI_PREFIX + 'm',
|
|
||||||
moveCursor: (row: number, col: number): string => {
|
// Foreground Colors
|
||||||
|
FgBlack = 30,
|
||||||
|
FgRed,
|
||||||
|
FgGreen,
|
||||||
|
FgYellow,
|
||||||
|
FgBlue,
|
||||||
|
FgMagenta,
|
||||||
|
FgCyan,
|
||||||
|
FgWhite,
|
||||||
|
FgDefault,
|
||||||
|
|
||||||
|
// Background Colors
|
||||||
|
BgBlack = 40,
|
||||||
|
BgRed,
|
||||||
|
BgGreen,
|
||||||
|
BgYellow,
|
||||||
|
BgBlue,
|
||||||
|
BgMagenta,
|
||||||
|
BgCyan,
|
||||||
|
BgWhite,
|
||||||
|
BgDefault,
|
||||||
|
|
||||||
|
// Bright Foreground Colors
|
||||||
|
FgBrightBlack = 90,
|
||||||
|
FgBrightRed,
|
||||||
|
FgBrightGreen,
|
||||||
|
FgBrightYellow,
|
||||||
|
FgBrightBlue,
|
||||||
|
FgBrightMagenta,
|
||||||
|
FgBrightCyan,
|
||||||
|
FgBrightWhite,
|
||||||
|
|
||||||
|
// Bright Background Colors
|
||||||
|
BgBrightBlack = 100,
|
||||||
|
BgBrightRed,
|
||||||
|
BgBrightGreen,
|
||||||
|
BgBrightYellow,
|
||||||
|
BgBrightBlue,
|
||||||
|
BgBrightMagenta,
|
||||||
|
BgBrightCyan,
|
||||||
|
BgBrightWhite,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Ground {
|
||||||
|
Fore = AnsiColor.FgDefault,
|
||||||
|
Back = AnsiColor.BgDefault,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ANSI escape code generation fns
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
const code = (
|
||||||
|
param: string | number | string[] | number[],
|
||||||
|
suffix: string = '',
|
||||||
|
): string => {
|
||||||
|
if (Array.isArray(param)) {
|
||||||
|
param = param.join(';');
|
||||||
|
}
|
||||||
|
|
||||||
|
return [ANSI_PREFIX, param, suffix].join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const moveCursor = (row: number, col: number): string => {
|
||||||
// Convert to 1-based counting
|
// Convert to 1-based counting
|
||||||
row++;
|
row++;
|
||||||
col++;
|
col++;
|
||||||
|
|
||||||
return ANSI_PREFIX + `${row};${col}H`;
|
return code([row, col], 'H');
|
||||||
},
|
};
|
||||||
moveCursorForward: (col: number): string => ANSI_PREFIX + `${col}C`,
|
const moveCursorForward = (col: number): string => code(col, 'C');
|
||||||
moveCursorDown: (row: number): string => ANSI_PREFIX + `${row}B`,
|
const moveCursorDown = (row: number): string => code(row, 'B');
|
||||||
|
const textFormat = (param: string | number | string[] | number[]): string =>
|
||||||
|
code(param, 'm');
|
||||||
|
const color256 = (value: number, ground: Ground = Ground.Fore): string =>
|
||||||
|
textFormat([ground, AnsiColor.Type256, value]);
|
||||||
|
const rgb = (
|
||||||
|
r: number,
|
||||||
|
g: number,
|
||||||
|
b: number,
|
||||||
|
ground: Ground = Ground.Fore,
|
||||||
|
): string => textFormat([ground, AnsiColor.TypeRGB, r, g, b]);
|
||||||
|
|
||||||
|
export const Ansi = {
|
||||||
|
ClearLine: code('K'),
|
||||||
|
ClearScreen: code('2J'),
|
||||||
|
ResetCursor: code('H'),
|
||||||
|
HideCursor: code('?25l'),
|
||||||
|
ShowCursor: code('?25h'),
|
||||||
|
GetCursorLocation: code('6n'),
|
||||||
|
InvertColor: textFormat(AnsiColor.Invert),
|
||||||
|
ResetFormatting: textFormat(''),
|
||||||
|
moveCursor,
|
||||||
|
moveCursorForward,
|
||||||
|
moveCursorDown,
|
||||||
|
textFormat,
|
||||||
|
color256,
|
||||||
|
rgb,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Ansi;
|
export default Ansi;
|
||||||
|
@ -137,7 +137,7 @@ export function ord(s: string): number {
|
|||||||
*
|
*
|
||||||
* @param s - the string to split into 'characters'
|
* @param s - the string to split into 'characters'
|
||||||
*/
|
*/
|
||||||
export function chars(s: string): string[] {
|
export function strChars(s: string): string[] {
|
||||||
return s.split(/(?:)/u);
|
return s.split(/(?:)/u);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ export function chars(s: string): string[] {
|
|||||||
* @param s - the string to check
|
* @param s - the string to check
|
||||||
*/
|
*/
|
||||||
export function strlen(s: string): number {
|
export function strlen(s: string): number {
|
||||||
return chars(s).length;
|
return strChars(s).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,7 +156,7 @@ export function strlen(s: string): number {
|
|||||||
* @param char - string to check
|
* @param char - string to check
|
||||||
*/
|
*/
|
||||||
export function isAscii(char: string): boolean {
|
export function isAscii(char: string): boolean {
|
||||||
return chars(char).every((char) => ord(char) < 0x80);
|
return strChars(char).every((char) => ord(char) < 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,7 +191,7 @@ export function ctrlKey(char: string): string {
|
|||||||
* @param maxLen
|
* @param maxLen
|
||||||
*/
|
*/
|
||||||
export function truncate(s: string, maxLen: number): string {
|
export function truncate(s: string, maxLen: number): string {
|
||||||
const chin = chars(s);
|
const chin = strChars(s);
|
||||||
if (maxLen >= chin.length) {
|
if (maxLen >= chin.length) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ export class Row {
|
|||||||
render: string[] = [];
|
render: string[] = [];
|
||||||
|
|
||||||
private constructor(s: string | string[] = '') {
|
private constructor(s: string | string[] = '') {
|
||||||
this.chars = Array.isArray(s) ? s : Util.chars(s);
|
this.chars = Array.isArray(s) ? s : Util.strChars(s);
|
||||||
this.render = [];
|
this.render = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,12 +46,12 @@ export class Row {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public append(s: string): void {
|
public append(s: string): void {
|
||||||
this.chars = this.chars.concat(Util.chars(s));
|
this.chars = this.chars.concat(Util.strChars(s));
|
||||||
this.updateRender();
|
this.updateRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
public insertChar(at: number, c: string): void {
|
public insertChar(at: number, c: string): void {
|
||||||
const newSlice = Util.chars(c);
|
const newSlice = Util.strChars(c);
|
||||||
if (at >= this.size) {
|
if (at >= this.size) {
|
||||||
this.chars = this.chars.concat(newSlice);
|
this.chars = this.chars.concat(newSlice);
|
||||||
} else {
|
} else {
|
||||||
@ -96,8 +96,8 @@ export class Row {
|
|||||||
|
|
||||||
public cxToRx(cx: number): number {
|
public cxToRx(cx: number): number {
|
||||||
let rx = 0;
|
let rx = 0;
|
||||||
let j = 0;
|
let j;
|
||||||
for (; j < cx; j++) {
|
for (j = 0; j < cx; j++) {
|
||||||
if (this.chars[j] === '\t') {
|
if (this.chars[j] === '\t') {
|
||||||
rx += (SCROLL_TAB_SIZE - 1) - (rx % SCROLL_TAB_SIZE);
|
rx += (SCROLL_TAB_SIZE - 1) - (rx % SCROLL_TAB_SIZE);
|
||||||
}
|
}
|
||||||
@ -162,7 +162,7 @@ export class Row {
|
|||||||
' '.repeat(SCROLL_TAB_SIZE),
|
' '.repeat(SCROLL_TAB_SIZE),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.render = Util.chars(newString);
|
this.render = Util.strChars(newString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ class Termios {
|
|||||||
// Actually set the new termios settings
|
// Actually set the new termios settings
|
||||||
res = this.#ffi.tcsetattr(STDIN_FILENO, TCSANOW, this.#ptr);
|
res = this.#ffi.tcsetattr(STDIN_FILENO, TCSANOW, this.#ptr);
|
||||||
if (res === -1) {
|
if (res === -1) {
|
||||||
die('Failed to update terminal settings. Can\'t enter raw mode');
|
die("Failed to update terminal settings. Can't enter raw mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#inRawMode = true;
|
this.#inRawMode = true;
|
||||||
@ -101,7 +101,7 @@ class Termios {
|
|||||||
// and aren't in raw mode. It just doesn't really matter.
|
// and aren't in raw mode. It just doesn't really matter.
|
||||||
if (!this.#inRawMode) {
|
if (!this.#inRawMode) {
|
||||||
log(
|
log(
|
||||||
'Attampting to disable raw mode when not in raw mode',
|
'Attempting to disable raw mode when not in raw mode',
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { RunTimeType } from './runtime.ts';
|
import { RunTimeType } from './runtime.ts';
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Runtime adapter interfaces
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The size of terminal in rows and columns
|
* The size of terminal in rows and columns
|
||||||
*/
|
*/
|
||||||
@ -43,6 +39,10 @@ export interface IFFI {
|
|||||||
close(): void;
|
close(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Runtime adapter interfaces
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The common interface for runtime adapters
|
* The common interface for runtime adapters
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user