@@ -7,15 +7,19 @@ import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serializ
7
7
import type { IBufferLine , IMarker , ITerminalOptions , ITheme , Terminal as RawXtermTerminal , Terminal as XTermTerminal } from '@xterm/xterm' ;
8
8
import { importAMDNodeModule } from 'vs/amdX' ;
9
9
import { $ , addDisposableListener , addStandardDisposableListener , getWindow } from 'vs/base/browser/dom' ;
10
+ import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel' ;
10
11
import { CancelablePromise , createCancelablePromise } from 'vs/base/common/async' ;
11
12
import { debounce , memoize , throttle } from 'vs/base/common/decorators' ;
12
13
import { Event } from 'vs/base/common/event' ;
13
14
import { Disposable , MutableDisposable , combinedDisposable , toDisposable } from 'vs/base/common/lifecycle' ;
15
+ import { OS } from 'vs/base/common/platform' ;
14
16
import 'vs/css!./media/stickyScroll' ;
17
+ import { localize } from 'vs/nls' ;
15
18
import { IMenu , IMenuService , MenuId } from 'vs/platform/actions/common/actions' ;
16
19
import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
17
20
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey' ;
18
21
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView' ;
22
+ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
19
23
import { ICommandDetectionCapability , ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities' ;
20
24
import { ICurrentPartialCommand } from 'vs/platform/terminal/common/capabilities/commandDetection/terminalCommand' ;
21
25
import { TerminalSettingId } from 'vs/platform/terminal/common/terminal' ;
@@ -62,6 +66,7 @@ export class TerminalStickyScrollOverlay extends Disposable {
62
66
@IConfigurationService configurationService : IConfigurationService ,
63
67
@IContextKeyService contextKeyService : IContextKeyService ,
64
68
@IContextMenuService private readonly _contextMenuService : IContextMenuService ,
69
+ @IKeybindingService private readonly _keybindingService : IKeybindingService ,
65
70
@IMenuService menuService : IMenuService ,
66
71
@IThemeService private readonly _themeService : IThemeService ,
67
72
) {
@@ -317,12 +322,34 @@ export class TerminalStickyScrollOverlay extends Disposable {
317
322
318
323
const overlay = this . _stickyScrollOverlay ;
319
324
320
- this . _element = $ ( '.terminal-sticky-scroll' ) ;
321
325
const hoverOverlay = $ ( '.hover-overlay' ) ;
322
- this . _element . append ( hoverOverlay ) ;
326
+ this . _element = $ ( '.terminal-sticky-scroll' , undefined , hoverOverlay ) ;
323
327
this . _xterm . raw . element . parentElement . append ( this . _element ) ;
324
328
this . _register ( toDisposable ( ( ) => this . _element ?. remove ( ) ) ) ;
325
329
330
+ // Create command navigation keybinding hint if appropriate
331
+ const scrollToPreviousCommandKeybinding = this . _keybindingService . lookupKeybinding ( 'workbench.action.terminal.scrollToPreviousCommand' ) ;
332
+ if ( scrollToPreviousCommandKeybinding ) {
333
+ const keybindingHint = $ ( '.keybinding-hint' ) ;
334
+ const localizedText = localize ( {
335
+ key : 'command-navigation-hint' ,
336
+ comment : [ '{0} is the localized keybinding to navigate commands' ]
337
+ } , '{0} to navigate commands' , '{0}' ) ;
338
+ const localizedTextPrefix = localizedText . substring ( 0 , localizedText . indexOf ( '{0}' ) ) ;
339
+ const localizedTextSuffix = localizedText . substring ( localizedText . indexOf ( '{0}' ) + 3 ) ;
340
+ const label = new KeybindingLabel ( keybindingHint , OS ) ;
341
+ label . set ( scrollToPreviousCommandKeybinding ) ;
342
+ // Insert and use a non-breaking space for boundaries to space out naturally
343
+ if ( localizedTextPrefix ) {
344
+ label . element . insertAdjacentText ( 'beforebegin' , localizedTextPrefix . replace ( / $ / , '\u00A0' ) ) ;
345
+ }
346
+ if ( localizedTextSuffix ) {
347
+ label . element . insertAdjacentText ( 'afterend' , localizedTextSuffix . replace ( / ^ / , '\u00A0' ) ) ;
348
+ }
349
+
350
+ hoverOverlay . append ( keybindingHint ) ;
351
+ }
352
+
326
353
const scrollBarWidth = ( this . _xterm . raw as any as { _core : IXtermCore } ) . _core . viewport ?. scrollBarWidth ;
327
354
if ( scrollBarWidth !== undefined ) {
328
355
this . _element . style . right = `${ scrollBarWidth } px` ;
0 commit comments