Current section

Files

Jump to
string_width src string_width_ffi.mjs
Raw

src/string_width_ffi.mjs

import { toList, Ok, Error } from "./gleam.mjs";
const ANSI_RE =
/\x1b(?:[\x30-\x4f\x51-\x57\x59-\x5a\x60-\x7e]|(?:\[[\x20-\x3f]*?[\x40-\x7e])|(?:[\x50\x58\x5d\x5e\x5f].*?(?:\x07|\x1b\\)))/gm;
const ASCII_RE = /[\x20-\x7e]+(?=[\x20-\x7e]|$)/g;
const SEGMENTER = new Intl.Segmenter();
export function get_terminal_size() {
if (globalThis.Deno) {
try {
const consoleSize = Deno.consoleSize();
if (consoleSize) {
return new Ok([consoleSize.rows, consoleSize.columns]);
}
} catch {}
const envRows = parseInt(Deno.env.get("LINES"), 10);
const envCols = parseInt(Deno.env.get("COLUMNS"), 10);
if (envRows && envCols) {
return new Ok([envRows, envCols]);
}
}
if (globalThis.process) {
if (process.stdout?.rows && process.stdout?.columns) {
return new Ok([process.stdout.rows, process.stdout.columns]);
}
if (process.stderr?.rows && process.stderr?.columns) {
return new Ok([process.stderr.rows, process.stderr.columns]);
}
if (process.stdin?.rows && process.stdin?.columns) {
return new Ok([process.stdin.rows, process.stdin.columns]);
}
const envRows = parseInt(process.env.LINES, 10);
const envCols = parseInt(process.env.COLUMNS, 10);
if (envRows && envCols) {
return new Ok([envRows, envCols]);
}
}
return new Error();
}
export function is_tty() {
return (
process.stdin.isTTY === true &&
process.stdout.isTTY === true &&
process.env["TERM"] != "DUMB"
);
}
export function prepare_measure(options, str) {
if (!options.count_ansi_codes) {
str = str.replaceAll(ANSI_RE, "");
}
const ascii_ranges = scan_poslen(ASCII_RE, str);
return [str, ascii_ranges, 1];
}
export function table_lookup(table, value) {
let hi = value >> 8; // $int.bitwise_shift_right(value, 8);
let md = (value & 0xff) >> 3; // $int.bitwise_shift_right($int.bitwise_and(value, 0xff), 3);
let lo = value & 7; // $int.bitwise_and(value, 7);
// return (remainderInt(
// $int.bitwise_shift_right(at(table, at(table, hi) * 32 + md), lo),
// 2
// )) !== 0;
return ((table.byteAt(table.byteAt(hi) * 32 + md) >> lo) & 1) > 0;
}
export function match_ansi(str) {
return scan_poslen(ANSI_RE, str);
}
export function strip_ansi(str) {
return str.replaceAll(ANSI_RE, "");
}
export function unsafe_split(str, at) {
return [str.slice(0, at), str.slice(at)];
}
export function fold_bytes(str, state, fun) {
for (let i = 0; i < str.length; ++i) {
state = fun(state, str.charCodeAt(i));
}
return state;
}
export function fold_codepoints(str, state, fun) {
for (const codePoint of str) {
state = fun(state, codePoint.codePointAt(0));
}
return state;
}
export function fold_graphemes(str, state, fun) {
for (const { segment } of SEGMENTER.segment(str)) {
state = fun(state, segment);
}
return state;
}
export function utf_codepoint_to_string(cp) {
return String.fromCodePoint(cp);
}
function scan_poslen(re, str) {
let match;
let matches = [];
re.lastIndex = 0;
while (null !== (match = re.exec(str))) {
matches.push([match.index, re.lastIndex - match.index]);
}
return toList(matches);
}