Merge pull request #2386 from jerch/extract_vt_features

document VT features in docstrings
This commit is contained in:
Daniel Imms
2020-02-04 06:50:07 -08:00
committed by GitHub
4 changed files with 964 additions and 103 deletions
+503
View File
@@ -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
View File
@@ -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
View File
@@ -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
+5
View File
@@ -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"