diff --git a/coderibbon-theia/src/browser/coderibbon-theia-frontend-module.ts b/coderibbon-theia/src/browser/coderibbon-theia-frontend-module.ts index 3639cc8..c7534f0 100644 --- a/coderibbon-theia/src/browser/coderibbon-theia-frontend-module.ts +++ b/coderibbon-theia/src/browser/coderibbon-theia-frontend-module.ts @@ -10,6 +10,7 @@ import { MenuModelRegistry, MessageService, CorePreferences, + quickInputServicePath, } from "@theia/core/lib/common"; import { PreferenceContribution } from "@theia/core/lib/common/preferences"; import { ApplicationShell } from "@theia/core/lib/browser/shell/application-shell"; @@ -18,6 +19,7 @@ import { DockPanel, FrontendApplicationContribution, KeybindingContribution, + WebSocketConnectionProvider, WidgetFactory, WidgetManager, } from "@theia/core/lib/browser"; @@ -35,6 +37,10 @@ import { CodeRibbonFuzzyFileOpenerWidget, CodeRibbonFuzzyFileOpenerContribution, } from "./cr-fuzzy-file-opener"; +import { + EmbeddableMonacoQuickInputImplementation, + EmbeddableMonacoQuickInputService, +} from "./embeddable-mqis"; import "../../src/browser/style/ribbon.less"; // temp CSS @@ -68,6 +74,22 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(MenuContribution).to(CodeRibbonTheiaMenuContribution); bind(KeybindingContribution).to(CodeRibbonTheiaKeybindingContribution); + // https://github.com/eclipse-theia/theia/blob/008c8340465f7e42298839881d814863bef0b039/packages/monaco/src/browser/monaco-frontend-module.ts#L166-L171 + // bind(EmbeddableMonacoQuickInputImplementation).toSelf().inSingletonScope(); + // bind(EmbeddableMonacoQuickInputService) + // .toSelf() + // .inSingletonScope() + // .onActivation( + // ({ container }, quickInputService: EmbeddableMonacoQuickInputService) => { + // WebSocketConnectionProvider.createHandler( + // container, + // quickInputServicePath, + // quickInputService, + // ); + // return quickInputService; + // }, + // ); + // crdebug("now binding the CRFFO widget"); // CRFFO widget bind(CodeRibbonFuzzyFileOpenerWidget).toSelf(); diff --git a/coderibbon-theia/src/browser/cr-fuzzy-file-opener.tsx b/coderibbon-theia/src/browser/cr-fuzzy-file-opener.tsx index 9526494..ed3b628 100644 --- a/coderibbon-theia/src/browser/cr-fuzzy-file-opener.tsx +++ b/coderibbon-theia/src/browser/cr-fuzzy-file-opener.tsx @@ -1,3 +1,5 @@ +/** @format */ + import * as React from "react"; import { injectable, @@ -14,6 +16,7 @@ import { crdebug } from "./cr-logger"; import { QuickFileSelectService } from "@theia/file-search/lib/browser/quick-file-select-service"; import { MonacoQuickInputService } from "@theia/monaco/lib/browser/monaco-quick-input-service"; +import { EmbeddableMonacoQuickInputService } from "./embeddable-mqis"; /** * since this is registered in theia's WidgetManager / WidgetFactory it is part of the inversify container (hence injectable) @@ -27,6 +30,8 @@ export class CodeRibbonFuzzyFileOpenerWidget extends ReactWidget { // TODO this should be the monaco input / quick open equivalent // protected inputElement?: HTMLInputElement; protected inputElementRef: React.RefObject; + // private inputBox: InputBox; + private tmp_input: any; @inject(QuickInputService) protected readonly quickInputService: QuickInputService; @@ -37,6 +42,9 @@ export class CodeRibbonFuzzyFileOpenerWidget extends ReactWidget { @inject(MonacoQuickInputService) protected readonly monacoQuickInputService: MonacoQuickInputService; + // @inject(EmbeddableMonacoQuickInputService) + // protected readonly embeddableMQIS: EmbeddableMonacoQuickInputService; + @inject(MessageService) protected readonly messageService!: MessageService; @@ -52,6 +60,8 @@ export class CodeRibbonFuzzyFileOpenerWidget extends ReactWidget { this.inputElementRef = React.createRef(); // TODO how? // this.inputBox = this.quickInputService.createInputBox(); + // this.tmp_input = this.embeddableMQIS.createQuickPick(); + this.update(); } @@ -78,6 +88,7 @@ export class CodeRibbonFuzzyFileOpenerWidget extends ReactWidget { placeholder="search project files..." autoComplete="off" /> + {/* {this.tmp_input} */} ); } diff --git a/coderibbon-theia/src/browser/embeddable-mqis.ts b/coderibbon-theia/src/browser/embeddable-mqis.ts new file mode 100644 index 0000000..2cd5bcb --- /dev/null +++ b/coderibbon-theia/src/browser/embeddable-mqis.ts @@ -0,0 +1,91 @@ +/** @format */ + +import { inject, injectable } from "@theia/core/shared/inversify"; +import { + MonacoQuickInputService, + MonacoQuickInputImplementation, +} from "@theia/monaco/lib/browser/monaco-quick-input-service"; +import { StandaloneServices } from "@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices"; +import { IStandaloneThemeService } from "@theia/monaco-editor-core/esm/vs/editor/standalone/common/standaloneTheme"; +import { ILayoutService } from "@theia/monaco-editor-core/esm/vs/platform/layout/browser/layoutService"; +import { IInstantiationService } from "@theia/monaco-editor-core/esm/vs/platform/instantiation/common/instantiation"; +import { + IContextKey, + IContextKeyService, +} from "@theia/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey"; +import { + IQuickInputOptions, + IQuickInputStyles, +} from "@theia/monaco-editor-core/esm/vs/platform/quickinput/browser/quickInput"; +import { QuickInputController } from "@theia/monaco-editor-core/esm/vs/platform/quickinput/browser/quickInputController"; +import { + IHoverDelegate, + IHoverDelegateOptions, +} from "@theia/monaco-editor-core/esm/vs/base/browser/ui/hover/hoverDelegate"; +import { IHoverWidget } from "@theia/monaco-editor-core/esm/vs/base/browser/ui/hover/hover"; + +import { crdebug } from "./cr-logger"; + +// HoverDelegate direct copy: +// https://github.com/eclipse-theia/theia/blob/008c8340465f7e42298839881d814863bef0b039/packages/monaco/src/browser/monaco-quick-input-service.ts#L63-L72 +class HoverDelegate implements IHoverDelegate { + showHover( + options: IHoverDelegateOptions, + focus?: boolean | undefined, + ): IHoverWidget | undefined { + return undefined; + } + onDidHideHover?: (() => void) | undefined; + delay: number; + placement?: "mouse" | "element" | undefined; + showNativeHover?: boolean | undefined; +} + +@injectable() +// @ts-expect-error Class 'EmbeddableMonacoQuickInputImplementation' incorrectly extends base class 'MonacoQuickInputImplementation'. +export class EmbeddableMonacoQuickInputImplementation extends MonacoQuickInputImplementation { + private initContainer(): void { + const container = (this.container = document.createElement("div")); + container.id = "quick-input-container"; + // TODO replace with a way to fetch this element out + document.body.appendChild(this.container); + crdebug("EMQIS: adding container element", this); + } + + private override initController(): void { + // this.initController(); + const contextKeyService = StandaloneServices.get(IContextKeyService); + const instantiationService = StandaloneServices.get(IInstantiationService); + const layoutService = StandaloneServices.get(ILayoutService); + + const options: IQuickInputOptions = { + idPrefix: "quickInput_", + container: this.container, + // @ts-expect-error computeStyles is private + styles: this.computeStyles(), + ignoreFocusOut: () => true, + backKeybindingLabel: () => undefined, + setContextKey: (id?: string) => this.setContextKey(id), + returnFocus: () => this.container.focus(), + hoverDelegate: new HoverDelegate(), + linkOpenerDelegate: () => { + // @monaco-uplift: not sure what to do here + }, + }; + this.controller = new QuickInputController( + options, + layoutService, + instantiationService, + contextKeyService, + ); + // @ts-expect-error updateLayout is private + this.updateLayout(); + } +} + +@injectable() +// @ts-expect-error Class 'EmbeddableMonacoQuickInputService' incorrectly extends base class 'MonacoQuickInputService'. +export class EmbeddableMonacoQuickInputService extends MonacoQuickInputService { + @inject(EmbeddableMonacoQuickInputImplementation) + private override monacoService: EmbeddableMonacoQuickInputImplementation; +}