diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index ebd42a95ec4..084c3c39808 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -141,32 +141,51 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ return await fileService.stat(resource); })); - const files = items.filter(i => !i.isDirectory); - const file = files[0]; - if (file === undefined) { - } else { - const filePath = file.resource.fsPath; - const funcListPath = filePath + '.functionList.text'; - console.log(`filePath: ${filePath}`); - // generate function list file - - // fs.writeFileSync(funcListPath, ''); - const funcList = extractDef(filePath); - console.log(`funcList: ${funcList}`); - - // write file list file - fs.writeFileSync(funcListPath, ''); - const writeStream = fs.createWriteStream(funcListPath); - for (const line of funcList) { - writeStream.write(line + '\n'); - } + const originalFiles = items.filter(i => !i.isDirectory); + const formattedResources = [] as URI[]; + for (const file of originalFiles) { + if (file === undefined) { + } else { + const filePath = file.resource.fsPath; + const funcListPath = filePath + '.functionList.text'; + // generate function list file + const { classList, functionList: funcList } = extractDef(filePath); + + // write file list file + fs.writeFileSync(funcListPath, ''); + const writeStream = fs.createWriteStream(funcListPath); + + // write class list + writeStream.write('[method]\n'); + for (const line of funcList) { + writeStream.write(line + '\n'); + } - writeStream.end(); + writeStream.write('\n[class]\n'); + for (const classLine of classList) { + writeStream.write(classLine + '\n'); + } + + writeStream.end(); + formattedResources.push(URI.file(funcListPath)); + } } + const formattedItems = await Promise.all(formattedResources.map(async resource => { + const item = explorerService.findClosest(resource); + if (item) { + // Explorer already resolved the item, no need to go to the file service #109780 + return item; + } - const editors_new = [file]; + return await fileService.stat(resource); + })); + const formattedFiles = formattedItems.filter(i => !i.isDirectory); + const formattedEditors = formattedFiles.map(f => ({ + resource: f.resource, + options: { pinned: true } + })); - await editorService.openEditors(editors_new, SIDE_GROUP); + await editorService.openEditors(formattedEditors, SIDE_GROUP); } } }); diff --git a/src/vs/workbench/contrib/files/browser/pickup.ts b/src/vs/workbench/contrib/files/browser/pickup.ts index 7a8bab9508f..88e3cc6f47c 100644 --- a/src/vs/workbench/contrib/files/browser/pickup.ts +++ b/src/vs/workbench/contrib/files/browser/pickup.ts @@ -5,39 +5,133 @@ /* eslint-disable local/code-import-patterns */ import * as fs from 'fs'; -const isDefElement = (element: string): boolean => { - return element === 'def' || element === 'class'; -}; +enum DeclareType { + function, + class, +} + +class DeclItem { + private readonly _parent: DeclItem | undefined; + private readonly _children: (DeclItem)[] = []; + private readonly _type: DeclareType; + private readonly _spaces: number; + private readonly _text: string; + public readonly depth: number = 0; + constructor( + readonly parent: DeclItem | undefined, + readonly type: DeclareType, + readonly spaces: number, + readonly text: string, + ) { + this._parent = parent; + this._type = type; + this._spaces = spaces; + this._text = text; + this._parent?._children.push(this); + this.depth = this._parent === undefined ? 0 : this._parent.depth + 1; + } + get spaceCount() { + return this._spaces; + } + + get parentItem() { + return this._parent; + } -const isBeforeDefElement = (element: string): boolean => { - return element === 'async' || element === ''; + get itemType() { + return this._type; + } + + get title() { + return this._text; + } + + get children() { + return this._children; + } +} + +const countSpacesAtBeginning = (line: string): number => { + return line.search(/\S|$/); }; -const isDefLine = (line: string): boolean => { +const checkLineType = (line: string): DeclareType | undefined => { + + const checkElementType = (element: string): DeclareType | undefined => { + if (element === 'def') { + return DeclareType.function; + } else if (element === 'class') { + return DeclareType.class; + } else { + return undefined; + } + }; + + const isBeforeDefElement = (element: string): boolean => { + return element === 'async' || element === ''; + }; + const elements = line.split(/\s+/); for (const element of elements) { if (isBeforeDefElement(element)) { continue; - } else if (isDefElement(element)) { - return true; + } else if (checkElementType(element) !== undefined) { + // functionまたはclassの定義文 + return checkElementType(element); } } - return false; + return undefined; }; -export const extractDef = (inputFilePath: string): string[] => { +const pushAllChildren = (parent: DeclItem, list: string[]) => { + list.push(parent.title); + for (const child of parent.children) { + pushAllChildren(child, list); + } +}; + +export const extractDef = (inputFilePath: string) => { + const roots = [] as DeclItem[]; + let currentRoot: DeclItem | undefined = undefined; let fileContent = ''; try { fileContent = fs.readFileSync(inputFilePath, 'utf8'); } catch (err) { - console.log(`Error while reading file: ${err}`); } const lines = fileContent.split('\n'); - const returnList = [] as string[]; for (const line of lines) { - if (isDefLine(line)) { - returnList.push(line); + const lineType = checkLineType(line); + if (lineType !== undefined) { + // functionまたはclassの定義文 + const spaces = countSpacesAtBeginning(line); + if (spaces === 0 || currentRoot === undefined) { + const newItem = new DeclItem(undefined, lineType, 0, line); + roots.push(newItem); + currentRoot = newItem; + } else { + let parent: DeclItem | undefined = currentRoot; + while (parent !== undefined && parent.spaceCount >= spaces) { + parent = parent.parentItem; + } + const newItem: DeclItem = new DeclItem(parent, lineType, spaces, line); + if (parent === undefined) { + roots.push(newItem); + } + currentRoot = newItem; + } + } + } + const classList = [] as string[]; + const functionList = [] as string[]; + for (const root of roots) { + if (root.itemType === DeclareType.class) { + pushAllChildren(root, classList); + } else { + pushAllChildren(root, functionList); } } - return returnList; + return { + classList, + functionList, + }; }; diff --git a/src/vs/workbench/contrib/files/common/fileOperations.ts b/src/vs/workbench/contrib/files/common/fileOperations.ts deleted file mode 100644 index 5c1c34ab38f..00000000000 --- a/src/vs/workbench/contrib/files/common/fileOperations.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -// eslint-disable-next-line local/code-import-patterns -import * as fs from 'fs'; - -export const generateFunctionListFile = (filePath: string, callback?: () => void | undefined): void => { - console.log('unchi'); - - return; -}; diff --git a/src/vs/workbench/contrib/sourceTree/browser/sourceTree.contribution.ts b/src/vs/workbench/contrib/sourceTree/browser/sourceTree.contribution.ts index 4d265415417..202381ea596 100644 --- a/src/vs/workbench/contrib/sourceTree/browser/sourceTree.contribution.ts +++ b/src/vs/workbench/contrib/sourceTree/browser/sourceTree.contribution.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { Registry } from 'vs/platform/registry/common/platform'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; -import { Extensions as ViewExtensions, IViewContainersRegistry, IViewDescriptor, IViewDescriptorService, IViewsRegistry, ViewContainerLocation } from 'vs/workbench/common/views'; +import { Extensions as ViewExtensions, IViewContainersRegistry, IViewDescriptor, IViewsRegistry, ViewContainerLocation } from 'vs/workbench/common/views'; import { sourceTreeIcon } from 'vs/workbench/contrib/sourceTree/browser/sourceTreeIcons'; import { SourceTreeView } from 'vs/workbench/contrib/sourceTree/browser/sourceTreeView'; // import { WelcomeView } from 'vs/workbench/contrib/sourceTree/browser/welcomeView'; diff --git a/src/vs/workbench/contrib/sourceTree/browser/sourceTreeView.ts b/src/vs/workbench/contrib/sourceTree/browser/sourceTreeView.ts index 4c354b20166..908f04d8288 100644 --- a/src/vs/workbench/contrib/sourceTree/browser/sourceTreeView.ts +++ b/src/vs/workbench/contrib/sourceTree/browser/sourceTreeView.ts @@ -22,7 +22,6 @@ import { ILabelService } from 'vs/platform/label/common/label'; export class SourceTreeView extends ViewPane { private activeFile: URI | undefined; // private activeEditor: EditorInput; - private container!: HTMLElement; constructor( options: IViewPaneOptions, @IKeybindingService keybindingService: IKeybindingService, @@ -72,9 +71,6 @@ export class SourceTreeView extends ViewPane { override renderBody(container: HTMLElement): void { super.renderBody(container); - - this.container = container; - // When the active file changes, update the view this._register(this.editorService.onDidActiveEditorChange(() => { this.selectActiveFile();