1'use strict'; 2const path = require('path'); 3const execa = require('execa'); 4 5const create = (columns, rows) => ({ 6 columns: parseInt(columns, 10), 7 rows: parseInt(rows, 10) 8}); 9 10module.exports = () => { 11 const env = process.env; 12 const stdout = process.stdout; 13 const stderr = process.stderr; 14 15 if (stdout && stdout.columns && stdout.rows) { 16 return create(stdout.columns, stdout.rows); 17 } 18 19 if (stderr && stderr.columns && stderr.rows) { 20 return create(stderr.columns, stderr.rows); 21 } 22 23 // These values are static, so not the first choice 24 if (env.COLUMNS && env.LINES) { 25 return create(env.COLUMNS, env.LINES); 26 } 27 28 if (process.platform === 'win32') { 29 try { 30 // Binary: https://github.com/sindresorhus/win-term-size 31 const size = execa.sync(path.join(__dirname, 'vendor/windows/term-size.exe')).stdout.split(/\r?\n/); 32 33 if (size.length === 2) { 34 return create(size[0], size[1]); 35 } 36 } catch (err) {} 37 } else { 38 if (process.platform === 'darwin') { 39 try { 40 // Binary: https://github.com/sindresorhus/macos-term-size 41 const size = execa.shellSync(path.join(__dirname, 'vendor/macos/term-size')).stdout.split(/\r?\n/); 42 43 if (size.length === 2) { 44 return create(size[0], size[1]); 45 } 46 } catch (err) {} 47 } 48 49 // `resize` is preferred as it works even when all file descriptors are redirected 50 // https://linux.die.net/man/1/resize 51 try { 52 const size = execa.sync('resize', ['-u']).stdout.match(/\d+/g); 53 54 if (size.length === 2) { 55 return create(size[0], size[1]); 56 } 57 } catch (err) {} 58 59 try { 60 const columns = execa.sync('tput', ['cols']).stdout; 61 const rows = execa.sync('tput', ['lines']).stdout; 62 63 if (columns && rows) { 64 return create(columns, rows); 65 } 66 } catch (err) {} 67 } 68 69 return create(80, 24); 70}; 71