Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Package suggestion for _test.go #1220

Merged
merged 13 commits into from
Sep 28, 2017
31 changes: 14 additions & 17 deletions src/goSuggest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

import vscode = require('vscode');
import cp = require('child_process');
import { dirname, basename } from 'path';
import { getBinPath, parameters, parseFilePrelude, isPositionInString, goKeywords, getToolsEnvVars, timeout } from './util';
import { getBinPath, parameters, parseFilePrelude, isPositionInString, goKeywords, getToolsEnvVars, timeout, guessPackageNameFromFile } from './util';
import { promptForMissingTool } from './goInstallTools';
import { getTextEditForAddImport } from './goImport';
import { getImportablePackages } from './goPackages';


function vscodeKindFromGoCodeClass(kind: string): vscode.CompletionItemKind {
switch (kind) {
case 'const':
Expand Down Expand Up @@ -148,21 +148,6 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider {
let suggestions = [];
let suggestionSet = new Set<string>();

// 'Smart Snippet' for package clause
// TODO: Factor this out into a general mechanism
if (!inputText.match(/package\s+(\w+)/)) {
let defaultPackageName =
basename(filename) === 'main.go'
? 'main'
: basename(dirname(filename));
if (defaultPackageName.match(/[a-zA-Z_]\w*/)) {
let packageItem = new vscode.CompletionItem('package ' + defaultPackageName);
packageItem.kind = vscode.CompletionItemKind.Snippet;
packageItem.insertText = 'package ' + defaultPackageName + '\r\n\r\n';
suggestions.push(packageItem);
}

}
if (results[1]) {
for (let suggest of results[1]) {
if (inString && suggest.class !== 'import') continue;
Expand Down Expand Up @@ -204,6 +189,18 @@ export class GoCompletionItemProvider implements vscode.CompletionItemProvider {
let importablePkgs = includeUnimportedPkgs ? this.getMatchingPackages(currentWord, suggestionSet) : [];
suggestions = suggestions.concat(importablePkgs);

// 'Smart Snippet' for package clause
// TODO: Factor this out into a general mechanism
if (!inputText.match(/package\s+(\w+)/)) {
return guessPackageNameFromFile(filename).then(pkgName => {
let packageItem = new vscode.CompletionItem('package ' + pkgName);
packageItem.kind = vscode.CompletionItemKind.Snippet;
packageItem.insertText = 'package ' + pkgName + '\r\n\r\n';
suggestions.push(packageItem);
resolve(suggestions);
}, () => resolve(suggestions));
}

resolve(suggestions);
} catch (e) {
reject(e);
Expand Down
52 changes: 52 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,55 @@ export function getImportPath(text: string): string {

return '';
}

// TODO: Add unit tests for the below

/**
* Guess the package name based on parent directory name of the given file
*
* Cases:
* - dir 'go-i18n' -> 'i18n'
* - dir 'go-spew' -> 'spew'
* - dir 'kingpin' -> 'kingpin'
* - dir 'go-expand-tilde' -> 'tilde'
* - dir 'gax-go' -> 'gax'
* - dir 'go-difflib' -> 'difflib'
* - dir 'jwt-go' -> 'jwt'
* - dir 'go-radix' -> 'radix'
*
* @param {string} filePath.
*/
export function guessPackageNameFromFile(filePath): Promise<string> {
return new Promise((resolve, reject) => {

const goFilename = path.basename(filePath);
if (goFilename === 'main.go') {
return resolve('main');
}

const directoryPath = path.dirname(filePath);
let segments = directoryPath.split(/[\.-]/);
segments = segments.filter(val => val !== 'go');

if (segments.length === 0 || !/[a-zA-Z_]\w*/.test(segments[segments.length - 1])) {
return reject();
}

const proposedPkgName = segments[segments.length - 1];

if (goFilename.endsWith('internal_test.go')) {
return resolve(proposedPkgName);
}

if (goFilename.endsWith('_test.go')) {
return resolve(proposedPkgName + '_test');
}

fs.stat(path.join(directoryPath, 'main.go'), (err, stats) => {
if (stats && stats.isFile()) {
return resolve('main');
}
return resolve(proposedPkgName);
});
});
}