color: #fafafa;
padding: 2px;
}
-
-#terminal-container .terminal:focus .terminal-cursor {
- background-color: #fafafa;
-}
this._terminal.charsets = [null]; // ??
}
+ /**
+ * CSI Ps SP q Set cursor style (DECSCUSR, VT520).
+ * Ps = 0 -> blinking block.
+ * Ps = 1 -> blinking block (default).
+ * Ps = 2 -> steady block.
+ * Ps = 3 -> blinking underline.
+ * Ps = 4 -> steady underline.
+ * Ps = 5 -> blinking bar (xterm).
+ * Ps = 6 -> steady bar (xterm).
+ */
+ public setCursorStyle(params?: number[]): void {
+ const param = params[0] < 1 ? 1 : params[0];
+ switch (param) {
+ case 1:
+ case 2:
+ this._terminal.setOption('cursorStyle', 'block');
+ break;
+ case 3:
+ case 4:
+ this._terminal.setOption('cursorStyle', 'underline');
+ break;
+ case 5:
+ case 6:
+ this._terminal.setOption('cursorStyle', 'bar');
+ break;
+ }
+ const isBlinking = param % 2 === 1;
+ this._terminal.setOption('cursorBlink', isBlinking);
+ }
+
/**
* CSI Ps ; Ps r
* Set Scrolling Region [top;bottom] (default = full size of win-
/** CSI m */ charAttributes(params?: number[]): void;
/** CSI n */ deviceStatus(params?: number[]): void;
/** CSI p */ softReset(params?: number[]): void;
+ /** CSI q */ setCursorStyle(params?: number[]): void;
/** CSI r */ setScrollRegion(params?: number[]): void;
/** CSI s */ saveCursor(params?: number[]): void;
/** CSI u */ restoreCursor(params?: number[]): void;
csiParamStateHandler['\''] = (parser) => parser.setPostfix('\'');
csiParamStateHandler[';'] = (parser) => parser.finalizeParam();
-const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string) => void} = {};
+const csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string) => void} = {};
csiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);
csiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);
csiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);
case '!': handler.softReset(params); break;
}
};
+csiStateHandler['q'] = (handler, params, prefix, postfix) => {
+ if (postfix === ' ') {
+ handler.setCursorStyle(params);
+ }
+};
csiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);
csiStateHandler['s'] = (handler, params) => handler.saveCursor(params);
csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);
case ParserState.CSI:
if (ch in csiStateHandler) {
- csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix);
+ csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix);
} else {
this._terminal.error('Unknown CSI code: %s.', ch);
}
resize: none;
}
-.terminal .terminal-cursor {
+.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor {
background-color: #fff;
color: #000;
}
background-color: transparent;
}
-.terminal.focus.xterm-cursor-blink .terminal-cursor {
+.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink .terminal-cursor {
animation: xterm-cursor-blink 1.2s infinite step-end;
}
}
}
+.terminal.xterm-cursor-style-bar .terminal-cursor,
+.terminal.xterm-cursor-style-underline .terminal-cursor {
+ position: relative;
+}
+.terminal.xterm-cursor-style-bar .terminal-cursor::before,
+.terminal.xterm-cursor-style-underline .terminal-cursor::before {
+ content: "";
+ display: block;
+ position: absolute;
+ background-color: #fff;
+}
+.terminal.xterm-cursor-style-bar .terminal-cursor::before {
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 1px;
+}
+.terminal.xterm-cursor-style-underline .terminal-cursor::before {
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 1px;
+}
+.terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before,
+.terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before {
+ animation: xterm-cursor-non-bar-blink 1.2s infinite step-end;
+}
+@keyframes xterm-cursor-non-bar-blink {
+ 0% { background-color: #fff; }
+ 50% { background-color: transparent; }
+}
+
.terminal .composition-view {
background: #000;
color: #FFF;
termName: 'xterm',
geometry: [80, 24],
cursorBlink: false,
+ cursorStyle: 'block',
visualBell: false,
popOnBell: false,
scrollback: 1000,
this.options[key] = value;
switch (key) {
case 'cursorBlink': this.element.classList.toggle('xterm-cursor-blink', value); break;
+ case 'cursorStyle':
+ // Style 'block' applies with no class
+ this.element.classList.toggle(`xterm-cursor-style-underline`, value === 'underline');
+ this.element.classList.toggle(`xterm-cursor-style-bar`, value === 'bar');
+ break;
}
};