-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathindex.js
104 lines (84 loc) · 2.56 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import process from 'node:process';
import {execFileSync} from 'node:child_process';
import fs from 'node:fs';
import tty from 'node:tty';
const defaultColumns = 80;
const defaultRows = 24;
const exec = (command, arguments_, {shell, env} = {}) =>
execFileSync(command, arguments_, {
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'ignore'],
timeout: 500,
shell,
env,
}).trim();
const create = (columns, rows) => ({
columns: Number.parseInt(columns, 10),
rows: Number.parseInt(rows, 10),
});
const createIfNotDefault = (maybeColumns, maybeRows) => {
const {columns, rows} = create(maybeColumns, maybeRows);
if (Number.isNaN(columns) || Number.isNaN(rows)) {
return;
}
if (columns === defaultColumns && rows === defaultRows) {
return;
}
return {columns, rows};
};
export default function terminalSize() {
const {env, stdout, stderr} = process;
if (stdout?.columns && stdout?.rows) {
return create(stdout.columns, stdout.rows);
}
if (stderr?.columns && stderr?.rows) {
return create(stderr.columns, stderr.rows);
}
// These values are static, so not the first choice.
if (env.COLUMNS && env.LINES) {
return create(env.COLUMNS, env.LINES);
}
const fallback = {
columns: defaultColumns,
rows: defaultRows,
};
if (process.platform === 'win32') {
// We include `tput` for Windows users using Git Bash.
return tput() ?? fallback;
}
if (process.platform === 'darwin') {
return devTty() ?? tput() ?? fallback;
}
return devTty() ?? tput() ?? resize() ?? fallback;
}
const devTty = () => {
try {
// eslint-disable-next-line no-bitwise
const flags = process.platform === 'darwin' ? fs.constants.O_EVTONLY | fs.constants.O_NONBLOCK : fs.constants.O_NONBLOCK;
// eslint-disable-next-line new-cap
const {columns, rows} = tty.WriteStream(fs.openSync('/dev/tty', flags));
return {columns, rows};
} catch {}
};
// On macOS, this only returns correct values when stdout is not redirected.
const tput = () => {
try {
// `tput` requires the `TERM` environment variable to be set.
const columns = exec('tput', ['cols'], {env: {TERM: 'dumb', ...process.env}});
const rows = exec('tput', ['lines'], {env: {TERM: 'dumb', ...process.env}});
if (columns && rows) {
return createIfNotDefault(columns, rows);
}
} catch {}
};
// Only exists on Linux.
const resize = () => {
// `resize` is preferred as it works even when all file descriptors are redirected
// https://linux.die.net/man/1/resize
try {
const size = exec('resize', ['-u']).match(/\d+/g);
if (size.length === 2) {
return createIfNotDefault(size[0], size[1]);
}
} catch {}
};