Put recently used main class in the top (#372)
* Put recently used main class in the top Signed-off-by: Jinbo Wang <jinbwan@microsoft.com> * Refactor the History interface to an accurate name * Combine all the boolean operations in one statement * Rename getId to getKey to keep properties consistent
This commit is contained in:
parent
ae23fcb02e
commit
c40301a1ed
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
|
||||
import * as anchor from "./anchor";
|
||||
|
@ -10,6 +10,8 @@ import * as utility from "./utility";
|
|||
|
||||
export class JavaDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
private isUserSettingsDirty: boolean = true;
|
||||
private debugHistory: MostRecentlyUsedHistory = new MostRecentlyUsedHistory();
|
||||
|
||||
constructor() {
|
||||
vscode.workspace.onDidChangeConfiguration((event) => {
|
||||
if (vscode.debug.activeDebugSession) {
|
||||
|
@ -213,30 +215,86 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
|
|||
});
|
||||
return undefined;
|
||||
}
|
||||
const pickItems = res.map((item) => {
|
||||
let name = item.mainClass;
|
||||
let details = `main class: ${item.mainClass}`;
|
||||
if (item.projectName !== undefined) {
|
||||
name += `<${item.projectName}>`;
|
||||
details += ` | project name: ${item.projectName}`;
|
||||
}
|
||||
return {
|
||||
description: details,
|
||||
label: name,
|
||||
item,
|
||||
};
|
||||
}).sort((a, b): number => {
|
||||
return a.label > b.label ? 1 : -1;
|
||||
});
|
||||
|
||||
const pickItems: IMainClassQuickPickItem[] = this.formatRecentlyUsedMainClassOptions(res);
|
||||
|
||||
const selection = pickItems.length > 1 ?
|
||||
await vscode.window.showQuickPick(pickItems, { placeHolder: "Select main class<project name>" })
|
||||
: pickItems[0];
|
||||
|
||||
if (selection && selection.item) {
|
||||
this.debugHistory.updateMRUTimestamp(selection.item);
|
||||
return selection.item;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private isOpenedInActiveEditor(file: string): boolean {
|
||||
const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor;
|
||||
const currentActiveFile: string = activeEditor ? activeEditor.document.uri.fsPath : undefined;
|
||||
|
||||
return file && currentActiveFile && path.relative(file, currentActiveFile) === "";
|
||||
}
|
||||
|
||||
private formatRecentlyUsedMainClassOptions(options: IMainClassOption[]): IMainClassQuickPickItem[] {
|
||||
// Sort the Main Class options with the recently used timestamp.
|
||||
options.sort((a: IMainClassOption, b: IMainClassOption) => {
|
||||
return this.debugHistory.getMRUTimestamp(b) - this.debugHistory.getMRUTimestamp(a);
|
||||
});
|
||||
|
||||
// Move the Main Class from Active Editor to the top.
|
||||
// If it's not the most recently used one, then put it as the second.
|
||||
let positionForActiveEditor = options.findIndex((value: IMainClassOption) => {
|
||||
return this.isOpenedInActiveEditor(value.filePath);
|
||||
});
|
||||
if (positionForActiveEditor >= 1) {
|
||||
let newPosition = 0;
|
||||
if (this.debugHistory.contains(options[0])) {
|
||||
newPosition = 1;
|
||||
}
|
||||
|
||||
if (newPosition !== positionForActiveEditor) {
|
||||
const update: IMainClassOption[] = options.splice(positionForActiveEditor, 1);
|
||||
options.splice(newPosition, 0, ...update);
|
||||
positionForActiveEditor = newPosition;
|
||||
}
|
||||
}
|
||||
|
||||
const pickItems: IMainClassQuickPickItem[] = this.formatMainClassOptions(options);
|
||||
|
||||
if (this.debugHistory.contains(options[0])) {
|
||||
pickItems[0].detail = "$(clock) recently used";
|
||||
}
|
||||
|
||||
if (positionForActiveEditor >= 0) {
|
||||
if (pickItems[positionForActiveEditor].detail) {
|
||||
pickItems[positionForActiveEditor].detail += `, active editor (${path.basename(options[positionForActiveEditor].filePath)})`;
|
||||
} else {
|
||||
pickItems[positionForActiveEditor].detail = `$(clock) active editor (${path.basename(options[positionForActiveEditor].filePath)})`;
|
||||
}
|
||||
}
|
||||
|
||||
return pickItems;
|
||||
}
|
||||
|
||||
private formatMainClassOptions(options: IMainClassOption[]): IMainClassQuickPickItem[] {
|
||||
return options.map((item) => {
|
||||
let label = item.mainClass;
|
||||
let description = `main class: ${item.mainClass}`;
|
||||
if (item.projectName) {
|
||||
label += `<${item.projectName}>`;
|
||||
description += ` | project name: ${item.projectName}`;
|
||||
}
|
||||
|
||||
return {
|
||||
label,
|
||||
description,
|
||||
detail: null,
|
||||
item,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function startDebugSession() {
|
||||
|
@ -288,6 +346,31 @@ function convertLogLevel(commonLogLevel: string) {
|
|||
}
|
||||
|
||||
interface IMainClassOption {
|
||||
readonly projectName?: string;
|
||||
readonly mainClass: string;
|
||||
readonly projectName?: string;
|
||||
readonly filePath?: string;
|
||||
}
|
||||
|
||||
interface IMainClassQuickPickItem extends vscode.QuickPickItem {
|
||||
item: IMainClassOption;
|
||||
}
|
||||
|
||||
class MostRecentlyUsedHistory {
|
||||
private cache: { [key: string]: number } = {};
|
||||
|
||||
public getMRUTimestamp(mainClassOption: IMainClassOption): number {
|
||||
return this.cache[this.getKey(mainClassOption)] || 0;
|
||||
}
|
||||
|
||||
public updateMRUTimestamp(mainClassOption: IMainClassOption): void {
|
||||
this.cache[this.getKey(mainClassOption)] = Date.now();
|
||||
}
|
||||
|
||||
public contains(mainClassOption: IMainClassOption): boolean {
|
||||
return Boolean(this.cache[this.getKey(mainClassOption)]);
|
||||
}
|
||||
|
||||
private getKey(mainClassOption: IMainClassOption): string {
|
||||
return mainClassOption.mainClass + "|" + mainClassOption.projectName;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue