diff --git a/.travis.yml b/.travis.yml
index 1878c3a4..7a37af1e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,6 @@
language: node_js
os:
- linux
- - osx
node_js:
- 6
before_install:
diff --git a/README.md b/README.md
index 05c26f84..730fc9af 100644
--- a/README.md
+++ b/README.md
@@ -120,6 +120,11 @@ computational environment for Jupyter, supporting interactive data science and s
- [**VTerm**](https://github.com/vterm/vterm): Extensible terminal emulator based on Electron and React.
- [**electerm**](http://electerm.html5beta.com): electerm is a terminal/ssh/sftp client(mac, win, linux) based on electron/node-pty/xterm.
- [**Kubebox**](https://github.com/astefanutti/kubebox): Terminal console for Kubernetes clusters.
+- [**Azure Cloud Shell**](https://shell.azure.com): Azure Cloud Shell is a Microsoft-managed admin machine built on Azure, for Azure.
+- [**atom-xterm**](https://atom.io/packages/atom-xterm): Atom plugin for providing terminals inside your Atom workspace.
+- [**rtty**](https://github.com/zhaojh329/rtty): A reverse proxy WebTTY. It is composed of the client and the server.
+- [**Pisth**](https://github.com/ColdGrub1384/Pisth): An SFTP and SSH client for iOS
+- [**abstruse**](https://github.com/bleenco/abstruse): Abstruse CI is a continuous integration platform based on Node.JS and Docker.
Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list.
diff --git a/demo/index.html b/demo/index.html
index 93399f9c..da348f5e 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -23,6 +23,9 @@
cursorBlink
+
+ macOptionIsMeta
+
cursorStyle
diff --git a/demo/main.js b/demo/main.js
index 95b15a0d..1faf77d8 100644
--- a/demo/main.js
+++ b/demo/main.js
@@ -27,6 +27,7 @@ var terminalContainer = document.getElementById('terminal-container'),
optionElements = {
cursorBlink: document.querySelector('#option-cursor-blink'),
cursorStyle: document.querySelector('#option-cursor-style'),
+ macOptionIsMeta: document.querySelector('#option-mac-option-is-meta'),
scrollback: document.querySelector('#option-scrollback'),
tabstopwidth: document.querySelector('#option-tabstopwidth'),
bellStyle: document.querySelector('#option-bell-style')
@@ -72,6 +73,9 @@ optionElements.cursorStyle.addEventListener('change', function () {
optionElements.bellStyle.addEventListener('change', function () {
term.setOption('bellStyle', optionElements.bellStyle.value);
});
+optionElements.macOptionIsMeta.addEventListener('change', function () {
+ term.setOption('macOptionIsMeta', optionElements.macOptionIsMeta.checked);
+});
optionElements.scrollback.addEventListener('change', function () {
term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10));
});
@@ -87,6 +91,7 @@ function createTerminal() {
terminalContainer.removeChild(terminalContainer.children[0]);
}
term = new Terminal({
+ macOptionIsMeta: optionElements.macOptionIsMeta.enabled,
cursorBlink: optionElements.cursorBlink.checked,
scrollback: parseInt(optionElements.scrollback.value, 10),
tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10)
diff --git a/fixtures/typings-test/typings-test.ts b/fixtures/typings-test/typings-test.ts
index 5a5f6c50..6761dcd5 100644
--- a/fixtures/typings-test/typings-test.ts
+++ b/fixtures/typings-test/typings-test.ts
@@ -144,6 +144,9 @@ namespace methods_core {
const r20: string = t.getOption('bellStyle');
const r21: boolean = t.getOption('enableBold');
const r22: number = t.getOption('letterSpacing');
+ const r23: boolean = t.getOption('macOptionIsMeta');
+ const r24: string = t.getOption('fontWeight');
+ const r25: string = t.getOption('fontWeightBold');
}
{
const t: Terminal = new Terminal();
@@ -157,6 +160,10 @@ namespace methods_core {
t.setOption('debug', true);
t.setOption('disableStdin', true);
t.setOption('enableBold', true);
+ t.setOption('fontWeight', 'normal');
+ t.setOption('fontWeight', 'bold');
+ t.setOption('fontWeightBold', 'normal');
+ t.setOption('fontWeightBold', 'bold');
t.setOption('popOnBell', true);
t.setOption('screenKeys', true);
t.setOption('useFlowControl', true);
@@ -177,6 +184,7 @@ namespace methods_core {
t.setOption('lineHeight', 1);
t.setOption('fontFamily', 'foo');
t.setOption('theme', {background: '#ff0000'});
+ t.setOption('macOptionIsMeta', true);
}
}
namespace scrolling {
diff --git a/gulpfile.js b/gulpfile.js
index 49d67ed6..7a65d7f2 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -18,11 +18,13 @@ const ts = require('gulp-typescript');
const util = require('gulp-util');
const webpack = require('webpack-stream');
-let buildDir = process.env.BUILD_DIR || 'build';
-let tsProject = ts.createProject('tsconfig.json');
-let srcDir = tsProject.config.compilerOptions.rootDir;
+const buildDir = process.env.BUILD_DIR || 'build';
+const tsProject = ts.createProject('tsconfig.json');
+const srcDir = tsProject.config.compilerOptions.rootDir;
let outDir = tsProject.config.compilerOptions.outDir;
+const addons = ['attach', 'fit', 'fullscreen', 'search', 'terminado', 'winptyCompat', 'zmodem'];
+
// Under some environments like TravisCI, this comes out at absolute which can
// break the build. This ensures that the outDir is absolute.
if (path.normalize(outDir).indexOf(__dirname) !== 0) {
@@ -45,15 +47,19 @@ gulp.task('tsc', function () {
tsResult.dts.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(outDir))
);
- let addons = ['attach', 'fit', 'fullscreen', 'search', 'terminado', 'winptyCompat', 'zmodem'];
let addonStreams = addons.map(function(addon) {
fs.emptyDirSync(`${outDir}/addons/${addon}`);
let tsProjectAddon = ts.createProject(`./src/addons/${addon}/tsconfig.json`);
let tsResultAddon = tsProjectAddon.src().pipe(sourcemaps.init()).pipe(tsProjectAddon());
- let tscAddon = tsResultAddon.js
- .pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''}))
- .pipe(gulp.dest(`${outDir}/addons/${addon}`));
+ let tscAddon = merge(
+ tsResultAddon.js
+ .pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''}))
+ .pipe(gulp.dest(`${outDir}/addons/${addon}`)),
+ tsResultAddon.dts
+ .pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''}))
+ .pipe(gulp.dest(`${outDir}/addons/${addon}`))
+ )
return tscAddon;
});
@@ -103,45 +109,29 @@ gulp.task('browserify', ['tsc'], function() {
});
gulp.task('browserify-addons', ['tsc'], function() {
- let searchOptions = {
- basedir: `${buildDir}/addons/search`,
- debug: true,
- entries: [`${outDir}/addons/search/search.js`],
- cache: {},
- packageCache: {}
- };
- let searchBundle = browserify(searchOptions)
- .external(path.join(outDir, 'Terminal.js'))
- .bundle()
- .pipe(source('./addons/search/search.js'))
- .pipe(buffer())
- .pipe(sourcemaps.init({loadMaps: true, sourceRoot: ''}))
- .pipe(sourcemaps.write('./'))
- .pipe(gulp.dest(buildDir));
+ const bundles = addons.map((addon) => {
+ const addonOptions = {
+ basedir: `${buildDir}/addons/${addon}`,
+ debug: true,
+ entries: [`${outDir}/addons/${addon}/${addon}.js`],
+ standalone: addon,
+ cache: {},
+ packageCache: {}
+ };
- let winptyCompatOptions = {
- basedir: `${buildDir}/addons/winptyCompat`,
- debug: true,
- entries: [`${outDir}/addons/winptyCompat/winptyCompat.js`],
- cache: {},
- packageCache: {}
- };
- let winptyCompatBundle = browserify(winptyCompatOptions)
- .external(path.join(outDir, 'Terminal.js'))
- .bundle()
- .pipe(source('./addons/winptyCompat/winptyCompat.js'))
- .pipe(buffer())
- .pipe(sourcemaps.init({loadMaps: true, sourceRoot: ''}))
- .pipe(sourcemaps.write('./'))
- .pipe(gulp.dest(buildDir));
+ const addonBundle = browserify(addonOptions)
+ .external(path.join(outDir, 'Terminal.js'))
+ .bundle()
+ .pipe(source(`./addons/${addon}/${addon}.js`))
+ .pipe(buffer())
+ .pipe(sourcemaps.init({loadMaps: true, sourceRoot: ''}))
+ .pipe(sourcemaps.write('./'))
+ .pipe(gulp.dest(buildDir));
- // Copy all add-ons from outDir to buildDir
- let copyAddons = gulp.src([
- // Copy JS addons
- `${outDir}/addons/**/*`
- ]).pipe(gulp.dest(`${buildDir}/addons`));
+ return addonBundle;
+ });
- return merge(searchBundle, winptyCompatBundle, copyAddons);
+ return merge(...bundles);
});
gulp.task('instrument-test', function () {
@@ -189,9 +179,11 @@ gulp.task('sorcery', ['browserify'], function () {
});
gulp.task('sorcery-addons', ['browserify-addons'], function () {
- var chain = sorcery.loadSync(`${buildDir}/addons/search/search.js`);
- chain.apply();
- chain.writeSync();
+ addons.forEach((addon) => {
+ const chain = sorcery.loadSync(`${buildDir}/addons/${addon}/${addon}.js`);
+ chain.apply();
+ chain.writeSync();
+ })
});
gulp.task('webpack', ['build'], function() {
diff --git a/package-lock.json b/package-lock.json
index c83a4d9a..f7c01276 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "xterm",
- "version": "2.9.1",
+ "version": "3.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -56,6 +56,16 @@
"integrity": "sha512-bJgf+gJF+zohYkhOOdY7cXVKa0jMZGICqIcdPRb1SFyPHI4sKau0tXTRLmT2T4S5bjx6cY9AuoMkB5v+TIL4wA==",
"dev": true
},
+ "JSONStream": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
+ "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=",
+ "dev": true,
+ "requires": {
+ "jsonparse": "1.3.1",
+ "through": "2.3.8"
+ }
+ },
"abab": {
"version": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz",
"integrity": "sha1-uB3l9ydOxOdW15fNg08wNkJyTl0=",
@@ -98,6 +108,15 @@
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
+ "argparse": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
"array-differ": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
@@ -199,6 +218,86 @@
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
"dev": true
},
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "esutils": "2.0.2",
+ "js-tokens": "3.0.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "2.2.1",
+ "escape-string-regexp": "1.0.5",
+ "has-ansi": "2.0.0",
+ "strip-ansi": "3.0.1",
+ "supports-color": "2.0.0"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "2.1.1"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
"base64-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
@@ -234,6 +333,16 @@
"hoek": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz"
}
},
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
"brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -246,9 +355,9 @@
"integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=",
"dev": true,
"requires": {
+ "JSONStream": "1.3.1",
"combine-source-map": "0.7.2",
"defined": "1.0.0",
- "JSONStream": "1.3.1",
"through2": "2.0.3",
"umd": "3.0.1"
}
@@ -276,6 +385,7 @@
"integrity": "sha1-tanJAgJD8McORnW+yCI7xifkFc4=",
"dev": true,
"requires": {
+ "JSONStream": "1.3.1",
"assert": "1.4.1",
"browser-pack": "6.0.2",
"browser-resolve": "1.11.2",
@@ -297,7 +407,6 @@
"https-browserify": "0.0.1",
"inherits": "2.0.3",
"insert-module-globals": "7.0.1",
- "JSONStream": "1.3.1",
"labeled-stream-splicer": "2.0.0",
"module-deps": "4.1.1",
"os-browserify": "0.1.2",
@@ -474,6 +583,12 @@
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
"dev": true
},
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
"builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
@@ -584,6 +699,21 @@
"through2": "2.0.3"
}
},
+ "color-convert": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
"combine-source-map": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz",
@@ -610,6 +740,12 @@
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
"dev": true
},
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
"concat-stream": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz",
@@ -740,43 +876,6 @@
"sha.js": "2.4.8"
}
},
- "cross-spawn-async": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz",
- "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=",
- "dev": true,
- "requires": {
- "lru-cache": "4.1.1",
- "which": "1.2.14"
- },
- "dependencies": {
- "isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
- "dev": true
- },
- "lru-cache": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
- "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
- "dev": true,
- "requires": {
- "pseudomap": "1.0.2",
- "yallist": "2.1.2"
- }
- },
- "which": {
- "version": "1.2.14",
- "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
- "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
- "dev": true,
- "requires": {
- "isexe": "2.0.0"
- }
- }
- }
- },
"cryptiles": {
"version": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
@@ -803,12 +902,6 @@
"randombytes": "2.0.5"
}
},
- "crypto-random-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
- "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
- "dev": true
- },
"cssom": {
"version": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
"integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=",
@@ -897,6 +990,12 @@
"defined": "1.0.0"
}
},
+ "diff": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
+ "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
+ "dev": true
+ },
"diffie-hellman": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
@@ -929,12 +1028,6 @@
"readable-stream": "1.1.14"
}
},
- "duplexer3": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
- "dev": true
- },
"each-props": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.0.tgz",
@@ -1035,34 +1128,6 @@
"create-hash": "1.1.3"
}
},
- "execa": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-0.4.0.tgz",
- "integrity": "sha1-TrZGejaglfq7KXD/nV4/t7zm68M=",
- "dev": true,
- "requires": {
- "cross-spawn-async": "2.2.5",
- "is-stream": "1.1.0",
- "npm-run-path": "1.0.0",
- "object-assign": "4.1.1",
- "path-key": "1.0.0",
- "strip-eof": "1.0.0"
- },
- "dependencies": {
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "dev": true
- }
- }
- },
"exit-on-epipe": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
@@ -1596,12 +1661,6 @@
"is-property": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
}
},
- "get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true
- },
"getpass": {
"version": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz",
"integrity": "sha1-KD/9n8ElaECHUxHBtg6MQBhxEOY=",
@@ -8461,6 +8520,12 @@
"ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
}
},
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
"has-gulplog": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz",
@@ -8589,12 +8654,6 @@
"integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
"dev": true
},
- "import-lazy": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
- "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
- "dev": true
- },
"indexof": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
@@ -8622,10 +8681,10 @@
"integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=",
"dev": true,
"requires": {
+ "JSONStream": "1.3.1",
"combine-source-map": "0.7.2",
"concat-stream": "1.5.2",
"is-buffer": "1.1.5",
- "JSONStream": "1.3.1",
"lexical-scope": "1.2.0",
"process": "0.11.10",
"through2": "2.0.3",
@@ -8704,6 +8763,30 @@
"jsbn": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz"
}
},
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+ "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+ "dev": true,
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "4.0.0"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+ "dev": true
+ }
+ }
+ },
"jsbn": {
"version": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
@@ -8972,16 +9055,6 @@
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
"dev": true
},
- "JSONStream": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
- "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=",
- "dev": true,
- "requires": {
- "jsonparse": "1.3.1",
- "through": "2.3.8"
- }
- },
"jsprim": {
"version": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz",
"integrity": "sha1-KnJW9wQSop7jZwqspiWZTE3P8lI=",
@@ -9151,15 +9224,6 @@
"lodash.escape": "3.2.0"
}
},
- "make-dir": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz",
- "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=",
- "dev": true,
- "requires": {
- "pify": "2.3.0"
- }
- },
"merge-stream": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
@@ -9260,6 +9324,15 @@
"integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
"dev": true
},
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
@@ -9539,6 +9612,7 @@
"integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=",
"dev": true,
"requires": {
+ "JSONStream": "1.3.1",
"browser-resolve": "1.11.2",
"cached-path-relative": "1.0.1",
"concat-stream": "1.5.2",
@@ -9546,7 +9620,6 @@
"detective": "4.5.0",
"duplexer2": "0.1.4",
"inherits": "2.0.3",
- "JSONStream": "1.3.1",
"parents": "1.0.1",
"readable-stream": "2.3.3",
"resolve": "1.4.0",
@@ -10660,15 +10733,6 @@
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
"dev": true
},
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"string-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
@@ -10678,6 +10742,15 @@
"strip-ansi": "3.0.1"
}
},
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -10781,15 +10854,6 @@
}
}
},
- "npm-run-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz",
- "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=",
- "dev": true,
- "requires": {
- "path-key": "1.0.0"
- }
- },
"oauth-sign": {
"version": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
@@ -10922,12 +10986,6 @@
"integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
"dev": true
},
- "path-key": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz",
- "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=",
- "dev": true
- },
"path-parse": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
@@ -10953,12 +11011,6 @@
"sha.js": "2.4.8"
}
},
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true
- },
"pinkie": {
"version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
@@ -11001,12 +11053,6 @@
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
"dev": true
},
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
"public-encrypt": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
@@ -11208,6 +11254,12 @@
"integrity": "sha1-/YYxojvHgmvvXYcb24c3jJVkeCg=",
"dev": true
},
+ "semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+ "dev": true
+ },
"sha.js": {
"version": "2.4.8",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz",
@@ -11350,6 +11402,12 @@
"integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=",
"dev": true
},
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
"sshpk": {
"version": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.2.tgz",
"integrity": "sha1-1agEziJpVRVjjnmNviMnPeBwpfo=",
@@ -11584,12 +11642,6 @@
"ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
}
},
- "strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
- "dev": true
- },
"subarg": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
@@ -11618,15 +11670,6 @@
"acorn": "4.0.13"
}
},
- "term-size": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/term-size/-/term-size-0.1.1.tgz",
- "integrity": "sha1-hzYLljlsq1dgljcUzaDQy+7K2co=",
- "dev": true,
- "requires": {
- "execa": "0.4.0"
- }
- },
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -11715,619 +11758,83 @@
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"dev": true
},
+ "tslib": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.1.tgz",
+ "integrity": "sha1-aUavLR1lGnsYY7Ux1uWvpBqkTqw=",
+ "dev": true
+ },
"tslint": {
- "version": "4.5.1",
- "resolved": "https://registry.npmjs.org/tslint/-/tslint-4.5.1.tgz",
- "integrity": "sha1-BTVocb7yOkNJBnNABvwYgza6gks=",
+ "version": "5.9.1",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz",
+ "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=",
"dev": true,
"requires": {
- "babel-code-frame": "6.22.0",
- "colors": "1.1.2",
- "diff": "3.3.0",
- "findup-sync": "0.3.0",
+ "babel-code-frame": "6.26.0",
+ "builtin-modules": "1.1.1",
+ "chalk": "2.3.0",
+ "commander": "2.13.0",
+ "diff": "3.4.0",
"glob": "7.1.2",
- "optimist": "0.6.1",
- "resolve": "1.3.3",
- "tsutils": "1.9.1",
- "update-notifier": "2.2.0"
+ "js-yaml": "3.10.0",
+ "minimatch": "3.0.4",
+ "resolve": "1.4.0",
+ "semver": "5.5.0",
+ "tslib": "1.8.1",
+ "tsutils": "2.19.0"
},
"dependencies": {
- "ansi-align": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
- "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
- "dev": true,
- "requires": {
- "string-width": "2.1.0"
- }
- },
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- },
"ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "babel-code-frame": {
- "version": "6.22.0",
- "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
- "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+ "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
"dev": true,
"requires": {
- "chalk": "1.1.3",
- "esutils": "2.0.2",
- "js-tokens": "3.0.2"
+ "color-convert": "1.9.1"
}
},
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
- "dev": true
- },
- "boxen": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.1.0.tgz",
- "integrity": "sha1-sbad1SIwXoB6md7ud329blFnsQI=",
- "dev": true,
- "requires": {
- "ansi-align": "2.0.0",
- "camelcase": "4.1.0",
- "chalk": "1.1.3",
- "cli-boxes": "1.0.0",
- "string-width": "2.1.0",
- "term-size": "0.1.1",
- "widest-line": "1.0.0"
- }
- },
- "brace-expansion": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
- "dev": true,
- "requires": {
- "balanced-match": "1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- },
- "capture-stack-trace": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz",
- "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=",
- "dev": true
- },
"chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+ "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
"dev": true,
"requires": {
- "ansi-styles": "2.2.1",
+ "ansi-styles": "3.2.0",
"escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
+ "supports-color": "4.5.0"
}
},
- "cli-boxes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
- "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
+ "commander": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
+ "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
"dev": true
},
- "code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
- "dev": true
- },
- "colors": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
- "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
- "dev": true
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true
- },
- "configstore": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.0.tgz",
- "integrity": "sha1-Rd+QcHPibfoc9LLVL1tgVF6qEdE=",
- "dev": true,
- "requires": {
- "dot-prop": "4.1.1",
- "graceful-fs": "4.1.11",
- "make-dir": "1.0.0",
- "unique-string": "1.0.0",
- "write-file-atomic": "2.1.0",
- "xdg-basedir": "3.0.0"
- }
- },
- "create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "dev": true,
- "requires": {
- "capture-stack-trace": "1.0.0"
- }
- },
- "deep-extend": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
- "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
- "dev": true
- },
- "diff": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.0.tgz",
- "integrity": "sha512-w0XZubFWn0Adlsapj9EAWX0FqWdO4tz8kc3RiYdWLh4k/V8PTb6i0SMgXt0vRM3zyKnT8tKO7mUlieRQHIjMNg==",
- "dev": true
- },
- "dot-prop": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.1.1.tgz",
- "integrity": "sha1-qEk/C3te7sglJbXHWH+n3nyoWcE=",
- "dev": true,
- "requires": {
- "is-obj": "1.0.1"
- }
- },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
- "esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
- "dev": true
- },
- "findup-sync": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
- "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
- "dev": true,
- "requires": {
- "glob": "5.0.15"
- },
- "dependencies": {
- "glob": {
- "version": "5.0.15",
- "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
- "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
- "dev": true,
- "requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
- }
- }
- }
- },
- "got": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
- "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
- "dev": true,
- "requires": {
- "create-error-class": "3.0.2",
- "duplexer3": "0.1.4",
- "get-stream": "3.0.0",
- "is-redirect": "1.0.0",
- "is-retry-allowed": "1.1.0",
- "is-stream": "1.1.0",
- "lowercase-keys": "1.0.0",
- "safe-buffer": "5.1.1",
- "timed-out": "4.0.1",
- "unzip-response": "2.0.1",
- "url-parse-lax": "1.0.0"
- }
- },
- "graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
- "dev": true
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "dev": true,
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "dev": true
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "dev": true,
- "requires": {
- "once": "1.4.0",
- "wrappy": "1.0.2"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true
- },
- "ini": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
- "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "is-npm": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
- "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
- "dev": true
- },
- "is-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
- "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
- "dev": true
- },
- "is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
- "dev": true
- },
- "is-retry-allowed": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
- "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
- "dev": true
- },
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true
- },
- "js-tokens": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
- "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
- "dev": true
- },
- "latest-version": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
- "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
- "dev": true,
- "requires": {
- "package-json": "4.0.1"
- }
- },
- "lowercase-keys": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
- "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
- "dev": true
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "dev": true,
- "requires": {
- "brace-expansion": "1.1.8"
- }
- },
- "minimist": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
- "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
- "dev": true
- },
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "dev": true
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "dev": true,
- "requires": {
- "wrappy": "1.0.2"
- }
- },
- "optimist": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
- "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
- "dev": true,
- "requires": {
- "minimist": "0.0.10",
- "wordwrap": "0.0.3"
- }
- },
- "package-json": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
- "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
- "dev": true,
- "requires": {
- "got": "6.7.1",
- "registry-auth-token": "3.3.1",
- "registry-url": "3.1.0",
- "semver": "5.3.0"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true
- },
- "prepend-http": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
- "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
- "dev": true
- },
- "rc": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
- "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
- "dev": true,
- "requires": {
- "deep-extend": "0.4.2",
- "ini": "1.3.4",
- "minimist": "1.2.0",
- "strip-json-comments": "2.0.1"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
- }
- },
- "registry-auth-token": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz",
- "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=",
- "dev": true,
- "requires": {
- "rc": "1.2.1",
- "safe-buffer": "5.1.1"
- }
- },
- "registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "dev": true,
- "requires": {
- "rc": "1.2.1"
- }
- },
- "resolve": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz",
- "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=",
- "dev": true,
- "requires": {
- "path-parse": "1.0.5"
- }
- },
- "semver": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
- "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
- "dev": true
- },
- "semver-diff": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
- "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
- "dev": true,
- "requires": {
- "semver": "5.3.0"
- }
- },
- "slide": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
- "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=",
- "dev": true
- },
- "string-width": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.0.tgz",
- "integrity": "sha1-AwZkVh/BRslCPsfZeP4kV0N/5tA=",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "3.0.0"
- }
- }
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "dev": true
- },
"supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- },
- "timed-out": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
- "dev": true
- },
- "unzip-response": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
- "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
- "dev": true
- },
- "update-notifier": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.2.0.tgz",
- "integrity": "sha1-G1g3z5DAc22IYncytmHBOPht5y8=",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
"dev": true,
"requires": {
- "boxen": "1.1.0",
- "chalk": "1.1.3",
- "configstore": "3.1.0",
- "import-lazy": "2.1.0",
- "is-npm": "1.0.0",
- "latest-version": "3.1.0",
- "semver-diff": "2.1.0",
- "xdg-basedir": "3.0.0"
+ "has-flag": "2.0.0"
}
- },
- "url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
- "dev": true,
- "requires": {
- "prepend-http": "1.0.4"
- }
- },
- "widest-line": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz",
- "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=",
- "dev": true,
- "requires": {
- "string-width": "1.0.2"
- },
- "dependencies": {
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "dev": true,
- "requires": {
- "number-is-nan": "1.0.1"
- }
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "dev": true,
- "requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
- "strip-ansi": "3.0.1"
- }
- }
- }
- },
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
- "dev": true
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "dev": true
- },
- "write-file-atomic": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz",
- "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "imurmurhash": "0.1.4",
- "slide": "1.1.6"
- }
- },
- "xdg-basedir": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
- "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
- "dev": true
}
}
},
"tsutils": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz",
- "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=",
- "dev": true
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.19.0.tgz",
+ "integrity": "sha512-qjgvrvtzRUtOmqlZTfBFtep6s+ymuBLsHOC4ee9JNA+AZIbnR/x4C2Y7QFhOGpD2R3lDp0BBcnxb0vnMVrU7Aw==",
+ "dev": true,
+ "requires": {
+ "tslib": "1.8.1"
+ }
},
"tty-browserify": {
"version": "0.0.0",
@@ -12372,15 +11879,6 @@
"integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=",
"dev": true
},
- "unique-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
- "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
- "dev": true,
- "requires": {
- "crypto-random-string": "1.0.0"
- }
- },
"url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
@@ -12632,12 +12130,6 @@
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
"dev": true
},
- "yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
- "dev": true
- },
"zmodem.js": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/zmodem.js/-/zmodem.js-0.1.6.tgz",
diff --git a/package.json b/package.json
index 1dfadf9f..cf3df57b 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "xterm",
"description": "Full xterm terminal, in your browser",
- "version": "3.0.0",
+ "version": "3.1.0-master",
"ignore": [
"demo",
"test",
@@ -66,7 +66,7 @@
"node-pty": "^0.7.2",
"nodemon": "1.10.2",
"sorcery": "^0.10.0",
- "tslint": "^4.0.2",
+ "tslint": "^5.9.1",
"typescript": "~2.4.0",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
diff --git a/src/Buffer.ts b/src/Buffer.ts
index 623c3854..39b0726c 100644
--- a/src/Buffer.ts
+++ b/src/Buffer.ts
@@ -121,11 +121,6 @@ export class Buffer implements IBuffer {
if (this._terminal.cols < newCols) {
const ch: CharData = [this._terminal.defAttr, ' ', 1, 32]; // does xterm use the default attr?
for (let i = 0; i < this._lines.length; i++) {
- // TODO: This should be removed, with tests setup for the case that was
- // causing the underlying bug, see https://github.com/sourcelair/xterm.js/issues/824
- if (this._lines.get(i) === undefined) {
- this._lines.set(i, this._terminal.blankLine(undefined, undefined, newCols));
- }
while (this._lines.get(i).length < newCols) {
this._lines.get(i).push(ch);
}
@@ -182,16 +177,13 @@ export class Buffer implements IBuffer {
}
// Make sure that the cursor stays on screen
- if (this.y >= newRows) {
- this.y = newRows - 1;
- }
+ this.x = Math.min(this.x, newCols - 1);
+ this.y = Math.min(this.y, newRows - 1);
if (addToY) {
this.y += addToY;
}
-
- if (this.x >= newCols) {
- this.x = newCols - 1;
- }
+ this.savedY = Math.min(this.savedY, newRows - 1);
+ this.savedX = Math.min(this.savedX, newCols - 1);
this.scrollTop = 0;
}
diff --git a/src/BufferSet.ts b/src/BufferSet.ts
index e31d2278..da8c75f2 100644
--- a/src/BufferSet.ts
+++ b/src/BufferSet.ts
@@ -61,24 +61,35 @@ export class BufferSet extends EventEmitter implements IBufferSet {
* Sets the normal Buffer of the BufferSet as its currently active Buffer
*/
public activateNormalBuffer(): void {
+ if (this._activeBuffer === this._normal) {
+ return;
+ }
// The alt buffer should always be cleared when we switch to the normal
// buffer. This frees up memory since the alt buffer should always be new
// when activated.
this._alt.clear();
-
this._activeBuffer = this._normal;
- this.emit('activate', this._normal);
+ this.emit('activate', {
+ activeBuffer: this._normal,
+ inactiveBuffer: this._alt
+ });
}
/**
* Sets the alt Buffer of the BufferSet as its currently active Buffer
*/
public activateAltBuffer(): void {
+ if (this._activeBuffer === this._alt) {
+ return;
+ }
// Since the alt buffer is always cleared when the normal buffer is
// activated, we want to fill it when switching to it.
this._alt.fillViewportRows();
this._activeBuffer = this._alt;
- this.emit('activate', this._alt);
+ this.emit('activate', {
+ activeBuffer: this._alt,
+ inactiveBuffer: this._normal
+ });
}
/**
diff --git a/src/Charsets.ts b/src/Charsets.ts
index 0ee91d32..e62e3f9c 100644
--- a/src/Charsets.ts
+++ b/src/Charsets.ts
@@ -3,19 +3,19 @@
* @license MIT
*/
-import { Charset } from './Types';
+import { ICharset } from './Interfaces';
/**
* The character sets supported by the terminal. These enable several languages
* to be represented within the terminal with only 8-bit encoding. See ISO 2022
* for a discussion on character sets. Only VT100 character sets are supported.
*/
-export const CHARSETS: { [key: string]: Charset } = {};
+export const CHARSETS: { [key: string]: ICharset } = {};
/**
* The default character set, US.
*/
-export const DEFAULT_CHARSET: Charset = CHARSETS['B'];
+export const DEFAULT_CHARSET: ICharset = CHARSETS['B'];
/**
* DEC Special Character and Line Drawing Set.
diff --git a/src/CompositionHelper.ts b/src/CompositionHelper.ts
index ca5b4f4b..e588be78 100644
--- a/src/CompositionHelper.ts
+++ b/src/CompositionHelper.ts
@@ -217,7 +217,7 @@ export class CompositionHelper {
if (!dontRecurse) {
setTimeout(() => this.updateCompositionElements(true), 0);
}
- };
+ }
/**
* Clears the textarea's position so that the cursor does not blink on IE.
@@ -226,5 +226,5 @@ export class CompositionHelper {
private clearTextareaPosition(): void {
this.textarea.style.left = '';
this.textarea.style.top = '';
- };
+ }
}
diff --git a/src/EscapeSequences.ts b/src/EscapeSequences.ts
index cb97c368..11cbd84e 100644
--- a/src/EscapeSequences.ts
+++ b/src/EscapeSequences.ts
@@ -76,4 +76,4 @@ export namespace C0 {
export const SP = '\x20';
/** Delete (Caret = ^?) */
export const DEL = '\x7f';
-};
+}
diff --git a/src/InputHandler.ts b/src/InputHandler.ts
index 1ba6dc7a..96e34cc0 100644
--- a/src/InputHandler.ts
+++ b/src/InputHandler.ts
@@ -26,7 +26,7 @@ export class InputHandler implements IInputHandler {
if (char >= ' ') {
// calculate print space
// expensive call, therefore we save width in line buffer
- const ch_width = wcwidth(code);
+ const chWidth = wcwidth(code);
if (this._terminal.charset && this._terminal.charset[char]) {
char = this._terminal.charset[char];
@@ -36,7 +36,7 @@ export class InputHandler implements IInputHandler {
// insert combining char in last cell
// FIXME: needs handling after cursor jumps
- if (!ch_width && this._terminal.buffer.x) {
+ if (!chWidth && this._terminal.buffer.x) {
// dont overflow left
if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1]) {
if (!this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][CHAR_DATA_WIDTH_INDEX]) {
@@ -56,7 +56,7 @@ export class InputHandler implements IInputHandler {
// goto next line if ch would overflow
// TODO: needs a global min terminal width of 2
- if (this._terminal.buffer.x + ch_width - 1 >= this._terminal.cols) {
+ if (this._terminal.buffer.x + chWidth - 1 >= this._terminal.cols) {
// autowrap - DECAWM
if (this._terminal.wraparoundMode) {
this._terminal.buffer.x = 0;
@@ -70,7 +70,7 @@ export class InputHandler implements IInputHandler {
(this._terminal.buffer.lines.get(this._terminal.buffer.y)).isWrapped = true;
}
} else {
- if (ch_width === 2) // FIXME: check for xterm behavior
+ if (chWidth === 2) // FIXME: check for xterm behavior
return;
}
}
@@ -79,7 +79,7 @@ export class InputHandler implements IInputHandler {
// insert mode: move characters to right
if (this._terminal.insertMode) {
// do this twice for a fullwidth char
- for (let moves = 0; moves < ch_width; ++moves) {
+ for (let moves = 0; moves < chWidth; ++moves) {
// remove last cell, if it's width is 0
// we have to adjust the second last cell as well
const removed = this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).pop();
@@ -94,12 +94,12 @@ export class InputHandler implements IInputHandler {
}
}
- this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, char, ch_width, char.charCodeAt(0)];
+ this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, char, chWidth, char.charCodeAt(0)];
this._terminal.buffer.x++;
this._terminal.updateRange(this._terminal.buffer.y);
// fullwidth char - set next cell width to zero and advance cursor
- if (ch_width === 2) {
+ if (chWidth === 2) {
this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, '', 0, undefined];
this._terminal.buffer.x++;
}
@@ -928,7 +928,6 @@ export class InputHandler implements IInputHandler {
case 47: // alt screen buffer
case 1047: // alt screen buffer
this._terminal.buffers.activateAltBuffer();
- this._terminal.selectionManager.setBuffer(this._terminal.buffer);
this._terminal.viewport.syncScrollArea();
this._terminal.showCursor();
break;
@@ -1100,7 +1099,6 @@ export class InputHandler implements IInputHandler {
// if (params[0] === 1049) {
// this.restoreCursor(params);
// }
- this._terminal.selectionManager.setBuffer(this._terminal.buffer);
this._terminal.refresh(0, this._terminal.rows - 1);
this._terminal.viewport.syncScrollArea();
this._terminal.showCursor();
diff --git a/src/Interfaces.ts b/src/Interfaces.ts
index f90cb8c0..34ab143b 100644
--- a/src/Interfaces.ts
+++ b/src/Interfaces.ts
@@ -3,10 +3,11 @@
* @license MIT
*/
-import { ILinkMatcherOptions } from './Interfaces';
-import { LinkMatcherHandler, LinkMatcherValidationCallback, Charset, LineData } from './Types';
+import { ICharset, ILinkMatcherOptions } from './Interfaces';
+import { LinkMatcherHandler, LinkMatcherValidationCallback, LineData } from './Types';
import { IColorSet, IRenderer } from './renderer/Interfaces';
import { IMouseZoneManager } from './input/Interfaces';
+import { FontWeight } from './shared/Types';
export interface IBrowser {
isNode: boolean;
@@ -74,10 +75,10 @@ export interface IInputHandlingTerminal extends IEventEmitter {
options: ITerminalOptions;
cols: number;
rows: number;
- charset: Charset;
+ charset: ICharset;
gcharset: number;
glevel: number;
- charsets: Charset[];
+ charsets: ICharset[];
applicationKeypad: boolean;
applicationCursor: boolean;
originMode: boolean;
@@ -116,7 +117,7 @@ export interface IInputHandlingTerminal extends IEventEmitter {
blankLine(cur?: boolean, isWrapped?: boolean): LineData;
is(term: string): boolean;
send(data: string): void;
- setgCharset(g: number, charset: Charset): void;
+ setgCharset(g: number, charset: ICharset): void;
resize(x: number, y: number): void;
log(text: string, data?: any): void;
reset(): void;
@@ -140,9 +141,12 @@ export interface ITerminalOptions {
enableBold?: boolean;
fontSize?: number;
fontFamily?: string;
+ fontWeight?: FontWeight;
+ fontWeightBold?: FontWeight;
handler?: (data: string) => void;
letterSpacing?: number;
lineHeight?: number;
+ macOptionIsMeta?: boolean;
rows?: number;
screenKeys?: boolean;
scrollback?: number;
@@ -169,7 +173,7 @@ export interface IBuffer {
prevStop(x?: number): number;
}
-export interface IBufferSet {
+export interface IBufferSet extends IEventEmitter {
alt: IBuffer;
normal: IBuffer;
active: IBuffer;
@@ -198,7 +202,6 @@ export interface ISelectionManager {
disable(): void;
enable(): void;
- setBuffer(buffer: IBuffer): void;
setSelection(row: number, col: number, length: number): void;
}
@@ -248,7 +251,7 @@ export interface IEventEmitter {
export interface IListenerType {
(data?: any): void;
listener?: (data?: any) => void;
-};
+}
export interface ILinkMatcherOptions {
/**
@@ -352,3 +355,24 @@ export interface ITheme {
brightCyan?: string;
brightWhite?: string;
}
+
+export interface ILinkMatcher {
+ id: number;
+ regex: RegExp;
+ handler: LinkMatcherHandler;
+ hoverTooltipCallback?: LinkMatcherHandler;
+ hoverLeaveCallback?: () => void;
+ matchIndex?: number;
+ validationCallback?: LinkMatcherValidationCallback;
+ priority?: number;
+}
+
+export interface ICharset {
+ [key: string]: string;
+}
+
+export interface ILinkHoverEvent {
+ x: number;
+ y: number;
+ length: number;
+}
diff --git a/src/Linkifier.test.ts b/src/Linkifier.test.ts
index 0878aafc..8b66dcaa 100644
--- a/src/Linkifier.test.ts
+++ b/src/Linkifier.test.ts
@@ -4,9 +4,9 @@
*/
import { assert } from 'chai';
-import { ITerminal, ILinkifier, IBuffer, IBufferAccessor, IElementAccessor } from './Interfaces';
+import { ITerminal, ILinkifier, ILinkMatcher, IBuffer, IBufferAccessor, IElementAccessor } from './Interfaces';
import { Linkifier } from './Linkifier';
-import { LinkMatcher, LineData } from './Types';
+import { LineData } from './Types';
import { IMouseZoneManager, IMouseZone } from './input/Interfaces';
import { MockBuffer } from './utils/TestUtils.test';
import { CircularList } from './utils/CircularList';
@@ -17,7 +17,7 @@ class TestLinkifier extends Linkifier {
Linkifier.TIME_BEFORE_LINKIFY = 0;
}
- public get linkMatchers(): LinkMatcher[] { return this._linkMatchers; }
+ public get linkMatchers(): ILinkMatcher[] { return this._linkMatchers; }
public linkifyRows(): void { super.linkifyRows(0, this._terminal.buffer.lines.length - 1); }
}
diff --git a/src/Linkifier.ts b/src/Linkifier.ts
index e6a63b5c..b5f30b56 100644
--- a/src/Linkifier.ts
+++ b/src/Linkifier.ts
@@ -3,8 +3,8 @@
* @license MIT
*/
-import { ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Interfaces';
-import { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEvent, LinkHoverEventTypes } from './Types';
+import { ILinkHoverEvent, ILinkMatcher, ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Interfaces';
+import { LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEventTypes } from './Types';
import { IMouseZoneManager } from './input/Interfaces';
import { MouseZone } from './input/MouseZoneManager';
import { EventEmitter } from './EventEmitter';
@@ -44,7 +44,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
*/
protected static TIME_BEFORE_LINKIFY = 200;
- protected _linkMatchers: LinkMatcher[] = [];
+ protected _linkMatchers: ILinkMatcher[] = [];
private _mouseZoneManager: IMouseZoneManager;
private _rowsTimeoutId: number;
@@ -82,12 +82,12 @@ export class Linkifier extends EventEmitter implements ILinkifier {
}
// Increase range to linkify
- if (!this._rowsToLinkify.start) {
+ if (this._rowsToLinkify.start === null) {
this._rowsToLinkify.start = start;
this._rowsToLinkify.end = end;
} else {
- this._rowsToLinkify.start = this._rowsToLinkify.start < start ? this._rowsToLinkify.start : start;
- this._rowsToLinkify.end = this._rowsToLinkify.end > end ? this._rowsToLinkify.end : end;
+ this._rowsToLinkify.start = Math.min(this._rowsToLinkify.start, start);
+ this._rowsToLinkify.end = Math.max(this._rowsToLinkify.end, end);
}
// Clear out any existing links on this row range
@@ -143,7 +143,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) {
throw new Error('handler must be defined');
}
- const matcher: LinkMatcher = {
+ const matcher: ILinkMatcher = {
id: this._nextLinkMatcherId++,
regex,
handler,
@@ -163,7 +163,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
* considered after older link matchers.
* @param matcher The link matcher to be added.
*/
- private _addLinkMatcherToList(matcher: LinkMatcher): void {
+ private _addLinkMatcherToList(matcher: ILinkMatcher): void {
if (this._linkMatchers.length === 0) {
this._linkMatchers.push(matcher);
return;
@@ -219,7 +219,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
* @param offset The how much of the row has already been linkified.
* @return The link element(s) that were added.
*/
- private _doLinkifyRow(rowIndex: number, text: string, matcher: LinkMatcher, offset: number = 0): void {
+ private _doLinkifyRow(rowIndex: number, text: string, matcher: ILinkMatcher, offset: number = 0): void {
// Iterate over nodes as we want to consider text nodes
let result = [];
const isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID;
@@ -264,7 +264,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
* @param uri The URI of the link.
* @param matcher The link matcher for the link.
*/
- private _addLink(x: number, y: number, uri: string, matcher: LinkMatcher): void {
+ private _addLink(x: number, y: number, uri: string, matcher: ILinkMatcher): void {
this._mouseZoneManager.add(new MouseZone(
x + 1,
x + 1 + uri.length,
@@ -276,17 +276,17 @@ export class Linkifier extends EventEmitter implements ILinkifier {
window.open(uri, '_blank');
},
e => {
- this.emit(LinkHoverEventTypes.HOVER, { x, y, length: uri.length});
+ this.emit(LinkHoverEventTypes.HOVER, { x, y, length: uri.length});
this._terminal.element.style.cursor = 'pointer';
},
e => {
- this.emit(LinkHoverEventTypes.TOOLTIP, { x, y, length: uri.length});
+ this.emit(LinkHoverEventTypes.TOOLTIP, { x, y, length: uri.length});
if (matcher.hoverTooltipCallback) {
matcher.hoverTooltipCallback(e, uri);
}
},
() => {
- this.emit(LinkHoverEventTypes.LEAVE, { x, y, length: uri.length});
+ this.emit(LinkHoverEventTypes.LEAVE, { x, y, length: uri.length});
this._terminal.element.style.cursor = '';
if (matcher.hoverLeaveCallback) {
matcher.hoverLeaveCallback();
diff --git a/src/SelectionManager.test.ts b/src/SelectionManager.test.ts
index a10dc669..97afcf2b 100644
--- a/src/SelectionManager.test.ts
+++ b/src/SelectionManager.test.ts
@@ -21,10 +21,9 @@ class TestMockTerminal extends MockTerminal {
class TestSelectionManager extends SelectionManager {
constructor(
terminal: ITerminal,
- buffer: IBuffer,
charMeasure: CharMeasure
) {
- super(terminal, buffer, charMeasure);
+ super(terminal, charMeasure);
}
public get model(): SelectionModel { return this._model; }
@@ -59,7 +58,7 @@ describe('SelectionManager', () => {
terminal.buffers = new BufferSet(terminal);
terminal.buffer = terminal.buffers.active;
buffer = terminal.buffer;
- selectionManager = new TestSelectionManager(terminal, buffer, null);
+ selectionManager = new TestSelectionManager(terminal, null);
});
function stringToRow(text: string): LineData {
diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts
index 83aaf6a3..934f6c6b 100644
--- a/src/SelectionManager.ts
+++ b/src/SelectionManager.ts
@@ -8,7 +8,7 @@ import * as Browser from './shared/utils/Browser';
import { CharMeasure } from './utils/CharMeasure';
import { CircularList } from './utils/CircularList';
import { EventEmitter } from './EventEmitter';
-import { ITerminal, ICircularList, ISelectionManager, IBuffer } from './Interfaces';
+import { ITerminal, ICircularList, ISelectionManager, IBuffer, IListenerType } from './Interfaces';
import { SelectionModel } from './SelectionModel';
import { LineData, CharData } from './Types';
import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer';
@@ -95,10 +95,10 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
private _mouseMoveListener: EventListener;
private _mouseUpListener: EventListener;
+ private _trimListener: IListenerType;
constructor(
private _terminal: ITerminal,
- private _buffer: IBuffer,
private _charMeasure: CharMeasure
) {
super();
@@ -109,18 +109,24 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
this._activeSelectionMode = SelectionMode.NORMAL;
}
+ private get _buffer(): IBuffer {
+ return this._terminal.buffers.active;
+ }
+
/**
* Initializes listener variables.
*/
private _initListeners(): void {
this._mouseMoveListener = event => this._onMouseMove(event);
this._mouseUpListener = event => this._onMouseUp(event);
+ this._trimListener = (amount: number) => this._onTrim(amount);
- // Only adjust the selection on trim, shiftElements is rarely used (only in
- // reverseIndex) and delete in a splice is only ever used when the same
- // number of elements was just added. Given this is could actually be
- // beneficial to leave the selection as is for these cases.
- this._buffer.lines.on('trim', (amount: number) => this._onTrim(amount));
+ this.initBuffersListeners();
+ }
+
+ public initBuffersListeners(): void {
+ this._terminal.buffer.lines.on('trim', this._trimListener);
+ this._terminal.buffers.on('activate', e => this._onBufferActivate(e));
}
/**
@@ -139,16 +145,6 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
this._enabled = true;
}
- /**
- * Sets the active buffer, this should be called when the alt buffer is
- * switched in or out.
- * @param buffer The active buffer.
- */
- public setBuffer(buffer: IBuffer): void {
- this._buffer = buffer;
- this.clearSelection();
- }
-
public get selectionStart(): [number, number] { return this._model.finalSelectionStart; }
public get selectionEnd(): [number, number] { return this._model.finalSelectionEnd; }
@@ -547,6 +543,16 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
this._terminal.emit('selection');
}
+ private _onBufferActivate(e: {activeBuffer: IBuffer, inactiveBuffer: IBuffer}): void {
+ this.clearSelection();
+ // Only adjust the selection on trim, shiftElements is rarely used (only in
+ // reverseIndex) and delete in a splice is only ever used when the same
+ // number of elements was just added. Given this is could actually be
+ // beneficial to leave the selection as is for these cases.
+ e.inactiveBuffer.lines.off('trim', this._trimListener);
+ e.activeBuffer.lines.on('trim', this._trimListener);
+ }
+
/**
* Converts a viewport column to the character index on the buffer line, the
* latter takes into account wide characters.
diff --git a/src/SelectionModel.test.ts b/src/SelectionModel.test.ts
index e195d6bd..eda94718 100644
--- a/src/SelectionModel.test.ts
+++ b/src/SelectionModel.test.ts
@@ -6,7 +6,7 @@
import { assert } from 'chai';
import { ITerminal } from './Interfaces';
import { SelectionModel } from './SelectionModel';
-import {BufferSet} from './BufferSet';
+import { BufferSet } from './BufferSet';
import { MockTerminal } from './utils/TestUtils.test';
class TestSelectionModel extends SelectionModel {
diff --git a/src/Terminal.integration.ts b/src/Terminal.integration.ts
index 00db4dd6..283c5bc0 100644
--- a/src/Terminal.integration.ts
+++ b/src/Terminal.integration.ts
@@ -15,17 +15,17 @@ import { assert } from 'chai';
import { Terminal } from './Terminal';
import { CHAR_DATA_CHAR_INDEX } from './Buffer';
-let primitive_pty: any;
+let primitivePty: any;
// fake sychronous pty write - read
// we just pipe the data from slave to master as a child program would do
// pty.js opens pipe fds with O_NONBLOCK
// just wait 10ms instead of setting fds to blocking mode
function ptyWriteRead(data: string, cb: (result: string) => void): void {
- fs.writeSync(primitive_pty.slave, data);
+ fs.writeSync(primitivePty.slave, data);
setTimeout(() => {
let b = new Buffer(64000);
- let bytes = fs.readSync(primitive_pty.master, b, 0, 64000, null);
+ let bytes = fs.readSync(primitivePty.master, b, 0, 64000, null);
cb(b.toString('utf8', 0, bytes));
});
}
@@ -37,7 +37,7 @@ function ptyReset(cb: (result: string) => void): void {
/* debug helpers */
// generate colorful noisy output to compare xterm and emulator cell states
-function formatError(in_: string, out_: string, expected: string): string {
+function formatError(input: string, output: string, expected: string): string {
function addLineNumber(start: number, color: string): (s: string) => string {
let counter = start || 0;
return function(s: string): string {
@@ -47,9 +47,9 @@ function formatError(in_: string, out_: string, expected: string): string {
}
let line80 = '12345678901234567890123456789012345678901234567890123456789012345678901234567890';
let s = '';
- s += '\n\x1b[34m' + JSON.stringify(in_);
+ s += '\n\x1b[34m' + JSON.stringify(input);
s += '\n\x1b[33m ' + line80 + '\n';
- s += out_.split('\n').map(addLineNumber(0, '\x1b[31m')).join('\n');
+ s += output.split('\n').map(addLineNumber(0, '\x1b[31m')).join('\n');
s += '\n\x1b[33m ' + line80 + '\n';
s += expected.split('\n').map(addLineNumber(0, '\x1b[32m')).join('\n');
return s;
@@ -58,15 +58,15 @@ function formatError(in_: string, out_: string, expected: string): string {
// simple debug output of terminal cells
function terminalToString(term: Terminal): string {
let result = '';
- let line_s = '';
+ let lineText = '';
for (let line = term.buffer.ybase; line < term.buffer.ybase + term.rows; line++) {
- line_s = '';
+ lineText = '';
for (let cell = 0; cell < term.cols; ++cell) {
- line_s += term.buffer.lines.get(line)[cell][CHAR_DATA_CHAR_INDEX];
+ lineText += term.buffer.lines.get(line)[cell][CHAR_DATA_CHAR_INDEX];
}
// rtrim empty cells as xterm does
- line_s = line_s.replace(/\s+$/, '');
- result += line_s;
+ lineText = lineText.replace(/\s+$/, '');
+ result += lineText;
result += '\n';
}
return result;
@@ -83,7 +83,7 @@ if (os.platform() !== 'win32') {
/** some helpers for pty interaction */
// we need a pty in between to get the termios decorations
// for the basic test cases a raw pty device is enough
- primitive_pty = pty.native.open(COLS, ROWS);
+ primitivePty = pty.native.open(COLS, ROWS);
/** tests */
describe('xterm output comparison', () => {
@@ -118,24 +118,24 @@ if (os.platform() !== 'win32') {
((filename: string) => {
it(filename.split('/').slice(-1)[0], done => {
ptyReset(() => {
- let in_file = fs.readFileSync(filename, 'utf8');
- ptyWriteRead(in_file, from_pty => {
+ let inFile = fs.readFileSync(filename, 'utf8');
+ ptyWriteRead(inFile, fromPty => {
// uncomment this to get log from terminal
// console.log = function(){};
// Perform a synchronous .write(data)
- xterm.writeBuffer.push(from_pty);
+ xterm.writeBuffer.push(fromPty);
xterm.innerWrite();
- let from_emulator = terminalToString(xterm);
+ let fromEmulator = terminalToString(xterm);
console.log = CONSOLE_LOG;
let expected = fs.readFileSync(filename.split('.')[0] + '.text', 'utf8');
// Some of the tests have whitespace on the right of lines, we trim all the linex
// from xterm.js so ignore this for now at least.
let expectedRightTrimmed = expected.split('\n').map(l => l.replace(/\s+$/, '')).join('\n');
- if (from_emulator !== expectedRightTrimmed) {
+ if (fromEmulator !== expectedRightTrimmed) {
// uncomment to get noisy output
- throw new Error(formatError(in_file, from_emulator, expected));
+ throw new Error(formatError(inFile, fromEmulator, expected));
// throw new Error('mismatch');
}
done();
diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts
index 9cb0b75c..946e9efb 100644
--- a/src/Terminal.test.ts
+++ b/src/Terminal.test.ts
@@ -503,6 +503,9 @@ describe('term.js addons', () => {
it('should return \\x1b[5C for alt+right', () => {
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
});
+ it('should return \\x1ba for alt+a', () => {
+ assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, '\x1ba');
+ });
});
describe('On macOS platforms', () => {
@@ -515,6 +518,19 @@ describe('term.js addons', () => {
it('should return \\x1bf for alt+right', () => {
assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1bf'); // CSI 5 C
});
+ it('should return undefined for alt+a', () => {
+ assert.strictEqual(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, undefined);
+ });
+ });
+
+ describe('with macOptionIsMeta', () => {
+ beforeEach(() => {
+ term.browser.isMac = true;
+ term.setOption('macOptionIsMeta', true);
+ });
+ it('should return \\x1ba for alt+a', () => {
+ assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, '\x1ba');
+ });
});
it('should return \\x1b[5A for alt+up', () => {
@@ -597,6 +613,22 @@ describe('term.js addons', () => {
};
});
+ describe('with macOptionIsMeta', () => {
+ beforeEach(() => {
+ term.browser.isMac = true;
+ term.setOption('macOptionIsMeta', true);
+ });
+
+ it('should interfere with the alt key on keyDown', () => {
+ evKeyDown.altKey = true;
+ evKeyDown.keyCode = 81;
+ assert.equal(term.keyDown(evKeyDown), false);
+ evKeyDown.altKey = true;
+ evKeyDown.keyCode = 192;
+ assert.equal(term.keyDown(evKeyDown), false);
+ });
+ });
+
describe('On Mac OS', () => {
beforeEach(() => {
term.browser.isMac = true;
diff --git a/src/Terminal.ts b/src/Terminal.ts
index 220af9e3..3746cb58 100644
--- a/src/Terminal.ts
+++ b/src/Terminal.ts
@@ -38,9 +38,9 @@ import { CharMeasure } from './utils/CharMeasure';
import * as Browser from './shared/utils/Browser';
import { MouseHelper } from './utils/MouseHelper';
import { CHARSETS } from './Charsets';
-import { CustomKeyEventHandler, Charset, LinkMatcherHandler, LinkMatcherValidationCallback, CharData, LineData } from './Types';
-import { ITerminal, IBrowser, ITerminalOptions, IInputHandlingTerminal, ILinkMatcherOptions, IViewport, ICompositionHelper, ITheme, ILinkifier } from './Interfaces';
-import { BellSound } from './utils/Sounds';
+import { CustomKeyEventHandler, LinkMatcherHandler, LinkMatcherValidationCallback, CharData, LineData } from './Types';
+import { ITerminal, IBrowser, ICharset, ITerminalOptions, IInputHandlingTerminal, ILinkMatcherOptions, IViewport, ICompositionHelper, ITheme, ILinkifier } from './Interfaces';
+import { BELL_SOUND } from './utils/Sounds';
import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';
import { IMouseZoneManager } from './input/Interfaces';
import { MouseZoneManager } from './input/MouseZoneManager';
@@ -69,16 +69,19 @@ const DEFAULT_OPTIONS: ITerminalOptions = {
termName: 'xterm',
cursorBlink: false,
cursorStyle: 'block',
- bellSound: BellSound,
+ bellSound: BELL_SOUND,
bellStyle: 'none',
enableBold: true,
fontFamily: 'courier-new, courier, monospace',
fontSize: 15,
+ fontWeight: 'normal',
+ fontWeightBold: 'bold',
lineHeight: 1.0,
letterSpacing: 0,
scrollback: 1000,
screenKeys: false,
debug: false,
+ macOptionIsMeta: false,
cancelEvents: false,
disableStdin: false,
useFlowControl: false,
@@ -130,10 +133,10 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
// charset
// The current charset
- public charset: Charset;
+ public charset: ICharset;
public gcharset: number;
public glevel: number;
- public charsets: Charset[];
+ public charsets: ICharset[];
// mouse properties
private decLocator: boolean; // This is unstable and never set
@@ -180,7 +183,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
private writeStopped: boolean;
// leftover surrogate high from previous write invocation
- private surrogate_high: string;
+ private surrogateHigh: string;
// Store if user went browsing history in scrollback
private userScrolling: boolean;
@@ -191,7 +194,6 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
public selectionManager: SelectionManager;
public linkifier: ILinkifier;
public buffers: BufferSet;
- public buffer: Buffer;
public viewport: IViewport;
private compositionHelper: ICompositionHelper;
public charMeasure: CharMeasure;
@@ -279,7 +281,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.xoffSentToCatchUp = false;
this.writeStopped = false;
- this.surrogate_high = '';
+ this.surrogateHigh = '';
this.userScrolling = false;
this.inputHandler = new InputHandler(this);
@@ -292,17 +294,19 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
// Create the terminal's buffers and set the current buffer
this.buffers = new BufferSet(this);
- this.buffer = this.buffers.active; // Convenience shortcut;
- this.buffers.on('activate', (buffer: Buffer) => {
- this.buffer = buffer;
- });
-
- // Ensure the selection manager has the correct buffer
if (this.selectionManager) {
- this.selectionManager.setBuffer(this.buffer);
+ this.selectionManager.clearSelection();
+ this.selectionManager.initBuffersListeners();
}
}
+ /**
+ * Convenience property to active buffer.
+ */
+ public get buffer(): Buffer {
+ return this.buffers.active;
+ }
+
/**
* back_color_erase feature for xterm.
*/
@@ -360,6 +364,16 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
value = 'block';
}
break;
+ case 'fontWeight':
+ if (!value) {
+ value = 'normal';
+ }
+ break;
+ case 'fontWeightBold':
+ if (!value) {
+ value = 'bold';
+ }
+ break;
case 'lineHeight':
if (value < 1) {
console.warn(`${key} cannot be less than 1, value: ${value}`);
@@ -413,11 +427,14 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
case 'enableBold':
case 'letterSpacing':
case 'lineHeight':
+ case 'fontWeight':
+ case 'fontWeightBold':
+ const didCharSizeChange = (key === 'fontWeight' || key === 'fontWeightBold' || key === 'enableBold');
+
// When the font changes the size of the cells may change which requires a renderer clear
this.renderer.clear();
- this.renderer.onResize(this.cols, this.rows, false);
+ this.renderer.onResize(this.cols, this.rows, didCharSizeChange);
this.refresh(0, this.rows - 1);
- // this.charMeasure.measure(this.options);
case 'scrollback':
this.buffers.resize(this.cols, this.rows);
this.viewport.syncScrollArea();
@@ -442,7 +459,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.element.classList.add('focus');
this.showCursor();
this.emit('focus');
- };
+ }
/**
* Blur the terminal, calling the blur function on the terminal's underlying
@@ -637,7 +654,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.charMeasure.on('charsizechanged', () => this.renderer.onResize(this.cols, this.rows, true));
this.renderer.on('resize', (dimensions) => this.viewport.syncScrollArea());
- this.selectionManager = new SelectionManager(this, this.buffer, this.charMeasure);
+ this.selectionManager = new SelectionManager(this, this.charMeasure);
this.element.addEventListener('mousedown', (e: MouseEvent) => this.selectionManager.onMouseDown(e));
this.selectionManager.on('refresh', data => this.renderer.onSelectionChanged(data.start, data.end));
this.selectionManager.on('newselection', text => {
@@ -1370,7 +1387,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
return this.cancel(ev, true);
}
- if (isThirdLevelShift(this.browser, ev)) {
+ if (this._isThirdLevelShift(this.browser, ev)) {
return true;
}
@@ -1391,6 +1408,19 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
return this.cancel(ev, true);
}
+ private _isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {
+ const thirdLevelKey =
+ (browser.isMac && !this.options.macOptionIsMeta && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
+ (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
+
+ if (ev.type === 'keypress') {
+ return thirdLevelKey;
+ }
+
+ // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)
+ return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);
+ }
+
/**
* Returns an object that determines how a KeyboardEvent should be handled. The key of the
* returned value is the new key code to pass to the PTY.
@@ -1570,6 +1600,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
// page up
if (ev.shiftKey) {
result.scrollLines = -(this.rows - 1);
+ } else if (modifiers) {
+ result.key = C0.ESC + '[5;' + (modifiers + 1) + '~';
} else {
result.key = C0.ESC + '[5~';
}
@@ -1578,6 +1610,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
// page down
if (ev.shiftKey) {
result.scrollLines = this.rows - 1;
+ } else if (modifiers) {
+ result.key = C0.ESC + '[6;' + (modifiers + 1) + '~';
} else {
result.key = C0.ESC + '[6~';
}
@@ -1691,8 +1725,8 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
// ^] - Operating System Command (OSC)
result.key = String.fromCharCode(29);
}
- } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {
- // On Mac this is a third level shift. Use instead.
+ } else if ((!this.browser.isMac || this.options.macOptionIsMeta) && ev.altKey && !ev.ctrlKey && !ev.metaKey) {
+ // On macOS this is a third level shift when !macOptionIsMeta. Use instead.
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);
} else if (ev.keyCode === 192) {
@@ -1725,7 +1759,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
* @param g
* @param charset
*/
- public setgCharset(g: number, charset: Charset): void {
+ public setgCharset(g: number, charset: ICharset): void {
this.charsets[g] = charset;
if (this.glevel === g) {
this.charset = charset;
@@ -1758,7 +1792,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
}
if (!key || (
- (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this.browser, ev)
+ (ev.altKey || ev.ctrlKey || ev.metaKey) && !this._isThirdLevelShift(this.browser, ev)
)) {
return false;
}
@@ -2072,11 +2106,9 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.options.cols = this.cols;
const customKeyEventHandler = this.customKeyEventHandler;
const inputHandler = this.inputHandler;
- const buffers = this.buffers;
this.setup();
this.customKeyEventHandler = customKeyEventHandler;
this.inputHandler = inputHandler;
- this.buffers = buffers;
this.refresh(0, this.rows - 1);
this.viewport.syncScrollArea();
}
@@ -2152,19 +2184,6 @@ function off(el: any, type: string, handler: (event: Event) => any, capture: boo
el.removeEventListener(type, handler, capture);
}
-function isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {
- const thirdLevelKey =
- (browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||
- (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);
-
- if (ev.type === 'keypress') {
- return thirdLevelKey;
- }
-
- // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)
- return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);
-}
-
function wasMondifierKeyOnlyEvent(ev: KeyboardEvent): boolean {
return ev.keyCode === 16 || // Shift
ev.keyCode === 17 || // Ctrl
@@ -2217,7 +2236,7 @@ function matchColorDistance(r1: number, g1: number, b1: number, r2: number, g2:
return Math.pow(30 * (r1 - r2), 2)
+ Math.pow(59 * (g1 - g2), 2)
+ Math.pow(11 * (b1 - b2), 2);
-};
+}
function matchColor_(r1: number, g1: number, b1: number): number {
diff --git a/src/Types.ts b/src/Types.ts
index a0c03fdd..3263282e 100644
--- a/src/Types.ts
+++ b/src/Types.ts
@@ -3,33 +3,16 @@
* @license MIT
*/
-export type LinkMatcher = {
- id: number,
- regex: RegExp,
- handler: LinkMatcherHandler,
- hoverTooltipCallback?: LinkMatcherHandler,
- hoverLeaveCallback?: () => void,
- matchIndex?: number,
- validationCallback?: LinkMatcherValidationCallback,
- priority?: number
-};
export type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void;
export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void;
export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
-export type Charset = {[key: string]: string};
export type CharData = [number, string, number, number];
export type LineData = CharData[];
-export type LinkHoverEvent = {
- x: number,
- y: number,
- length: number
-};
-
export enum LinkHoverEventTypes {
HOVER = 'linkhover',
TOOLTIP = 'linktooltip',
LEAVE = 'linkleave'
-};
+}
diff --git a/src/Viewport.ts b/src/Viewport.ts
index 1ea7fa0b..fcac68ad 100644
--- a/src/Viewport.ts
+++ b/src/Viewport.ts
@@ -119,7 +119,7 @@ export class Viewport implements IViewport {
this.viewportElement.scrollTop += ev.deltaY * multiplier;
// Prevent the page from scrolling when the terminal scrolls
ev.preventDefault();
- };
+ }
/**
* Handles the touchstart event, recording the touch occurred.
@@ -127,7 +127,7 @@ export class Viewport implements IViewport {
*/
public onTouchStart(ev: TouchEvent): void {
this.lastTouchY = ev.touches[0].pageY;
- };
+ }
/**
* Handles the touchmove event, scrolling the viewport if the position shifted.
@@ -141,5 +141,5 @@ export class Viewport implements IViewport {
}
this.viewportElement.scrollTop += deltaY;
ev.preventDefault();
- };
+ }
}
diff --git a/src/addons/attach/Interfaces.ts b/src/addons/attach/Interfaces.ts
new file mode 100644
index 00000000..ab809af9
--- /dev/null
+++ b/src/addons/attach/Interfaces.ts
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
+ * @license MIT
+ *
+ * Implements the attach method, that attaches the terminal to a WebSocket stream.
+ */
+
+import { Terminal } from 'xterm';
+
+export interface IAttachAddonTerminal extends Terminal {
+ __socket?: WebSocket;
+ __attachSocketBuffer?: string;
+
+ __getMessage?(ev: MessageEvent): void;
+ __flushBuffer?(): void;
+ __pushToBuffer?(data: string): void;
+ __sendData?(data: string): void;
+}
diff --git a/src/addons/attach/attach.test.ts b/src/addons/attach/attach.test.ts
index 9bf0e070..018cfb31 100644
--- a/src/addons/attach/attach.test.ts
+++ b/src/addons/attach/attach.test.ts
@@ -5,14 +5,14 @@
import { assert, expect } from 'chai';
-import * as attach from './attach'
+import * as attach from './attach';
class MockTerminal {}
describe('attach addon', () => {
describe('apply', () => {
it('should do register the `attach` and `detach` methods', () => {
- attach.apply(MockTerminal);
+ attach.apply(MockTerminal);
assert.equal(typeof (MockTerminal).prototype.attach, 'function');
assert.equal(typeof (MockTerminal).prototype.detach, 'function');
});
diff --git a/src/addons/attach/attach.ts b/src/addons/attach/attach.ts
index 4e0d5941..cbfd4a24 100644
--- a/src/addons/attach/attach.ts
+++ b/src/addons/attach/attach.ts
@@ -5,118 +5,118 @@
* Implements the attach method, that attaches the terminal to a WebSocket stream.
*/
+///
+
+import { Terminal } from 'xterm';
+import { IAttachAddonTerminal } from './Interfaces';
+
/**
* Attaches the given terminal to the given socket.
*
- * @param {Terminal} term - The terminal to be attached to the given socket.
- * @param {WebSocket} socket - The socket to attach the current terminal.
- * @param {boolean} bidirectional - Whether the terminal should send data
- * to the socket as well.
- * @param {boolean} buffered - Whether the rendering of incoming data
- * should happen instantly or at a maximum
- * frequency of 1 rendering per 10ms.
+ * @param term The terminal to be attached to the given socket.
+ * @param socket The socket to attach the current terminal.
+ * @param bidirectional Whether the terminal should send data to the socket as well.
+ * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum
+ * frequency of 1 rendering per 10ms.
*/
-export function attach(term, socket, bidirectional, buffered) {
- bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
- term.socket = socket;
+export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean, buffered: boolean): void {
+ const addonTerminal = term;
+ bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional;
+ addonTerminal.__socket = socket;
- term._flushBuffer = function() {
- term.write(term._attachSocketBuffer);
- term._attachSocketBuffer = null;
+ addonTerminal.__flushBuffer = () => {
+ addonTerminal.write(addonTerminal.__attachSocketBuffer);
+ addonTerminal.__attachSocketBuffer = null;
};
- term._pushToBuffer = function(data) {
- if (term._attachSocketBuffer) {
- term._attachSocketBuffer += data;
+ addonTerminal.__pushToBuffer = (data: string) => {
+ if (addonTerminal.__attachSocketBuffer) {
+ addonTerminal.__attachSocketBuffer += data;
} else {
- term._attachSocketBuffer = data;
- setTimeout(term._flushBuffer, 10);
+ addonTerminal.__attachSocketBuffer = data;
+ setTimeout(addonTerminal.__flushBuffer, 10);
}
};
- var myTextDecoder;
+ let myTextDecoder;
- term._getMessage = function(ev) {
- var str;
- if (typeof ev.data === "object") {
+ addonTerminal.__getMessage = function(ev: MessageEvent): void {
+ let str;
+ if (typeof ev.data === 'object') {
if (ev.data instanceof ArrayBuffer) {
if (!myTextDecoder) {
myTextDecoder = new TextDecoder();
}
str = myTextDecoder.decode( ev.data );
- }
- else {
- throw "TODO: handle Blob?";
+ } else {
+ throw 'TODO: handle Blob?';
}
}
if (buffered) {
- term._pushToBuffer(str || ev.data);
+ addonTerminal.__pushToBuffer(str || ev.data);
} else {
- term.write(str || ev.data);
+ addonTerminal.write(str || ev.data);
}
};
- term._sendData = function(data) {
+ addonTerminal.__sendData = (data: string) => {
if (socket.readyState !== 1) {
return;
}
socket.send(data);
};
- socket.addEventListener('message', term._getMessage);
+ socket.addEventListener('message', addonTerminal.__getMessage);
if (bidirectional) {
- term.on('data', term._sendData);
+ addonTerminal.on('data', addonTerminal.__sendData);
}
- socket.addEventListener('close', term.detach.bind(term, socket));
- socket.addEventListener('error', term.detach.bind(term, socket));
-};
+ socket.addEventListener('close', () => detach(addonTerminal, socket));
+ socket.addEventListener('error', () => detach(addonTerminal, socket));
+}
/**
* Detaches the given terminal from the given socket
*
- * @param {Terminal} term - The terminal to be detached from the given socket.
- * @param {WebSocket} socket - The socket from which to detach the current
- * terminal.
+ * @param term The terminal to be detached from the given socket.
+ * @param socket The socket from which to detach the current terminal.
*/
-export function detach(term, socket) {
- term.off('data', term._sendData);
+export function detach(term: Terminal, socket: WebSocket): void {
+ const addonTerminal = term;
+ addonTerminal.off('data', addonTerminal.__sendData);
- socket = (typeof socket == 'undefined') ? term.socket : socket;
+ socket = (typeof socket === 'undefined') ? addonTerminal.__socket : socket;
if (socket) {
- socket.removeEventListener('message', term._getMessage);
+ socket.removeEventListener('message', addonTerminal.__getMessage);
}
- delete term.socket;
-};
+ delete addonTerminal.__socket;
+}
-export function apply(terminalConstructor) {
+export function apply(terminalConstructor: typeof Terminal): void {
/**
* Attaches the current terminal to the given socket
*
- * @param {WebSocket} socket - The socket to attach the current terminal.
- * @param {boolean} bidirectional - Whether the terminal should send data
- * to the socket as well.
- * @param {boolean} buffered - Whether the rendering of incoming data
- * should happen instantly or at a maximum
- * frequency of 1 rendering per 10ms.
+ * @param socket The socket to attach the current terminal.
+ * @param bidirectional Whether the terminal should send data to the socket as well.
+ * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum
+ * frequency of 1 rendering per 10ms.
*/
- terminalConstructor.prototype.attach = function(socket, bidirectional, buffered) {
- return attach(this, socket, bidirectional, buffered);
+ (terminalConstructor.prototype).attach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean): void {
+ attach(this, socket, bidirectional, buffered);
};
/**
* Detaches the current terminal from the given socket.
*
- * @param {WebSocket} socket - The socket from which to detach the current
- * terminal.
+ * @param socket The socket from which to detach the current terminal.
*/
- terminalConstructor.prototype.detach = function(socket) {
- return detach(this, socket);
+ (terminalConstructor.prototype).detach = function (socket: WebSocket): void {
+ detach(this, socket);
};
}
diff --git a/src/addons/attach/tsconfig.json b/src/addons/attach/tsconfig.json
index 97722324..a4e8e78b 100644
--- a/src/addons/attach/tsconfig.json
+++ b/src/addons/attach/tsconfig.json
@@ -5,6 +5,7 @@
"rootDir": ".",
"outDir": "../../../lib/addons/attach/",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
}
}
diff --git a/src/addons/fit/fit.test.ts b/src/addons/fit/fit.test.ts
index 159cc987..9a6d89fd 100644
--- a/src/addons/fit/fit.test.ts
+++ b/src/addons/fit/fit.test.ts
@@ -5,14 +5,14 @@
import { assert, expect } from 'chai';
-import * as fit from './fit'
+import * as fit from './fit';
class MockTerminal {}
describe('fit addon', () => {
describe('apply', () => {
it('should do register the `proposeGeometry` and `fit` methods', () => {
- fit.apply(MockTerminal);
+ fit.apply(MockTerminal);
assert.equal(typeof (MockTerminal).prototype.proposeGeometry, 'function');
assert.equal(typeof (MockTerminal).prototype.fit, 'function');
});
diff --git a/src/addons/fit/fit.ts b/src/addons/fit/fit.ts
index b87ccc07..75e854d9 100644
--- a/src/addons/fit/fit.ts
+++ b/src/addons/fit/fit.ts
@@ -13,43 +13,52 @@
* row and truncate its width with the current number of columns).
*/
-export function proposeGeometry(term) {
+///
+
+import { Terminal } from 'xterm';
+
+export interface IGeometry {
+ rows: number;
+ cols: number;
+}
+
+export function proposeGeometry(term: Terminal): IGeometry {
if (!term.element.parentElement) {
return null;
}
- var parentElementStyle = window.getComputedStyle(term.element.parentElement);
- var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
- var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17);
- var elementStyle = window.getComputedStyle(term.element);
- var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom'));
- var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left'));
- var availableHeight = parentElementHeight - elementPaddingVer;
- var availableWidth = parentElementWidth - elementPaddingHor;
- var geometry = {
- cols: Math.floor(availableWidth / term.renderer.dimensions.actualCellWidth),
- rows: Math.floor(availableHeight / term.renderer.dimensions.actualCellHeight)
+ const parentElementStyle = window.getComputedStyle(term.element.parentElement);
+ const parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
+ const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17);
+ const elementStyle = window.getComputedStyle(term.element);
+ const elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom'));
+ const elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left'));
+ const availableHeight = parentElementHeight - elementPaddingVer;
+ const availableWidth = parentElementWidth - elementPaddingHor;
+ const geometry = {
+ cols: Math.floor(availableWidth / (term).renderer.dimensions.actualCellWidth),
+ rows: Math.floor(availableHeight / (term).renderer.dimensions.actualCellHeight)
};
return geometry;
-};
+}
-export function fit(term) {
- var geometry = proposeGeometry(term);
+export function fit(term: Terminal): void {
+ const geometry = proposeGeometry(term);
if (geometry) {
// Force a full render
if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
- term.renderer.clear();
+ (term).renderer.clear();
term.resize(geometry.cols, geometry.rows);
}
}
-};
+}
-export function apply(terminalConstructor) {
- terminalConstructor.prototype.proposeGeometry = function() {
+export function apply(terminalConstructor: typeof Terminal): void {
+ (terminalConstructor.prototype).proposeGeometry = function (): IGeometry {
return proposeGeometry(this);
- }
+ };
- terminalConstructor.prototype.fit = function() {
- return fit(this);
- }
+ (terminalConstructor.prototype).fit = function (): void {
+ fit(this);
+ };
}
diff --git a/src/addons/fit/tsconfig.json b/src/addons/fit/tsconfig.json
index 949f8b60..78b3c410 100644
--- a/src/addons/fit/tsconfig.json
+++ b/src/addons/fit/tsconfig.json
@@ -5,6 +5,7 @@
"rootDir": ".",
"outDir": "../../../lib/addons/fit/",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
}
}
diff --git a/src/addons/fullscreen/fullscreen.test.ts b/src/addons/fullscreen/fullscreen.test.ts
index c77ea75c..bb98bd30 100644
--- a/src/addons/fullscreen/fullscreen.test.ts
+++ b/src/addons/fullscreen/fullscreen.test.ts
@@ -5,14 +5,14 @@
import { assert, expect } from 'chai';
-import * as fullscreen from './fullscreen'
+import * as fullscreen from './fullscreen';
class MockTerminal {}
describe('fullscreen addon', () => {
describe('apply', () => {
it('should do register the `toggleFullscreen` method', () => {
- fullscreen.apply(MockTerminal);
+ fullscreen.apply(MockTerminal);
assert.equal(typeof (MockTerminal).prototype.toggleFullScreen, 'function');
});
});
diff --git a/src/addons/fullscreen/fullscreen.ts b/src/addons/fullscreen/fullscreen.ts
index 31ab5189..47440667 100644
--- a/src/addons/fullscreen/fullscreen.ts
+++ b/src/addons/fullscreen/fullscreen.ts
@@ -3,15 +3,19 @@
* @license MIT
*/
+///
+
+import { Terminal } from 'xterm';
+
/**
* Toggle the given terminal's fullscreen mode.
- * @param {Terminal} term - The terminal to toggle full screen mode
- * @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false)
+ * @param term The terminal to toggle full screen mode
+ * @param fullscreen Toggle fullscreen on (true) or off (false)
*/
-export function toggleFullScreen(term, fullscreen) {
- var fn;
+export function toggleFullScreen(term: Terminal, fullscreen: boolean): void {
+ let fn: string;
- if (typeof fullscreen == 'undefined') {
+ if (typeof fullscreen === 'undefined') {
fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add';
} else if (!fullscreen) {
fn = 'remove';
@@ -20,10 +24,10 @@ export function toggleFullScreen(term, fullscreen) {
}
term.element.classList[fn]('fullscreen');
-};
+}
-export function apply(terminalConstructor) {
- terminalConstructor.prototype.toggleFullScreen = function (fullscreen) {
- return toggleFullScreen(this, fullscreen);
+export function apply(terminalConstructor: typeof Terminal): void {
+ (terminalConstructor.prototype).toggleFullScreen = function (fullscreen: boolean): void {
+ toggleFullScreen(this, fullscreen);
};
}
diff --git a/src/addons/fullscreen/tsconfig.json b/src/addons/fullscreen/tsconfig.json
index b04144c1..35ecb7ce 100644
--- a/src/addons/fullscreen/tsconfig.json
+++ b/src/addons/fullscreen/tsconfig.json
@@ -5,6 +5,7 @@
"rootDir": ".",
"outDir": "../../../lib/addons/fullscreen/",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
}
}
diff --git a/src/addons/search/Interfaces.ts b/src/addons/search/Interfaces.ts
new file mode 100644
index 00000000..6faa03e2
--- /dev/null
+++ b/src/addons/search/Interfaces.ts
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
+ * @license MIT
+ */
+
+import { Terminal } from 'xterm';
+
+export interface ISearchAddonTerminal extends Terminal {
+ __searchHelper?: ISearchHelper;
+
+ // TODO: Reuse ITerminal from core
+ buffer: any;
+ selectionManager: any;
+}
+
+export interface ISearchHelper {
+ findNext(term: string): boolean;
+ findPrevious(term: string): boolean;
+}
diff --git a/src/addons/search/SearchHelper.ts b/src/addons/search/SearchHelper.ts
index 5735dd48..2abc3b38 100644
--- a/src/addons/search/SearchHelper.ts
+++ b/src/addons/search/SearchHelper.ts
@@ -3,8 +3,7 @@
* @license MIT
*/
-// import { ITerminal } from '../../Interfaces';
-// import { translateBufferLineToString } from '../../utils/BufferLine';
+import { ISearchHelper, ISearchAddonTerminal } from './Interfaces';
interface ISearchResult {
term: string;
@@ -15,8 +14,8 @@ interface ISearchResult {
/**
* A class that knows how to search the terminal and how to display the results.
*/
-export class SearchHelper {
- constructor(private _terminal: any) {
+export class SearchHelper implements ISearchHelper {
+ constructor(private _terminal: ISearchAddonTerminal) {
// TODO: Search for multiple instances on 1 line
// TODO: Don't use the actual selection, instead use a "find selection" so multiple instances can be highlighted
// TODO: Highlight other instances in the viewport
@@ -114,8 +113,23 @@ export class SearchHelper {
private _findInLine(term: string, y: number): ISearchResult {
const lowerStringLine = this._terminal.buffer.translateBufferLineToString(y, true).toLowerCase();
const lowerTerm = term.toLowerCase();
- const searchIndex = lowerStringLine.indexOf(lowerTerm);
+ let searchIndex = lowerStringLine.indexOf(lowerTerm);
if (searchIndex >= 0) {
+ const line = this._terminal.buffer.lines.get(y);
+ for (let i = 0; i < searchIndex; i++) {
+ const charData = line[i];
+ // Adjust the searchIndex to normalize emoji into single chars
+ const char = charData[1/*CHAR_DATA_CHAR_INDEX*/];
+ if (char.length > 1) {
+ searchIndex -= char.length - 1;
+ }
+ // Adjust the searchIndex for empty characters following wide unicode
+ // chars (eg. CJK)
+ const charWidth = charData[2/*CHAR_DATA_WIDTH_INDEX*/];
+ if (charWidth === 0) {
+ searchIndex++;
+ }
+ }
return {
term,
col: searchIndex,
@@ -134,7 +148,7 @@ export class SearchHelper {
return false;
}
this._terminal.selectionManager.setSelection(result.col, result.row, result.term.length);
- this._terminal.scrollLines(result.row - this._terminal.buffer.ydisp, false);
+ this._terminal.scrollLines(result.row - this._terminal.buffer.ydisp);
return true;
}
}
diff --git a/src/addons/search/search.ts b/src/addons/search/search.ts
index 480fea7f..5c0b2b96 100644
--- a/src/addons/search/search.ts
+++ b/src/addons/search/search.ts
@@ -3,8 +3,11 @@
* @license MIT
*/
-import { SearchHelper } from './SearchHelper';
+///
+import { SearchHelper } from './SearchHelper';
+import { Terminal } from 'xterm';
+import { ISearchAddonTerminal } from './Interfaces';
/**
* Find the next instance of the term, then scroll to and select it. If it
@@ -12,12 +15,13 @@ import { SearchHelper } from './SearchHelper';
* @param term Tne search term.
* @return Whether a result was found.
*/
-export function findNext(terminal: any, term: string): boolean {
- if (!terminal._searchHelper) {
- terminal.searchHelper = new SearchHelper(terminal);
+export function findNext(terminal: Terminal, term: string): boolean {
+ const addonTerminal = terminal;
+ if (!addonTerminal.__searchHelper) {
+ addonTerminal.__searchHelper = new SearchHelper(addonTerminal);
}
- return (terminal.searchHelper).findNext(term);
-};
+ return addonTerminal.__searchHelper.findNext(term);
+}
/**
* Find the previous instance of the term, then scroll to and select it. If it
@@ -25,19 +29,20 @@ export function findNext(terminal: any, term: string): boolean {
* @param term Tne search term.
* @return Whether a result was found.
*/
-export function findPrevious(terminal: any, term: string): boolean {
- if (!terminal._searchHelper) {
- terminal.searchHelper = new SearchHelper(terminal);
- }
- return (terminal.searchHelper).findPrevious(term);
-};
-
-export function apply(terminalConstructor) {
- terminalConstructor.prototype.findNext = function(term) {
- return findNext(this, term);
- }
-
- terminalConstructor.prototype.findPrevious = function(term) {
- return findPrevious(this, term);
+export function findPrevious(terminal: Terminal, term: string): boolean {
+ const addonTerminal = terminal;
+ if (!addonTerminal.__searchHelper) {
+ addonTerminal.__searchHelper = new SearchHelper(addonTerminal);
}
+ return addonTerminal.__searchHelper.findPrevious(term);
+}
+
+export function apply(terminalConstructor: typeof Terminal): void {
+ (terminalConstructor.prototype).findNext = function(term: string): boolean {
+ return findNext(this, term);
+ };
+
+ (terminalConstructor.prototype).findPrevious = function(term: string): boolean {
+ return findPrevious(this, term);
+ };
}
diff --git a/src/addons/search/tsconfig.json b/src/addons/search/tsconfig.json
index 7f72e47f..d1c3d7e0 100644
--- a/src/addons/search/tsconfig.json
+++ b/src/addons/search/tsconfig.json
@@ -5,6 +5,7 @@
"rootDir": ".",
"outDir": "../../../lib/addons/search/",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
}
}
diff --git a/src/addons/terminado/Interfaces.ts b/src/addons/terminado/Interfaces.ts
new file mode 100644
index 00000000..8f17b0cc
--- /dev/null
+++ b/src/addons/terminado/Interfaces.ts
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
+ * @license MIT
+ *
+ * Implements the attach method, that attaches the terminal to a WebSocket stream.
+ */
+
+import { Terminal } from 'xterm';
+
+export interface ITerminadoAddonTerminal extends Terminal {
+ __socket?: WebSocket;
+ __attachSocketBuffer?: string;
+
+ __getMessage?(ev: MessageEvent): void;
+ __flushBuffer?(): void;
+ __pushToBuffer?(data: string): void;
+ __sendData?(data: string): void;
+ __setSize?(size: {rows: number, cols: number}): void;
+}
diff --git a/src/addons/terminado/terminado.test.ts b/src/addons/terminado/terminado.test.ts
index fe059898..2e4a53c5 100644
--- a/src/addons/terminado/terminado.test.ts
+++ b/src/addons/terminado/terminado.test.ts
@@ -5,14 +5,14 @@
import { assert, expect } from 'chai';
-import * as terminado from './terminado'
+import * as terminado from './terminado';
class MockTerminal {}
describe('terminado addon', () => {
describe('apply', () => {
it('should do register the `terminadoAttach` and `terminadoDetach` methods', () => {
- terminado.apply(MockTerminal);
+ terminado.apply(MockTerminal);
assert.equal(typeof (MockTerminal).prototype.terminadoAttach, 'function');
assert.equal(typeof (MockTerminal).prototype.terminadoDetach, 'function');
});
diff --git a/src/addons/terminado/terminado.ts b/src/addons/terminado/terminado.ts
index 9a7c7ad6..4acf9dd8 100644
--- a/src/addons/terminado/terminado.ts
+++ b/src/addons/terminado/terminado.ts
@@ -6,106 +6,107 @@
* WebSocket stream.
*/
+///
+
+import { Terminal } from 'xterm';
+import { ITerminadoAddonTerminal } from './Interfaces';
+
/**
* Attaches the given terminal to the given socket.
*
- * @param {Terminal} term - The terminal to be attached to the given socket.
- * @param {WebSocket} socket - The socket to attach the current terminal.
- * @param {boolean} bidirectional - Whether the terminal should send data
- * to the socket as well.
- * @param {boolean} buffered - Whether the rendering of incoming data
- * should happen instantly or at a maximum
- * frequency of 1 rendering per 10ms.
+ * @param term The terminal to be attached to the given socket.
+ * @param socket The socket to attach the current terminal.
+ * @param bidirectional Whether the terminal should send data to the socket as well.
+ * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum
+ * frequency of 1 rendering per 10ms.
*/
-export function terminadoAttach(term, socket, bidirectional, buffered) {
- bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
- term.socket = socket;
+export function terminadoAttach(term: Terminal, socket: WebSocket, bidirectional: boolean, buffered: boolean): void {
+ const addonTerminal = term;
+ bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional;
+ addonTerminal.__socket = socket;
- term._flushBuffer = function() {
- term.write(term._attachSocketBuffer);
- term._attachSocketBuffer = null;
+ addonTerminal.__flushBuffer = () => {
+ addonTerminal.write(addonTerminal.__attachSocketBuffer);
+ addonTerminal.__attachSocketBuffer = null;
};
- term._pushToBuffer = function(data) {
- if (term._attachSocketBuffer) {
- term._attachSocketBuffer += data;
+ addonTerminal.__pushToBuffer = (data: string) => {
+ if (addonTerminal.__attachSocketBuffer) {
+ addonTerminal.__attachSocketBuffer += data;
} else {
- term._attachSocketBuffer = data;
- setTimeout(term._flushBuffer, 10);
+ addonTerminal.__attachSocketBuffer = data;
+ setTimeout(addonTerminal.__flushBuffer, 10);
}
};
- term._getMessage = function(ev) {
- var data = JSON.parse(ev.data)
- if( data[0] == "stdout" ) {
+ addonTerminal.__getMessage = (ev: MessageEvent) => {
+ const data = JSON.parse(ev.data);
+ if (data[0] === 'stdout') {
if (buffered) {
- term._pushToBuffer(data[1]);
+ addonTerminal.__pushToBuffer(data[1]);
} else {
- term.write(data[1]);
+ addonTerminal.write(data[1]);
}
}
};
- term._sendData = function(data) {
+ addonTerminal.__sendData = (data: string) => {
socket.send(JSON.stringify(['stdin', data]));
};
- term._setSize = function(size) {
+ addonTerminal.__setSize = (size: {rows: number, cols: number}) => {
socket.send(JSON.stringify(['set_size', size.rows, size.cols]));
};
- socket.addEventListener('message', term._getMessage);
+ socket.addEventListener('message', addonTerminal.__getMessage);
if (bidirectional) {
- term.on('data', term._sendData);
+ addonTerminal.on('data', addonTerminal.__sendData);
}
- term.on('resize', term._setSize);
+ addonTerminal.on('resize', addonTerminal.__setSize);
- socket.addEventListener('close', term.terminadoDetach.bind(term, socket));
- socket.addEventListener('error', term.terminadoDetach.bind(term, socket));
-};
+ socket.addEventListener('close', () => terminadoDetach(addonTerminal, socket));
+ socket.addEventListener('error', () => terminadoDetach(addonTerminal, socket));
+}
/**
* Detaches the given terminal from the given socket
*
- * @param {Xterm} term - The terminal to be detached from the given socket.
- * @param {WebSocket} socket - The socket from which to detach the current
- * terminal.
+ * @param term The terminal to be detached from the given socket.
+ * @param socket The socket from which to detach the current terminal.
*/
-export function terminadoDetach(term, socket) {
- term.off('data', term._sendData);
+export function terminadoDetach(term: Terminal, socket: WebSocket): void {
+ const addonTerminal = term;
+ addonTerminal.off('data', addonTerminal.__sendData);
- socket = (typeof socket == 'undefined') ? term.socket : socket;
+ socket = (typeof socket === 'undefined') ? addonTerminal.__socket : socket;
if (socket) {
- socket.removeEventListener('message', term._getMessage);
+ socket.removeEventListener('message', addonTerminal.__getMessage);
}
- delete term.socket;
-};
+ delete addonTerminal.__socket;
+}
-export function apply(terminalConstructor) {
+export function apply(terminalConstructor: typeof Terminal): void {
/**
* Attaches the current terminal to the given socket
*
- * @param {WebSocket} socket - The socket to attach the current terminal.
- * @param {boolean} bidirectional - Whether the terminal should send data
- * to the socket as well.
- * @param {boolean} buffered - Whether the rendering of incoming data
- * should happen instantly or at a maximum
- * frequency of 1 rendering per 10ms.
+ * @param socket - The socket to attach the current terminal.
+ * @param bidirectional - Whether the terminal should send data to the socket as well.
+ * @param buffered - Whether the rendering of incoming data should happen instantly or at a
+ * maximum frequency of 1 rendering per 10ms.
*/
- terminalConstructor.prototype.terminadoAttach = function(socket, bidirectional, buffered) {
+ (terminalConstructor.prototype).terminadoAttach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean): void {
return terminadoAttach(this, socket, bidirectional, buffered);
};
/**
* Detaches the current terminal from the given socket.
*
- * @param {WebSocket} socket - The socket from which to detach the current
- * terminal.
+ * @param socket The socket from which to detach the current terminal.
*/
- terminalConstructor.prototype.terminadoDetach = function(socket) {
+ (terminalConstructor.prototype).terminadoDetach = function (socket: WebSocket): void {
return terminadoDetach(this, socket);
};
}
diff --git a/src/addons/terminado/tsconfig.json b/src/addons/terminado/tsconfig.json
index 775b20d5..84e3ac32 100644
--- a/src/addons/terminado/tsconfig.json
+++ b/src/addons/terminado/tsconfig.json
@@ -5,6 +5,7 @@
"rootDir": ".",
"outDir": "../../../lib/addons/terminado/",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
}
}
diff --git a/src/addons/winptyCompat/Interfaces.ts b/src/addons/winptyCompat/Interfaces.ts
new file mode 100644
index 00000000..8e02c64b
--- /dev/null
+++ b/src/addons/winptyCompat/Interfaces.ts
@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
+ * @license MIT
+ */
+
+import { Terminal } from 'xterm';
+
+export interface IWinptyCompatAddonTerminal extends Terminal {
+ buffer: any;
+}
diff --git a/src/addons/winptyCompat/tsconfig.json b/src/addons/winptyCompat/tsconfig.json
index e15a09a8..a51f7332 100644
--- a/src/addons/winptyCompat/tsconfig.json
+++ b/src/addons/winptyCompat/tsconfig.json
@@ -5,6 +5,7 @@
"rootDir": ".",
"outDir": "../../../lib/addons/winptyCompat/",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
}
}
diff --git a/src/addons/winptyCompat/winptyCompat.test.ts b/src/addons/winptyCompat/winptyCompat.test.ts
index 21e54e56..0c9269ed 100644
--- a/src/addons/winptyCompat/winptyCompat.test.ts
+++ b/src/addons/winptyCompat/winptyCompat.test.ts
@@ -5,14 +5,14 @@
import { assert, expect } from 'chai';
-import * as winptyCompat from './winptyCompat'
+import * as winptyCompat from './winptyCompat';
class MockTerminal {}
describe('winptyCompat addon', () => {
describe('apply', () => {
it('should do register the `winptyCompatInit` method', () => {
- winptyCompat.apply(MockTerminal);
+ winptyCompat.apply(MockTerminal);
assert.equal(typeof (MockTerminal).prototype.winptyCompatInit, 'function');
});
});
diff --git a/src/addons/winptyCompat/winptyCompat.ts b/src/addons/winptyCompat/winptyCompat.ts
index 723bf011..61524e12 100644
--- a/src/addons/winptyCompat/winptyCompat.ts
+++ b/src/addons/winptyCompat/winptyCompat.ts
@@ -3,36 +3,43 @@
* @license MIT
*/
-export function winptyCompatInit(terminal): void {
- // Don't do anything when the platform is not Windows
- const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;
- if (!isWindows) {
- return;
+///
+
+import { Terminal } from 'xterm';
+import { IWinptyCompatAddonTerminal } from './Interfaces';
+
+export function winptyCompatInit(terminal: Terminal): void {
+ const addonTerminal = terminal;
+
+ // Don't do anything when the platform is not Windows
+ const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;
+ if (!isWindows) {
+ return;
+ }
+
+ // Winpty does not support wraparound mode which means that lines will never
+ // be marked as wrapped. This causes issues for things like copying a line
+ // retaining the wrapped new line characters or if consumers are listening
+ // in on the data stream.
+ //
+ // The workaround for this is to listen to every incoming line feed and mark
+ // the line as wrapped if the last character in the previous line is not a
+ // space. This is certainly not without its problems, but generally on
+ // Windows when text reaches the end of the terminal it's likely going to be
+ // wrapped.
+ addonTerminal.on('linefeed', () => {
+ const line = addonTerminal.buffer.lines.get(addonTerminal.buffer.ybase + addonTerminal.buffer.y - 1);
+ const lastChar = line[addonTerminal.cols - 1];
+
+ if (lastChar[3] !== 32 /* ' ' */) {
+ const nextLine = addonTerminal.buffer.lines.get(addonTerminal.buffer.ybase + addonTerminal.buffer.y);
+ (nextLine).isWrapped = true;
}
-
- // Winpty does not support wraparound mode which means that lines will never
- // be marked as wrapped. This causes issues for things like copying a line
- // retaining the wrapped new line characters or if consumers are listening
- // in on the data stream.
- //
- // The workaround for this is to listen to every incoming line feed and mark
- // the line as wrapped if the last character in the previous line is not a
- // space. This is certainly not without its problems, but generally on
- // Windows when text reaches the end of the terminal it's likely going to be
- // wrapped.
- terminal.on('linefeed', () => {
- const line = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y - 1);
- const lastChar = line[terminal.cols - 1];
-
- if (lastChar[3] !== 32 /* ' ' */) {
- const nextLine = terminal.buffer.lines.get(terminal.buffer.ybase + terminal.buffer.y);
- (nextLine).isWrapped = true;
- }
- });
+ });
}
-export function apply(terminalConstructor) {
- terminalConstructor.prototype.winptyCompatInit = function(): void {
+export function apply(terminalConstructor: typeof Terminal): void {
+ (terminalConstructor.prototype).winptyCompatInit = function (): void {
winptyCompatInit(this);
};
}
diff --git a/src/addons/zmodem/tsconfig.json b/src/addons/zmodem/tsconfig.json
index 9ded72e5..abae1238 100644
--- a/src/addons/zmodem/tsconfig.json
+++ b/src/addons/zmodem/tsconfig.json
@@ -5,6 +5,7 @@
"rootDir": ".",
"outDir": "../../../lib/addons/zmodem/",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
}
}
diff --git a/src/addons/zmodem/zmodem.test.ts b/src/addons/zmodem/zmodem.test.ts
index 3cb28316..682e62c8 100644
--- a/src/addons/zmodem/zmodem.test.ts
+++ b/src/addons/zmodem/zmodem.test.ts
@@ -5,14 +5,14 @@
import { assert, expect } from 'chai';
-import * as zmodem from './zmodem'
+import * as zmodem from './zmodem';
class MockTerminal {}
describe('zmodem addon', () => {
describe('apply', () => {
it('should do register the `zmodemAttach` method and `zmodemBrowser` attribute', () => {
- zmodem.apply(MockTerminal);
+ zmodem.apply(MockTerminal);
assert.equal(typeof (MockTerminal).prototype.zmodemAttach, 'function');
assert.equal(typeof (MockTerminal).prototype.zmodemBrowser, 'object');
});
diff --git a/src/addons/zmodem/zmodem.ts b/src/addons/zmodem/zmodem.ts
index 57bdde3c..e8a7824d 100644
--- a/src/addons/zmodem/zmodem.ts
+++ b/src/addons/zmodem/zmodem.ts
@@ -1,3 +1,12 @@
+/**
+ * Copyright (c) 2017 The xterm.js authors. All rights reserved.
+ * @license MIT
+ */
+
+///
+
+import { Terminal } from 'xterm';
+
/**
*
* Allow xterm.js to handle ZMODEM uploads and downloads.
@@ -27,47 +36,40 @@
* via `detach()` and a re-`attach()`.)
*/
-let Zmodem;
+let zmodem;
-export function zmodemAttach(term, ws, opts) {
- if (!opts) opts = {};
+export interface IZModemOptions {
+ noTerminalWriteOutsideSession?: boolean;
+}
- var senderFunc = function _ws_sender_func(octets) {
- ws.send(new Uint8Array(octets));
- };
+export function zmodemAttach(term: Terminal, ws: WebSocket, opts: IZModemOptions = {}): void {
+ const senderFunc = (octets: ArrayLike) => ws.send(new Uint8Array(octets));
- var zsentry;
+ let zsentry;
- function _shouldWrite() {
+ function _shouldWrite(): boolean {
return !!zsentry.get_confirmed_session() || !opts.noTerminalWriteOutsideSession;
}
- zsentry = new Zmodem.Sentry( {
- to_terminal: function _to_terminal(octets) {
+ zsentry = new zmodem.Sentry({
+ to_terminal: (octets: ArrayLike) => {
if (_shouldWrite()) {
term.write(
String.fromCharCode.apply(String, octets)
);
}
},
-
sender: senderFunc,
+ on_retract: () => (term).emit('zmodemRetract'),
+ on_detect: (detection: any) => (term).emit('zmodemDetect', detection)
+ });
- on_retract: function _on_retract() {
- term.emit('zmodemRetract');
- },
+ function handleWSMessage(evt: MessageEvent): void {
- on_detect: function _on_detect(detection) {
- term.emit('zmodemDetect', detection);
- },
- } );
-
- function handleWSMessage(evt) {
-
- //In testing with xterm.js’s demo the first message was
- //always text even if the rest were binary. While that
- //may be specific to xterm.js’s demo, ultimately we
- //should reject anything that isn’t binary.
+ // In testing with xterm.js’s demo the first message was
+ // always text even if the rest were binary. While that
+ // may be specific to xterm.js’s demo, ultimately we
+ // should reject anything that isn’t binary.
if (typeof evt.data === 'string') {
if (_shouldWrite()) {
term.write(evt.data);
@@ -82,9 +84,9 @@ export function zmodemAttach(term, ws, opts) {
ws.addEventListener('message', handleWSMessage);
}
-export function apply(terminalConstructor) {
- Zmodem = (typeof window == 'object') ? (window).ZModem : {Browser: null}; // Nullify browser for tests
+export function apply(terminalConstructor: typeof Terminal): void {
+ zmodem = (typeof window === 'object') ? (window).ZModem : {Browser: null}; // Nullify browser for tests
- terminalConstructor.prototype.zmodemAttach = zmodemAttach.bind(this, this);
- terminalConstructor.prototype.zmodemBrowser = Zmodem.Browser
+ (terminalConstructor.prototype).zmodemAttach = zmodemAttach.bind(this, this);
+ (terminalConstructor.prototype).zmodemBrowser = zmodem.Browser;
}
diff --git a/src/input/MouseZoneManager.ts b/src/input/MouseZoneManager.ts
index 8fae3171..6fbe1c67 100644
--- a/src/input/MouseZoneManager.ts
+++ b/src/input/MouseZoneManager.ts
@@ -178,7 +178,7 @@ export class MouseZoneManager implements IMouseZoneManager {
if (zone.y === coords[1] && zone.x1 <= coords[0] && zone.x2 > coords[0]) {
return zone;
}
- };
+ }
return null;
}
}
diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts
index b4becbce..bf952d06 100644
--- a/src/renderer/BaseRenderLayer.ts
+++ b/src/renderer/BaseRenderLayer.ts
@@ -201,7 +201,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
* @param color The color of the character.
*/
protected fillCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number): void {
- this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;
+ this._ctx.font = this._getFont(terminal, false);
this._ctx.textBaseline = 'top';
this._clipRow(terminal, y);
this._ctx.fillText(
@@ -269,7 +269,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
charAtlasCellWidth,
this._scaledCharHeight);
} else {
- this._drawUncachedChar(terminal, char, width, fg, x, y, bold, dim);
+ this._drawUncachedChar(terminal, char, width, fg, x, y, bold && terminal.options.enableBold, dim);
}
// This draws the atlas (for debugging purposes)
// this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
@@ -289,10 +289,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
*/
private _drawUncachedChar(terminal: ITerminal, char: string, width: number, fg: number, x: number, y: number, bold: boolean, dim: boolean): void {
this._ctx.save();
- this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;
- if (bold && terminal.options.enableBold) {
- this._ctx.font = `bold ${this._ctx.font}`;
- }
+ this._ctx.font = this._getFont(terminal, bold);
this._ctx.textBaseline = 'top';
if (fg === INVERTED_DEFAULT_COLOR) {
@@ -332,5 +329,16 @@ export abstract class BaseRenderLayer implements IRenderLayer {
this._scaledCellHeight);
this._ctx.clip();
}
+
+ /**
+ * Gets the current font.
+ * @param terminal The terminal.
+ * @param isBold If we should use the bold fontWeight.
+ */
+ protected _getFont(terminal: ITerminal, isBold: boolean): string {
+ const fontWeight = isBold ? terminal.options.fontWeightBold : terminal.options.fontWeight;
+
+ return `${fontWeight} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;
+ }
}
diff --git a/src/renderer/CharAtlas.ts b/src/renderer/CharAtlas.ts
index 3bc4291a..2738843c 100644
--- a/src/renderer/CharAtlas.ts
+++ b/src/renderer/CharAtlas.ts
@@ -13,6 +13,8 @@ export const CHAR_ATLAS_CELL_SPACING = 1;
interface ICharAtlasConfig {
fontSize: number;
fontFamily: string;
+ fontWeight: string;
+ fontWeightBold: string;
scaledCharWidth: number;
scaledCharHeight: number;
colors: IColorSet;
@@ -76,6 +78,8 @@ export function acquireCharAtlas(terminal: ITerminal, colors: IColorSet, scaledC
scaledCharHeight,
fontSize: terminal.options.fontSize,
fontFamily: terminal.options.fontFamily,
+ fontWeight: terminal.options.fontWeight,
+ fontWeightBold: terminal.options.fontWeightBold,
background: colors.background,
foreground: colors.foreground,
ansiColors: colors.ansi,
@@ -105,6 +109,8 @@ function generateConfig(scaledCharWidth: number, scaledCharHeight: number, termi
scaledCharHeight,
fontFamily: terminal.options.fontFamily,
fontSize: terminal.options.fontSize,
+ fontWeight: terminal.options.fontWeight,
+ fontWeightBold: terminal.options.fontWeightBold,
colors: clonedColors
};
}
@@ -117,6 +123,8 @@ function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean {
}
return a.fontFamily === b.fontFamily &&
a.fontSize === b.fontSize &&
+ a.fontWeight === b.fontWeight &&
+ a.fontWeightBold === b.fontWeightBold &&
a.scaledCharWidth === b.scaledCharWidth &&
a.scaledCharHeight === b.scaledCharHeight &&
a.colors.foreground === b.colors.foreground &&
diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts
index 689d6914..6ac489fc 100644
--- a/src/renderer/CursorRenderLayer.ts
+++ b/src/renderer/CursorRenderLayer.ts
@@ -11,7 +11,7 @@ import { FLAGS } from './Types';
import { BaseRenderLayer } from './BaseRenderLayer';
import { CharData } from '../Types';
-interface CursorState {
+interface ICursorState {
x: number;
y: number;
isFocused: boolean;
@@ -25,7 +25,7 @@ interface CursorState {
const BLINK_INTERVAL = 600;
export class CursorRenderLayer extends BaseRenderLayer {
- private _state: CursorState;
+ private _state: ICursorState;
private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, charData: CharData) => void};
private _cursorBlinkStateManager: CursorBlinkStateManager;
private _isFocused: boolean;
@@ -108,9 +108,10 @@ export class CursorRenderLayer extends BaseRenderLayer {
}
public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {
- // Only render if the animation frame is not active
if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) {
this._render(terminal, false);
+ } else {
+ this._cursorBlinkStateManager.restartBlinkAnimation(terminal);
}
}
diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts
index 8f3b63a5..87fbddbd 100644
--- a/src/renderer/LinkRenderLayer.ts
+++ b/src/renderer/LinkRenderLayer.ts
@@ -4,20 +4,20 @@
*/
import { IColorSet, IRenderDimensions } from './Interfaces';
-import { IBuffer, ICharMeasure, ITerminal, ILinkifierAccessor } from '../Interfaces';
+import { IBuffer, ICharMeasure, ILinkHoverEvent, ITerminal, ILinkifierAccessor } from '../Interfaces';
import { CHAR_DATA_ATTR_INDEX } from '../Buffer';
import { GridCache } from './GridCache';
import { FLAGS } from './Types';
import { BaseRenderLayer, INVERTED_DEFAULT_COLOR } from './BaseRenderLayer';
-import { LinkHoverEvent, LinkHoverEventTypes } from '../Types';
+import { LinkHoverEventTypes } from '../Types';
export class LinkRenderLayer extends BaseRenderLayer {
- private _state: LinkHoverEvent = null;
+ private _state: ILinkHoverEvent = null;
constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ILinkifierAccessor) {
super(container, 'link', zIndex, true, colors);
- terminal.linkifier.on(LinkHoverEventTypes.HOVER, (e: LinkHoverEvent) => this._onLinkHover(e));
- terminal.linkifier.on(LinkHoverEventTypes.LEAVE, (e: LinkHoverEvent) => this._onLinkLeave(e));
+ terminal.linkifier.on(LinkHoverEventTypes.HOVER, (e: ILinkHoverEvent) => this._onLinkHover(e));
+ terminal.linkifier.on(LinkHoverEventTypes.LEAVE, (e: ILinkHoverEvent) => this._onLinkLeave(e));
}
public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void {
@@ -37,13 +37,13 @@ export class LinkRenderLayer extends BaseRenderLayer {
}
}
- private _onLinkHover(e: LinkHoverEvent): void {
+ private _onLinkHover(e: ILinkHoverEvent): void {
this._ctx.fillStyle = this._colors.foreground;
this.fillBottomLineAtCells(e.x, e.y, e.length);
this._state = e;
}
- private _onLinkLeave(e: LinkHoverEvent): void {
+ private _onLinkLeave(e: ILinkHoverEvent): void {
this._clearCurrentLink();
}
}
diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts
index 31547da4..680d9490 100644
--- a/src/renderer/Renderer.ts
+++ b/src/renderer/Renderer.ts
@@ -57,6 +57,7 @@ export class Renderer extends EventEmitter implements IRenderer {
};
this._devicePixelRatio = window.devicePixelRatio;
this._updateDimensions();
+ this.onOptionsChanged();
this._screenDprMonitor = new ScreenDprMonitor();
this._screenDprMonitor.setListener(() => this.onWindowResize(window.devicePixelRatio));
diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts
index 2ecb6ec6..141d9823 100644
--- a/src/renderer/TextRenderLayer.ts
+++ b/src/renderer/TextRenderLayer.ts
@@ -33,7 +33,7 @@ export class TextRenderLayer extends BaseRenderLayer {
super.resize(terminal, dim, charSizeChanged);
// Clear the character width cache if the font or width has changed
- const terminalFont = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;
+ const terminalFont = this._getFont(terminal, false);
if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) {
this._characterWidth = dim.scaledCharWidth;
this._characterFont = terminalFont;
@@ -166,7 +166,7 @@ export class TextRenderLayer extends BaseRenderLayer {
this._ctx.save();
if (flags & FLAGS.BOLD) {
- this._ctx.font = `bold ${this._ctx.font}`;
+ this._ctx.font = this._getFont(terminal, true);
// Convert the FG color to the bold variant
if (fg < 8) {
fg += 8;
@@ -192,9 +192,9 @@ export class TextRenderLayer extends BaseRenderLayer {
}
}
- /**
- * Whether a character is overlapping to the next cell.
- */
+ /**
+ * Whether a character is overlapping to the next cell.
+ */
private _isOverlapping(charData: CharData): boolean {
// Only single cell characters can be overlapping, rendering issues can
// occur without this check
diff --git a/src/renderer/Types.ts b/src/renderer/Types.ts
index 31705a3f..834f8813 100644
--- a/src/renderer/Types.ts
+++ b/src/renderer/Types.ts
@@ -13,4 +13,4 @@ export enum FLAGS {
INVERSE = 8,
INVISIBLE = 16,
DIM = 32
-};
+}
diff --git a/src/shared/CharAtlasGenerator.ts b/src/shared/CharAtlasGenerator.ts
index 9452f8c6..9b895c9c 100644
--- a/src/shared/CharAtlasGenerator.ts
+++ b/src/shared/CharAtlasGenerator.ts
@@ -4,6 +4,7 @@
*/
import { isFirefox } from './utils/Browser';
+import { FontWeight } from './Types';
declare const Promise: any;
@@ -19,6 +20,8 @@ export interface ICharAtlasRequest {
scaledCharHeight: number;
fontSize: number;
fontFamily: string;
+ fontWeight: FontWeight;
+ fontWeightBold: FontWeight;
background: string;
foreground: string;
ansiColors: string[];
@@ -47,7 +50,7 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
ctx.save();
ctx.fillStyle = request.foreground;
- ctx.font = `${request.fontSize * request.devicePixelRatio}px ${request.fontFamily}`;
+ ctx.font = getFont(request.fontWeight, request);
ctx.textBaseline = 'top';
// Default color
@@ -61,7 +64,7 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
}
// Default color bold
ctx.save();
- ctx.font = `bold ${ctx.font}`;
+ ctx.font = getFont(request.fontWeightBold, request);
for (let i = 0; i < 256; i++) {
ctx.save();
ctx.beginPath();
@@ -73,11 +76,11 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number
ctx.restore();
// Colors 0-15
- ctx.font = `${request.fontSize * request.devicePixelRatio}px ${request.fontFamily}`;
+ ctx.font = getFont(request.fontWeight, request);
for (let colorIndex = 0; colorIndex < 16; colorIndex++) {
// colors 8-15 are bold
if (colorIndex === 8) {
- ctx.font = `bold ${ctx.font}`;
+ ctx.font = getFont(request.fontWeightBold, request);
}
const y = (colorIndex + 2) * cellHeight;
// Draw ascii characters
@@ -131,3 +134,7 @@ function clearColor(imageData: ImageData, r: number, g: number, b: number): void
}
}
}
+
+function getFont(fontWeight: FontWeight, request: ICharAtlasRequest): string {
+ return `${fontWeight} ${request.fontSize * request.devicePixelRatio}px ${request.fontFamily}`;
+}
diff --git a/src/shared/Types.ts b/src/shared/Types.ts
new file mode 100644
index 00000000..b61525bd
--- /dev/null
+++ b/src/shared/Types.ts
@@ -0,0 +1,6 @@
+/**
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
+ * @license MIT
+ */
+
+ export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
diff --git a/src/utils/Sounds.ts b/src/utils/Sounds.ts
index 03f36f42..be26d4a5 100644
--- a/src/utils/Sounds.ts
+++ b/src/utils/Sounds.ts
@@ -7,4 +7,4 @@
// This sound is released under the Creative Commons Attribution 3.0 Unported
// (CC BY 3.0) license. It was created by 'altemark'. No modifications have been
// made, apart from the conversion to base64.
-export const BellSound = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';
+export const BELL_SOUND = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';
diff --git a/src/utils/TestUtils.test.ts b/src/utils/TestUtils.test.ts
index 80e25277..8e8900a1 100644
--- a/src/utils/TestUtils.test.ts
+++ b/src/utils/TestUtils.test.ts
@@ -6,7 +6,7 @@
import { ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, IListenerType, IInputHandlingTerminal, IViewport, ICircularList, ICompositionHelper, ITheme, ILinkifier, IMouseHelper } from '../Interfaces';
import { LineData } from '../Types';
import { Buffer } from '../Buffer';
-import * as Browser from './Browser';
+import * as Browser from '../shared/utils/Browser';
import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Interfaces';
export class MockTerminal implements ITerminal {
diff --git a/tsconfig.json b/tsconfig.json
index 38bfd2fa..a3aa790c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,7 +5,8 @@
"rootDir": "src",
"outDir": "lib",
"sourceMap": true,
- "removeComments": true
+ "removeComments": true,
+ "declaration": true
},
"include": [
"src/**/*"
diff --git a/tslint.json b/tslint.json
index 4d4d4aa5..b5367f6a 100644
--- a/tslint.json
+++ b/tslint.json
@@ -1,5 +1,9 @@
{
"rules": {
+ "array-type": [
+ true,
+ "array"
+ ],
"class-name": true,
"comment-format": [
true,
@@ -9,6 +13,11 @@
true,
"spaces"
],
+ "interface-name": [
+ true,
+ "always-prefix"
+ ],
+ "interface-over-type-literal": true,
"typedef": [
true,
"call-signature",
@@ -18,10 +27,7 @@
"no-eval": true,
"no-internal-module": true,
"no-trailing-whitespace": true,
- "one-variable-per-declaration": [
- true,
- true
- ],
+ "one-variable-per-declaration": true,
"no-unsafe-finally": true,
"no-var-keyword": true,
"quotemark": [
@@ -48,15 +54,21 @@
],
"variable-name": [
true,
- "ban-keywords"
+ "ban-keywords",
+ "check-format",
+ "allow-leading-underscore"
],
"whitespace": [
true,
"check-branch",
"check-decl",
+ "check-module",
"check-operator",
+ "check-rest-spread",
"check-separator",
- "check-type"
+ "check-type",
+ "check-type-operator",
+ "check-preblock"
]
}
}
diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts
index 83199e08..37f169e8 100644
--- a/typings/xterm.d.ts
+++ b/typings/xterm.d.ts
@@ -8,6 +8,11 @@
*/
declare module 'xterm' {
+ /**
+ * A string representing text font weight.
+ */
+ export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
+
/**
* An object containing start up options for the terminal.
*/
@@ -57,6 +62,16 @@ declare module 'xterm' {
*/
fontFamily?: string;
+ /**
+ * The font weight used to render non-bold text.
+ */
+ fontWeight?: FontWeight;
+
+ /**
+ * The font weight used to render bold text.
+ */
+ fontWeightBold?: FontWeight;
+
/**
* The spacing in whole pixels between characters..
*/
@@ -67,6 +82,11 @@ declare module 'xterm' {
*/
lineHeight?: number;
+ /**
+ * Whether to treat option as the meta key.
+ */
+ macOptionIsMeta?: boolean;
+
/**
* The number of rows in the terminal.
*/
@@ -404,12 +424,12 @@ declare module 'xterm' {
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
- getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'termName'): string;
+ getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'fontWeight' | 'fontWeightBold'| 'termName'): string;
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
*/
- getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean;
+ getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean;
/**
* Retrieves an option's value from the terminal.
* @param key The option key.
@@ -437,6 +457,12 @@ declare module 'xterm' {
* @param value The option value.
*/
setOption(key: 'fontFamily' | 'termName' | 'bellSound', value: string): void;
+ /**
+ * Sets an option on the terminal.
+ * @param key The option key.
+ * @param value The option value.
+ */
+ setOption(key: 'fontWeight' | 'fontWeightBold', value: null | 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'): void;
/**
* Sets an option on the terminal.
* @param key The option key.
@@ -454,7 +480,7 @@ declare module 'xterm' {
* @param key The option key.
* @param value The option value.
*/
- setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void;
+ setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void;
/**
* Sets an option on the terminal.
* @param key The option key.