diff --git a/demo/client.ts b/demo/client.ts index 92bac731..e05a7105 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -221,6 +221,7 @@ function initOptions(term: TerminalType): void { bellSound: null, bellStyle: ['none', 'sound'], cursorStyle: ['block', 'underline', 'bar'], + fastScrollModifier: ['alt', 'ctrl', 'shift', undefined], fontFamily: null, fontWeight: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index 4f9363d9..d200ef8c 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -7,7 +7,7 @@ import { Disposable } from 'common/Lifecycle'; import { addDisposableDomListener } from 'browser/Lifecycle'; import { IColorSet, IViewport } from 'browser/Types'; import { ICharSizeService, IRenderService } from 'browser/services/Services'; -import { IBufferService } from 'common/services/Services'; +import { IBufferService, IOptionsService } from 'common/services/Services'; const FALLBACK_SCROLL_BAR_WIDTH = 15; @@ -37,6 +37,7 @@ export class Viewport extends Disposable implements IViewport { private readonly _viewportElement: HTMLElement, private readonly _scrollArea: HTMLElement, @IBufferService private readonly _bufferService: IBufferService, + @IOptionsService private readonly _optionsService: IOptionsService, @ICharSizeService private readonly _charSizeService: ICharSizeService, @IRenderService private readonly _renderService: IRenderService ) { @@ -191,7 +192,7 @@ export class Viewport extends Disposable implements IViewport { } // Fallback to WheelEvent.DOM_DELTA_PIXEL - let amount = ev.deltaY; + let amount = this._applyFastScrollModifier(ev.deltaY, ev); if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { amount *= this._currentRowHeight; } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { @@ -212,7 +213,7 @@ export class Viewport extends Disposable implements IViewport { } // Fallback to WheelEvent.DOM_DELTA_LINE - let amount = ev.deltaY; + let amount = this._applyFastScrollModifier(ev.deltaY, ev); if (ev.deltaMode === WheelEvent.DOM_DELTA_PIXEL) { amount /= this._currentRowHeight + 0.0; // Prevent integer division this._wheelPartialScroll += amount; @@ -224,6 +225,17 @@ export class Viewport extends Disposable implements IViewport { return amount; } + private _applyFastScrollModifier(amount: number, ev: WheelEvent): number { + const modifier = this._optionsService.options.fastScrollModifier; + // Multiply the scroll speed when the modifier is down + if ((modifier === 'alt' && ev.altKey) || + (modifier === 'ctrl' && ev.ctrlKey) || + (modifier === 'shift' && ev.shiftKey)) { + return amount * Math.max(1, this._optionsService.options.fastScrollSensitivity); + } + return amount; + } + /** * Handles the touchstart event, recording the touch occurred. * @param ev The touch event. diff --git a/src/common/services/OptionsService.ts b/src/common/services/OptionsService.ts index 9a5d2151..bde40c11 100644 --- a/src/common/services/OptionsService.ts +++ b/src/common/services/OptionsService.ts @@ -23,6 +23,8 @@ export const DEFAULT_OPTIONS: ITerminalOptions = Object.freeze({ bellSound: DEFAULT_BELL_SOUND, bellStyle: 'none', drawBoldTextInBrightColors: true, + fastScrollModifier: 'alt', + fastScrollSensitivity: 5, fontFamily: 'courier-new, courier, monospace', fontSize: 15, fontWeight: 'normal', diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index 568eeaff..1df59f84 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -180,6 +180,8 @@ export interface IPartialTerminalOptions { cursorStyle?: 'block' | 'underline' | 'bar'; disableStdin?: boolean; drawBoldTextInBrightColors?: boolean; + fastScrollModifier?: 'alt' | 'ctrl' | 'shift'; + fastScrollSensitivity?: number; fontSize?: number; fontFamily?: string; fontWeight?: FontWeight; @@ -209,6 +211,8 @@ export interface ITerminalOptions { cursorStyle: 'block' | 'underline' | 'bar'; disableStdin: boolean; drawBoldTextInBrightColors: boolean; + fastScrollModifier: 'alt' | 'ctrl' | 'shift' | undefined; + fastScrollSensitivity: number; fontSize: number; fontFamily: string; fontWeight: FontWeight; diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 44ef66bd..a64ad85c 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -82,6 +82,16 @@ declare module 'xterm' { */ drawBoldTextInBrightColors?: boolean; + /** + * The modifier key hold to multiply scroll speed. + */ + fastScrollModifier?: 'alt' | 'ctrl' | 'shift' | undefined; + + /** + * The scroll speed multiplier used for fast scrolling. + */ + fastScrollSensitivity?: number; + /** * The font size used to render text. */