Merge branch 'xtermjs:master' into master

This commit is contained in:
Svante Boberg
2022-08-04 22:05:07 +02:00
committed by GitHub
15 changed files with 82 additions and 122 deletions
+1 -1
View File
@@ -21,6 +21,6 @@
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+1 -1
View File
@@ -22,6 +22,6 @@
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+1 -1
View File
@@ -21,6 +21,6 @@
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+1 -1
View File
@@ -42,6 +42,6 @@
"yauzl": "^2.10.0"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+3 -12
View File
@@ -3,8 +3,7 @@
* @license MIT
*/
import { FontList } from 'font-finder';
import { Font, loadBuffer, loadFile } from 'font-ligatures';
import { Font, loadBuffer } from 'font-ligatures';
import parse from './parse';
@@ -24,7 +23,7 @@ interface IFontAccessNavigator {
};
}
let fontsPromise: Promise<FontList | Record<string, IFontMetadata[]>> | undefined = undefined;
let fontsPromise: Promise<Record<string, IFontMetadata[]>> | undefined = undefined;
/**
* Loads the font ligature wrapper for the specified font family if it could be
@@ -81,14 +80,6 @@ export default async function load(fontFamily: string, cacheSize: number): Promi
console.error(err.name, err.message);
}
}
// Node environment or no font access API
else {
try {
fontsPromise = (await import('font-finder')).list();
} catch (err) {
// No-op
}
}
if (!fontsPromise) {
fontsPromise = Promise.resolve({});
}
@@ -110,7 +101,7 @@ export default async function load(fontFamily: string, cacheSize: number): Promi
const buffer = await bytes.arrayBuffer();
return loadBuffer(buffer, { cacheSize });
}
return await loadFile(font.path, { cacheSize });
return undefined;
}
}
@@ -69,76 +69,6 @@ describe('xterm-addon-ligatures', () => {
assert.deepEqual(term.joiner!(input), []);
});
it('returns the correct set of ranges once the font has loaded', done => {
assert.deepEqual(term.joiner!(input), []);
onRefresh.callsFake(() => {
assert.deepEqual(term.joiner!(input), [[2, 4], [7, 10]]);
done();
});
});
it('handles quoted font names', done => {
term.options.fontFamily = '"Fira Code", monospace';
assert.deepEqual(term.joiner!(input), []);
onRefresh.callsFake(() => {
assert.deepEqual(term.joiner!(input), [[2, 4], [7, 10]]);
done();
});
});
it('falls back to later fonts if earlier ones are not present', done => {
term.options.fontFamily = 'notinstalled, Fira Code, monospace';
assert.deepEqual(term.joiner!(input), []);
onRefresh.callsFake(() => {
assert.deepEqual(term.joiner!(input), [[2, 4], [7, 10]]);
done();
});
});
it('uses the current font value', done => {
// The first three calls are all synchronous so that we don't allow time for
// any fonts to load while we're switching things around
term.options.fontFamily = 'Fira Code';
assert.deepEqual(term.joiner!(input), []);
term.options.fontFamily = 'notinstalled';
assert.deepEqual(term.joiner!(input), []);
term.options.fontFamily = 'Iosevka';
assert.deepEqual(term.joiner!(input), []);
onRefresh.callsFake(() => {
assert.deepEqual(term.joiner!(input), [[2, 4]]);
// And switch it back to Fira Code for good measure
term.options.fontFamily = 'Fira Code';
// At this point, we haven't loaded the new font, so the result reverts
// back to empty until that happens
assert.deepEqual(term.joiner!(input), []);
onRefresh.callsFake(() => {
assert.deepEqual(term.joiner!(input), [[2, 4], [7, 10]]);
done();
});
});
});
it('allows multiple terminal instances that use different fonts', done => {
const onRefresh2 = sinon.stub();
const term2 = new MockTerminal(onRefresh2);
term2.options.fontFamily = 'Iosevka';
ligatureSupport.enableLigatures(term2 as any);
assert.deepEqual(term.joiner!(input), []);
onRefresh.callsFake(() => {
assert.deepEqual(term.joiner!(input), [[2, 4], [7, 10]]);
assert.deepEqual(term2.joiner!(input), []);
onRefresh2.callsFake(() => {
assert.deepEqual(term2.joiner!(input), [[2, 4]]);
assert.deepEqual(term.joiner!(input), [[2, 4], [7, 10]]);
done();
});
});
});
it('fails if it finds but cannot load the font', async () => {
term.options.fontFamily = 'Nonexistant Font, monospace';
assert.deepEqual(term.joiner!(input), []);
+1 -1
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import { Terminal } from 'xterm';
import type { Terminal } from 'xterm';
import { Font } from 'font-ligatures';
import load from './font';
@@ -11,7 +11,6 @@ const mainFile = 'xterm-addon-ligatures.js';
module.exports = {
entry: `./out/${addonName}.js`,
devtool: 'source-map',
target: 'electron-renderer',
module: {
rules: [
{
@@ -30,18 +29,19 @@ module.exports = {
},
mode: 'production',
externals: {
'font-finder': 'font-finder',
'fs': 'fs',
'path': 'path',
'stream': 'stream',
'os': 'os',
'util': 'util'
},
resolve: {
// The ligature modules contains fallbacks for node environments, we never want to browserify them
fallback: {
stream: false,
util: false,
fs: false,
os: false,
path: false
path: false,
stream: false,
util: false
}
}
};
+1 -1
View File
@@ -21,6 +21,6 @@
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+1 -1
View File
@@ -24,6 +24,6 @@
"benchmark-eval": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json --eval out-benchmark/benchmark/*benchmark.js"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+1 -1
View File
@@ -21,6 +21,6 @@
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+1 -1
View File
@@ -21,6 +21,6 @@
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+1 -1
View File
@@ -22,6 +22,6 @@
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^4.0.0"
"xterm": "^5.0.0"
}
}
+62 -24
View File
@@ -82,7 +82,7 @@ interface IDemoAddon<T extends AddonType> {
never;
}
const addons: { [T in AddonType]: IDemoAddon<T>} = {
const addons: { [T in AddonType]: IDemoAddon<T> } = {
attach: { name: 'attach', ctor: AttachAddon, canChange: false },
canvas: { name: 'canvas', ctor: CanvasAddon, canChange: true },
fit: { name: 'fit', ctor: FitAddon, canChange: false },
@@ -188,6 +188,7 @@ if (document.location.pathname === '/test') {
document.getElementById('load-test').addEventListener('click', loadTest);
document.getElementById('powerline-symbol-test').addEventListener('click', powerlineSymbolTest);
document.getElementById('underline-test').addEventListener('click', underlineTest);
document.getElementById('ansi-colors').addEventListener('click', ansiColorsTest);
document.getElementById('add-decoration').addEventListener('click', addDecoration);
document.getElementById('add-overview-ruler').addEventListener('click', addOverviewRuler);
}
@@ -230,18 +231,23 @@ function createTerminal(): void {
const rows = size.rows;
const url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows;
fetch(url, {method: 'POST'});
fetch(url, { method: 'POST' });
});
protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
term.open(terminalContainer);
addons.fit.instance!.fit();
typedTerm.loadAddon(addons.webgl.instance);
setTimeout(() => {
addTextureAtlas(addons.webgl.instance.textureAtlas);
addons.webgl.instance.onChangeTextureAtlas(e => addTextureAtlas(e));
}, 0);
try {
typedTerm.loadAddon(addons.webgl.instance);
setTimeout(() => {
addTextureAtlas(addons.webgl.instance.textureAtlas);
addons.webgl.instance.onChangeTextureAtlas(e => addTextureAtlas(e));
}, 0);
}
catch {
addons.webgl.instance = undefined;
}
term.focus();
addDomListener(paddingElement, 'change', setPadding);
@@ -270,7 +276,7 @@ function createTerminal(): void {
// Set terminal size again to set the specific dimensions on the demo
updateTerminalSize();
fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then((res) => {
fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, { method: 'POST' }).then((res) => {
res.text().then((processId) => {
pid = processId;
socketURL += processId;
@@ -315,7 +321,7 @@ function runFakeTerminal(): void {
if (ev.keyCode === 13) {
term.prompt();
} else if (ev.keyCode === 8) {
// Do not delete the prompt
// Do not delete the prompt
if (term._core.buffer.x > 2) {
term.write('\b \b');
}
@@ -501,13 +507,20 @@ function initAddons(term: TerminalType): void {
addDomListener(checkbox, 'change', () => {
if (checkbox.checked) {
addon.instance = new addon.ctor();
term.loadAddon(addon.instance);
if (name === 'webgl') {
(addon.instance as WebglAddon).onChangeTextureAtlas(e => addTextureAtlas(e));
} else if (name === 'unicode11') {
term.unicode.activeVersion = '11';
} else if (name === 'search') {
addon.instance.onDidChangeResults(e => updateFindResults(e));
try {
term.loadAddon(addon.instance);
if (name === 'webgl') {
(addon.instance as WebglAddon).onChangeTextureAtlas(e => addTextureAtlas(e));
} else if (name === 'unicode11') {
term.unicode.activeVersion = '11';
} else if (name === 'search') {
addon.instance.onDidChangeResults(e => updateFindResults(e));
}
}
catch {
addon.instance = undefined;
checkbox.checked = false;
checkbox.disabled = true;
}
} else {
if (name === 'webgl') {
@@ -789,6 +802,31 @@ function underlineTest() {
term.write('\x1b[0m\n\r');
}
function ansiColorsTest() {
term.writeln(`\x1b[0m\n\n\rStandard colors: Bright colors:`);
for (let i = 0; i < 16; i++) {
term.write(`\x1b[48;5;${i}m ${i.toString().padEnd(2, ' ').padStart(3, ' ')} \x1b[0m`);
}
term.writeln(`\x1b[0m\n\n\rColors 17-231 from 256 palette:`);
for (let i = 0; i < 6; i++) {
const startId = 16 + i * 36;
const endId = 16 + (i + 1) * 36 - 1;
term.write(`${startId.toString().padStart(3, ' ')}-${endId.toString().padStart(3, ' ')} `);
for (let j = 0; j < 36; j++) {
const id = 16 + i * 36 + j;
term.write(`\x1b[48;5;${id}m${(id % 10).toString().padStart(2, ' ')}\x1b[0m`);
}
term.write(`\r\n`);
}
term.writeln(`\x1b[0m\n\rGreyscale from 256 palette:`);
term.write('232-255 ');
for (let i = 232; i < 256; i++) {
term.write(`\x1b[48;5;${i}m ${(i % 10)} \x1b[0m`);
}
}
function addDecoration() {
term.options['overviewRulerWidth'] = 15;
const marker = term.registerMarker(1);
@@ -806,13 +844,13 @@ function addDecoration() {
function addOverviewRuler() {
term.options['overviewRulerWidth'] = 15;
term.registerDecoration({marker: term.registerMarker(1), overviewRulerOptions: { color: '#ef2929' }});
term.registerDecoration({marker: term.registerMarker(3), overviewRulerOptions: { color: '#8ae234' }});
term.registerDecoration({marker: term.registerMarker(5), overviewRulerOptions: { color: '#729fcf' }});
term.registerDecoration({marker: term.registerMarker(7), overviewRulerOptions: { color: '#ef2929', position: 'left' }});
term.registerDecoration({marker: term.registerMarker(7), overviewRulerOptions: { color: '#8ae234', position: 'center' }});
term.registerDecoration({marker: term.registerMarker(7), overviewRulerOptions: { color: '#729fcf', position: 'right' }});
term.registerDecoration({marker: term.registerMarker(10), overviewRulerOptions: { color: '#8ae234', position: 'center' }});
term.registerDecoration({marker: term.registerMarker(10), overviewRulerOptions: { color: '#ffffff80', position: 'full' }});
term.registerDecoration({ marker: term.registerMarker(1), overviewRulerOptions: { color: '#ef2929' } });
term.registerDecoration({ marker: term.registerMarker(3), overviewRulerOptions: { color: '#8ae234' } });
term.registerDecoration({ marker: term.registerMarker(5), overviewRulerOptions: { color: '#729fcf' } });
term.registerDecoration({ marker: term.registerMarker(7), overviewRulerOptions: { color: '#ef2929', position: 'left' } });
term.registerDecoration({ marker: term.registerMarker(7), overviewRulerOptions: { color: '#8ae234', position: 'center' } });
term.registerDecoration({ marker: term.registerMarker(7), overviewRulerOptions: { color: '#729fcf', position: 'right' } });
term.registerDecoration({ marker: term.registerMarker(10), overviewRulerOptions: { color: '#8ae234', position: 'center' } });
term.registerDecoration({ marker: term.registerMarker(10), overviewRulerOptions: { color: '#ffffff80', position: 'full' } });
}
+1
View File
@@ -78,6 +78,7 @@
<dd><button id="custom-glyph" title="Write custom box drawing and block element characters to the terminal">Test custom glyphs</button></dd>
<dd><button id="powerline-symbol-test" title="Write powerline symbol characters to the terminal (\ue0a0+)">Powerline symbol test</button></dd>
<dd><button id="underline-test" title="Write text with Kitty's extended underline sequences">Underline test</button></dd>
<dd><button id="ansi-colors" title="Write a wide range of ansi colors">Ansi colors test</button></dd>
<dt>Decorations</dt>
<dd><button id="add-decoration" title="Add a decoration to the terminal">Decoration</button></dd>