我正在为《骑马与砍杀:战团脚本语言》开发代码格式化程序和代码片段支持,这是一款游戏,我遇到了严重的问题,我的格式化程序根本无法工作。片段按预期工作。我在这篇文章的底部解释了我打算做什么。 这是我的工作
扩展.js
const acorn = require('acorn');
const escodegen = require('escodegen');
const vscode = require('vscode');
function formatWarbandScriptLanguageCode(code) {
const parsedAst = acorn.parse(code, { ecmaVersion: 5 });
let indentationLevel = 0;
traverse(parsedAst, {
enter(node, parent) {
if (node.type === 'CallExpression') {
const operationNames = [
'try_begin',
'try_for_range',
'try_for_range_backwards',
'try_for_parties',
'try_for_agents',
'try_for_prop_instances',
'try_for_players',
'try_for_dict_keys',
];
if (operationNames.includes(node.callee.name)) {
// Insert a newline before the operation call
if (parent.body.indexOf(node) === 0) {
const newlineNode = {
type: 'WhiteSpace',
value: '\n' + ' '.repeat(indentationLevel), // Adjust the desired indentation
};
parent.body.unshift(newlineNode);
}
// Add a tab indentation to the arguments of the operation
node.arguments.forEach(arg => {
if (arg.type === 'ArrayExpression') {
arg.elements.forEach(element => {
element.loc.indent += 1; // Adjust the indentation level
});
}
});
indentationLevel++;
}
}
},
leave(node) {
if (node.type === 'CallExpression') {
const operationNames = [
'try_begin',
'try_for_range',
'try_for_range_backwards',
'try_for_parties',
'try_for_agents',
'try_for_prop_instances',
'try_for_players',
'try_for_dict_keys',
];
if (operationNames.includes(node.callee.name)) {
indentationLevel--;
}
}
},
});
const formattedCode = escodegen.generate(parsedAst);
return formattedCode;
}
function activate(context) {
console.log('M&B Warband API extension is now active.');
// ... other activation code ...
let disposable = vscode.commands.registerCommand('mbap.formatWarbandScript', () => {
const editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
const document = editor.document;
const text = document.getText();
// Format the code
const formattedCode = formatWarbandScriptLanguageCode(text);
// Apply the formatted code
const edit = new vscode.TextEdit(
new vscode.Range(0, 0, document.lineCount, 0),
formattedCode
);
const workspaceEdit = new vscode.WorkspaceEdit();
workspaceEdit.set(document.uri, [edit]);
vscode.workspace.applyEdit(workspaceEdit);
});
context.subscriptions.push(disposable);
}
// This method is called when your extension is deactivated
function deactivate() {
console.log('M&B Warband API extension is now deactivated.');
}
module.exports = {
activate,
deactivate
};
package.json
{
"name": "mbap",
"displayName": "M&B: Warband API",
"description": "Mount & Blade: Warband language support for Microsoft Visual Studio Code by Azremen and Sart",
"publisher": "Azremen",
"version": "0.1.18",
"homepage": "https://github.com/Azremen/MB-Warband-API-VSC/blob/main/README.md",
"engines": {
"vscode": "^1.62.0"
},
"repository": {
"type": "git",
"url": "https://github.com/Azremen/MB-Warband-API-VSC.git"
},
"categories": [
"Programming Languages"
],
"main": "./extension.js",
"activationEvents": [
"onCommand:mbap.formatWarbandScript"
],
"contributes": {
"languages": [
{
"id": "warbandsl",
"aliases": [
"Warband Script Language"
],
"extensions": [
".py"
],
"configuration": "./language-configuration.json"
}
],
"commands": [
{
"command": "mbap.formatWarbandScript",
"title": "Format Warband Script Language Code"
}
],
"snippets": [
{
"language": "warbandsl",
"path": "./snippets/mbap.code-snippets"
}
],
"keybindings": [
{
"command": "mbap.formatWarbandScript",
"key": "alt+shift+f",
"when": "editorTextFocus && resourceLangId == warbandsl"
}
]
},
"configuration": {
"title": "Warband Script Language Formatter",
"properties": {
"warbandsl.indentation": {
"type": "string",
"enum": [
"tabs",
"spaces"
],
"default": "spaces",
"description": "Indentation style for Warband Script Language Formatter."
},
"warbandsl.tabSize": {
"type": "number",
"default": 4,
"description": "Number of spaces or tabs to use for indentation."
}
}
},
"dependencies": {
"acorn": "^8.0.1",
"escodegen": "^2.0.0"
}
}
Visual Studio Code 给出
unexpected token(1:5)
error,并在 alt+shift+f
键盘按键组合上弹出一个窗口,应该可以格式化所需的文件。据我所知,Visual Studio Code 尝试运行 mbap.formatWarbandScript
命令。
我打算将每个元素移动到
operationNames
array 之后的下一行,然后插入一个选项卡。完成后,会有一条 'try_end'
line 应该与这些线对齐。我无法测试它,因为它根本不起作用。
在阅读评论并简化我的问题后,我得出结论,因为我完全重新设计了我的项目,这是我的工作:
扩展.js
const vscode = require('vscode');
const { execFileSync } = require('child_process');
const os = require('os');
const fs = require('fs');
function formatAndSaveDocument() {
const activeEditor = vscode.window.activeTextEditor;
if (activeEditor) {
const document = activeEditor.document;
const operationNames = [
"try_begin",
"try_for_range",
"try_for_range_backwards",
"try_for_parties",
"try_for_agents",
"try_for_prop_instances",
"try_for_players",
"try_for_dict_keys",
"else_try",
];
const originalContent = document.getText();
// Create a temporary file to store the original content
const tempFilePath = `${os.tmpdir()}/temp_mbap_script.py`;
fs.writeFileSync(tempFilePath, originalContent, 'utf-8');
// Use black command-line tool to format the content and get the formatted code
const blackCmd = `black --quiet ${tempFilePath}`;
execFileSync(blackCmd, {
encoding: 'utf-8',
shell: true
});
// Read the black-formatted content from the temporary file
const blackFormattedCode = fs.readFileSync(tempFilePath, 'utf-8');
// Delete the temporary file
fs.unlinkSync(tempFilePath);
// Apply your custom formatting with adjusted indentation levels for specific operation names
const customFormattedLines = [];
let currentIndentationLevel = 0;
for (const line of blackFormattedCode.split('\n')) {
const trimmedLine = line.trim();
if (trimmedLine.includes("try_end") || trimmedLine.includes("else_try")) {
currentIndentationLevel--;
}
const customIndentation = '\t'.repeat(Math.max(0, currentIndentationLevel));
const customFormattedLine = customIndentation + line;
customFormattedLines.push(customFormattedLine);
if (operationNames.some(op => trimmedLine.includes(op))) {
currentIndentationLevel++;
}
}
const customFormattedCode = customFormattedLines.join('\n');
const edit = new vscode.WorkspaceEdit();
edit.replace(document.uri, new vscode.Range(0, 0, document.lineCount, 0), customFormattedCode);
vscode.workspace.applyEdit(edit).then(success => {
if (success) {
vscode.window.showInformationMessage('Formatted and saved the document.');
} else {
vscode.window.showErrorMessage('An error occurred while formatting and saving the document.');
}
});
}
}
function checkAndInstallBlack() {
const terminal = vscode.window.createTerminal('Install Black');
terminal.sendText('pip show black', true);
terminal.processId.then(pid => {
terminal.show();
terminal.dispose();
});
}
function activate(context) {
// Register the formatAndSaveDocument command
const disposable = vscode.commands.registerCommand('mbap.formatWarbandScript', formatAndSaveDocument);
// Run the checkAndInstallBlack function when the extension is activated
checkAndInstallBlack();
// Add the disposable to the context for cleanup
context.subscriptions.push(disposable);
}
exports.activate = activate;
我尝试随着进展添加注释行。我希望这可以帮助任何尝试以任何方式做类似事情的人。