Merge pull request #2386 from jerch/extract_vt_features
document VT features in docstrings
This commit is contained in:
@@ -0,0 +1,503 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*
|
||||
* Script to extract vt features documented in docstrings.
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const Mustache = require('mustache');
|
||||
|
||||
/**
|
||||
* regexp to fetch all comments
|
||||
* Fetches all multiline comments and single lines containing '// @vt:'.
|
||||
*/
|
||||
const REX_COMMENTS = /^\s*?[/][*][*]([\s\S]*?)[*][/]|^\s*?\/\/ ([@]vt[:].*?)$/mug;
|
||||
|
||||
/**
|
||||
* regexp to parse the @vt line
|
||||
* expected data - "@vt: <status> <kind> <mnemonic> "<name>" "<sequence>" "<short description>"
|
||||
*/
|
||||
const REX_VT_LINE = /^[@]vt\:\s*(\w+|#\w+|#\w+\[.*?\])\s*(\w+)\s*(\w+)\s*"(.*?)"\s*"(.*?)"\s*"(.*?)".*$/;
|
||||
|
||||
// known vt command types
|
||||
const TYPES = [
|
||||
'C0',
|
||||
'C1',
|
||||
'ESC',
|
||||
'CSI',
|
||||
'DCS',
|
||||
'OSC',
|
||||
'APC',
|
||||
'PM',
|
||||
'SOS'
|
||||
];
|
||||
|
||||
const MARKDOWN_TMPL = `
|
||||
{::options parse_block_html="true" /}
|
||||
|
||||
xterm.js version: {{version}}
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<nav>
|
||||
|
||||
- [General notes](#general-notes)
|
||||
{{#C0.length}}
|
||||
- [C0](#c0)
|
||||
{{/C0.length}}
|
||||
{{#C1.length}}
|
||||
- [C1](#c1)
|
||||
{{/C1.length}}
|
||||
{{#CSI.length}}
|
||||
- [CSI](#csi)
|
||||
{{/CSI.length}}
|
||||
{{#DCS.length}}
|
||||
- [DCS](#dcs)
|
||||
{{/DCS.length}}
|
||||
{{#ESC.length}}
|
||||
- [ESC](#esc)
|
||||
{{/ESC.length}}
|
||||
{{#OSC.length}}
|
||||
- [OSC](#osc)
|
||||
{{/OSC.length}}
|
||||
|
||||
</nav>
|
||||
|
||||
|
||||
## General notes
|
||||
|
||||
This document lists xterm.js' support of terminal sequences. The sequences are grouped by their sequence type:
|
||||
|
||||
- C0: single byte command (7bit control codes, byte range \`\\x00\` .. \`\\x1F\`, \`\\x7F\`)
|
||||
- C1: single byte command (8bit control codes, byte range \`\\x80\` .. \`\\x9F\`)
|
||||
- ESC: sequence starting with \`ESC\` (\`\\x1B\`)
|
||||
- CSI - Control Sequence Introducer: sequence starting with \`ESC [\` (7bit) or CSI (\`\\x9B\`, 8bit)
|
||||
- DCS - Device Control String: sequence starting with \`ESC P\` (7bit) or DCS (\`\\x90\`, 8bit)
|
||||
- OSC - Operating System Command: sequence starting with \`ESC ]\` (7bit) or OSC (\`\\x9D\`, 8bit)
|
||||
|
||||
Application Program Command (APC), Privacy Message (PM) and Start of String (SOS) are recognized but not supported,
|
||||
any sequence of these types will be ignored. They are also not hookable by the API.
|
||||
|
||||
Note that the list only contains sequences implemented in xterm.js' core codebase. Missing sequences are either
|
||||
not supported or unstable/experimental. Furthermore addons or integrations can provide additional custom sequences.
|
||||
|
||||
To denote the sequences the tables use the same abbreviations as xterm does:
|
||||
- \`Ps\`: A single (usually optional) numeric parameter, composed of one or more decimal digits.
|
||||
- \`Pm\`: A multiple numeric parameter composed of any number of single numeric parameters, separated by ; character(s),
|
||||
e.g. \` Ps ; Ps ; ... \`.
|
||||
- \`Pt\`: A text parameter composed of printable characters. Note that for most commands with \`Pt\` only
|
||||
ASCII printables are specified to work. Additionally the parser will let pass any codepoint greater than C1 as printable.
|
||||
|
||||
|
||||
|
||||
{{#C0.length}}
|
||||
## C0
|
||||
|
||||
| Mnemonic | Name | Sequence | Short Description | Support |
|
||||
| -------- | ---- | -------- | ----------------- | ------- |
|
||||
{{#C0}}
|
||||
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{{shortDescription}}} {{#longDescription.length}}_[more](#{{longTarget}}){: .link-details}_{{/longDescription.length}} | {{{status}}} |
|
||||
{{/C0}}
|
||||
|
||||
{{#C0.hasLongDescriptions}}
|
||||
{{#C0}}
|
||||
{{#longDescription.length}}
|
||||
<section class="sequence-details">
|
||||
|
||||
### {{name}}
|
||||
{{#longDescription}}
|
||||
{{{.}}}
|
||||
{{/longDescription}}
|
||||
|
||||
</section>
|
||||
{{/longDescription.length}}
|
||||
{{/C0}}
|
||||
{{/C0.hasLongDescriptions}}
|
||||
|
||||
{{/C0.length}}
|
||||
|
||||
|
||||
{{#C1.length}}
|
||||
## C1
|
||||
|
||||
| Mnemonic | Name | Sequence | Short Description | Support |
|
||||
| -------- | ---- | -------- | ----------------- | ------- |
|
||||
{{#C1}}
|
||||
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{{shortDescription}}} {{#longDescription.length}}_[more](#{{longTarget}}){: .link-details}_{{/longDescription.length}} | {{{status}}} |
|
||||
{{/C1}}
|
||||
|
||||
{{#C1.hasLongDescriptions}}
|
||||
{{#C1}}
|
||||
{{#longDescription.length}}
|
||||
<section class="sequence-details">
|
||||
|
||||
### {{name}}
|
||||
{{#longDescription}}
|
||||
{{{.}}}
|
||||
{{/longDescription}}
|
||||
|
||||
</section>
|
||||
{{/longDescription.length}}
|
||||
{{/C1}}
|
||||
{{/C1.hasLongDescriptions}}
|
||||
|
||||
{{/C1.length}}
|
||||
|
||||
|
||||
{{#CSI.length}}
|
||||
## CSI
|
||||
|
||||
| Mnemonic | Name | Sequence | Short Description | Support |
|
||||
| -------- | ---- | -------- | ----------------- | ------- |
|
||||
{{#CSI}}
|
||||
| {{mnemonic}} | {{name}} | \`\`{{{sequence}}}\`\` | {{{shortDescription}}} {{#longDescription.length}}_[more](#{{longTarget}}){: .link-details}_{{/longDescription.length}} | {{{status}}} |
|
||||
{{/CSI}}
|
||||
|
||||
{{#CSI.hasLongDescriptions}}
|
||||
{{#CSI}}
|
||||
{{#longDescription.length}}
|
||||
<section class="sequence-details">
|
||||
|
||||
### {{name}}
|
||||
{{#longDescription}}
|
||||
{{{.}}}
|
||||
{{/longDescription}}
|
||||
|
||||
</section>
|
||||
{{/longDescription.length}}
|
||||
{{/CSI}}
|
||||
{{/CSI.hasLongDescriptions}}
|
||||
|
||||
{{/CSI.length}}
|
||||
|
||||
|
||||
{{#DCS.length}}
|
||||
## DCS
|
||||
|
||||
| Mnemonic | Name | Sequence | Short Description | Support |
|
||||
| -------- | ---- | -------- | ----------------- | ------- |
|
||||
{{#DCS}}
|
||||
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{{shortDescription}}} {{#longDescription.length}}_[more](#{{longTarget}}){: .link-details}_{{/longDescription.length}} | {{{status}}} |
|
||||
{{/DCS}}
|
||||
|
||||
{{#DCS.hasLongDescriptions}}
|
||||
{{#DCS}}
|
||||
{{#longDescription.length}}
|
||||
<section class="sequence-details">
|
||||
|
||||
### {{name}}
|
||||
{{#longDescription}}
|
||||
{{{.}}}
|
||||
{{/longDescription}}
|
||||
|
||||
</section>
|
||||
{{/longDescription.length}}
|
||||
{{/DCS}}
|
||||
{{/DCS.hasLongDescriptions}}
|
||||
|
||||
{{/DCS.length}}
|
||||
|
||||
|
||||
{{#ESC.length}}
|
||||
## ESC
|
||||
|
||||
| Mnemonic | Name | Sequence | Short Description | Support |
|
||||
| -------- | ---- | -------- | ----------------- | ------- |
|
||||
{{#ESC}}
|
||||
| {{mnemonic}} | {{name}} | \`{{sequence}}\` | {{{shortDescription}}} {{#longDescription.length}}_[more](#{{longTarget}}){: .link-details}_{{/longDescription.length}} | {{{status}}} |
|
||||
{{/ESC}}
|
||||
|
||||
{{#ESC.hasLongDescriptions}}
|
||||
{{#ESC}}
|
||||
{{#longDescription.length}}
|
||||
<section class="sequence-details">
|
||||
|
||||
### {{name}}
|
||||
{{#longDescription}}
|
||||
{{{.}}}
|
||||
{{/longDescription}}
|
||||
|
||||
</section>
|
||||
{{/longDescription.length}}
|
||||
{{/ESC}}
|
||||
{{/ESC.hasLongDescriptions}}
|
||||
|
||||
{{/ESC.length}}
|
||||
|
||||
|
||||
{{#OSC.length}}
|
||||
## OSC
|
||||
|
||||
**Note**: Other than listed in the table, the parser recognizes both ST (ECMA-48) and BEL (xterm) as OSC sequence finalizer.
|
||||
|
||||
| Identifier | Sequence | Short Description | Support |
|
||||
| ---------- | -------- | ----------------- | ------- |
|
||||
{{#OSC}}
|
||||
| {{mnemonic}} | \`{{sequence}}\` | {{{shortDescription}}} {{#longDescription.length}}_[more](#{{longTarget}}){: .link-details}_{{/longDescription.length}} | {{{status}}} |
|
||||
{{/OSC}}
|
||||
|
||||
{{#OSC.hasLongDescriptions}}
|
||||
{{#OSC}}
|
||||
{{#longDescription.length}}
|
||||
<section class="sequence-details">
|
||||
|
||||
### {{name}}
|
||||
{{#longDescription}}
|
||||
{{{.}}}
|
||||
{{/longDescription}}
|
||||
|
||||
</section>
|
||||
{{/longDescription.length}}
|
||||
{{/OSC}}
|
||||
{{/OSC.hasLongDescriptions}}
|
||||
|
||||
{{/OSC.length}}
|
||||
|
||||
<script type="text/javascript">
|
||||
const linkStates = {};
|
||||
|
||||
function hideDetailSections() {
|
||||
for (let section of document.getElementsByClassName('sequence-details')) section.style.display = 'none';
|
||||
}
|
||||
|
||||
function decorateDetailLinks() {
|
||||
for (let link of document.getElementsByClassName('link-details')) {
|
||||
link.addEventListener("click", toggleDetails, false);
|
||||
if (linkStates[link.href] === undefined) {
|
||||
linkStates[link.href] = {open: false, links: [], trElem: null};
|
||||
}
|
||||
linkStates[link.href].links.push(link);
|
||||
}
|
||||
}
|
||||
|
||||
function openDetails(link) {
|
||||
const closestTr = link.closest('tr');
|
||||
if (!closestTr || !closestTr.parentNode) return;
|
||||
const closestSection = document.getElementById(link.href.split('#')[1]).closest('section');
|
||||
if (!closestSection || !closestSection.innerHTML) return;
|
||||
const content = closestSection.innerHTML.split('</h3>')[1];
|
||||
|
||||
const newRow = closestTr.parentNode.insertRow(closestTr.rowIndex);
|
||||
const cell = newRow.insertCell(0);
|
||||
cell.innerHTML = '<div style="font-style: italic">' + content + '</div>';
|
||||
cell.colSpan = closestTr.children.length;
|
||||
const state = linkStates[link.href];
|
||||
state.trElem = newRow;
|
||||
state.open = true;
|
||||
if (link.innerHTML === 'more') link.innerHTML = 'less';
|
||||
}
|
||||
|
||||
function closeDetails(link) {
|
||||
const state = linkStates[link.href];
|
||||
if (state.trElem && state.trElem.rowIndex !== -1) {
|
||||
if (state.trElem.parentNode) state.trElem.parentNode.deleteRow(state.trElem.rowIndex-1); // why -1 here?
|
||||
state.trElem.remove();
|
||||
state.trElem = null;
|
||||
}
|
||||
state.open = false;
|
||||
if (link.innerHTML === 'less') link.innerHTML = 'more';
|
||||
}
|
||||
|
||||
function toggleDetails(ev) {
|
||||
if (!ev.target || !ev.target.href) return;
|
||||
const isOpen = linkStates[ev.target.href].open;
|
||||
if (isOpen === undefined) return;
|
||||
if (isOpen) closeDetails(ev.target);
|
||||
else openDetails(ev.target);
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function load() {
|
||||
hideDetailSections();
|
||||
decorateDetailLinks();
|
||||
}
|
||||
load(); // we are inlined behind all needed data, thus dont wait for onload (avoids flickering)
|
||||
</script>
|
||||
`
|
||||
|
||||
// support status marcos
|
||||
// applied for:
|
||||
// - status field of single @vt line
|
||||
// - all lines in long description
|
||||
const MACRO = [
|
||||
// #Y - supported
|
||||
[/#Y/g, s => '<span title="supported">✓</span>'],
|
||||
// #N - unsupported
|
||||
[/#N/g, s => '<span title="unsupported">✗</span>'],
|
||||
// #P[reason] - partial support with a reason as title
|
||||
[/#P\[(.*?)\]/g, (s, p1) => `<span title="${p1}" style="text-decoration: underline">Partial</span>`],
|
||||
// #B[reason] - supported but broken in a certain way, reason in title
|
||||
[/#B\[(.*?)\]/g, (s, p1) => `<span title="${p1}" style="text-decoration: underline">Broken</span>`]
|
||||
];
|
||||
|
||||
function applyMacros(s) {
|
||||
for (let i = 0; i < MACRO.length; ++i) {
|
||||
s = s.replace(MACRO[i][0], MACRO[i][1]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function replaceStatus(s) {
|
||||
if (s === 'supported') return '<span title="supported">✓</span>';
|
||||
if (s === 'unsupported') return '<span title="unsupported">✗</span>';
|
||||
return s;
|
||||
}
|
||||
|
||||
function createAnchorSlug(s) {
|
||||
return s.toLowerCase().split(' ').join('-');
|
||||
}
|
||||
|
||||
function empty(ar) {
|
||||
return !ar.filter(Boolean, ar).length;
|
||||
}
|
||||
|
||||
function* parseMultiLineGen(filename, s) {
|
||||
if (!~s.indexOf('@vt:')) {
|
||||
return;
|
||||
}
|
||||
const lines = s.split('\n').map(el => el.trim().replace(/[*]/, '').replace(/\s/, ''));
|
||||
let grabLine = false;
|
||||
let longDescription = [];
|
||||
let feature = undefined;
|
||||
let noLineCount = 0;
|
||||
for (const line of lines) {
|
||||
if (grabLine) {
|
||||
if (!line) noLineCount++;
|
||||
if (noLineCount >= 2) {
|
||||
if (feature) {
|
||||
feature.longDescription = empty(longDescription) ? [] : longDescription;
|
||||
feature.longTarget = createAnchorSlug(feature.name);
|
||||
yield feature;
|
||||
}
|
||||
grabLine = false;
|
||||
longDescription = [];
|
||||
feature = undefined;
|
||||
noLineCount = 0;
|
||||
}
|
||||
else if (line.indexOf('@vt:') === 0) {
|
||||
if (feature) {
|
||||
feature.longDescription = empty(longDescription) ? [] : longDescription;
|
||||
feature.longTarget = createAnchorSlug(feature.name);
|
||||
yield feature;
|
||||
}
|
||||
grabLine = true;
|
||||
longDescription = [];
|
||||
feature = undefined;
|
||||
noLineCount = 0;
|
||||
} else {
|
||||
//longDescription.push(line);
|
||||
longDescription.push(applyMacros(line));
|
||||
if (line) noLineCount = 0;
|
||||
}
|
||||
}
|
||||
if (line.indexOf('@vt:') === 0) {
|
||||
feature = parseSingleLine(filename, line);
|
||||
grabLine = true;
|
||||
}
|
||||
}
|
||||
if (grabLine && feature) {
|
||||
feature.longDescription = empty(longDescription) ? [] : longDescription;
|
||||
feature.longTarget = createAnchorSlug(feature.name);
|
||||
yield feature;
|
||||
}
|
||||
}
|
||||
|
||||
function parseSingleLine(filename, s) {
|
||||
const line = s.trim();
|
||||
const match = line.match(REX_VT_LINE);
|
||||
if (match !== null) {
|
||||
if (!~TYPES.indexOf(match[2])) {
|
||||
throw new Error(`unkown vt-command type "${match[2]}" specified in "${filename}"`);
|
||||
}
|
||||
return {
|
||||
status: match[1],
|
||||
type: match[2],
|
||||
mnemonic: match[3],
|
||||
name: match[4],
|
||||
sequence: match[5],
|
||||
shortDescription: match[6],
|
||||
longDescription: [],
|
||||
longTarget: '',
|
||||
source: filename
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getSorter(entry) {
|
||||
switch (entry) {
|
||||
case 'C0':
|
||||
case 'C1':
|
||||
// NOTE: expects hex value notation at last position in sequence
|
||||
return (a, b) => parseInt(a.sequence.slice(-2), 16) - parseInt(b.sequence.slice(-2), 16);
|
||||
case 'OSC':
|
||||
// NOTE: expects the decimal function identifier in mnemonic
|
||||
return (a, b) => parseInt(a.mnemonic) - parseInt(b.mnemonic);
|
||||
case 'DCS':
|
||||
return (a, b) => a.mnemonic > b.mnemonic;
|
||||
case 'CSI':
|
||||
case 'ESC':
|
||||
// default sort order by final byte
|
||||
return (a, b) => {
|
||||
// ugly hack to fix sorting of workaround in HPA sequence "CSI Ps ` "
|
||||
// for HPA compare with length - 2 instead
|
||||
const HPA = 'CSI Ps ` ';
|
||||
const aa = a.sequence === HPA ? a.sequence.slice(0, -1) : a.sequence;
|
||||
const bb = b.sequence === HPA ? b.sequence.slice(0, -1) : b.sequence;
|
||||
return aa.charCodeAt(aa.length - 1) - bb.charCodeAt(bb.length - 1);
|
||||
};
|
||||
default:
|
||||
return (a, b) => a.sequence > b.sequence;
|
||||
}
|
||||
};
|
||||
|
||||
function postProcessData(features) {
|
||||
const featureTable = {};
|
||||
for (const feature of features) {
|
||||
// feature.status = replaceStatus(feature.status);
|
||||
feature.status = applyMacros(feature.status);
|
||||
if (featureTable[feature.type] === undefined) {
|
||||
featureTable[feature.type] = [];
|
||||
}
|
||||
featureTable[feature.type].push(feature);
|
||||
if (feature.longDescription.length) {
|
||||
featureTable[feature.type].hasLongDescriptions = true;
|
||||
}
|
||||
}
|
||||
for (const entry in featureTable) {
|
||||
featureTable[entry].sort(getSorter(entry));
|
||||
}
|
||||
// console.error(featureTable);
|
||||
featureTable.version = require('../package.json').version;
|
||||
console.log(Mustache.render(MARKDOWN_TMPL, featureTable));
|
||||
}
|
||||
|
||||
function main(filenames) {
|
||||
// console.error(filenames);
|
||||
let leftToProcess = filenames.length;
|
||||
const features = [];
|
||||
for (const filename of filenames) {
|
||||
fs.readFile(filename, 'utf-8', (err, data) => {
|
||||
let match;
|
||||
while ((match = REX_COMMENTS.exec(data)) !== null) {
|
||||
if (match.index === REX_COMMENTS.lastIndex) {
|
||||
REX_COMMENTS.lastIndex++;
|
||||
}
|
||||
if (match[1]) {
|
||||
for (let feature of parseMultiLineGen(filename, match[1])) {
|
||||
if (feature) features.push(feature);
|
||||
}
|
||||
} else {
|
||||
const feature = parseSingleLine(filename, match[2]);
|
||||
if (feature) features.push(feature);
|
||||
}
|
||||
}
|
||||
leftToProcess--;
|
||||
if (!leftToProcess) {
|
||||
postProcessData(features);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
main(process.argv.slice(2))
|
||||
+3
-1
@@ -26,7 +26,8 @@
|
||||
"benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json",
|
||||
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/test/benchmark/*benchmark.js",
|
||||
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/test/benchmark/*benchmark.js",
|
||||
"clean": "rm -rf lib out addons/*/lib addons/*/out"
|
||||
"clean": "rm -rf lib out addons/*/lib addons/*/out",
|
||||
"vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^3.4.34",
|
||||
@@ -46,6 +47,7 @@
|
||||
"glob": "^7.0.5",
|
||||
"jsdom": "^11.11.0",
|
||||
"mocha": "^6.1.4",
|
||||
"mustache": "^3.0.1",
|
||||
"node-pty": "^0.9.0",
|
||||
"nyc": "13",
|
||||
"puppeteer": "^1.15.0",
|
||||
|
||||
+453
-102
@@ -27,6 +27,30 @@ import { DcsHandler } from 'common/parser/DcsParser';
|
||||
*/
|
||||
const GLEVEL: {[key: string]: number} = {'(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2};
|
||||
|
||||
/**
|
||||
* VT commands done by the parser - FIXME: move this to the parser?
|
||||
*/
|
||||
// @vt: #Y ESC CSI "Control Sequence Introducer" "ESC [" "Start of a CSI sequence."
|
||||
// @vt: #Y ESC OSC "Operating System Command" "ESC ]" "Start of an OSC sequence."
|
||||
// @vt: #Y ESC DCS "Device Control String" "ESC P" "Start of a DCS sequence."
|
||||
// @vt: #Y ESC ST "String Terminator" "ESC \" "Terminator used for string type sequences."
|
||||
// @vt: #Y ESC PM "Privacy Message" "ESC ^" "Start of a privacy message."
|
||||
// @vt: #Y ESC APC "Application Program Command" "ESC _" "Start of an APC sequence."
|
||||
// @vt: #Y C1 CSI "Control Sequence Introducer" "\x9B" "Start of a CSI sequence."
|
||||
// @vt: #Y C1 OSC "Operating System Command" "\x9D" "Start of an OSC sequence."
|
||||
// @vt: #Y C1 DCS "Device Control String" "\x90" "Start of a DCS sequence."
|
||||
// @vt: #Y C1 ST "String Terminator" "\x9C" "Terminator used for string type sequences."
|
||||
// @vt: #Y C1 PM "Privacy Message" "\x9E" "Start of a privacy message."
|
||||
// @vt: #Y C1 APC "Application Program Command" "\x9F" "Start of an APC sequence."
|
||||
// @vt: #Y C0 NUL "Null" "\0, \x00" "NUL is ignored."
|
||||
// @vt: #Y C0 ESC "Escape" "\e, \x1B" "Start of a sequence. Cancels any other sequence."
|
||||
|
||||
/**
|
||||
* Document common VT features here that are currently unsupported
|
||||
*/
|
||||
// @vt: #N DCS SIXEL "SIXEL Graphics" "DCS Ps ; Ps ; Ps ; q Pt ST" "Draw SIXEL image starting at cursor position."
|
||||
// @vt: #N OSC 1 "Set Icon Name" "OSC 1 ; Pt BEL" "Set icon name."
|
||||
|
||||
/**
|
||||
* Max length of the UTF32 input buffer. Real memory consumption is 4 times higher.
|
||||
*/
|
||||
@@ -42,6 +66,27 @@ const MAX_PARSEBUFFER_LENGTH = 131072;
|
||||
* DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html)
|
||||
* Request Status String (DECRQSS), VT420 and up.
|
||||
* Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html)
|
||||
*
|
||||
* @vt: #P[See limited support below.] DCS DECRQSS "Request Selection or Setting" "DCS $ q Pt ST" "Request several terminal settings."
|
||||
* Response is in the form `ESC P 1 $ r Pt ST` for valid requests, where `Pt` contains the corresponding CSI string,
|
||||
* `ESC P 0 ST` for invalid requests.
|
||||
*
|
||||
* Supported requests and responses:
|
||||
*
|
||||
* | Type | Request | Response (`Pt`) |
|
||||
* | -------------------------------- | ----------------- | ----------------------------------------------------- |
|
||||
* | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) |
|
||||
* | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` |
|
||||
* | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` |
|
||||
* | Protection Attribute (DECSCA) | `DCS $ q " q ST` | always reporting `0 " q` (DECSCA is unsupported) |
|
||||
* | Conformance Level (DECSCL) | `DCS $ q " p ST` | always reporting `61 ; 1 " p` (DECSCL is unsupported) |
|
||||
*
|
||||
*
|
||||
* TODO:
|
||||
* - fix SGR report
|
||||
* - either implement DECSCA or remove the report
|
||||
* - either check which conformance is better suited or remove the report completely
|
||||
* --> we are currently a mixture of all up to VT400 but dont follow anyone strictly
|
||||
*/
|
||||
class DECRQSS implements IDcsHandler {
|
||||
private _data: Uint32Array = new Uint32Array(0);
|
||||
@@ -73,7 +118,7 @@ class DECRQSS implements IDcsHandler {
|
||||
case '"q': // DECSCA
|
||||
return this._coreService.triggerDataEvent(`${C0.ESC}P1$r0"q${C0.ESC}\\`);
|
||||
case '"p': // DECSCL
|
||||
return this._coreService.triggerDataEvent(`${C0.ESC}P1$r61"p${C0.ESC}\\`);
|
||||
return this._coreService.triggerDataEvent(`${C0.ESC}P1$r61;1"p${C0.ESC}\\`);
|
||||
case 'r': // DECSTBM
|
||||
const pt = '' + (this._bufferService.buffer.scrollTop + 1) +
|
||||
';' + (this._bufferService.buffer.scrollBottom + 1) + 'r';
|
||||
@@ -98,18 +143,24 @@ class DECRQSS implements IDcsHandler {
|
||||
* DCS Ps; Ps| Pt ST
|
||||
* DECUDK (https://vt100.net/docs/vt510-rm/DECUDK.html)
|
||||
* not supported
|
||||
*
|
||||
* @vt: #N DCS DECUDK "User Defined Keys" "DCS Ps ; Ps | Pt ST" "Definitions for user-defined keys."
|
||||
*/
|
||||
|
||||
/**
|
||||
* DCS + q Pt ST (xterm)
|
||||
* Request Terminfo String
|
||||
* not implemented
|
||||
*
|
||||
* @vt: #N DCS XTGETTCAP "Request Terminfo String" "DCS + q Pt ST" "Request Terminfo String."
|
||||
*/
|
||||
|
||||
/**
|
||||
* DCS + p Pt ST (xterm)
|
||||
* Set Terminfo Data
|
||||
* not supported
|
||||
*
|
||||
* @vt: #N DCS XTSETTCAP "Set Terminfo Data" "DCS + p Pt ST" "Set Terminfo Data."
|
||||
*/
|
||||
|
||||
|
||||
@@ -425,7 +476,6 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
|
||||
// insert combining char at last cursor position
|
||||
// FIXME: needs handling after cursor jumps
|
||||
// buffer.x should never be 0 for a combining char
|
||||
// since they always follow a cell consuming char
|
||||
// therefore we can test for buffer.x to avoid overflow left
|
||||
@@ -442,10 +492,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
|
||||
// goto next line if ch would overflow
|
||||
// TODO: needs a global min terminal width of 2
|
||||
// FIXME: additionally ensure chWidth fits into a line
|
||||
// --> maybe forbid cols<xy at higher level as it would
|
||||
// introduce a bad runtime penalty here
|
||||
// NOTE: To avoid costly width checks here,
|
||||
// the terminal does not allow a cols < 2.
|
||||
if (buffer.x + chWidth - 1 >= cols) {
|
||||
// autowrap - DECAWM
|
||||
// automatically wraps to the beginning of the next line
|
||||
@@ -554,6 +602,10 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* BEL
|
||||
* Bell (Ctrl-G).
|
||||
*
|
||||
* @vt: #Y C0 BEL "Bell" "\a, \x07" "Ring the bell."
|
||||
* The behavior of the bell is further customizable with `ITerminalOptions.bellStyle`
|
||||
* and `ITerminalOptions.bellSound`.
|
||||
*/
|
||||
public bell(): void {
|
||||
this._onRequestBell.fire();
|
||||
@@ -562,6 +614,12 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* LF
|
||||
* Line Feed or New Line (NL). (LF is Ctrl-J).
|
||||
*
|
||||
* @vt: #Y C0 LF "Line Feed" "\n, \x0A" "Move the cursor one row down, scrolling if needed."
|
||||
* Scrolling is restricted to scroll margins and will only happen on the bottom line.
|
||||
*
|
||||
* @vt: #Y C0 VT "Vertical Tabulation" "\v, \x0B" "Treated as LF."
|
||||
* @vt: #Y C0 FF "Form Feed" "\f, \x0C" "Treated as LF."
|
||||
*/
|
||||
public lineFeed(): void {
|
||||
// make buffer local for faster access
|
||||
@@ -590,6 +648,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CR
|
||||
* Carriage Return (Ctrl-M).
|
||||
*
|
||||
* @vt: #Y C0 CR "Carriage Return" "\r, \x0D" "Move the cursor to the beginning of the row."
|
||||
*/
|
||||
public carriageReturn(): void {
|
||||
this._bufferService.buffer.x = 0;
|
||||
@@ -598,6 +658,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* BS
|
||||
* Backspace (Ctrl-H).
|
||||
*
|
||||
* @vt: #Y C0 BS "Backspace" "\b, \x08" "Move the cursor one position to the left."
|
||||
*/
|
||||
public backspace(): void {
|
||||
this._restrictCursor();
|
||||
@@ -609,6 +671,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* TAB
|
||||
* Horizontal Tab (HT) (Ctrl-I).
|
||||
*
|
||||
* @vt: #Y C0 HT "Horizontal Tabulation" "\t, \x09" "Move the cursor to the next character tab stop."
|
||||
*/
|
||||
public tab(): void {
|
||||
if (this._bufferService.buffer.x >= this._bufferService.cols) {
|
||||
@@ -625,6 +689,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* SO
|
||||
* Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the
|
||||
* G1 character set.
|
||||
*
|
||||
* @vt: #P[Only limited ISO-2022 charset support.] C0 SO "Shift Out" "\x0E" "Switch to an alternative character set."
|
||||
*/
|
||||
public shiftOut(): void {
|
||||
this._charsetService.setgLevel(1);
|
||||
@@ -634,6 +700,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* SI
|
||||
* Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0
|
||||
* character set (the default).
|
||||
*
|
||||
* @vt: #Y C0 SI "Shift In" "\x0F" "Return to regular character set after Shift Out."
|
||||
*/
|
||||
public shiftIn(): void {
|
||||
this._charsetService.setgLevel(0);
|
||||
@@ -679,6 +747,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps A
|
||||
* Cursor Up Ps Times (default = 1) (CUU).
|
||||
*
|
||||
* @vt: #Y CSI CUU "Cursor Up" "CSI Ps A" "Move cursor `Ps` times up (default=1)."
|
||||
* If the cursor would pass the top scroll margin, it will stop there.
|
||||
*/
|
||||
public cursorUp(params: IParams): void {
|
||||
// stop at scrollTop
|
||||
@@ -693,6 +764,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps B
|
||||
* Cursor Down Ps Times (default = 1) (CUD).
|
||||
*
|
||||
* @vt: #Y CSI CUD "Cursor Down" "CSI Ps B" "Move cursor `Ps` times down (default=1)."
|
||||
* If the cursor would pass the bottom scroll margin, it will stop there.
|
||||
*/
|
||||
public cursorDown(params: IParams): void {
|
||||
// stop at scrollBottom
|
||||
@@ -707,6 +781,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps C
|
||||
* Cursor Forward Ps Times (default = 1) (CUF).
|
||||
*
|
||||
* @vt: #Y CSI CUF "Cursor Forward" "CSI Ps C" "Move cursor `Ps` times forward (default=1)."
|
||||
*/
|
||||
public cursorForward(params: IParams): void {
|
||||
this._moveCursor(params.params[0] || 1, 0);
|
||||
@@ -715,6 +791,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps D
|
||||
* Cursor Backward Ps Times (default = 1) (CUB).
|
||||
*
|
||||
* @vt: #Y CSI CUB "Cursor Backward" "CSI Ps D" "Move cursor `Ps` times backward (default=1)."
|
||||
*/
|
||||
public cursorBackward(params: IParams): void {
|
||||
this._moveCursor(-(params.params[0] || 1), 0);
|
||||
@@ -724,6 +802,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* CSI Ps E
|
||||
* Cursor Next Line Ps Times (default = 1) (CNL).
|
||||
* Other than cursorDown (CUD) also set the cursor to first column.
|
||||
*
|
||||
* @vt: #Y CSI CNL "Cursor Next Line" "CSI Ps E" "Move cursor `Ps` times down (default=1) and to the first column."
|
||||
* Same as CUD, additionally places the cursor at the first column.
|
||||
*/
|
||||
public cursorNextLine(params: IParams): void {
|
||||
this.cursorDown(params);
|
||||
@@ -734,6 +815,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* CSI Ps F
|
||||
* Cursor Previous Line Ps Times (default = 1) (CPL).
|
||||
* Other than cursorUp (CUU) also set the cursor to first column.
|
||||
*
|
||||
* @vt: #Y CSI CPL "Cursor Backward" "CSI Ps F" "Move cursor `Ps` times up (default=1) and to the first column."
|
||||
* Same as CUU, additionally places the cursor at the first column.
|
||||
*/
|
||||
public cursorPrecedingLine(params: IParams): void {
|
||||
this.cursorUp(params);
|
||||
@@ -743,6 +827,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps G
|
||||
* Cursor Character Absolute [column] (default = [row,1]) (CHA).
|
||||
*
|
||||
* @vt: #Y CSI CHA "Cursor Horizontal Absolute" "CSI Ps G" "Move cursor to `Ps`-th column of the active row (default=1)."
|
||||
*/
|
||||
public cursorCharAbsolute(params: IParams): void {
|
||||
this._setCursor((params.params[0] || 1) - 1, this._bufferService.buffer.y);
|
||||
@@ -751,6 +837,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps ; Ps H
|
||||
* Cursor Position [row;column] (default = [1,1]) (CUP).
|
||||
*
|
||||
* @vt: #Y CSI CUP "Cursor Position" "CSI Ps ; Ps H" "Set cursor to position [`Ps`, `Ps`] (default = [1, 1])."
|
||||
* If ORIGIN mode is set, places the cursor to the absolute position within the scroll margins.
|
||||
* If ORIGIN mode is not set, places the cursor to the absolute position within the viewport.
|
||||
* Note that the coordinates are 1-based, thus the top left position starts at `1 ; 1`.
|
||||
*/
|
||||
public cursorPosition(params: IParams): void {
|
||||
this._setCursor(
|
||||
@@ -764,6 +855,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* CSI Pm ` Character Position Absolute
|
||||
* [column] (default = [row,1]) (HPA).
|
||||
* Currently same functionality as CHA.
|
||||
*
|
||||
* @vt: #Y CSI HPA "Horizontal Position Absolute" "CSI Ps ` " "Same as CHA."
|
||||
*/
|
||||
public charPosAbsolute(params: IParams): void {
|
||||
this._setCursor((params.params[0] || 1) - 1, this._bufferService.buffer.y);
|
||||
@@ -772,7 +865,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Pm a Character Position Relative
|
||||
* [columns] (default = [row,col+1]) (HPR)
|
||||
* Currently same functionality as CUF.
|
||||
*
|
||||
* @vt: #Y CSI HPR "Horizontal Position Relative" "CSI Ps a" "Same as CUF."
|
||||
*/
|
||||
public hPositionRelative(params: IParams): void {
|
||||
this._moveCursor(params.params[0] || 1, 0);
|
||||
@@ -781,6 +875,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Pm d Vertical Position Absolute (VPA)
|
||||
* [row] (default = [1,column])
|
||||
*
|
||||
* @vt: #Y CSI VPA "Vertical Position Absolute" "CSI Ps d" "Move cursor to `Ps`-th row (default=1)."
|
||||
*/
|
||||
public linePosAbsolute(params: IParams): void {
|
||||
this._setCursor(this._bufferService.buffer.x, (params.params[0] || 1) - 1);
|
||||
@@ -790,6 +886,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* CSI Pm e Vertical Position Relative (VPR)
|
||||
* [rows] (default = [row+1,column])
|
||||
* reuse CSI Ps B ?
|
||||
*
|
||||
* @vt: #Y CSI VPR "Vertical Position Relative" "CSI Ps e" "Move cursor `Ps` times down (default=1)."
|
||||
*/
|
||||
public vPositionRelative(params: IParams): void {
|
||||
this._moveCursor(0, params.params[0] || 1);
|
||||
@@ -800,6 +898,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Horizontal and Vertical Position [row;column] (default =
|
||||
* [1,1]) (HVP).
|
||||
* Same as CUP.
|
||||
*
|
||||
* @vt: #Y CSI HVP "Horizontal and Vertical Position" "CSI Ps ; Ps f" "Same as CUP."
|
||||
*/
|
||||
public hVPosition(params: IParams): void {
|
||||
this.cursorPosition(params);
|
||||
@@ -812,6 +912,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Potentially:
|
||||
* Ps = 2 -> Clear Stops on Line.
|
||||
* http://vt100.net/annarbor/aaa-ug/section6.html
|
||||
*
|
||||
* @vt: #Y CSI TBC "Tab Clear" "CSI Ps g" "Clear tab stops at current position (0) or all (3) (default=0)."
|
||||
* Clearing tabstops off the active row (Ps = 2, VT100) is currently not supported.
|
||||
*/
|
||||
public tabClear(params: IParams): void {
|
||||
const param = params.params[0];
|
||||
@@ -825,6 +928,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps I
|
||||
* Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).
|
||||
*
|
||||
* @vt: #Y CSI CHT "Cursor Horizontal Tabulation" "CSI Ps I" "Move cursor `Ps` times tabs forward (default=1)."
|
||||
*/
|
||||
public cursorForwardTab(params: IParams): void {
|
||||
if (this._bufferService.buffer.x >= this._bufferService.cols) {
|
||||
@@ -838,6 +943,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
/**
|
||||
* CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
|
||||
*
|
||||
* @vt: #Y CSI CBT "Cursor Backward Tabulation" "CSI Ps Z" "Move cursor `Ps` tabs backward (default=1)."
|
||||
*/
|
||||
public cursorBackwardTab(params: IParams): void {
|
||||
if (this._bufferService.buffer.x >= this._bufferService.cols) {
|
||||
@@ -896,6 +1003,18 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 0 -> Selective Erase Below (default).
|
||||
* Ps = 1 -> Selective Erase Above.
|
||||
* Ps = 2 -> Selective Erase All.
|
||||
*
|
||||
* @vt: #Y CSI ED "Erase In Display" "CSI Ps J" "Erase various parts of the viewport."
|
||||
* Supported param values:
|
||||
*
|
||||
* | Ps | Effect |
|
||||
* | -- | ------------------------------------------------------------ |
|
||||
* | 0 | Erase from the cursor through the end of the viewport. |
|
||||
* | 1 | Erase from the beginning of the viewport through the cursor. |
|
||||
* | 2 | Erase complete viewport. |
|
||||
* | 3 | Erase scrollback. |
|
||||
*
|
||||
* @vt: #P[Protection attributes are not supported.] CSI DECSED "Selective Erase In Display" "CSI ? Ps J" "Currently the same as ED."
|
||||
*/
|
||||
public eraseInDisplay(params: IParams): void {
|
||||
this._restrictCursor();
|
||||
@@ -956,6 +1075,17 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 0 -> Selective Erase to Right (default).
|
||||
* Ps = 1 -> Selective Erase to Left.
|
||||
* Ps = 2 -> Selective Erase All.
|
||||
*
|
||||
* @vt: #Y CSI EL "Erase In Line" "CSI Ps K" "Erase various parts of the active row."
|
||||
* Supported param values:
|
||||
*
|
||||
* | Ps | Effect |
|
||||
* | -- | -------------------------------------------------------- |
|
||||
* | 0 | Erase from the cursor through the end of the row. |
|
||||
* | 1 | Erase from the beginning of the line through the cursor. |
|
||||
* | 2 | Erase complete line. |
|
||||
*
|
||||
* @vt: #P[Protection attributes are not supported.] CSI DECSEL "Selective Erase In Line" "CSI ? Ps K" "Currently the same as EL."
|
||||
*/
|
||||
public eraseInLine(params: IParams): void {
|
||||
this._restrictCursor();
|
||||
@@ -976,6 +1106,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps L
|
||||
* Insert Ps Line(s) (default = 1) (IL).
|
||||
*
|
||||
* @vt: #Y CSI IL "Insert Line" "CSI Ps L" "Insert `Ps` blank lines at active row (default=1)."
|
||||
* For every inserted line at the scroll top one line at the scroll bottom gets removed.
|
||||
* The cursor is set to the first column.
|
||||
* IL has no effect if the cursor is outside the scroll margins.
|
||||
*/
|
||||
public insertLines(params: IParams): void {
|
||||
this._restrictCursor();
|
||||
@@ -1006,6 +1141,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps M
|
||||
* Delete Ps Line(s) (default = 1) (DL).
|
||||
*
|
||||
* @vt: #Y CSI DL "Delete Line" "CSI Ps M" "Delete `Ps` lines at active row (default=1)."
|
||||
* For every deleted line at the scroll top one blank line at the scroll bottom gets appended.
|
||||
* The cursor is set to the first column.
|
||||
* DL has no effect if the cursor is outside the scroll margins.
|
||||
*/
|
||||
public deleteLines(params: IParams): void {
|
||||
this._restrictCursor();
|
||||
@@ -1037,6 +1177,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps @
|
||||
* Insert Ps (Blank) Character(s) (default = 1) (ICH).
|
||||
*
|
||||
* @vt: #Y CSI ICH "Insert Characters" "CSI Ps @" "Insert `Ps` (blank) characters (default = 1)."
|
||||
* The ICH sequence inserts `Ps` blank characters. The cursor remains at the beginning of the blank characters.
|
||||
* Text between the cursor and right margin moves to the right. Characters moved past the right margin are lost.
|
||||
*
|
||||
*
|
||||
* FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)
|
||||
*/
|
||||
public insertChars(params: IParams): void {
|
||||
this._restrictCursor();
|
||||
@@ -1055,6 +1202,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps P
|
||||
* Delete Ps Character(s) (default = 1) (DCH).
|
||||
*
|
||||
* @vt: #Y CSI DCH "Delete Character" "CSI Ps P" "Delete `Ps` characters (default=1)."
|
||||
* As characters are deleted, the remaining characters between the cursor and right margin move to the left.
|
||||
* Character attributes move with the characters. The terminal adds blank characters at the right margin.
|
||||
*
|
||||
*
|
||||
* FIXME: check against xterm - should not work outside of scroll margins (see VT520 manual)
|
||||
*/
|
||||
public deleteChars(params: IParams): void {
|
||||
this._restrictCursor();
|
||||
@@ -1072,6 +1226,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
/**
|
||||
* CSI Ps S Scroll up Ps lines (default = 1) (SU).
|
||||
*
|
||||
* @vt: #Y CSI SU "Scroll Up" "CSI Ps S" "Scroll `Ps` lines up (default=1)."
|
||||
*
|
||||
*
|
||||
* FIXME: scrolled out lines at top = 1 should add to scrollback (xterm)
|
||||
*/
|
||||
public scrollUp(params: IParams): void {
|
||||
let param = params.params[0] || 1;
|
||||
@@ -1088,6 +1247,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
/**
|
||||
* CSI Ps T Scroll down Ps lines (default = 1) (SD).
|
||||
*
|
||||
* @vt: #Y CSI SD "Scroll Down" "CSI Ps T" "Scroll `Ps` lines down (default=1)."
|
||||
*/
|
||||
public scrollDown(params: IParams): void {
|
||||
let param = params.params[0] || 1;
|
||||
@@ -1115,6 +1276,10 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
*
|
||||
* Supported:
|
||||
* - always left shift (no line orientation setting respected)
|
||||
*
|
||||
* @vt: #Y CSI SL "Scroll Left" "CSI Ps SP @" "Scroll viewport `Ps` times to the left."
|
||||
* SL moves the content of all lines within the scroll margins `Ps` times to the left.
|
||||
* SL has no effect outside of the scroll margins.
|
||||
*/
|
||||
public scrollLeft(params: IParams): void {
|
||||
const buffer = this._bufferService.buffer;
|
||||
@@ -1143,6 +1308,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
*
|
||||
* Supported:
|
||||
* - always right shift (no line orientation setting respected)
|
||||
*
|
||||
* @vt: #Y CSI SR "Scroll Right" "CSI Ps SP A" "Scroll viewport `Ps` times to the right."
|
||||
* SL moves the content of all lines within the scroll margins `Ps` times to the right.
|
||||
* Content at the right margin is lost.
|
||||
* SL has no effect outside of the scroll margins.
|
||||
*/
|
||||
public scrollRight(params: IParams): void {
|
||||
const buffer = this._bufferService.buffer;
|
||||
@@ -1161,6 +1331,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Pm ' }
|
||||
* Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.
|
||||
*
|
||||
* @vt: #Y CSI DECIC "Insert Columns" "CSI Ps ' }" "Insert `Ps` columns at cursor position."
|
||||
* DECIC inserts `Ps` times blank columns at the cursor position for all lines with the scroll margins,
|
||||
* moving content to the right. Content at the right margin is lost.
|
||||
* DECIC has no effect outside the scrolling margins.
|
||||
*/
|
||||
public insertColumns(params: IParams): void {
|
||||
const buffer = this._bufferService.buffer;
|
||||
@@ -1179,6 +1354,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Pm ' ~
|
||||
* Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.
|
||||
*
|
||||
* @vt: #Y CSI DECDC "Delete Columns" "CSI Ps ' ~" "Delete `Ps` columns at cursor position."
|
||||
* DECDC deletes `Ps` times columns at the cursor position for all lines with the scroll margins,
|
||||
* moving content to the left. Blank columns are added at the right margin.
|
||||
* DECDC has no effect outside the scrolling margins.
|
||||
*/
|
||||
public deleteColumns(params: IParams): void {
|
||||
const buffer = this._bufferService.buffer;
|
||||
@@ -1197,6 +1377,10 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Ps X
|
||||
* Erase Ps Character(s) (default = 1) (ECH).
|
||||
*
|
||||
* @vt: #Y CSI ECH "Erase Character" "CSI Ps X" "Erase `Ps` characters from current cursor position to the right (default=1)."
|
||||
* ED erases `Ps` characters from current cursor position to the right.
|
||||
* ED works inside or outside the scrolling margins.
|
||||
*/
|
||||
public eraseChars(params: IParams): void {
|
||||
this._restrictCursor();
|
||||
@@ -1233,6 +1417,11 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
*
|
||||
* Note: To get reset on a valid sequence working correctly without much runtime penalty,
|
||||
* the preceding codepoint is stored on the parser in `this.print` and reset during `parser.parse`.
|
||||
*
|
||||
* @vt: #Y CSI REP "Repeat Preceding Character" "CSI Ps b" "Repeat preceding character `Ps` times (default=1)."
|
||||
* REP repeats the previous character `Ps` times advancing the cursor, also wrapping if DECAWM is set.
|
||||
* REP has no effect if the sequence does not follow a printable ASCII character
|
||||
* (NOOP for any other sequence in between or NON ASCII characters).
|
||||
*/
|
||||
public repeatPrecedingCharacter(params: IParams): void {
|
||||
if (!this._parser.precedingCodepoint) {
|
||||
@@ -1266,6 +1455,24 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 1 5 -> Technical characters.
|
||||
* Ps = 2 2 -> ANSI color, e.g., VT525.
|
||||
* Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).
|
||||
*
|
||||
* @vt: #Y CSI DA1 "Primary Device Attributes" "CSI c" "Send primary device attributes."
|
||||
*
|
||||
*
|
||||
* TODO: fix and cleanup response
|
||||
*/
|
||||
public sendDeviceAttributesPrimary(params: IParams): void {
|
||||
if (params.params[0] > 0) {
|
||||
return;
|
||||
}
|
||||
if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {
|
||||
this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');
|
||||
} else if (this._terminal.is('linux')) {
|
||||
this._coreService.triggerDataEvent(C0.ESC + '[?6c');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI > Ps c
|
||||
* Send Device Attributes (Secondary DA).
|
||||
* Ps = 0 or omitted -> request the terminal's identification
|
||||
@@ -1283,17 +1490,12 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* More information:
|
||||
* xterm/charproc.c - line 2012, for more information.
|
||||
* vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)
|
||||
*
|
||||
* @vt: #Y CSI DA2 "Secondary Device Attributes" "CSI > c" "Send primary device attributes."
|
||||
*
|
||||
*
|
||||
* TODO: fix and cleanup response
|
||||
*/
|
||||
public sendDeviceAttributesPrimary(params: IParams): void {
|
||||
if (params.params[0] > 0) {
|
||||
return;
|
||||
}
|
||||
if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {
|
||||
this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');
|
||||
} else if (this._terminal.is('linux')) {
|
||||
this._coreService.triggerDataEvent(C0.ESC + '[?6c');
|
||||
}
|
||||
}
|
||||
public sendDeviceAttributesSecondary(params: IParams): void {
|
||||
if (params.params[0] > 0) {
|
||||
return;
|
||||
@@ -1320,6 +1522,34 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 4 -> Insert Mode (IRM).
|
||||
* Ps = 1 2 -> Send/receive (SRM).
|
||||
* Ps = 2 0 -> Automatic Newline (LNM).
|
||||
*
|
||||
* @vt: #P[Only IRM is supported.] CSI SM "Set Mode" "CSI Pm h" "Set various terminal modes."
|
||||
* Supported param values by SM:
|
||||
*
|
||||
* | Param | Action | Support |
|
||||
* | ----- | -------------------------------------- | ------- |
|
||||
* | 2 | Keyboard Action Mode (KAM). Always on. | #N |
|
||||
* | 4 | Insert Mode (IRM). | #Y |
|
||||
* | 12 | Send/receive (SRM). Always off. | #N |
|
||||
* | 20 | Automatic Newline (LNM). Always off. | #N |
|
||||
*
|
||||
*
|
||||
* FIXME: why is LNM commented out?
|
||||
*/
|
||||
public setMode(params: IParams): void {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
switch (params.params[i]) {
|
||||
case 4:
|
||||
this._terminal.insertMode = true;
|
||||
break;
|
||||
case 20:
|
||||
// this._t.convertEol = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI ? Pm h
|
||||
* DEC Private Mode Set (DECSET).
|
||||
* Ps = 1 -> Application Cursor Keys (DECCKM).
|
||||
@@ -1399,19 +1629,38 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 2 0 0 4 -> Set bracketed paste mode.
|
||||
* Modes:
|
||||
* http: *vt100.net/docs/vt220-rm/chapter4.html
|
||||
*
|
||||
* @vt: #P[See below for supported modes.] CSI DECSET "DEC Private Set Mode" "CSI ? Pm h" "Set various terminal attributes."
|
||||
* Supported param values by DECSET:
|
||||
*
|
||||
* | param | Action | Support |
|
||||
* | ----- | ------------------------------------------------------- | --------|
|
||||
* | 1 | Application Cursor Keys (DECCKM). | #Y |
|
||||
* | 2 | Designate US-ASCII for character sets G0-G3 (DECANM). | #Y |
|
||||
* | 3 | 132 Column Mode (DECCOLM). | #Y |
|
||||
* | 6 | Origin Mode (DECOM). | #Y |
|
||||
* | 7 | Auto-wrap Mode (DECAWM). | #Y |
|
||||
* | 8 | Auto-repeat Keys (DECARM). Always on. | #N |
|
||||
* | 9 | X10 xterm mouse protocol. | #Y |
|
||||
* | 12 | Start Blinking Cursor. | #Y |
|
||||
* | 25 | Show Cursor (DECTCEM). | #Y |
|
||||
* | 47 | Use Alternate Screen Buffer. | #Y |
|
||||
* | 66 | Application keypad (DECNKM). | #Y |
|
||||
* | 1000 | X11 xterm mouse protocol. | #Y |
|
||||
* | 1002 | Use Cell Motion Mouse Tracking. | #Y |
|
||||
* | 1003 | Use All Motion Mouse Tracking. | #Y |
|
||||
* | 1004 | Send FocusIn/FocusOut events | #Y |
|
||||
* | 1005 | Enable UTF-8 Mouse Mode. | #N |
|
||||
* | 1006 | Enable SGR Mouse Mode. | #Y |
|
||||
* | 1015 | Enable urxvt Mouse Mode. | #N |
|
||||
* | 1047 | Use Alternate Screen Buffer. | #Y |
|
||||
* | 1048 | Save cursor as in DECSC. | #Y |
|
||||
* | 1049 | Save cursor and switch to alternate buffer clearing it. | #P[Does not clear the alternate buffer.] |
|
||||
* | 2004 | Set bracketed paste mode. | #Y |
|
||||
*
|
||||
*
|
||||
* FIXME: implement DECSCNM, 1049 should clear altbuffer
|
||||
*/
|
||||
public setMode(params: IParams): void {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
switch (params.params[i]) {
|
||||
case 4:
|
||||
this._terminal.insertMode = true;
|
||||
break;
|
||||
case 20:
|
||||
// this._t.convertEol = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public setModePrivate(params: IParams): void {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
switch (params.params[i]) {
|
||||
@@ -1506,6 +1755,34 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 4 -> Replace Mode (IRM).
|
||||
* Ps = 1 2 -> Send/receive (SRM).
|
||||
* Ps = 2 0 -> Normal Linefeed (LNM).
|
||||
*
|
||||
* @vt: #P[Only IRM is supported.] CSI RM "Reset Mode" "CSI Pm l" "Set various terminal attributes."
|
||||
* Supported param values by RM:
|
||||
*
|
||||
* | Param | Action | Support |
|
||||
* | ----- | -------------------------------------- | ------- |
|
||||
* | 2 | Keyboard Action Mode (KAM). Always on. | #N |
|
||||
* | 4 | Replace Mode (IRM). (default) | #Y |
|
||||
* | 12 | Send/receive (SRM). Always off. | #N |
|
||||
* | 20 | Normal Linefeed (LNM). Always off. | #N |
|
||||
*
|
||||
*
|
||||
* FIXME: why is LNM commented out?
|
||||
*/
|
||||
public resetMode(params: IParams): void {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
switch (params.params[i]) {
|
||||
case 4:
|
||||
this._terminal.insertMode = false;
|
||||
break;
|
||||
case 20:
|
||||
// this._t.convertEol = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI ? Pm l
|
||||
* DEC Private Mode Reset (DECRST).
|
||||
* Ps = 1 -> Normal Cursor Keys (DECCKM).
|
||||
@@ -1581,19 +1858,38 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).
|
||||
* Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.
|
||||
* Ps = 2 0 0 4 -> Reset bracketed paste mode.
|
||||
*
|
||||
* @vt: #P[See below for supported modes.] CSI DECRST "DEC Private Reset Mode" "CSI ? Pm l" "Reset various terminal attributes."
|
||||
* Supported param values by DECRST:
|
||||
*
|
||||
* | param | Action | Support |
|
||||
* | ----- | ------------------------------------------------------- | ------- |
|
||||
* | 1 | Normal Cursor Keys (DECCKM). | #Y |
|
||||
* | 2 | Designate VT52 mode (DECANM). | #N |
|
||||
* | 3 | 80 Column Mode (DECCOLM). | #B[Switches to old column width instead of 80.] |
|
||||
* | 6 | Normal Cursor Mode (DECOM). | #Y |
|
||||
* | 7 | No Wraparound Mode (DECAWM). | #Y |
|
||||
* | 8 | No Auto-repeat Keys (DECARM). | #N |
|
||||
* | 9 | Don't send Mouse X & Y on button press. | #Y |
|
||||
* | 12 | Stop Blinking Cursor. | #Y |
|
||||
* | 25 | Hide Cursor (DECTCEM). | #Y |
|
||||
* | 47 | Use Normal Screen Buffer. | #Y |
|
||||
* | 66 | Numeric keypad (DECNKM). | #Y |
|
||||
* | 1000 | Don't send Mouse reports. | #Y |
|
||||
* | 1002 | Don't use Cell Motion Mouse Tracking. | #Y |
|
||||
* | 1003 | Don't use All Motion Mouse Tracking. | #Y |
|
||||
* | 1004 | Don't send FocusIn/FocusOut events. | #Y |
|
||||
* | 1005 | Disable UTF-8 Mouse Mode. | #N |
|
||||
* | 1006 | Disable SGR Mouse Mode. | #Y |
|
||||
* | 1015 | Disable urxvt Mouse Mode. | #N |
|
||||
* | 1047 | Use Normal Screen Buffer (clearing screen if in alt). | #Y |
|
||||
* | 1048 | Restore cursor as in DECRC. | #Y |
|
||||
* | 1049 | Use Normal Screen Buffer and restore cursor. | #Y |
|
||||
* | 2004 | Reset bracketed paste mode. | #Y |
|
||||
*
|
||||
*
|
||||
* FIXME: DECCOLM is currently broken (already fixed in window options PR)
|
||||
*/
|
||||
public resetMode(params: IParams): void {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
switch (params.params[i]) {
|
||||
case 4:
|
||||
this._terminal.insertMode = false;
|
||||
break;
|
||||
case 20:
|
||||
// this._t.convertEol = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public resetModePrivate(params: IParams): void {
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
switch (params.params[i]) {
|
||||
@@ -1743,68 +2039,72 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
|
||||
/**
|
||||
* CSI Pm m Character Attributes (SGR).
|
||||
* Ps = 0 -> Normal (default).
|
||||
* Ps = 1 -> Bold.
|
||||
* Ps = 2 -> Faint, decreased intensity (ISO 6429).
|
||||
* Ps = 4 -> Underlined.
|
||||
* Ps = 5 -> Blink (appears as Bold).
|
||||
* Ps = 7 -> Inverse.
|
||||
* Ps = 8 -> Invisible, i.e., hidden (VT300).
|
||||
* Ps = 2 2 -> Normal (neither bold nor faint).
|
||||
* Ps = 2 4 -> Not underlined.
|
||||
* Ps = 2 5 -> Steady (not blinking).
|
||||
* Ps = 2 7 -> Positive (not inverse).
|
||||
* Ps = 2 8 -> Visible, i.e., not hidden (VT300).
|
||||
* Ps = 3 0 -> Set foreground color to Black.
|
||||
* Ps = 3 1 -> Set foreground color to Red.
|
||||
* Ps = 3 2 -> Set foreground color to Green.
|
||||
* Ps = 3 3 -> Set foreground color to Yellow.
|
||||
* Ps = 3 4 -> Set foreground color to Blue.
|
||||
* Ps = 3 5 -> Set foreground color to Magenta.
|
||||
* Ps = 3 6 -> Set foreground color to Cyan.
|
||||
* Ps = 3 7 -> Set foreground color to White.
|
||||
* Ps = 3 9 -> Set foreground color to default (original).
|
||||
* Ps = 4 0 -> Set background color to Black.
|
||||
* Ps = 4 1 -> Set background color to Red.
|
||||
* Ps = 4 2 -> Set background color to Green.
|
||||
* Ps = 4 3 -> Set background color to Yellow.
|
||||
* Ps = 4 4 -> Set background color to Blue.
|
||||
* Ps = 4 5 -> Set background color to Magenta.
|
||||
* Ps = 4 6 -> Set background color to Cyan.
|
||||
* Ps = 4 7 -> Set background color to White.
|
||||
* Ps = 4 9 -> Set background color to default (original).
|
||||
*
|
||||
* If 16-color support is compiled, the following apply. Assume
|
||||
* that xterm's resources are set so that the ISO color codes are
|
||||
* the first 8 of a set of 16. Then the aixterm colors are the
|
||||
* bright versions of the ISO colors:
|
||||
* Ps = 9 0 -> Set foreground color to Black.
|
||||
* Ps = 9 1 -> Set foreground color to Red.
|
||||
* Ps = 9 2 -> Set foreground color to Green.
|
||||
* Ps = 9 3 -> Set foreground color to Yellow.
|
||||
* Ps = 9 4 -> Set foreground color to Blue.
|
||||
* Ps = 9 5 -> Set foreground color to Magenta.
|
||||
* Ps = 9 6 -> Set foreground color to Cyan.
|
||||
* Ps = 9 7 -> Set foreground color to White.
|
||||
* Ps = 1 0 0 -> Set background color to Black.
|
||||
* Ps = 1 0 1 -> Set background color to Red.
|
||||
* Ps = 1 0 2 -> Set background color to Green.
|
||||
* Ps = 1 0 3 -> Set background color to Yellow.
|
||||
* Ps = 1 0 4 -> Set background color to Blue.
|
||||
* Ps = 1 0 5 -> Set background color to Magenta.
|
||||
* Ps = 1 0 6 -> Set background color to Cyan.
|
||||
* Ps = 1 0 7 -> Set background color to White.
|
||||
* @vt: #P[See below for supported attributes.] CSI SGR "Select Graphic Rendition" "CSI Pm m" "Set/Reset various text attributes."
|
||||
* SGR selects one or more character attributes at the same time. Multiple params (up to 32)
|
||||
* are applied from in order from left to right. The changed attributes are applied to all new
|
||||
* characters received. If you move characters in the viewport by scrolling or any other means,
|
||||
* then the attributes move with the characters.
|
||||
*
|
||||
* If xterm is compiled with the 16-color support disabled, it
|
||||
* supports the following, from rxvt:
|
||||
* Ps = 1 0 0 -> Set foreground and background color to
|
||||
* default.
|
||||
* Supported param values by SGR:
|
||||
*
|
||||
* If 88- or 256-color support is compiled, the following apply.
|
||||
* Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second
|
||||
* Ps.
|
||||
* Ps = 4 8 ; 5 ; Ps -> Set background color to the second
|
||||
* Ps.
|
||||
* | Param | Meaning | Support |
|
||||
* | --------- | -------------------------------------------------------- | ------- |
|
||||
* | 0 | Normal (default). Resets any other preceding SGR. | #Y |
|
||||
* | 1 | Bold. (also see `options.drawBoldTextInBrightColors`) | #Y |
|
||||
* | 2 | Faint, decreased intensity. | #Y |
|
||||
* | 3 | Italic. | #Y |
|
||||
* | 4 | Underlined. (no support for newer underline styles) | #Y |
|
||||
* | 5 | Slowly blinking. | #N |
|
||||
* | 6 | Rapidly blinking. | #N |
|
||||
* | 7 | Inverse. Flips foreground and background color. | #Y |
|
||||
* | 8 | Invisible (hidden). | #Y |
|
||||
* | 9 | Crossed-out characters. | #N |
|
||||
* | 21 | Doubly underlined. | #N |
|
||||
* | 22 | Normal (neither bold nor faint). | #Y |
|
||||
* | 23 | No italic. | #Y |
|
||||
* | 24 | Not underlined. | #Y |
|
||||
* | 25 | Steady (not blinking). | #Y |
|
||||
* | 27 | Positive (not inverse). | #Y |
|
||||
* | 28 | Visible (not hidden). | #Y |
|
||||
* | 29 | Not Crossed-out. | #N |
|
||||
* | 30 | Foreground color: Black. | #Y |
|
||||
* | 31 | Foreground color: Red. | #Y |
|
||||
* | 32 | Foreground color: Green. | #Y |
|
||||
* | 33 | Foreground color: Yellow. | #Y |
|
||||
* | 34 | Foreground color: Blue. | #Y |
|
||||
* | 35 | Foreground color: Magenta. | #Y |
|
||||
* | 36 | Foreground color: Cyan. | #Y |
|
||||
* | 37 | Foreground color: White. | #Y |
|
||||
* | 38 | Foreground color: Extended color. | #P[Support for RGB and indexed colors, see below.] |
|
||||
* | 39 | Foreground color: Default (original). | #Y |
|
||||
* | 40 | Background color: Black. | #Y |
|
||||
* | 41 | Background color: Red. | #Y |
|
||||
* | 42 | Background color: Green. | #Y |
|
||||
* | 43 | Background color: Yellow. | #Y |
|
||||
* | 44 | Background color: Blue. | #Y |
|
||||
* | 45 | Background color: Magenta. | #Y |
|
||||
* | 46 | Background color: Cyan. | #Y |
|
||||
* | 47 | Background color: White. | #Y |
|
||||
* | 48 | Background color: Extended color. | #P[Support for RGB and indexed colors, see below.] |
|
||||
* | 49 | Background color: Default (original). | #Y |
|
||||
* | 90 - 97 | Bright foreground color (analogous to 30 - 37). | #Y |
|
||||
* | 100 - 107 | Bright background color (analogous to 40 - 47). | #Y |
|
||||
*
|
||||
* Extended colors are supported for foreground (Ps=38) and background (Ps=48) as follows:
|
||||
*
|
||||
* | Ps + 1 | Meaning | Support |
|
||||
* | ------ | ------------------------------------------------------------- | ------- |
|
||||
* | 0 | Implementation defined. | #N |
|
||||
* | 1 | Transparent. | #N |
|
||||
* | 2 | RGB color as `Ps ; 2 ; R ; G ; B` or `Ps : 2 : : R : G : B`. | #Y |
|
||||
* | 3 | CMY color. | #N |
|
||||
* | 4 | CMYK color. | #N |
|
||||
* | 5 | Indexed (256 colors) as `Ps ; 5 ; INDEX` or `Ps : 5 : INDEX`. | #Y |
|
||||
*
|
||||
*
|
||||
* FIXME: blinking is implemented in attrs, but not working in renderers?
|
||||
* FIXME: remove dead branch for p=100
|
||||
*/
|
||||
public charAttributes(params: IParams): void {
|
||||
// Optimize a single SGR0.
|
||||
@@ -1892,7 +2192,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
} else if (p === 38 || p === 48) {
|
||||
// fg color 256 and RGB
|
||||
i += this._extractColor(params, i, attr);
|
||||
} else if (p === 100) {
|
||||
} else if (p === 100) { // FIXME: dead branch, p=100 already handled above!
|
||||
// reset fg/bg
|
||||
attr.fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK);
|
||||
attr.fg |= DEFAULT_ATTR_DATA.fg & (Attributes.PCOLOR_MASK | Attributes.RGB_MASK);
|
||||
@@ -1926,6 +2226,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 5 3 -> Report Locator status as
|
||||
* CSI ? 5 3 n Locator available, if compiled-in, or
|
||||
* CSI ? 5 0 n No Locator, if not.
|
||||
*
|
||||
* @vt: #Y CSI DSR "Device Status Report" "CSI Ps n" "Request cursor position (CPR) with `Ps` = 6."
|
||||
*/
|
||||
public deviceStatus(params: IParams): void {
|
||||
switch (params.params[0]) {
|
||||
@@ -1942,6 +2244,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// @vt: #P[Only CPR is supported.] CSI DECDSR "DEC Device Status Report" "CSI ? Ps n" "Only CPR is supported (same as DSR)."
|
||||
public deviceStatusPrivate(params: IParams): void {
|
||||
// modern xterm doesnt seem to
|
||||
// respond to any of these except ?6, 6, and 5
|
||||
@@ -1974,6 +2277,20 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI ! p Soft terminal reset (DECSTR).
|
||||
* http://vt100.net/docs/vt220-rm/table4-10.html
|
||||
*
|
||||
* @vt: #Y CSI DECSTR "Soft Terminal Reset" "CSI ! p" "Reset several terminal attributes to initial state."
|
||||
* There are two terminal reset sequences - RIS and DECSTR. While RIS performs almost a full terminal bootstrap,
|
||||
* DECSTR only resets certain attributes. For most needs DECSTR should be sufficient.
|
||||
*
|
||||
* The following terminal attributes are reset to default values:
|
||||
* - cursor is reset (default = visible, home position)
|
||||
* - IRM is reset (dafault = false)
|
||||
* - scroll margins are reset (default = viewport size)
|
||||
* - erase attributes are reset to default
|
||||
* - charsets are reset
|
||||
*
|
||||
*
|
||||
* FIXME: there are several more attributes missing (see VT520 manual)
|
||||
*/
|
||||
public softReset(params: IParams): void {
|
||||
this._coreService.isCursorHidden = false;
|
||||
@@ -1996,6 +2313,15 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* Ps = 4 -> steady underline.
|
||||
* Ps = 5 -> blinking bar (xterm).
|
||||
* Ps = 6 -> steady bar (xterm).
|
||||
*
|
||||
* @vt: #Y CSI DECSCUSR "Set Cursor Style" "CSI Ps SP q" "Set cursor style."
|
||||
* Supported cursor styles:
|
||||
* - empty, 0 or 1: steady block
|
||||
* - 2: blink block
|
||||
* - 3: steady underline
|
||||
* - 4: blink underline
|
||||
* - 5: steady bar
|
||||
* - 6: blink bar
|
||||
*/
|
||||
public setCursorStyle(params: IParams): void {
|
||||
const param = params.params[0] || 1;
|
||||
@@ -2021,6 +2347,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* CSI Ps ; Ps r
|
||||
* Set Scrolling Region [top;bottom] (default = full size of win-
|
||||
* dow) (DECSTBM).
|
||||
*
|
||||
* @vt: #Y CSI DECSTBM "Set Top and Bottom Margin" "CSI Ps ; Ps r" "Set top and bottom margins of the viewport [top;bottom] (default = viewport size)."
|
||||
*/
|
||||
public setScrollRegion(params: IParams): void {
|
||||
const top = params.params[0] || 1;
|
||||
@@ -2042,6 +2370,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* CSI s
|
||||
* ESC 7
|
||||
* Save cursor (ANSI.SYS).
|
||||
*
|
||||
* @vt: #P[TODO...] CSI SCOSC "Save Cursor" "CSI s" "Save cursor position, charmap and text attributes."
|
||||
* @vt: #Y ESC SC "Save Cursor" "ESC 7" "Save cursor position, charmap and text attributes."
|
||||
*/
|
||||
public saveCursor(params?: IParams): void {
|
||||
this._bufferService.buffer.savedX = this._bufferService.buffer.x;
|
||||
@@ -2056,6 +2387,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* CSI u
|
||||
* ESC 8
|
||||
* Restore cursor (ANSI.SYS).
|
||||
*
|
||||
* @vt: #P[TODO...] CSI SCORC "Restore Cursor" "CSI u" "Restore cursor position, charmap and text attributes."
|
||||
* @vt: #Y ESC RC "Restore Cursor" "ESC 8" "Restore cursor position, charmap and text attributes."
|
||||
*/
|
||||
public restoreCursor(params?: IParams): void {
|
||||
this._bufferService.buffer.x = this._bufferService.buffer.savedX || 0;
|
||||
@@ -2074,6 +2408,12 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* OSC 0; <data> ST (set icon name + window title)
|
||||
* OSC 2; <data> ST (set window title)
|
||||
* Proxy to set window title. Icon name is not supported.
|
||||
*
|
||||
* @vt: #P[Icon name is not exposed.] OSC 0 "Set Windows Title and Icon Name" "OSC 0 ; Pt BEL" "Set window title and icon name."
|
||||
* Icon name is not supported. For Window Title see below.
|
||||
*
|
||||
* @vt: #Y OSC 2 "Set Windows Title" "OSC 2 ; Pt BEL" "Set window title."
|
||||
* xterm.js does not manipulate the title directly, instead exposes changes via the event `Terminal.onTitleChange`.
|
||||
*/
|
||||
public setTitle(data: string): void {
|
||||
this._terminal.handleTitle(data);
|
||||
@@ -2084,6 +2424,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* C1.NEL
|
||||
* DEC mnemonic: NEL (https://vt100.net/docs/vt510-rm/NEL)
|
||||
* Moves cursor to first position on next line.
|
||||
*
|
||||
* @vt: #Y C1 NEL "Next Line" "\x85" "Move the cursor to the beginning of the next row."
|
||||
* @vt: #Y ESC NEL "Next Line" "ESC E" "Move the cursor to the beginning of the next row."
|
||||
*/
|
||||
public nextLine(): void {
|
||||
this._bufferService.buffer.x = 0;
|
||||
@@ -2156,6 +2499,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* C1.IND
|
||||
* DEC mnemonic: IND (https://vt100.net/docs/vt510-rm/IND.html)
|
||||
* Moves the cursor down one line in the same column.
|
||||
*
|
||||
* @vt: #Y C1 IND "Index" "\x84" "Move the cursor one line down scrolling if needed."
|
||||
* @vt: #Y ESC IND "Index" "ESC D" "Move the cursor one line down scrolling if needed."
|
||||
*/
|
||||
public index(): void {
|
||||
this._restrictCursor();
|
||||
@@ -2176,6 +2522,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* DEC mnemonic: HTS (https://vt100.net/docs/vt510-rm/HTS.html)
|
||||
* Sets a horizontal tab stop at the column position indicated by
|
||||
* the value of the active column when the terminal receives an HTS.
|
||||
*
|
||||
* @vt: #Y C1 HTS "Horizontal Tabulation Set" "\x88" "Places a tab stop at the current cursor position."
|
||||
* @vt: #Y ESC HTS "Horizontal Tabulation Set" "ESC H" "Places a tab stop at the current cursor position."
|
||||
*/
|
||||
public tabSet(): void {
|
||||
this._bufferService.buffer.tabs[this._bufferService.buffer.x] = true;
|
||||
@@ -2187,6 +2536,8 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* DEC mnemonic: HTS
|
||||
* Moves the cursor up one line in the same column. If the cursor is at the top margin,
|
||||
* the page scrolls down.
|
||||
*
|
||||
* @vt: #Y ESC IR "Reverse Index" "ESC M" "Move the cursor one line up scrolling if needed."
|
||||
*/
|
||||
public reverseIndex(): void {
|
||||
this._restrictCursor();
|
||||
@@ -2249,7 +2600,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* This control function fills the complete screen area with
|
||||
* a test pattern (E) used for adjusting screen alignment.
|
||||
*
|
||||
* TODO: move DECALN into compat addon
|
||||
* @vt: #Y ESC DECALN "Screen Alignment Pattern" "ESC # 8" "Fill viewport with a test pattern (E)."
|
||||
*/
|
||||
public screenAlignmentPattern(): void {
|
||||
// prepare cell data
|
||||
|
||||
@@ -3421,6 +3421,11 @@ ms@2.1.1, ms@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
|
||||
mustache@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mustache/-/mustache-3.0.1.tgz#873855f23aa8a95b150fb96d9836edbc5a1d248a"
|
||||
integrity sha512-jFI/4UVRsRYdUbuDTKT7KzfOp7FiD5WzYmmwNwXyUVypC0xjoTL78Fqc0jHUPIvvGD+6DQSPHIt1NE7D1ArsqA==
|
||||
|
||||
mute-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||
|
||||
Reference in New Issue
Block a user