Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/node/terminalEncoding.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
/**
7
* This code is also used by standalone cli's. Avoid adding dependencies to keep the size of the cli small.
8
*/
9
import { exec } from 'child_process';
10
import { isWindows } from '../common/platform.js';
11
12
const windowsTerminalEncodings = {
13
'437': 'cp437', // United States
14
'850': 'cp850', // Multilingual(Latin I)
15
'852': 'cp852', // Slavic(Latin II)
16
'855': 'cp855', // Cyrillic(Russian)
17
'857': 'cp857', // Turkish
18
'860': 'cp860', // Portuguese
19
'861': 'cp861', // Icelandic
20
'863': 'cp863', // Canadian - French
21
'865': 'cp865', // Nordic
22
'866': 'cp866', // Russian
23
'869': 'cp869', // Modern Greek
24
'936': 'cp936', // Simplified Chinese
25
'1252': 'cp1252' // West European Latin
26
};
27
28
function toIconvLiteEncoding(encodingName: string): string {
29
const normalizedEncodingName = encodingName.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
30
const mapped = JSCHARDET_TO_ICONV_ENCODINGS[normalizedEncodingName];
31
32
return mapped || normalizedEncodingName;
33
}
34
35
const JSCHARDET_TO_ICONV_ENCODINGS: { [name: string]: string } = {
36
'ibm866': 'cp866',
37
'big5': 'cp950'
38
};
39
40
const UTF8 = 'utf8';
41
42
export async function resolveTerminalEncoding(verbose?: boolean): Promise<string> {
43
let rawEncodingPromise: Promise<string | undefined>;
44
45
// Support a global environment variable to win over other mechanics
46
const cliEncodingEnv = process.env['VSCODE_CLI_ENCODING'];
47
if (cliEncodingEnv) {
48
if (verbose) {
49
console.log(`Found VSCODE_CLI_ENCODING variable: ${cliEncodingEnv}`);
50
}
51
52
rawEncodingPromise = Promise.resolve(cliEncodingEnv);
53
}
54
55
// Windows: educated guess
56
else if (isWindows) {
57
rawEncodingPromise = new Promise<string | undefined>(resolve => {
58
if (verbose) {
59
console.log('Running "chcp" to detect terminal encoding...');
60
}
61
62
exec('chcp', (err, stdout, stderr) => {
63
if (stdout) {
64
if (verbose) {
65
console.log(`Output from "chcp" command is: ${stdout}`);
66
}
67
68
const windowsTerminalEncodingKeys = Object.keys(windowsTerminalEncodings) as Array<keyof typeof windowsTerminalEncodings>;
69
for (const key of windowsTerminalEncodingKeys) {
70
if (stdout.indexOf(key) >= 0) {
71
return resolve(windowsTerminalEncodings[key]);
72
}
73
}
74
}
75
76
return resolve(undefined);
77
});
78
});
79
}
80
// Linux/Mac: use "locale charmap" command
81
else {
82
rawEncodingPromise = new Promise<string>(resolve => {
83
if (verbose) {
84
console.log('Running "locale charmap" to detect terminal encoding...');
85
}
86
87
exec('locale charmap', (err, stdout, stderr) => resolve(stdout));
88
});
89
}
90
91
const rawEncoding = await rawEncodingPromise;
92
if (verbose) {
93
console.log(`Detected raw terminal encoding: ${rawEncoding}`);
94
}
95
96
if (!rawEncoding || rawEncoding.toLowerCase() === 'utf-8' || rawEncoding.toLowerCase() === UTF8) {
97
return UTF8;
98
}
99
100
return toIconvLiteEncoding(rawEncoding);
101
}
102
103