From 3b7de2818f28a29de3e4becc6bf6e84e3fa93d24 Mon Sep 17 00:00:00 2001 From: Thomas Schlage Date: Wed, 21 Mar 2018 16:59:46 +0100 Subject: [PATCH] Added configuration to enable absolute paths --- package.json | 10 +++++++++ src/helpers/path-helper.ts | 22 +++++++++++++------ src/import-action.ts | 16 +++----------- src/import-completion.ts | 22 +++---------------- src/import-db.ts | 44 ++++++++++++++++++++++++++++---------- src/import-fixer.ts | 36 +++++++++++++++---------------- src/import-scanner.ts | 2 +- src/node-upload.ts | 2 +- 8 files changed, 84 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index 045bf00..b2cf6cb 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,16 @@ "default": "**/*.{js,jsx,ts,tsx}", "description": "Glob for files to watch and scan, e.g ./src/** ./src/app/**/*.ts. Defaults to **/*.{ts,tsx}" }, + "autoimport.absolute": { + "type": "boolean", + "default": false, + "description": "True if the imports should be absolute to the workspace root" + }, + "autoimport.sourceRoot": { + "type": "string", + "default": "./", + "description": "Change this if your absolute urls are not absolute from workspace root e.g ./src" + }, "autoimport.showNotifications": { "type": "boolean", "default": false, diff --git a/src/helpers/path-helper.ts b/src/helpers/path-helper.ts index 92189e8..21dfd1a 100644 --- a/src/helpers/path-helper.ts +++ b/src/helpers/path-helper.ts @@ -1,8 +1,9 @@ import * as path from 'path'; +import * as fs from 'fs'; export class PathHelper { - public static normalisePath(relativePath) { + public static normalisePath(path, absolute) { let removeFileExtenion = (rp) => { if (rp) { rp = rp.substring(0, rp.lastIndexOf('.')) @@ -25,14 +26,23 @@ export class PathHelper { return rp; } - relativePath = makeRelativePath(relativePath); - relativePath = removeFileExtenion(relativePath); + if (!absolute) { + path = makeRelativePath(path); + } + path = removeFileExtenion(path); - return relativePath; + return path; } public static getRelativePath(a, b): string { - return path.relative(path.dirname(a), b); + // Ensure we have a path to a folder + if (fs.lstatSync(a).isFile()) { + a = path.dirname(a); + } + return path.relative(a, b); } -} \ No newline at end of file + public static joinPaths(a, b): string { + return path.join(a, b); + } +} diff --git a/src/import-action.ts b/src/import-action.ts index b483744..fabb38b 100644 --- a/src/import-action.ts +++ b/src/import-action.ts @@ -73,20 +73,10 @@ export class ImportAction implements vscode.CodeActionProvider { } private actionHandler(context: Context): vscode.Command[] { - let path = (imp: ImportObject) => { - if ((imp.file).discovered) { - return imp.file.fsPath; - } else { - let rp = PathHelper.normalisePath( - PathHelper.getRelativePath(context.document.uri.fsPath, imp.file.fsPath)); - return rp; - } - }; - let handlers = []; - context.imports.forEach(i => { + context.imports.forEach(imp => { handlers.push({ - title: `Import ${i.name} from ${path(i)}`, + title: `Import ${imp.name} from ${imp.getPath(context.document)}`, command: 'extension.fixImport', arguments: [context.document, context.range, context.context, context.token, context.imports] }); @@ -101,4 +91,4 @@ export class ImportAction implements vscode.CodeActionProvider { document, range, context, token } } -} \ No newline at end of file +} diff --git a/src/import-completion.ts b/src/import-completion.ts index 625f49d..d53ba9f 100644 --- a/src/import-completion.ts +++ b/src/import-completion.ts @@ -43,28 +43,12 @@ export class ImportCompletion implements vscode.CompletionItemProvider { private buildCompletionItem(imp: ImportObject, document: vscode.TextDocument): any { - - let path = this.createDescription(imp, document); - return { label: imp.name, kind: vscode.CompletionItemKind.Reference, - detail: `import from ${path}`, - documentation: `Import ${imp.name} from ${path}`, + detail: `import from ${imp.getPath(document)}`, + documentation: `Import ${imp.name} from ${imp.getPath(document)}`, command: { title: 'AI: Autocomplete', command: 'extension.resolveImport', arguments: [{ imp, document }] } } } - - private createDescription(imp: ImportObject, document: vscode.TextDocument) { - let path = (imp: ImportObject) => { - if ((imp.file).discovered) { - return imp.file.fsPath; - } else { - let rp = PathHelper.normalisePath( - PathHelper.getRelativePath(document.uri.fsPath, imp.file.fsPath)); - return rp; - } - }; - return path(imp); - } -} \ No newline at end of file +} diff --git a/src/import-db.ts b/src/import-db.ts index ecb0774..9384ab6 100644 --- a/src/import-db.ts +++ b/src/import-db.ts @@ -1,11 +1,36 @@ import * as Path from 'path'; import * as vscode from 'vscode'; +import { PathHelper } from './helpers/path-helper'; -export interface ImportObject { - name: string, - file: vscode.Uri, - isDefault: boolean, + +export class ImportObject { + + name: string; + file: vscode.Uri; + isDefault: boolean; + discovered: boolean; + + constructor(name: string, file: vscode.Uri, isDefault: boolean, discovered: boolean = false) { + this.name = name; + this.file = file; + this.isDefault = isDefault; + this.discovered = discovered; + } + + getPath(document: vscode.TextDocument): string { + if (this.discovered) { + return this.file.fsPath; + } + const absolute = vscode.workspace.getConfiguration('autoimport').get('absolute'); + let basePath = document.uri.fsPath; + + if (absolute) { + const sourceRoot = vscode.workspace.getConfiguration('autoimport').get('sourceRoot'); + basePath = PathHelper.joinPaths(vscode.workspace.rootPath, sourceRoot); + } + return PathHelper.normalisePath(PathHelper.getRelativePath(basePath, this.file.fsPath), absolute); + } } @@ -42,7 +67,7 @@ export class ImportDb { } - public static saveImport(name: string, data: any, file: any, isDefault: boolean = false): void { + public static saveImport(name: string, data: any, file: any, isDefault: boolean = false, discovered: boolean): void { name = name.trim(); @@ -50,11 +75,8 @@ export class ImportDb { return; } - let obj: ImportObject = { - name, - file, - isDefault, - } + + let obj: ImportObject = new ImportObject(name, file, isDefault, discovered); let exists = ImportDb.imports.findIndex(m => m.name === obj.name && m.file.fsPath === file.fsPath); @@ -63,4 +85,4 @@ export class ImportDb { } } -} \ No newline at end of file +} diff --git a/src/import-fixer.ts b/src/import-fixer.ts index ae35f17..fab04d9 100644 --- a/src/import-fixer.ts +++ b/src/import-fixer.ts @@ -25,34 +25,32 @@ export class ImportFixer { public getTextEdit(document: vscode.TextDocument, imports: Array) { - let edit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); - let importObj: vscode.Uri | any = imports[0].file; - let importName: string = imports[0].name; + const edit: vscode.WorkspaceEdit = new vscode.WorkspaceEdit(); + const importObj: ImportObject = imports[0]; + const path = importObj.getPath(document); - let relativePath = this.normaliseRelativePath(importObj, this.getRelativePath(document, importObj)); - - if (this.alreadyResolved(document, relativePath, importName)) { + if (this.alreadyResolved(document, path, importObj.name)) { return edit; } - if (this.shouldMergeImport(document, relativePath)) { + if (this.shouldMergeImport(document, path)) { edit.replace(document.uri, new vscode.Range(0, 0, document.lineCount, 0), - this.mergeImports(document, edit, importName, importObj, relativePath)); + this.mergeImports(document, edit, importObj.name, importObj.file, path)); } else if (/^\/(\/\*) *@flow/.test(document.getText())) { edit.insert(document.uri, new vscode.Position(1, 0), - this.createImportStatement(imports[0].name, relativePath, true, imports[0].isDefault)); + this.createImportStatement(imports[0].name, path, true, imports[0].isDefault)); } else { let insertPosition: vscode.Position = document.positionAt(document.getText().lastIndexOf('import')).translate(1, 0); edit.insert(document.uri, insertPosition, - this.createImportStatement(imports[0].name, relativePath, true, imports[0].isDefault)); + this.createImportStatement(imports[0].name, path, true, imports[0].isDefault)); } return edit; } - private alreadyResolved(document: vscode.TextDocument, relativePath, importName) { + private alreadyResolved(document: vscode.TextDocument, path, importName) { - let exp = new RegExp('(?:import\ \{)(?:.*)(?:\}\ from\ \')(?:' + relativePath + ')(?:\'\;)') + let exp = new RegExp('(?:import\ \{)(?:.*)(?:\}\ from\ \')(?:' + path + ')(?:\'\;)') let currentDoc = document.getText(); @@ -65,7 +63,7 @@ export class ImportFixer { return false; } - private shouldMergeImport(document: vscode.TextDocument, relativePath): boolean { + private shouldMergeImport(document: vscode.TextDocument, path): boolean { let currentDoc = document.getText(); let isCommentLine = (text: string): boolean => { @@ -73,12 +71,12 @@ export class ImportFixer { return firstTwoLetters === '//' || firstTwoLetters === '/*'; } - return currentDoc.indexOf(relativePath) !== -1 && !isCommentLine(currentDoc); + return currentDoc.indexOf(path) !== -1 && !isCommentLine(currentDoc); } - private mergeImports(document: vscode.TextDocument, edit: vscode.WorkspaceEdit, name, file, relativePath: string) { + private mergeImports(document: vscode.TextDocument, edit: vscode.WorkspaceEdit, name, file, path: string) { - let exp = new RegExp('(?:import\ \{)(?:.*)(?:\}\ from\ \')(?:' + relativePath + ')(?:\'\;)') + let exp = new RegExp('(?:import\ \{)(?:.*)(?:\}\ from\ \')(?:' + path + ')(?:\'\;)') let currentDoc = document.getText(); @@ -88,13 +86,13 @@ export class ImportFixer { let workingString = foundImport[0]; workingString = workingString - .replace(/{|}|from|import|'|"| |;/gi, '').replace(relativePath, ''); + .replace(/{|}|from|import|'|"| |;/gi, '').replace(path, ''); let importArray = workingString.split(','); importArray.push(name) - let newImport = this.createImportStatement(importArray.join(', '), relativePath); + let newImport = this.createImportStatement(importArray.join(', '), path); currentDoc = currentDoc.replace(exp, newImport); } @@ -153,4 +151,4 @@ export class ImportFixer { return relativePath; } -} \ No newline at end of file +} diff --git a/src/import-scanner.ts b/src/import-scanner.ts index 85af0e8..ac3a113 100644 --- a/src/import-scanner.ts +++ b/src/import-scanner.ts @@ -114,4 +114,4 @@ export class ImportScanner { }) } } -} \ No newline at end of file +} diff --git a/src/node-upload.ts b/src/node-upload.ts index d6111fb..6c5cfd8 100644 --- a/src/node-upload.ts +++ b/src/node-upload.ts @@ -22,7 +22,7 @@ export class NodeUpload { let map = mappings[key]; if (map) { map.forEach(exp => { - ImportDb.saveImport(exp, exp, { fsPath: key, discovered: true }) + ImportDb.saveImport(exp, exp, {fsPath: key}, false, true) }); } }