diff --git a/.travis.yml b/.travis.yml index 3e99d8ef5..5cf2521c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ install: - go get -u -v sourcegraph.com/sqs/goreturns - go get -u -v golang.org/x/tools/cmd/gorename - go get -u -v github.com/tpng/gopkgs - - go get -u -v github.com/newhook/go-symbols + - go get -u -v github.com/acroca/go-symbols - go get -u -v github.com/alecthomas/gometalinter - go get -u -v github.com/cweill/gotests/... - GO15VENDOREXPERIMENT=1 diff --git a/README.md b/README.md index d6884f7d3..a485d0b6d 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ If you wish to have the extension use a separate GOPATH for its tools, provide t - goreturns: `go get -u -v sourcegraph.com/sqs/goreturns` - gorename: `go get -u -v golang.org/x/tools/cmd/gorename` - gopkgs: `go get -u -v github.com/tpng/gopkgs` -- go-symbols: `go get -u -v github.com/newhook/go-symbols` +- go-symbols: `go get -u -v github.com/acroca/go-symbols` - guru: `go get -u -v golang.org/x/tools/cmd/guru` - gotests: `go get -u -v github.com/cweill/gotests/...` - godoc: `go get -u -v golang.org/x/tools/cmd/godoc` @@ -214,7 +214,7 @@ go get -u -v github.com/lukehoban/go-outline go get -u -v sourcegraph.com/sqs/goreturns go get -u -v golang.org/x/tools/cmd/gorename go get -u -v github.com/tpng/gopkgs -go get -u -v github.com/newhook/go-symbols +go get -u -v github.com/acroca/go-symbols go get -u -v golang.org/x/tools/cmd/guru go get -u -v github.com/cweill/gotests/... go get -u -v golang.org/x/tools/cmd/godoc diff --git a/package.json b/package.json index a6cca4e88..13b1a34e1 100644 --- a/package.json +++ b/package.json @@ -596,6 +596,14 @@ "testCoverage": false }, "description": "Enable/Disable entries from the context menu in the editor." + }, + "go.gotoSymbol.ignoreFolders": { + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "Folder names (not paths) to ignore while using Go to Symbol in Workspace feature" } } }, @@ -637,7 +645,7 @@ "when": "editorTextFocus && config.go.editorContextMenuCommands.generateTestForPackage && resourceLangId == go", "command": "go.test.generate.package" }, - { + { "when": "editorTextFocus && config.go.editorContextMenuCommands.addImport && resourceLangId == go", "command": "go.import.add" }, diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts index 40f78f869..08fd23fce 100644 --- a/src/goInstallTools.ts +++ b/src/goInstallTools.ts @@ -23,7 +23,7 @@ function getTools(goVersion: SemVersion): { [key: string]: string } { 'gocode': 'github.com/nsf/gocode', 'gopkgs': 'github.com/tpng/gopkgs', 'go-outline': 'github.com/lukehoban/go-outline', - 'go-symbols': 'github.com/newhook/go-symbols', + 'go-symbols': 'github.com/acroca/go-symbols', 'guru': 'golang.org/x/tools/cmd/guru', 'gorename': 'golang.org/x/tools/cmd/gorename', 'gomodifytags': 'github.com/fatih/gomodifytags' diff --git a/src/goSymbol.ts b/src/goSymbol.ts index e979b5812..3af2e3205 100644 --- a/src/goSymbol.ts +++ b/src/goSymbol.ts @@ -7,9 +7,9 @@ import vscode = require('vscode'); import cp = require('child_process'); import { getBinPath } from './util'; -import { promptForMissingTool } from './goInstallTools'; +import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools'; -// Keep in sync with github.com/newhook/go-symbols' +// Keep in sync with github.com/acroca/go-symbols' interface GoSymbolDeclaration { name: string; kind: string; @@ -47,11 +47,24 @@ export class GoWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider symbols.push(symbolInfo); }); }; - let symArgs = vscode.workspace.getConfiguration('go')['symbols']; - let args = [vscode.workspace.rootPath, query]; - if (symArgs !== undefined && symArgs !== '') { - args.unshift(symArgs); + + return getWorkspaceSymbols(vscode.workspace.rootPath, query).then(results => { + let symbols: vscode.SymbolInformation[] = []; + convertToCodeSymbols(results, symbols); + return symbols; + }); + } +} + +export function getWorkspaceSymbols(workspacePath: string, query: string, goConfig?: vscode.WorkspaceConfiguration, ignoreFolderFeatureOn: boolean = true): Thenable { + if (!goConfig) { + goConfig = vscode.workspace.getConfiguration('go'); } + let gotoSymbolConfig = goConfig['gotoSymbol']; + let ignoreFolders: string[] = gotoSymbolConfig ? gotoSymbolConfig['ignoreFolders'] : []; + let args = (ignoreFolderFeatureOn && ignoreFolders && ignoreFolders.length > 0) ? ['-ignore', ignoreFolders.join(',')] : []; + args.push(workspacePath); + args.push(query); let gosyms = getBinPath('go-symbols'); return new Promise((resolve, reject) => { let p = cp.execFile(gosyms, args, { maxBuffer: 1024 * 1024 }, (err, stdout, stderr) => { @@ -59,16 +72,19 @@ export class GoWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider if (err && (err).code === 'ENOENT') { promptForMissingTool('go-symbols'); } + if (err && stderr && stderr.startsWith('flag provided but not defined: -ignore')) { + promptForUpdatingTool('go-symbols'); + return getWorkspaceSymbols(workspacePath, query, goConfig, false).then(results => { + return resolve(results); + }); + } if (err) return resolve(null); let result = stdout.toString(); let decls = JSON.parse(result); - let symbols: vscode.SymbolInformation[] = []; - convertToCodeSymbols(decls, symbols); - return resolve(symbols); + return resolve(decls); } catch (e) { reject(e); } }); }); } -} diff --git a/test/go.test.ts b/test/go.test.ts index 800d1a29a..e4dc5741f 100644 --- a/test/go.test.ts +++ b/test/go.test.ts @@ -11,6 +11,7 @@ import { GoHoverProvider } from '../src/goExtraInfo'; import { GoCompletionItemProvider } from '../src/goSuggest'; import { GoSignatureHelpProvider } from '../src/goSignature'; import { GoDefinitionProvider } from '../src/goDeclaration'; +import { getWorkspaceSymbols } from '../src/goSymbol'; import { check } from '../src/goCheck'; import cp = require('child_process'); import { getEditsFromUnifiedDiffStr, getEdits } from '../src/diffUtils'; @@ -709,4 +710,36 @@ It returns the number of bytes written and any write error encountered. return Promise.all([gopkgsPromise, listPkgPromise]); }).then(() => done(), done); }); + + test('Workspace Symbols', (done) => { + // This test needs a go project that has vendor folder and vendor packages + // Since the Go extension takes a dependency on the godef tool at github.com/rogpeppe/godef + // which has vendor packages, we are using it here to test the "replace vendor packages with relative path" feature. + // If the extension ever stops depending on godef tool or if godef ever stops having vendor packages, then this test + // will fail and will have to be replaced with any other go project with vendor packages + + let workspacePath = path.join(process.env['GOPATH'], 'src', 'github.com', 'rogpeppe', 'godef'); + let configWithoutIgnoringFolders = Object.create(vscode.workspace.getConfiguration('go'), { + 'gotoSymbol': { + value: { + 'ignoreFolders': [] + } + } + }); + let configWithIgnoringFolders = Object.create(vscode.workspace.getConfiguration('go'), { + 'gotoSymbol': { + value: { + 'ignoreFolders': ['vendor'] + } + } + }); + let withoutIgnoringFolders = getWorkspaceSymbols(workspacePath, 'WinInfo', configWithoutIgnoringFolders).then(results => { + assert.equal(results[0].name, 'WinInfo'); + assert.equal(results[0].path, path.join(workspacePath, 'vendor/9fans.net/go/acme/acme.go')); + }); + let withIgnoringFolders = getWorkspaceSymbols(workspacePath, 'WinInfo', configWithIgnoringFolders).then(results => { + assert.equal(results.length, 0); + }); + Promise.all([withIgnoringFolders, withoutIgnoringFolders]).then(() => done(), done); + }); });