mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
feat(unstable): add Deno.consoleSize (#6520)
This commit is contained in:
parent
dc6b3ef714
commit
1bcc35b84a
5 changed files with 115 additions and 3 deletions
|
@ -12,7 +12,7 @@ export { openPlugin } from "./ops/plugins.ts";
|
|||
export { transpileOnly, compile, bundle } from "./compiler_api.ts";
|
||||
export { applySourceMap, formatDiagnostics } from "./ops/errors.ts";
|
||||
export { signal, signals, Signal, SignalStream } from "./signals.ts";
|
||||
export { setRaw } from "./ops/tty.ts";
|
||||
export { setRaw, consoleSize } from "./ops/tty.ts";
|
||||
export { utimeSync, utime } from "./ops/fs/utime.ts";
|
||||
export { ftruncateSync, ftruncate } from "./ops/fs/truncate.ts";
|
||||
export { shutdown, ShutdownMode } from "./net.ts";
|
||||
|
|
15
cli/js/lib.deno.unstable.d.ts
vendored
15
cli/js/lib.deno.unstable.d.ts
vendored
|
@ -43,6 +43,21 @@ declare namespace Deno {
|
|||
* Requires `allow-read` and `allow-write` permissions. */
|
||||
export function link(oldpath: string, newpath: string): Promise<void>;
|
||||
|
||||
/** **UNSTABLE**: New API, yet to be vetted.
|
||||
*
|
||||
* Gets the size of the console as columns/rows.
|
||||
*
|
||||
* ```ts
|
||||
* const { columns, rows } = await Deno.consoleSize(Deno.stdout.rid);
|
||||
* ```
|
||||
*/
|
||||
export function consoleSize(
|
||||
rid: number
|
||||
): {
|
||||
columns: number;
|
||||
rows: number;
|
||||
};
|
||||
|
||||
export type SymlinkOptions = {
|
||||
type: "file" | "dir";
|
||||
};
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
import { sendSync } from "./dispatch_json.ts";
|
||||
|
||||
export function consoleSize(rid: number): [number, number] {
|
||||
return sendSync("op_console_size", { rid });
|
||||
}
|
||||
|
||||
export function isatty(rid: number): boolean {
|
||||
return sendSync("op_isatty", { rid });
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use deno_core::CoreIsolateState;
|
|||
use deno_core::ZeroCopyBuf;
|
||||
#[cfg(unix)]
|
||||
use nix::sys::termios;
|
||||
use serde_derive::Deserialize;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
#[cfg(windows)]
|
||||
|
@ -38,6 +38,7 @@ fn get_windows_handle(
|
|||
pub fn init(i: &mut CoreIsolate, s: &State) {
|
||||
i.register_op("op_set_raw", s.stateful_json_op2(op_set_raw));
|
||||
i.register_op("op_isatty", s.stateful_json_op2(op_isatty));
|
||||
i.register_op("op_console_size", s.stateful_json_op2(op_console_size));
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -250,3 +251,80 @@ pub fn op_isatty(
|
|||
})?;
|
||||
Ok(JsonOp::Sync(json!(isatty)))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ConsoleSizeArgs {
|
||||
rid: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct ConsoleSize {
|
||||
columns: u32,
|
||||
rows: u32,
|
||||
}
|
||||
|
||||
pub fn op_console_size(
|
||||
isolate_state: &mut CoreIsolateState,
|
||||
state: &State,
|
||||
args: Value,
|
||||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<JsonOp, OpError> {
|
||||
state.check_unstable("Deno.consoleSize");
|
||||
let args: ConsoleSizeArgs = serde_json::from_value(args)?;
|
||||
let rid = args.rid;
|
||||
|
||||
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||
let size =
|
||||
std_file_resource(&mut resource_table, rid as u32, move |r| match r {
|
||||
Ok(std_file) => {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::io::AsRawHandle;
|
||||
let handle = std_file.as_raw_handle();
|
||||
|
||||
unsafe {
|
||||
let mut bufinfo: winapi::um::wincon::CONSOLE_SCREEN_BUFFER_INFO =
|
||||
std::mem::zeroed();
|
||||
|
||||
if winapi::um::wincon::GetConsoleScreenBufferInfo(
|
||||
handle,
|
||||
&mut bufinfo,
|
||||
) == 0
|
||||
{
|
||||
// TODO (caspervonb) use GetLastError
|
||||
return Err(OpError::other(
|
||||
winapi::um::errhandlingapi::GetLastError().to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(ConsoleSize {
|
||||
columns: bufinfo.dwSize.X as u32,
|
||||
rows: bufinfo.dwSize.Y as u32,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
let fd = std_file.as_raw_fd();
|
||||
unsafe {
|
||||
let mut size: libc::winsize = std::mem::zeroed();
|
||||
if libc::ioctl(fd, libc::TIOCGWINSZ, &mut size as *mut _) != 0 {
|
||||
return Err(OpError::from(std::io::Error::last_os_error()));
|
||||
}
|
||||
|
||||
// TODO (caspervonb) return a tuple instead
|
||||
Ok(ConsoleSize {
|
||||
columns: size.ws_col as u32,
|
||||
rows: size.ws_row as u32,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => Err(OpError::bad_resource_id()),
|
||||
})?;
|
||||
|
||||
Ok(JsonOp::Sync(json!(size)))
|
||||
}
|
||||
|
|
|
@ -1,8 +1,23 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assert } from "./test_util.ts";
|
||||
import { unitTest, assert, assertThrows } from "./test_util.ts";
|
||||
|
||||
// Note tests for Deno.setRaw is in integration tests.
|
||||
|
||||
unitTest({ perms: { read: true } }, function consoleSizeFile(): void {
|
||||
const file = Deno.openSync("cli/tests/hello.txt");
|
||||
assertThrows(() => {
|
||||
Deno.consoleSize(file.rid);
|
||||
}, Error);
|
||||
file.close();
|
||||
});
|
||||
|
||||
unitTest(function consoleSizeError(): void {
|
||||
assertThrows(() => {
|
||||
// Absurdly large rid.
|
||||
Deno.consoleSize(0x7fffffff);
|
||||
}, Deno.errors.BadResource);
|
||||
});
|
||||
|
||||
unitTest({ perms: { read: true } }, function isatty(): void {
|
||||
// CI not under TTY, so cannot test stdin/stdout/stderr.
|
||||
const f = Deno.openSync("cli/tests/hello.txt");
|
||||
|
|
Loading…
Reference in a new issue