Skip to content

Commit

Permalink
Fixed #5543: implemented "show all opened terminals" quick-open command
Browse files Browse the repository at this point in the history
Signed-off-by: fangnx <naxin.fang@ericsson.com>
  • Loading branch information
fangnx authored and fangnx committed Jun 26, 2019
1 parent 910bf41 commit 1d5170b
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ export namespace TerminalCommands {
category: TERMINAL_CATEGORY,
label: 'Split Terminal'
};
/**
* Command that displays all terminals that are currently opened
*/
export const SHOW_ALL_OPENED_TERMINALS: Command = {
id: 'workbench.action.showAllTerminals',
category: 'View',
label: 'Show All Opened Terminals'
};
}

@injectable()
Expand Down
10 changes: 9 additions & 1 deletion packages/terminal/src/browser/terminal-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { ContainerModule, Container } from 'inversify';
import { CommandContribution, MenuContribution } from '@theia/core/lib/common';
import { bindContributionProvider } from '@theia/core';
import { KeybindingContribution, WebSocketConnectionProvider, WidgetFactory, KeybindingContext } from '@theia/core/lib/browser';
import { KeybindingContribution, WebSocketConnectionProvider, WidgetFactory, KeybindingContext, QuickOpenContribution } from '@theia/core/lib/browser';
import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
import { TerminalFrontendContribution } from './terminal-frontend-contribution';
import { TerminalWidgetImpl, TERMINAL_WIDGET_FACTORY_ID } from './terminal-widget-impl';
Expand All @@ -33,6 +33,7 @@ import { URLMatcher, LocalhostMatcher } from './terminal-linkmatcher';
import { TerminalContribution } from './terminal-contribution';
import { TerminalLinkmatcherFiles } from './terminal-linkmatcher-files';
import { TerminalLinkmatcherDiffPre, TerminalLinkmatcherDiffPost } from './terminal-linkmatcher-diff';
import { TerminalQuickOpenService, TerminalQuickOpenContribution } from './terminal-quick-open-service';

import '../../src/browser/terminal.css';
import 'xterm/lib/xterm.css';
Expand Down Expand Up @@ -65,6 +66,13 @@ export default new ContainerModule(bind => {
}
}));

bind(TerminalQuickOpenService).toSelf().inSingletonScope();

bind(TerminalQuickOpenContribution).toSelf().inSingletonScope();
for (const identifier of [CommandContribution, QuickOpenContribution]) {
bind(identifier).toService(TerminalQuickOpenContribution);
}

bind(TerminalFrontendContribution).toSelf().inSingletonScope();
bind(TerminalService).toService(TerminalFrontendContribution);
for (const identifier of [CommandContribution, MenuContribution, KeybindingContribution, TabBarToolbarContribution]) {
Expand Down
156 changes: 156 additions & 0 deletions packages/terminal/src/browser/terminal-quick-open-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/********************************************************************************
* Copyright (C) 2019 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { inject, injectable } from 'inversify';
import {
QuickOpenModel, QuickOpenItem, QuickOpenHandler,
QuickOpenOptions, QuickOpenItemOptions, QuickOpenMode,
PrefixQuickOpenService,
QuickOpenContribution, QuickOpenHandlerRegistry
} from '@theia/core/lib/browser';
import { CommandContribution } from '@theia/core/lib/common';
import { CommandRegistry } from '@theia/core/lib/common';
import { TerminalWidget } from './base/terminal-widget';
import { TerminalService } from './base/terminal-service';
import { TerminalCommands } from './terminal-frontend-contribution';

@injectable()
export class TerminalQuickOpenService implements QuickOpenModel, QuickOpenHandler {

@inject(PrefixQuickOpenService)
protected readonly prefixQuickOpenService: PrefixQuickOpenService;

@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;

@inject(TerminalService)
protected readonly terminalService: TerminalService;

readonly prefix: string = 'term ';

get description(): string {
return 'Show All Opened Terminals';
}

getModel(): QuickOpenModel {
return this;
}

getOptions(): QuickOpenOptions {
return {
fuzzyMatchLabel: {
enableSeparateSubstringMatching: true
},
fuzzyMatchDescription: {
enableSeparateSubstringMatching: true
}
};
}

open(): void {
this.prefixQuickOpenService.open(this.prefix);
}

async onType(lookFor: string, acceptor: (items: QuickOpenItem[]) => void): Promise<void> {
const terminalItems: QuickOpenItem[] = [];

// Get the list of currently opened terminal widgets, sorted by the widget id.
const widgets: TerminalWidget[] = this.terminalService.all
.sort((a: TerminalWidget, b: TerminalWidget) => (a.id.localeCompare(b.id)));

for (const widget of widgets) {
const item = await this.toItem(widget);
terminalItems.push(item);
}
// Append a quick open item to create a new terminal.
const createNewTerminalItem = new QuickOpenItem({
label: 'Open New Terminal',
iconClass: 'fa fa-plus',
run: this.doCreateNewTerminal()
});
terminalItems.push(createNewTerminalItem);

acceptor(terminalItems);
return;
}

/**
* Get the function that can create a new terminal.
* @param {TerminalWidget} widget - the terminal widget to be opened.
* @returns Function that would create a new terminal if mode === QuickOpenMode.OPEN.
*/
protected doCreateNewTerminal(): (mode: QuickOpenMode) => boolean {
return (mode: QuickOpenMode) => {
if (mode !== QuickOpenMode.OPEN) {
return false;
}
this.commandRegistry.executeCommand(TerminalCommands.NEW.id);
return true;
};
}

/**
* Convert the terminal widget to the quick open item.
* @param {TerminalWidget} widget - the terminal widget.
* @returns The quick open item.
*/
protected async toItem(widget: TerminalWidget): Promise<QuickOpenItem<QuickOpenItemOptions>> {

const options: QuickOpenItemOptions = {
label: widget.id,
description: widget.title.label,
tooltip: widget.title.label,
hidden: false,
run: this.getRunFunction(widget)
};
return new QuickOpenItem<QuickOpenItemOptions>(options);
}

/**
* Get the function that can open the editor file.
* @param {TerminalWidget} widget - the terminal widget to be opened.
* @returns Function that would open the terminal if mode === QuickOpenMode.OPEN.
*/
protected getRunFunction(widget: TerminalWidget): (mode: QuickOpenMode) => boolean {
return (mode: QuickOpenMode) => {
if (mode !== QuickOpenMode.OPEN) {
return false;
}
this.terminalService.open(widget);
return true;
};
}
}

/**
* TODO: merge it to TerminalFrontendContribution
*/
@injectable()
export class TerminalQuickOpenContribution implements CommandContribution, QuickOpenContribution {

@inject(TerminalQuickOpenService)
protected readonly terminalQuickOpenService: TerminalQuickOpenService;

registerQuickOpenHandlers(handlers: QuickOpenHandlerRegistry): void {
handlers.registerHandler(this.terminalQuickOpenService);
}

registerCommands(commands: CommandRegistry): void {
commands.registerCommand(TerminalCommands.SHOW_ALL_OPENED_TERMINALS, {
execute: () => this.terminalQuickOpenService.open()
});
}
}

0 comments on commit 1d5170b

Please sign in to comment.