aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/extension.js5
-rw-r--r--src/group-imports.js97
-rw-r--r--src/implement-interface.js18
-rw-r--r--src/interfaces-provider.js4
-rw-r--r--src/utils.js52
5 files changed, 160 insertions, 16 deletions
diff --git a/src/extension.js b/src/extension.js
index 850d5be..81ba639 100644
--- a/src/extension.js
+++ b/src/extension.js
@@ -1,6 +1,7 @@
const vscode = require('vscode');
const { ErrorsWrapper, wrapError } = require('./errors');
const selectReceiver = require('./implement-interface');
+const groupImports = require('./group-imports');
/**
* @param {vscode.ExtensionContext} context
*/
@@ -19,9 +20,7 @@ function activate(context) {
);
context.subscriptions.push(wrapErrorCommand);
- vscode.commands.registerCommand("gotools.imports", function () {
- // TODO
- })
+ context.subscriptions.push(vscode.commands.registerCommand("gotools.group-imports", groupImports))
context.subscriptions.push(vscode.commands.registerCommand("gotools.implement", selectReceiver));
}
diff --git a/src/group-imports.js b/src/group-imports.js
new file mode 100644
index 0000000..00300e4
--- /dev/null
+++ b/src/group-imports.js
@@ -0,0 +1,97 @@
+const vscode = require('vscode');
+const { getModuleName, getImportsRange, getFileContent } = require('./utils');
+
+const BUILTIN_TYPE = "builtin"
+const THIRD_PARTY_TYPE = "thirdParty"
+const VENDOR_TYPE = "vendor"
+const LOCAL_TYPE = "local"
+
+
+function getImports(fileContent) {
+ try {
+ let importsRegex = new RegExp("(?<=import \\(\n).*?(?=\\))", "s")
+ let imports = importsRegex.exec(fileContent)[0]
+ return imports
+ } catch(_) {
+ vscode.window.showErrorMessage("Could not find imports")
+ }
+}
+
+function convertImportsToList(imports) {
+ return imports.split("\n")
+}
+
+function getImportType(import_) {
+ let goModName = getModuleName() + "/"
+ let vendorPath = goModName.substring(0, goModName.lastIndexOf('/'));
+
+ let isBuiltin = !import_.includes(".") && !import_.includes(goModName)
+ let isThirdParty = import_.includes(".") && !import_.includes(goModName)
+ let isLocal = import_.includes(goModName)
+ let isVendor = import_.includes(vendorPath) && !isLocal
+
+ if(isBuiltin) {
+ return BUILTIN_TYPE
+ } else if (isVendor) {
+ return VENDOR_TYPE
+ } else if(isThirdParty) {
+ return THIRD_PARTY_TYPE
+ } else if(isLocal) {
+ return LOCAL_TYPE
+ }
+}
+
+function importGroupsToString(importsGroup) {
+ return Object.keys(importsGroup)
+ .filter((key) => importsGroup[key].length)
+ .map((key) => importsGroup[key].join('\n'))
+ .join('\n\n');
+}
+
+function saveImportsGroup(importsGroup, importRanges, activeEditor) {
+ const edit = new vscode.WorkspaceEdit();
+ const range = new vscode.Range(
+ importRanges.start,
+ 0,
+ importRanges.end - 1,
+ Number.MAX_VALUE
+ );
+
+ let importsParsed = importGroupsToString(importsGroup)
+ let documentUri = activeEditor.document.uri
+
+ edit.replace(documentUri, range, importsParsed);
+ vscode.workspace.applyEdit(edit).then(activeEditor.document.save);
+}
+
+
+function getImportGroups(importsList) {
+ const importsGroup = {
+ [BUILTIN_TYPE]: [],
+ [THIRD_PARTY_TYPE]: [],
+ [VENDOR_TYPE]: [],
+ [LOCAL_TYPE]: [],
+ };
+
+
+ importsList.filter(n => n).forEach(import_ => {
+ let importType = getImportType(import_)
+ importsGroup[importType].push(import_)
+ })
+
+ return importsGroup
+}
+
+function formatImports() {
+ const activeEditor = vscode.window.activeTextEditor
+ let fileContent = getFileContent(activeEditor)
+ let imports = getImports(fileContent)
+ let importsList = convertImportsToList(imports)
+ let importsGroup = getImportGroups(importsList)
+ let importsRange = getImportsRange(fileContent)
+ saveImportsGroup(importsGroup,importsRange,activeEditor)
+}
+
+
+
+module.exports = formatImports; \ No newline at end of file
diff --git a/src/implement-interface.js b/src/implement-interface.js
index 8c6f3a3..a165902 100644
--- a/src/implement-interface.js
+++ b/src/implement-interface.js
@@ -1,11 +1,9 @@
const vscode = require('vscode');
const { dirname } = require('path');
const cp = require('child_process');
-const provideInterfaces = require('./interfaces-provider');
+const { provideInterfaces } = require('./interfaces-provider');
const debounce = require('lodash.debounce');
-
-
function selectReceiver() {
const receiverInput = vscode.window.createInputBox();
const pattern = /^([a-zA-Z_][a-zA-Z0-9_]*)\s+(\*?(?:[a-zA-Z_][a-zA-Z0-9]*\.)?[a-zA-Z_][a-zA-Z0-9_]*)$/;
@@ -15,11 +13,11 @@ function selectReceiver() {
if (value != "" && !value.match(pattern)) {
receiverInput.validationMessage = `Valid format: "f *File", "m MyType", "c CustomType"`;
} else {
- receiverInput.validationMessage = '';
+ receiverInput.validationMessage = '';
}
});
- receiverInput.onDidAccept(e => {
+ receiverInput.onDidAccept(() => {
const receiver = receiverInput.value;
const matches = receiver.match(pattern);
if (!matches) {
@@ -45,8 +43,7 @@ function selectInterface(receiver) {
quickPick.placeholder = "Which interface would you like to implement?";
const debounced = debounce((value) => {
provideInterfaces(value, (interfaces) => {
- const items = interfaces.map((label) => ({ label }));
- quickPick.items = items;
+ quickPick.items = interfaces;
});
}, 400, { trailing: true });
@@ -56,7 +53,7 @@ function selectInterface(receiver) {
quickPick.onDidChangeSelection(selection => {
if (selection[0]) {
- implement(selection[0].label, receiver);
+ implement(selection[0].detail + '.' + selection[0].label, receiver);
}
quickPick.hide();
});
@@ -72,7 +69,7 @@ function implement(interface_, receiver) {
vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Generating stub methods..."
- }, (progress, token) => {
+ }, () => {
return new Promise((resolve) => {
const r = `${receiver.name} ${receiver.type_}`
cp.exec(`impl "${r}" ${interface_}`,
@@ -84,8 +81,7 @@ function implement(interface_, receiver) {
}
const position = editor.selection.active;
-
- editor.insertSnippet(new vscode.SnippetString("\n" + stdout), position.with(position.line+1, 0));
+ editor.insertSnippet(new vscode.SnippetString("\n" + stdout), position.with(position.line + 1, 0));
resolve(true);
});
});
diff --git a/src/interfaces-provider.js b/src/interfaces-provider.js
index d42995e..969c562 100644
--- a/src/interfaces-provider.js
+++ b/src/interfaces-provider.js
@@ -9,9 +9,9 @@ function provideInterfaces(keyword, callback) {
(objects) => {
const interfaces = objects.
filter(x => x.kind == vscode.SymbolKind.Interface).
- map(x => x.name)
+ map(x => ({ label: x.name, detail: x.containerName }))
callback(interfaces);
});
}
-module.exports = provideInterfaces \ No newline at end of file
+module.exports = { provideInterfaces }; \ No newline at end of file
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 0000000..eddee94
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,52 @@
+const vscode = require('vscode');
+const path = require('path')
+const fs = require('fs')
+
+
+function getModuleName() {
+ try {
+ let workspacePath = vscode.workspace.workspaceFolders[0].uri.path
+ let modPath = path.join(workspacePath, "go.mod")
+ let data = fs.readFileSync(modPath).toString()
+ let moduleNameReg = new RegExp("(?<=module ).*")
+ let moduleName =moduleNameReg.exec(data)
+
+ return moduleName[0]
+ } catch (err) {
+ vscode.window.showInformationMessage("Could not get module name")
+ }
+}
+
+function getFileContent(activeEditor) {
+ return activeEditor.document.getText()
+}
+
+function getImportsRange(documentText) {
+ let start = 1;
+ let documentLines = documentText.split('\n')
+ for (var line of documentLines) {
+ if (line.includes('import (')) {
+ break;
+ }
+ start++;
+ }
+
+ let end = start;
+ for (var line of documentLines.slice(start)) {
+ if (line.includes(')')) {
+ break;
+ }
+ end++;
+ }
+
+ return {
+ end,
+ start,
+ };
+};
+
+
+
+module.exports = {
+ getModuleName, getFileContent, getImportsRange
+}; \ No newline at end of file