diff --git a/js/console.ts b/js/console.ts index a9f2db021b..60d4101f18 100644 --- a/js/console.ts +++ b/js/console.ts @@ -1,5 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { isTypedArray } from "./util"; +import { TextEncoder } from "./text_encoding"; +import { File, stdout } from "./files"; // tslint:disable-next-line:no-any type ConsoleContext = Set; @@ -23,6 +25,20 @@ const CHAR_LOWERCASE_F = 102; /* f */ const CHAR_LOWERCASE_O = 111; /* o */ const CHAR_UPPERCASE_O = 79; /* O */ const CHAR_LOWERCASE_C = 99; /* c */ +export class CSI { + static kClear = "\x1b[1;1H"; + static kClearScreenDown = "\x1b[0J"; +} + +function cursorTo(stream: File, x: number, y?: number) { + const uint8 = new TextEncoder().encode(CSI.kClear); + stream.write(uint8); +} + +function clearScreenDown(stream: File) { + const uint8 = new TextEncoder().encode(CSI.kClearScreenDown); + stream.write(uint8); +} // tslint:disable-next-line:no-any function getClassInstanceName(instance: any): string { @@ -639,6 +655,12 @@ export class Console { this.log(); // When the collapsed state ended, outputs a sinle new line. } }; + + clear = (): void => { + this.indentLevel = 0; + cursorTo(stdout, 0, 0); + clearScreenDown(stdout); + }; } /** diff --git a/js/console_test.ts b/js/console_test.ts index 46a3497844..e34e25d8f1 100644 --- a/js/console_test.ts +++ b/js/console_test.ts @@ -1,5 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { Console, libdeno, stringifyArgs, inspect } from "deno"; +import { Console, libdeno, stringifyArgs, inspect, write, stdout } from "deno"; import { test, assertEqual } from "./test_util.ts"; const console = new Console(libdeno.print); @@ -116,7 +116,7 @@ test(function consoleTestStringifyCircular() { assertEqual( stringify(console), // tslint:disable-next-line:max-line-length - "Console { printFunc: [Function], log: [Function], debug: [Function], info: [Function], dir: [Function], warn: [Function], error: [Function], assert: [Function], count: [Function], countReset: [Function], time: [Function], timeLog: [Function], timeEnd: [Function], group: [Function], groupCollapsed: [Function], groupEnd: [Function], indentLevel: 0, collapsedAt: null }" + "Console { printFunc: [Function], log: [Function], debug: [Function], info: [Function], dir: [Function], warn: [Function], error: [Function], assert: [Function], count: [Function], countReset: [Function], time: [Function], timeLog: [Function], timeEnd: [Function], group: [Function], groupCollapsed: [Function], groupEnd: [Function], clear: [Function], indentLevel: 0, collapsedAt: null }" ); // test inspect is working the same assertEqual(inspect(nestedObj), nestedObjExpected); @@ -249,6 +249,24 @@ test(function consoleTestError() { } }); +test(function consoleTestClear() { + const stdoutWrite = stdout.write; + const uint8 = new TextEncoder().encode("\x1b[1;1H" + "\x1b[0J"); + let buffer = new Uint8Array(0); + + stdout.write = async u8 => { + const tmp = new Uint8Array(buffer.length + u8.length); + tmp.set(buffer, 0); + tmp.set(u8, buffer.length); + buffer = tmp; + + return await write(stdout.rid, u8); + }; + console.clear(); + stdout.write = stdoutWrite; + assertEqual(buffer, uint8); +}); + // Test bound this issue test(function consoleDetachedLog() { const log = console.log; @@ -265,6 +283,7 @@ test(function consoleDetachedLog() { const consoleTimeEnd = console.timeEnd; const consoleGroup = console.group; const consoleGroupEnd = console.groupEnd; + const consoleClear = console.clear; log("Hello world"); dir("Hello world"); debug("Hello world"); @@ -279,4 +298,5 @@ test(function consoleDetachedLog() { consoleTimeEnd("Hello world"); consoleGroup("Hello world"); consoleGroupEnd(); + console.clear(); });