Skip to content

Commit

Permalink
Fix string formatter handling of log symbols for non-Unicode termin…
Browse files Browse the repository at this point in the history
…als (#7981)
  • Loading branch information
Mouvedia committed Sep 3, 2024
1 parent 6e350f2 commit 53b342f
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-cameras-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": patch
---

Fixed: `string` formatter handling of log symbols for non-Unicode terminals
28 changes: 28 additions & 0 deletions lib/formatters/__tests__/stringFormatter.test.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import process from 'node:process';

import stripAnsi from 'strip-ansi';
import { stripIndent } from 'common-tags';

import { getCleanFormatterOutput } from '../../testUtils/getCleanOutput.mjs';
import isUnicodeSupported from '../../utils/isUnicodeSupported.mjs';
import stringFormatter from '../stringFormatter.mjs';

describe('stringFormatter', () => {
Expand Down Expand Up @@ -57,6 +59,32 @@ path/to/file.css
× 1 problem (1 error, 0 warnings)`);
});

it('outputs symbols depending on the unicode support', () => {
const results = [
{
source: 'path/to/file.css',
warnings: [
{
line: 1,
column: 1,
rule: 'bar',
severity: 'error',
text: 'Unexpected foo',
},
],
},
];

const errorSymbol = isUnicodeSupported() ? '✖' : '×';
const output = stripAnsi(stringFormatter(results, { ruleMetadata: {} })).trim();

expect(output).toBe(stripIndent`
path/to/file.css
1:1 ${errorSymbol} Unexpected foo bar
${errorSymbol} 1 problem (1 error, 0 warnings)`);
});

it('outputs fixable error and warning counts', () => {
const results = [
{
Expand Down
15 changes: 9 additions & 6 deletions lib/formatters/stringFormatter.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const stringWidth = require('string-width');
const table = require('table');
const validateTypes = require('../utils/validateTypes.cjs');
const calcSeverityCounts = require('./calcSeverityCounts.cjs');
const isUnicodeSupported = require('../utils/isUnicodeSupported.cjs');
const pluralize = require('../utils/pluralize.cjs');
const preprocessWarnings = require('./preprocessWarnings.cjs');
const terminalLink = require('./terminalLink.cjs');
Expand All @@ -22,22 +23,24 @@ const MARGIN_WIDTHS = 9;
* @param {string} s
* @returns {string}
*/
function nope(s) {
function identity(s) {
return s;
}

const levelColors = {
info: blue,
warning: yellow,
error: red,
success: nope,
success: identity,
};

const supportsUnicode = isUnicodeSupported();

const symbols = {
info: blue('ℹ'),
warning: yellow('⚠'),
error: red('✖'),
success: green('✔'),
info: blue(supportsUnicode ? 'ℹ' : 'i'),
warning: yellow(supportsUnicode ? '⚠' : '‼'),
error: red(supportsUnicode ? '✖' : '),
success: green(supportsUnicode ? '✔' : '√'),
};

/**
Expand Down
15 changes: 9 additions & 6 deletions lib/formatters/stringFormatter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import table from 'table';

import { assertNumber } from '../utils/validateTypes.mjs';
import calcSeverityCounts from './calcSeverityCounts.mjs';
import isUnicodeSupported from '../utils/isUnicodeSupported.mjs';
import pluralize from '../utils/pluralize.mjs';
import preprocessWarnings from './preprocessWarnings.mjs';
import terminalLink from './terminalLink.mjs';
Expand All @@ -20,22 +21,24 @@ const MARGIN_WIDTHS = 9;
* @param {string} s
* @returns {string}
*/
function nope(s) {
function identity(s) {
return s;
}

const levelColors = {
info: blue,
warning: yellow,
error: red,
success: nope,
success: identity,
};

const supportsUnicode = isUnicodeSupported();

const symbols = {
info: blue('ℹ'),
warning: yellow('⚠'),
error: red('✖'),
success: green('✔'),
info: blue(supportsUnicode ? 'ℹ' : 'i'),
warning: yellow(supportsUnicode ? '⚠' : '‼'),
error: red(supportsUnicode ? '✖' : '),
success: green(supportsUnicode ? '✔' : '√'),
};

/**
Expand Down
32 changes: 32 additions & 0 deletions lib/utils/isUnicodeSupported.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// NOTICE: This file is generated by Rollup. To modify it,
// please instead edit the ESM counterpart and rebuild with Rollup (npm run build).
'use strict';

const process = require('node:process');

/**
* Originally copied from https://github.com/sindresorhus/is-unicode-supported/blob/506f27260df3636555714bf10ed40ab9e6a6c96e/index.js
* @version 2.0.0
* @summary Detect whether the terminal supports Unicode
* @see https://github.com/sindresorhus/is-unicode-supported/pull/1#issuecomment-827321546
* @see microsoft/terminal#13680
*/
function isUnicodeSupported() {
if (process.platform !== 'win32') {
return process.env.TERM !== 'linux'; // Linux console (kernel)
}

return (
Boolean(process.env.WT_SESSION) || // Windows Terminal
Boolean(process.env.TERMINUS_SUBLIME) || // Terminus (<0.2.27)
process.env.ConEmuTask === '{cmd::Cmder}' || // ConEmu and cmder
process.env.TERM_PROGRAM === 'Terminus-Sublime' ||
process.env.TERM_PROGRAM === 'vscode' ||
process.env.TERM === 'xterm-256color' ||
process.env.TERM === 'alacritty' ||
process.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm' ||
process.env.TERM?.startsWith('rxvt-unicode') // fork of rxvt
);
}

module.exports = isUnicodeSupported;
26 changes: 26 additions & 0 deletions lib/utils/isUnicodeSupported.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import process from 'node:process';

/**
* Originally copied from https://github.com/sindresorhus/is-unicode-supported/blob/506f27260df3636555714bf10ed40ab9e6a6c96e/index.js
* @version 2.0.0
* @summary Detect whether the terminal supports Unicode
* @see https://github.com/sindresorhus/is-unicode-supported/pull/1#issuecomment-827321546
* @see microsoft/terminal#13680
*/
export default function isUnicodeSupported() {
if (process.platform !== 'win32') {
return process.env.TERM !== 'linux'; // Linux console (kernel)
}

return (
Boolean(process.env.WT_SESSION) || // Windows Terminal
Boolean(process.env.TERMINUS_SUBLIME) || // Terminus (<0.2.27)
process.env.ConEmuTask === '{cmd::Cmder}' || // ConEmu and cmder
process.env.TERM_PROGRAM === 'Terminus-Sublime' ||
process.env.TERM_PROGRAM === 'vscode' ||
process.env.TERM === 'xterm-256color' ||
process.env.TERM === 'alacritty' ||
process.env.TERMINAL_EMULATOR === 'JetBrains-JediTerm' ||
process.env.TERM?.startsWith('rxvt-unicode') // fork of rxvt
);
}

0 comments on commit 53b342f

Please sign in to comment.