├── .github ├── FUNDING.yml └── workflows │ └── node.js.yml ├── .gitignore ├── .prettierrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.d.ts ├── index.js ├── package-lock.json ├── package.json └── test └── index.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: knownasilya 4 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [master] 9 | pull_request: 10 | branches: [master] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [12.x, 14.x, 16.x, 18.x, 20.x] 19 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 20 | 21 | steps: 22 | - uses: actions/checkout@v3 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v3 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | cache: 'npm' 28 | - run: npm ci 29 | - run: npm run build --if-present 30 | - run: npm test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | *.log 4 | *.swp 5 | .DS_Store 6 | .nyc_output -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## [4.1.0](https://github.com/knownasilya/cli-width/compare/v4.0.0...v4.1.0) (2023-08-05) 6 | 7 | 8 | ### Features 9 | 10 | * ts types and test against node 18 and 20 ([bc2884f](https://github.com/knownasilya/cli-width/commit/bc2884f5346f5465715327970ebca1bfa4bfe807)) 11 | 12 | ## [4.0.0](https://github.com/knownasilya/cli-width/compare/v3.0.0...v4.0.0) (2022-03-29) 13 | 14 | 15 | ### ⚠ BREAKING CHANGES 16 | 17 | * drop support for node < 12 18 | 19 | ### Bug Fixes 20 | 21 | * drop support for node < 12 ([50fcd88](https://github.com/knownasilya/cli-width/commit/50fcd8850eb62465b5e1a06df9d5a9a07b6c965c)) 22 | 23 | ## [3.0.0](https://github.com/knownasilya/cli-width/compare/v2.2.1...v3.0.0) (2020-04-14) 24 | 25 | 26 | ### ⚠ BREAKING CHANGES 27 | 28 | * Dropped support for node < 10 29 | * Dropped support for IOjs 30 | 31 | ### Bug Fixes 32 | 33 | * drop node < 10 ([e42f6a7](https://github.com/knownasilya/cli-width/commit/e42f6a756ea47f85f736e6de2d7364d4d60a7dfe)) 34 | 35 | ### [2.2.1](https://github.com/knownasilya/cli-width/compare/v2.2.0...v2.2.1) (2020-04-14) 36 | 37 | 38 | ### Bug Fixes 39 | 40 | * add more node versions to travis ([f7bc148](https://github.com/knownasilya/cli-width/commit/f7bc14846c2547769681bfc56afed3d0b04aa11e)) 41 | * Reduce nesting in index.js and add package-lock.json ([#14](https://github.com/knownasilya/cli-width/issues/14)) ([92d8d6b](https://github.com/knownasilya/cli-width/commit/92d8d6b8e4ce3702b12356c5427723005fccf9b8)) 42 | * update deprecated deps and change coverage script ([db06065](https://github.com/knownasilya/cli-width/commit/db0606592f8347eb9f35abdf87c570e1d731463c)) 43 | 44 | 45 | # [2.2.0](https://github.com/knownasilya/cli-width/compare/v2.1.1...v2.2.0) (2017-08-22) 46 | 47 | 48 | ### Features 49 | 50 | * return default if env is 0 ([1833baf](https://github.com/knownasilya/cli-width/commit/1833baf)), closes [#9](https://github.com/knownasilya/cli-width/issues/9) 51 | 52 | 53 | 54 | 55 | ## [2.1.1](https://github.com/knownasilya/cli-width/compare/v2.1.0...v2.1.1) (2017-08-22) 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Ilya Radchenko 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cli-width 2 | 3 | Get stdout window width, with four fallbacks, `tty`, `output.columns`, a custom environment variable and then a default. 4 | 5 | [![npm version](https://badge.fury.io/js/cli-width.svg)](http://badge.fury.io/js/cli-width) 6 | [![Coverage Status](https://coveralls.io/repos/knownasilya/cli-width/badge.svg?branch=master&service=github)](https://coveralls.io/github/knownasilya/cli-width?branch=master) 7 | 8 | Tested against Node v12 to v20. 9 | Includes TypeScript types. 10 | 11 | ## Usage 12 | 13 | ``` 14 | npm install --save cli-width 15 | ``` 16 | 17 | ```js 18 | const cliWidth = require('cli-width'); 19 | 20 | cliWidth(); // maybe 204 :) 21 | ``` 22 | 23 | You can also set the `CLI_WIDTH` environment variable. 24 | 25 | If none of the methods are supported, and the environment variable isn't set, 26 | the default width value is going to be `0`, that can be changed using the configurable `options`. 27 | 28 | ## API 29 | 30 | ### cliWidth([options]) 31 | 32 | `cliWidth` can be configured using an `options` parameter, the possible properties are: 33 | 34 | - **defaultWidth**\ Defines a default value to be used if none of the methods are available, defaults to `0` 35 | - **output**\ A stream to be used to read width values from, defaults to `process.stdout` 36 | - **tty**\ TTY module to try to read width from as a fallback, defaults to `require('tty')` 37 | 38 | ### Examples 39 | 40 | Defining both a default width value and a stream output to try to read from: 41 | 42 | ```js 43 | const cliWidth = require('cli-width'); 44 | const ttys = require('ttys'); 45 | 46 | cliWidth({ 47 | defaultWidth: 80, 48 | output: ttys.output, 49 | }); 50 | ``` 51 | 52 | Defines a different tty module to read width from: 53 | 54 | ```js 55 | const cliWidth = require('cli-width'); 56 | const ttys = require('ttys'); 57 | 58 | cliWidth({ 59 | tty: ttys, 60 | }); 61 | ``` 62 | 63 | ## Tests 64 | 65 | ```bash 66 | npm install 67 | npm test 68 | ``` 69 | 70 | Coverage can be generated with `npm run coverage`. 71 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for cli-width 4.0 2 | /// 3 | 4 | import { Stream } from 'stream'; 5 | import tty = require('tty'); 6 | 7 | declare function cliWidth(options?: { 8 | defaultWidth?: number; 9 | output?: Stream; 10 | tty?: typeof tty; 11 | }): number; 12 | 13 | export = cliWidth; 14 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = cliWidth; 4 | 5 | function normalizeOpts(options) { 6 | const defaultOpts = { 7 | defaultWidth: 0, 8 | output: process.stdout, 9 | tty: require('tty'), 10 | }; 11 | 12 | if (!options) { 13 | return defaultOpts; 14 | } 15 | 16 | Object.keys(defaultOpts).forEach(function (key) { 17 | if (!options[key]) { 18 | options[key] = defaultOpts[key]; 19 | } 20 | }); 21 | 22 | return options; 23 | } 24 | 25 | function cliWidth(options) { 26 | const opts = normalizeOpts(options); 27 | 28 | if (opts.output.getWindowSize) { 29 | return opts.output.getWindowSize()[0] || opts.defaultWidth; 30 | } 31 | 32 | if (opts.tty.getWindowSize) { 33 | return opts.tty.getWindowSize()[1] || opts.defaultWidth; 34 | } 35 | 36 | if (opts.output.columns) { 37 | return opts.output.columns; 38 | } 39 | 40 | if (process.env.CLI_WIDTH) { 41 | const width = parseInt(process.env.CLI_WIDTH, 10); 42 | 43 | if (!isNaN(width) && width !== 0) { 44 | return width; 45 | } 46 | } 47 | 48 | return opts.defaultWidth; 49 | } 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cli-width", 3 | "version": "4.1.0", 4 | "description": "Get stdout window width, with two fallbacks, tty and then a default.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test | tspec", 8 | "coverage": "nyc node test | tspec", 9 | "coveralls": "npm run coverage -s && coveralls < coverage/lcov.info", 10 | "release": "standard-version" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git@github.com:knownasilya/cli-width.git" 15 | }, 16 | "author": "Ilya Radchenko ", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/knownasilya/cli-width/issues" 20 | }, 21 | "homepage": "https://github.com/knownasilya/cli-width", 22 | "engines": { 23 | "node": ">= 12" 24 | }, 25 | "devDependencies": { 26 | "coveralls": "^3.1.1", 27 | "nyc": "^15.1.0", 28 | "standard-version": "^9.3.2", 29 | "tap-spec": "^5.0.0", 30 | "tape": "^5.5.2" 31 | }, 32 | "volta": { 33 | "node": "12.22.11", 34 | "npm": "8.5.5" 35 | }, 36 | "files": [ 37 | "index.js", 38 | "index.d.ts" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var tty = require('tty'); 4 | var test = require('tape'); 5 | var lib = require('../'); 6 | 7 | 8 | test('uses process.stdout.getWindowSize', function (t) { 9 | // mock stdout.getWindowSize 10 | process.stdout.getWindowSize = function () { 11 | return [100]; 12 | }; 13 | 14 | t.equal(lib(), 100, 'equal to mocked, 100'); 15 | t.end(); 16 | }); 17 | 18 | test('uses defaultWidth if process.stdout.getWindowSize reports width of 0', function (t) { 19 | process.stdout.getWindowSize = function () { 20 | return [0]; 21 | }; 22 | 23 | t.equal(lib({ defaultWidth: 10 }), 10, 'equal to mocked, 10'); 24 | t.end(); 25 | }) 26 | 27 | test('uses tty.getWindowSize', function (t) { 28 | process.stdout.getWindowSize = undefined; 29 | tty.getWindowSize = function () { 30 | return [3, 5]; 31 | }; 32 | 33 | t.equal(lib(), 5, 'equal to mocked, 5'); 34 | t.end(); 35 | }); 36 | 37 | test('uses default if tty.getWindowSize reports width of 0', function (t) { 38 | process.stdout.getWindowSize = undefined; 39 | tty.getWindowSize = function () { 40 | return [0, 0]; 41 | }; 42 | 43 | t.equal(lib({ defaultWidth: 10 }), 10, 'equal to mocked, 10'); 44 | t.end(); 45 | }) 46 | 47 | test('uses custom env var', function (t) { 48 | var oldWidth = process.stdout.columns; 49 | process.stdout.columns = undefined; 50 | tty.getWindowSize = undefined; 51 | process.env.CLI_WIDTH = 30; 52 | 53 | t.equal(lib(), 30, 'equal to mocked, 30'); 54 | 55 | delete process.env.CLI_WIDTH; 56 | process.stdout.columns = oldWidth; 57 | t.end(); 58 | }); 59 | 60 | test('uses default if env var is not a number', function (t) { 61 | var oldWidth = process.stdout.columns; 62 | process.stdout.columns = undefined; 63 | process.env.CLI_WIDTH = 'foo'; 64 | 65 | t.equal(lib(), 0, 'default unset value, 0'); 66 | 67 | delete process.env.CLI_WIDTH; 68 | process.stdout.columns = oldWidth; 69 | t.end(); 70 | }); 71 | 72 | test('uses default', function (t) { 73 | var oldWidth = process.stdout.columns; 74 | process.stdout.columns = undefined; 75 | tty.getWindowSize = undefined; 76 | 77 | t.equal(lib(), 0, 'default unset value, 0'); 78 | 79 | process.stdout.columns = oldWidth; 80 | t.end(); 81 | }); 82 | 83 | test('uses overridden default', function (t) { 84 | var oldWidth = process.stdout.columns; 85 | process.stdout.columns = undefined; 86 | 87 | t.equal(lib({ defaultWidth: 10 }), 10, 'user-set defaultWidth value, 10'); 88 | 89 | process.stdout.columns = oldWidth; 90 | t.end(); 91 | }); 92 | 93 | test('uses user-configured output stream', function (t) { 94 | var outputMock = { 95 | getWindowSize: function () { 96 | return [10]; 97 | } 98 | }; 99 | 100 | t.equal(lib({ output: outputMock }), 10, 'user-set output stream, 10'); 101 | 102 | t.end(); 103 | }); 104 | 105 | test('uses user-configured tty', function (t) { 106 | var ttyMock = { 107 | getWindowSize: function () { 108 | return [2, 5]; 109 | } 110 | }; 111 | 112 | t.equal(lib({ tty: ttyMock }), 5, 'user-set tty, 5'); 113 | 114 | t.end(); 115 | }); 116 | 117 | test('uses output.columns', function (t) { 118 | var oldWidth = process.stdout.columns; 119 | process.stdout.columns = 15; 120 | process.stdout.getWindowSize = undefined; 121 | delete process.env.CLI_WIDTH; 122 | 123 | t.equal(lib({ output: process.stdout }), 15, 'user-set output, 15'); 124 | 125 | process.stdout.columns = oldWidth; 126 | t.end(); 127 | }) 128 | --------------------------------------------------------------------------------