From a6cc2c3534c228f8cd06eb6e20204083878008c3 Mon Sep 17 00:00:00 2001 From: Shannon Wynter Date: Wed, 20 Jun 2018 14:35:09 +1000 Subject: [PATCH 1/4] Initial work on adding an import folder to workspace --- package.json | 4 ++++ src/goImport.ts | 31 ++++++++++++++++++++++++++++++- src/goMain.ts | 6 +++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fea1b8a23..a9fdb5629 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,10 @@ "title": "Go: Add Import", "description": "Add an import declaration" }, + { + "command": "go.import.workspace", + "title": "Go: Add import to workspace" + }, { "command": "go.tools.install", "title": "Go: Install/Update Tools", diff --git a/src/goImport.ts b/src/goImport.ts index 0585fb9a0..ed2bfdd61 100644 --- a/src/goImport.ts +++ b/src/goImport.ts @@ -6,10 +6,13 @@ 'use strict'; import vscode = require('vscode'); -import { parseFilePrelude } from './util'; +import path = require('path'); +import fs = require('fs'); +import { parseFilePrelude, getCurrentGoPath, getImportPath, getWorkspaceFolderPath } from './util'; import { documentSymbols } from './goOutline'; import { promptForMissingTool } from './goInstallTools'; import { getImportablePackages } from './goPackages'; +import { fixDriveCasingInWindows, getCurrentGoWorkspaceFromGOPATH } from './goPath'; const missingToolMsg = 'Missing tool: '; @@ -53,6 +56,17 @@ function askUserForImport(): Thenable { }); } +function askUserWhichImport(): Thenable { + return getImports(vscode.window.activeTextEditor.document).then(packages => { + return vscode.window.showQuickPick(packages); + }, err => { + if (typeof err === 'string' && err.startsWith(missingToolMsg)) { + promptForMissingTool(err.substr(missingToolMsg.length)); + } + }); +} + + export function getTextEditForAddImport(arg: string): vscode.TextEdit[] { // Import name wasn't provided if (arg === undefined) { @@ -104,3 +118,18 @@ export function addImport(arg: string) { } }); } + +export function addImportToWorkspace(arg: string) { + let p = arg ? Promise.resolve(arg) : askUserWhichImport(); + p.then(imp => { + if (typeof imp === 'string') { + let filePath = fixDriveCasingInWindows(vscode.window.activeTextEditor.document.fileName); + let fileDirPath = path.dirname(filePath); + let currentWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), fileDirPath); + let globalPackagePath = path.join(currentWorkspace, imp); + if (fs.existsSync(globalPackagePath)) { + vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, null, { uri: vscode.Uri.file(globalPackagePath) }); + } + } + }); +} \ No newline at end of file diff --git a/src/goMain.ts b/src/goMain.ts index 731da4b7f..f06547762 100644 --- a/src/goMain.ts +++ b/src/goMain.ts @@ -27,7 +27,7 @@ import { initGoCover } from './goCover'; import { testAtCursor, testCurrentPackage, testCurrentFile, testPrevious, testWorkspace } from './goTest'; import { showTestOutput, cancelRunningTests } from './testUtils'; import * as goGenerateTests from './goGenerateTests'; -import { addImport } from './goImport'; +import { addImport, addImportToWorkspace } from './goImport'; import { installAllTools, checkLanguageServer } from './goInstallTools'; import { isGoPathSet, getBinPath, sendTelemetryEvent, getExtensionCommands, getGoVersion, getCurrentGoPath, getToolsGopath, handleDiagnosticErrors, disposeTelemetryReporter, getToolsEnvVars } from './util'; import { LanguageClient, RevealOutputChannelOn, FormattingOptions, ProvideDocumentFormattingEditsSignature, ProvideCompletionItemsSignature } from 'vscode-languageclient'; @@ -274,6 +274,10 @@ export function activate(ctx: vscode.ExtensionContext): void { return addImport(typeof arg === 'string' ? arg : null); })); + ctx.subscriptions.push(vscode.commands.registerCommand('go.import.workspace', (arg: string) => { + return addImportToWorkspace(typeof arg === 'string' ? arg : null); + })); + ctx.subscriptions.push(vscode.commands.registerCommand('go.tools.install', () => { installAllTools(); })); From 2b44ebcd02478abbcef5f3ca8bd4c87434fcc53f Mon Sep 17 00:00:00 2001 From: Shannon Wynter Date: Wed, 20 Jun 2018 23:51:05 +1000 Subject: [PATCH 2/4] Work from selection rather than prompting user --- src/goImport.ts | 69 ++++++++++++++++++++++++++++++++----------------- src/util.ts | 2 +- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/goImport.ts b/src/goImport.ts index ed2bfdd61..351269db7 100644 --- a/src/goImport.ts +++ b/src/goImport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import path = require('path'); import fs = require('fs'); -import { parseFilePrelude, getCurrentGoPath, getImportPath, getWorkspaceFolderPath } from './util'; +import { parseFilePrelude, getCurrentGoPath, getImportPath, getRootWorkspaceFolder } from './util'; import { documentSymbols } from './goOutline'; import { promptForMissingTool } from './goInstallTools'; import { getImportablePackages } from './goPackages'; @@ -56,17 +56,6 @@ function askUserForImport(): Thenable { }); } -function askUserWhichImport(): Thenable { - return getImports(vscode.window.activeTextEditor.document).then(packages => { - return vscode.window.showQuickPick(packages); - }, err => { - if (typeof err === 'string' && err.startsWith(missingToolMsg)) { - promptForMissingTool(err.substr(missingToolMsg.length)); - } - }); -} - - export function getTextEditForAddImport(arg: string): vscode.TextEdit[] { // Import name wasn't provided if (arg === undefined) { @@ -120,16 +109,50 @@ export function addImport(arg: string) { } export function addImportToWorkspace(arg: string) { - let p = arg ? Promise.resolve(arg) : askUserWhichImport(); - p.then(imp => { - if (typeof imp === 'string') { - let filePath = fixDriveCasingInWindows(vscode.window.activeTextEditor.document.fileName); - let fileDirPath = path.dirname(filePath); - let currentWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), fileDirPath); - let globalPackagePath = path.join(currentWorkspace, imp); - if (fs.existsSync(globalPackagePath)) { - vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, null, { uri: vscode.Uri.file(globalPackagePath) }); + const editor = vscode.window.activeTextEditor; + const selection = editor.selection; + + let importPath = ''; + if (selection.isSingleLine) { + // Attempt to load a partial import path based on currently selected text + let selectedText = editor.document.getText(selection); + if (selectedText.length > 0) { + if (!selectedText.startsWith('"')) { + selectedText = '"' + selectedText; + } + if (!selectedText.endsWith('"')) { + selectedText = selectedText + '"'; } + importPath = getImportPath(selectedText); } - }); -} \ No newline at end of file + } + + if (importPath === '') { + // Failing that use the current line + let selectedText = editor.document.lineAt(selection.active.line).text; + importPath = getImportPath(selectedText); + } + + if (importPath === '') { + vscode.window.showErrorMessage('No import path to add'); + return; + } + + let filePath = fixDriveCasingInWindows(editor.document.fileName); + let fileDirPath = path.dirname(filePath); + let currentWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), fileDirPath); + let globalPackagePath = path.join(currentWorkspace, importPath); + if (!fs.existsSync(globalPackagePath)) { + vscode.window.showErrorMessage('Import path not found on disk'); + return; + } + + const importPathUri = vscode.Uri.file(globalPackagePath); + const existingWorkspaceFolder = getRootWorkspaceFolder(importPathUri); + if (existingWorkspaceFolder !== undefined) { + vscode.window.showInformationMessage('Already available under ' + existingWorkspaceFolder.name); + return; + } + + vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, null, { uri: importPathUri }); +} diff --git a/src/util.ts b/src/util.ts index 946e1bfaa..b7f918ce0 100644 --- a/src/util.ts +++ b/src/util.ts @@ -811,4 +811,4 @@ export function makeMemoizedByteOffsetConverter(buffer: Buffer): (byteOffset: nu memo.insert(byteOffset, nearest.value + charDelta); return nearest.value + charDelta; }; -} \ No newline at end of file +} From c133b8ea0040ce35bb4c6394cd3f70a12887f701 Mon Sep 17 00:00:00 2001 From: Shannon Wynter Date: Mon, 2 Jul 2018 12:46:07 +1000 Subject: [PATCH 3/4] Address feedback --- package.json | 5 +++-- src/goImport.ts | 44 ++++++++++++++++++++++++-------------------- src/goMain.ts | 4 ++-- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index a9fdb5629..bda9a9d98 100644 --- a/package.json +++ b/package.json @@ -155,8 +155,9 @@ "description": "Add an import declaration" }, { - "command": "go.import.workspace", - "title": "Go: Add import to workspace" + "command": "go.add.package.workspace", + "title": "Go: Add Package to Workspace", + "description": "Add a package from the imports list to the workspace." }, { "command": "go.tools.install", diff --git a/src/goImport.ts b/src/goImport.ts index 351269db7..2d514f301 100644 --- a/src/goImport.ts +++ b/src/goImport.ts @@ -6,13 +6,11 @@ 'use strict'; import vscode = require('vscode'); -import path = require('path'); -import fs = require('fs'); -import { parseFilePrelude, getCurrentGoPath, getImportPath, getRootWorkspaceFolder } from './util'; +import cp = require('child_process'); +import { parseFilePrelude, getCurrentGoPath, getImportPath, getRootWorkspaceFolder, getBinPath } from './util'; import { documentSymbols } from './goOutline'; import { promptForMissingTool } from './goInstallTools'; import { getImportablePackages } from './goPackages'; -import { fixDriveCasingInWindows, getCurrentGoWorkspaceFromGOPATH } from './goPath'; const missingToolMsg = 'Missing tool: '; @@ -108,7 +106,7 @@ export function addImport(arg: string) { }); } -export function addImportToWorkspace(arg: string) { +export function addImportToWorkspace() { const editor = vscode.window.activeTextEditor; const selection = editor.selection; @@ -138,21 +136,27 @@ export function addImportToWorkspace(arg: string) { return; } - let filePath = fixDriveCasingInWindows(editor.document.fileName); - let fileDirPath = path.dirname(filePath); - let currentWorkspace = getCurrentGoWorkspaceFromGOPATH(getCurrentGoPath(), fileDirPath); - let globalPackagePath = path.join(currentWorkspace, importPath); - if (!fs.existsSync(globalPackagePath)) { - vscode.window.showErrorMessage('Import path not found on disk'); - return; - } + const goRuntimePath = getBinPath('go'); + const env = Object.assign({}, process.env, { GOPATH: getCurrentGoPath() }); - const importPathUri = vscode.Uri.file(globalPackagePath); - const existingWorkspaceFolder = getRootWorkspaceFolder(importPathUri); - if (existingWorkspaceFolder !== undefined) { - vscode.window.showInformationMessage('Already available under ' + existingWorkspaceFolder.name); - return; - } + cp.execFile(goRuntimePath, ['list', '-f', '{{.Dir}}', importPath], { env }, (err, stdout, stderr) => { + if (!stdout) { + return; + } - vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, null, { uri: importPathUri }); + let dirs = stdout.split('\n'); + if (dirs.length === 0) { + return; + } + + const importPathUri = vscode.Uri.file(dirs[0]); + + const existingWorkspaceFolder = getRootWorkspaceFolder(importPathUri); + if (existingWorkspaceFolder !== undefined) { + vscode.window.showInformationMessage('Already available under ' + existingWorkspaceFolder.name); + return; + } + + vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders.length : 0, null, { uri: importPathUri }); + }); } diff --git a/src/goMain.ts b/src/goMain.ts index f06547762..b869fb7cb 100644 --- a/src/goMain.ts +++ b/src/goMain.ts @@ -274,8 +274,8 @@ export function activate(ctx: vscode.ExtensionContext): void { return addImport(typeof arg === 'string' ? arg : null); })); - ctx.subscriptions.push(vscode.commands.registerCommand('go.import.workspace', (arg: string) => { - return addImportToWorkspace(typeof arg === 'string' ? arg : null); + ctx.subscriptions.push(vscode.commands.registerCommand('go.add.package.workspace', () => { + addImportToWorkspace(); })); ctx.subscriptions.push(vscode.commands.registerCommand('go.tools.install', () => { From 2c4cdd8fb3fb9518006189815c61334fdcde6d4c Mon Sep 17 00:00:00 2001 From: Shannon Wynter Date: Tue, 17 Jul 2018 11:23:31 +1000 Subject: [PATCH 4/4] Address more comments --- src/goImport.ts | 10 +++++----- src/util.ts | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/goImport.ts b/src/goImport.ts index 2d514f301..842537542 100644 --- a/src/goImport.ts +++ b/src/goImport.ts @@ -7,7 +7,7 @@ import vscode = require('vscode'); import cp = require('child_process'); -import { parseFilePrelude, getCurrentGoPath, getImportPath, getRootWorkspaceFolder, getBinPath } from './util'; +import { parseFilePrelude, getImportPath, getBinPath, getToolsEnvVars } from './util'; import { documentSymbols } from './goOutline'; import { promptForMissingTool } from './goInstallTools'; import { getImportablePackages } from './goPackages'; @@ -111,9 +111,9 @@ export function addImportToWorkspace() { const selection = editor.selection; let importPath = ''; - if (selection.isSingleLine) { + if (!selection.isEmpty) { // Attempt to load a partial import path based on currently selected text - let selectedText = editor.document.getText(selection); + let selectedText = editor.document.getText(selection).trim(); if (selectedText.length > 0) { if (!selectedText.startsWith('"')) { selectedText = '"' + selectedText; @@ -137,7 +137,7 @@ export function addImportToWorkspace() { } const goRuntimePath = getBinPath('go'); - const env = Object.assign({}, process.env, { GOPATH: getCurrentGoPath() }); + const env = getToolsEnvVars(); cp.execFile(goRuntimePath, ['list', '-f', '{{.Dir}}', importPath], { env }, (err, stdout, stderr) => { if (!stdout) { @@ -151,7 +151,7 @@ export function addImportToWorkspace() { const importPathUri = vscode.Uri.file(dirs[0]); - const existingWorkspaceFolder = getRootWorkspaceFolder(importPathUri); + const existingWorkspaceFolder = vscode.workspace.getWorkspaceFolder(importPathUri); if (existingWorkspaceFolder !== undefined) { vscode.window.showInformationMessage('Already available under ' + existingWorkspaceFolder.name); return; diff --git a/src/util.ts b/src/util.ts index b7f918ce0..a57b9f40a 100644 --- a/src/util.ts +++ b/src/util.ts @@ -812,3 +812,4 @@ export function makeMemoizedByteOffsetConverter(buffer: Buffer): (byteOffset: nu return nearest.value + charDelta; }; } +