diff --git a/src/InputHandler.ts b/src/InputHandler.ts index fb37f4ab..356f3b3d 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1788,6 +1788,9 @@ export class InputHandler extends Disposable implements IInputHandler { case 25: // show cursor this._coreService.isCursorHidden = false; break; + case 1039: + this._coreService.decPrivateModes.altEnterMode = true; + break; case 1048: // alt screen cursor this.saveCursor(); break; @@ -2003,6 +2006,9 @@ export class InputHandler extends Disposable implements IInputHandler { case 25: // hide cursor this._coreService.isCursorHidden = true; break; + case 1039: + this._coreService.decPrivateModes.altEnterMode = false; + break; case 1048: // alt screen cursor this.restoreCursor(); break; diff --git a/src/Terminal.ts b/src/Terminal.ts index 1bcac1f0..0ca1b186 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1222,7 +1222,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp return false; } - const result = evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, this.browser.isMac, this.options.macOptionIsMeta); + const result = evaluateKeyboardEvent(event, this._coreService.decPrivateModes.altEnterMode, this._coreService.decPrivateModes.applicationCursorKeys, this.browser.isMac, this.options.macOptionIsMeta); this.updateCursorStyle(event); diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 4d9070cd..b4636ebf 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -59,6 +59,7 @@ export class MockCoreService implements ICoreService { isCursorHidden: boolean = false; isFocused: boolean = false; decPrivateModes: IDecPrivateModes = { + altEnterMode: true, applicationCursorKeys: false, applicationKeypad: false, origin: false, diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index b250b45e..4df53bd4 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -152,6 +152,7 @@ export interface IMarker extends IDisposable { } export interface IDecPrivateModes { + altEnterMode: boolean; applicationCursorKeys: boolean; applicationKeypad: boolean; origin: boolean; diff --git a/src/common/input/Keyboard.test.ts b/src/common/input/Keyboard.test.ts index a304923e..ce492f0c 100644 --- a/src/common/input/Keyboard.test.ts +++ b/src/common/input/Keyboard.test.ts @@ -16,6 +16,7 @@ function testEvaluateKeyboardEvent(partialEvent: { key?: string; type?: string; }, partialOptions: { + altEnterMode?: boolean; applicationCursorMode?: boolean; isMac?: boolean; macOptionIsMeta?: boolean; @@ -30,11 +31,12 @@ function testEvaluateKeyboardEvent(partialEvent: { type: partialEvent.type || '' }; const options = { + altEnterMode: partialOptions.altEnterMode || true, applicationCursorMode: partialOptions.applicationCursorMode || false, isMac: partialOptions.isMac || false, macOptionIsMeta: partialOptions.macOptionIsMeta || false }; - return evaluateKeyboardEvent(event, options.applicationCursorMode, options.isMac, options.macOptionIsMeta); + return evaluateKeyboardEvent(event, options.altEnterMode, options.applicationCursorMode, options.isMac, options.macOptionIsMeta); } describe('Keyboard', () => { @@ -86,6 +88,9 @@ describe('Keyboard', () => { it('should return \\x1b[3;3~ for alt+delete', () => { assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~'); }); + it('should return \\x1b\\r for alt+enter', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 13 }).key, '\x1b\r'); + }); it('should return \\x1b[5D for ctrl+left', () => { assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D }); diff --git a/src/common/input/Keyboard.ts b/src/common/input/Keyboard.ts index 1bf378c1..34433dea 100644 --- a/src/common/input/Keyboard.ts +++ b/src/common/input/Keyboard.ts @@ -37,6 +37,7 @@ const KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = { export function evaluateKeyboardEvent( ev: IKeyboardEvent, + altEnterMode: boolean, applicationCursorMode: boolean, isMac: boolean, macOptionIsMeta: boolean @@ -103,7 +104,12 @@ export function evaluateKeyboardEvent( break; case 13: // return/enter - result.key = C0.CR; + if (altEnterMode && modifiers === 2) { + result.key = C0.ESC + C0.CR; + } + else { + result.key = C0.CR; + } result.cancel = true; break; case 27: diff --git a/src/common/services/CoreService.ts b/src/common/services/CoreService.ts index df9161e9..1ae906cc 100644 --- a/src/common/services/CoreService.ts +++ b/src/common/services/CoreService.ts @@ -9,6 +9,7 @@ import { IDecPrivateModes, ICharset } from 'common/Types'; import { clone } from 'common/Clone'; const DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({ + altEnterMode: true, applicationCursorKeys: false, applicationKeypad: false, origin: false,