@@ -7,15 +7,19 @@ import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serializ
77import type { IBufferLine , IMarker , ITerminalOptions , ITheme , Terminal as RawXtermTerminal , Terminal as XTermTerminal } from '@xterm/xterm' ;
88import { importAMDNodeModule } from 'vs/amdX' ;
99import { $ , addDisposableListener , addStandardDisposableListener , getWindow } from 'vs/base/browser/dom' ;
10+ import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel' ;
1011import { CancelablePromise , createCancelablePromise } from 'vs/base/common/async' ;
1112import { debounce , memoize , throttle } from 'vs/base/common/decorators' ;
1213import { Event } from 'vs/base/common/event' ;
1314import { Disposable , MutableDisposable , combinedDisposable , toDisposable } from 'vs/base/common/lifecycle' ;
15+ import { OS } from 'vs/base/common/platform' ;
1416import 'vs/css!./media/stickyScroll' ;
17+ import { localize } from 'vs/nls' ;
1518import { IMenu , IMenuService , MenuId } from 'vs/platform/actions/common/actions' ;
1619import { IConfigurationService } from 'vs/platform/configuration/common/configuration' ;
1720import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey' ;
1821import { IContextMenuService } from 'vs/platform/contextview/browser/contextView' ;
22+ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding' ;
1923import { ICommandDetectionCapability , ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities' ;
2024import { ICurrentPartialCommand } from 'vs/platform/terminal/common/capabilities/commandDetection/terminalCommand' ;
2125import { TerminalSettingId } from 'vs/platform/terminal/common/terminal' ;
@@ -62,6 +66,7 @@ export class TerminalStickyScrollOverlay extends Disposable {
6266 @IConfigurationService configurationService : IConfigurationService ,
6367 @IContextKeyService contextKeyService : IContextKeyService ,
6468 @IContextMenuService private readonly _contextMenuService : IContextMenuService ,
69+ @IKeybindingService private readonly _keybindingService : IKeybindingService ,
6570 @IMenuService menuService : IMenuService ,
6671 @IThemeService private readonly _themeService : IThemeService ,
6772 ) {
@@ -317,12 +322,34 @@ export class TerminalStickyScrollOverlay extends Disposable {
317322
318323 const overlay = this . _stickyScrollOverlay ;
319324
320- this . _element = $ ( '.terminal-sticky-scroll' ) ;
321325 const hoverOverlay = $ ( '.hover-overlay' ) ;
322- this . _element . append ( hoverOverlay ) ;
326+ this . _element = $ ( '.terminal-sticky-scroll' , undefined , hoverOverlay ) ;
323327 this . _xterm . raw . element . parentElement . append ( this . _element ) ;
324328 this . _register ( toDisposable ( ( ) => this . _element ?. remove ( ) ) ) ;
325329
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+
326353 const scrollBarWidth = ( this . _xterm . raw as any as { _core : IXtermCore } ) . _core . viewport ?. scrollBarWidth ;
327354 if ( scrollBarWidth !== undefined ) {
328355 this . _element . style . right = `${ scrollBarWidth } px` ;
0 commit comments