group imports command
This commit is contained in:
parent
80815c107e
commit
a8fa5bf1cf
7 changed files with 176 additions and 18 deletions
11
README.md
11
README.md
|
@ -24,7 +24,7 @@ Extension in active development! Your contribution is always welcome :)
|
|||
|
||||
# Interface implementation
|
||||
|
||||
Command "Go: Implement Interface Methods" based on https://github.com/ricardoerikson/vscode-go-impl-methods/ extension.
|
||||
Command "Go: Implement Interface Methods" based on https://github.com/ricardoerikson/vscode-go-impl-methods/ extension by Ricardo Erikson.
|
||||
|
||||
Install the impl package as follows:
|
||||
|
||||
|
@ -37,3 +37,12 @@ go get -u github.com/josharian/impl
|
|||
1. At command pallete select command "Go: Implement Interface Methods"
|
||||
2. Write receiver for methods. Example: "f *File", "m MyType", "c CustomType"
|
||||
3. Select interface to implement
|
||||
|
||||
|
||||
# Group imports
|
||||
|
||||
Group imports command based on https://github.com/gustavo-bordin/golang-imports-group/ extension by Gustavo Bordin.
|
||||
|
||||
## Usage
|
||||
|
||||
1. At command pallete select command "Go: Group imports"
|
|
@ -2,7 +2,7 @@
|
|||
"name": "gotools",
|
||||
"displayName": "Golang Tools",
|
||||
"description": "Tools for productive work",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"engines": {
|
||||
"vscode": "^1.80.0"
|
||||
},
|
||||
|
@ -56,6 +56,11 @@
|
|||
"command": "gotools.implement",
|
||||
"title": "Implement Interface Methods",
|
||||
"category": "Go"
|
||||
},
|
||||
{
|
||||
"command": "gotools.group-imports",
|
||||
"title": "Group imports",
|
||||
"category": "Go"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
97
src/group-imports.js
Normal file
97
src/group-imports.js
Normal file
|
@ -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;
|
|
@ -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_]*)$/;
|
||||
|
@ -19,7 +17,7 @@ function selectReceiver() {
|
|||
}
|
||||
});
|
||||
|
||||
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,7 +81,6 @@ function implement(interface_, receiver) {
|
|||
}
|
||||
|
||||
const position = editor.selection.active;
|
||||
|
||||
editor.insertSnippet(new vscode.SnippetString("\n" + stdout), position.with(position.line + 1, 0));
|
||||
resolve(true);
|
||||
});
|
||||
|
|
|
@ -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
|
||||
module.exports = { provideInterfaces };
|
52
src/utils.js
Normal file
52
src/utils.js
Normal file
|
@ -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
|
||||
};
|
Loading…
Reference in a new issue