mirror of
https://github.com/moeru-ai/airi-factorio.git
synced 2025-09-04 17:02:04 +00:00
feat: vscode extension for evaluate typescript code blocks
This commit is contained in:
18
.vscode/launch.json
vendored
Normal file
18
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "VSCode Factorio RCON Evaluator",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/packages/vscode-factorio-rcon-evaluator"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/packages/vscode-factorio-rcon-evaluator/dist/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "npm: build:extension"
|
||||
}
|
||||
]
|
||||
}
|
23
.vscode/tasks.json
vendored
Normal file
23
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "build:extension",
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
{
|
||||
"base": "$ts-webpack-watch",
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": "Build start",
|
||||
"endsPattern": "Build complete"
|
||||
}
|
||||
}
|
||||
],
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,41 +1,55 @@
|
||||
import antfu from '@antfu/eslint-config'
|
||||
|
||||
export default antfu({
|
||||
rules: {
|
||||
'ts/naming-convention': 'off',
|
||||
export default antfu(
|
||||
// #region naming-convention
|
||||
{
|
||||
rules: {
|
||||
'ts/naming-convention': 'off',
|
||||
},
|
||||
yaml: false,
|
||||
markdown: false,
|
||||
},
|
||||
yaml: false,
|
||||
markdown: false,
|
||||
}, {
|
||||
rules: {
|
||||
'ts/naming-convention': 'error',
|
||||
{
|
||||
rules: {
|
||||
'ts/naming-convention': 'error',
|
||||
},
|
||||
files: ['**/*.ts'],
|
||||
ignores: ['eslint.config.ts'],
|
||||
},
|
||||
files: ['**/*.ts'],
|
||||
ignores: ['eslint.config.ts'],
|
||||
}, {
|
||||
rules: {
|
||||
'ts/naming-convention': [
|
||||
'error',
|
||||
{
|
||||
selector: [
|
||||
'property',
|
||||
'parameter',
|
||||
'variable',
|
||||
],
|
||||
format: ['snake_case'],
|
||||
},
|
||||
],
|
||||
// rule conflict with ts/naming-convention when using snake_case
|
||||
'unused-imports/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^unused_',
|
||||
destructuredArrayIgnorePattern: '^unused_',
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
'ts/naming-convention': [
|
||||
'error',
|
||||
{
|
||||
selector: [
|
||||
'property',
|
||||
'parameter',
|
||||
'variable',
|
||||
],
|
||||
format: ['snake_case'],
|
||||
},
|
||||
],
|
||||
// rule conflict with ts/naming-convention when using snake_case
|
||||
'unused-imports/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^unused_',
|
||||
destructuredArrayIgnorePattern: '^unused_',
|
||||
},
|
||||
],
|
||||
},
|
||||
files: [
|
||||
'packages/autorio/**/*.ts',
|
||||
'packages/tstl-plugin-reload-factorio-mod/example/*.ts',
|
||||
],
|
||||
},
|
||||
files: [
|
||||
'packages/autorio/**/*.ts',
|
||||
'packages/tstl-plugin-reload-factorio-mod/example/*.ts',
|
||||
],
|
||||
})
|
||||
// #endregion
|
||||
// #region no-console
|
||||
{
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
},
|
||||
files: ['packages/vscode-factorio-rcon-evaluator/**/*.ts'],
|
||||
},
|
||||
// #endregion
|
||||
)
|
||||
|
@@ -20,6 +20,8 @@
|
||||
"dev": "pnpm dev:packages",
|
||||
"build:packages": "pnpm -r --filter=./packages/* run build",
|
||||
"dev:packages": "pnpm -r --filter=./packages/* run dev",
|
||||
"dev:extension": "pnpm -r --filter=./packages/vscode-factorio-rcon-evaluator run dev",
|
||||
"build:extension": "pnpm -r --filter=./packages/vscode-factorio-rcon-evaluator run build",
|
||||
"lint": "eslint --cache .",
|
||||
"lint:fix": "eslint --cache --fix .",
|
||||
"typecheck": "pnpm -r --filter=./packages/* run typecheck",
|
||||
@@ -34,11 +36,14 @@
|
||||
"lint-staged": "^16.1.2",
|
||||
"simple-git-hooks": "^2.13.0",
|
||||
"taze": "^19.1.0",
|
||||
"typed-factorio": "^3.26.0",
|
||||
"typescript": "~5.8.3"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@vscode/vsce-sign",
|
||||
"esbuild",
|
||||
"keytar",
|
||||
"simple-git-hooks",
|
||||
"unrs-resolver"
|
||||
]
|
||||
|
@@ -2,7 +2,6 @@
|
||||
"name": "@proj-airi/factorio-wrapper",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"description": "Run factorio server and convert std stream to websocket stream",
|
||||
"author": "LemonNekoGH",
|
||||
"license": "MIT",
|
||||
|
21
packages/vscode-factorio-rcon-evaluator/LICENSE
Normal file
21
packages/vscode-factorio-rcon-evaluator/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024-PRESENT LemonNeko
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
7
packages/vscode-factorio-rcon-evaluator/README.md
Normal file
7
packages/vscode-factorio-rcon-evaluator/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# vscode-factorio-rcon-evaluator
|
||||
|
||||
## TODO-List
|
||||
|
||||
- [ ] One-click evaluation of the current code block
|
||||
- [ ] Read configurations
|
||||
- [ ] Better error handling: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#a-minimal-compiler
|
86
packages/vscode-factorio-rcon-evaluator/package.json
Normal file
86
packages/vscode-factorio-rcon-evaluator/package.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"publisher": "LemonNeko",
|
||||
"name": "vscode-factorio-rcon-evaluator",
|
||||
"displayName": "Factorio RCON Evaluator",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"description": "Evaluate factorio lua script via rcon protocol in VSCode",
|
||||
"author": "LemonNekoGH",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/moeru-ai/airi-factorio",
|
||||
"directory": "packages/vscode-factorio-rcon-evaluator"
|
||||
},
|
||||
"keywords": [
|
||||
"factorio",
|
||||
"rcon",
|
||||
"vscode",
|
||||
"lua",
|
||||
"typescript"
|
||||
],
|
||||
"preview": true,
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"main": "./dist/index.js",
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"dist",
|
||||
"package.json"
|
||||
],
|
||||
"engines": {
|
||||
"vscode": "^1.100.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onStartupFinished"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "factorio-rcon-evaluator.run",
|
||||
"title": "Evaluate Selected Code"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"rconHost": {
|
||||
"type": "string",
|
||||
"default": "localhost",
|
||||
"description": "The hostname of the Factorio server."
|
||||
},
|
||||
"rconPort": {
|
||||
"type": "number",
|
||||
"default": 27015,
|
||||
"description": "The RCON port of the Factorio server."
|
||||
},
|
||||
"rconPassword": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "The RCON password for the Factorio server."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts --external vscode",
|
||||
"dev": "nr build --watch src",
|
||||
"publish": "nr build && vsce publish --no-dependencies",
|
||||
"package": "nr build && vsce package --no-dependencies",
|
||||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"lua-types": "^2.13.1",
|
||||
"rcon-client": "^4.2.5",
|
||||
"typed-factorio": "^3.26.0",
|
||||
"typescript-to-lua": "^1.31.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/vscode": "^1.100.0",
|
||||
"@vscode/vsce": "^3.6.0",
|
||||
"tsdown": "^0.13.0",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
89
packages/vscode-factorio-rcon-evaluator/src/index.ts
Normal file
89
packages/vscode-factorio-rcon-evaluator/src/index.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import type { ExtensionContext, OutputChannel } from 'vscode'
|
||||
import { Rcon } from 'rcon-client'
|
||||
import { BuildMode, LuaLibImportKind, LuaTarget, transpileString } from 'typescript-to-lua'
|
||||
import { commands, window, workspace } from 'vscode'
|
||||
|
||||
async function evaluate(channel: OutputChannel) {
|
||||
const editor = window.activeTextEditor
|
||||
if (!editor) {
|
||||
window.showErrorMessage('No active text editor found.')
|
||||
return
|
||||
}
|
||||
|
||||
const selectedText = editor.document.getText(editor.selection)
|
||||
if (!selectedText) {
|
||||
window.showErrorMessage('No text` selected in the editor.')
|
||||
return
|
||||
}
|
||||
|
||||
const transpileResult = transpileString(
|
||||
selectedText.trim(),
|
||||
{
|
||||
luaTarget: LuaTarget.LuaJIT,
|
||||
luaLibImport: LuaLibImportKind.Inline,
|
||||
buildMode: BuildMode.Default,
|
||||
noCheck: true,
|
||||
noHeader: true,
|
||||
noImplicitSelf: true,
|
||||
},
|
||||
)
|
||||
if (transpileResult.diagnostics.length > 0) {
|
||||
transpileResult.diagnostics.forEach((diagnostic) => {
|
||||
if (typeof diagnostic.messageText === 'string') {
|
||||
channel.appendLine(`Error: ${diagnostic.messageText} at ${diagnostic.start}`)
|
||||
}
|
||||
else {
|
||||
channel.appendLine(`Error: ${diagnostic.messageText.messageText} at ${diagnostic.start}`)
|
||||
}
|
||||
})
|
||||
|
||||
const errMsgResult = await window.showErrorMessage(`Transpilation failed, check the output channel for details.`, 'Open Output Channel')
|
||||
if (errMsgResult === 'Open Output Channel') {
|
||||
channel.show()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (!transpileResult.file || !transpileResult.file.lua) {
|
||||
window.showErrorMessage('Transpilation did not produce valid Lua code.')
|
||||
return
|
||||
}
|
||||
|
||||
// send to Factorio RCON
|
||||
try {
|
||||
const config = workspace.getConfiguration('factorio-rcon-evaluator')
|
||||
const host = config.get<string>('rconHost', 'localhost')
|
||||
const port = config.get<number>('rconPort', 27105)
|
||||
const password = config.get<string>('rconPassword', '123456')
|
||||
|
||||
channel.appendLine(`Connecting to RCON at ${host}:${port} with password ${password ? '***' : 'not set'}`)
|
||||
|
||||
const rcon = await Rcon.connect({
|
||||
host,
|
||||
port,
|
||||
password,
|
||||
})
|
||||
|
||||
const response = await rcon.send(`/sc ${transpileResult.file.lua}`)
|
||||
channel.appendLine(`RCON Response: ${response}`)
|
||||
channel.show()
|
||||
|
||||
await rcon.end()
|
||||
}
|
||||
catch (error) {
|
||||
channel.appendLine(`Error send to RCON: ${error instanceof Error ? error.message : String(error)}`)
|
||||
window.showErrorMessage(`Failed to send to RCON: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
export async function activate(ctx: ExtensionContext) {
|
||||
const channel = window.createOutputChannel('Factorio RCON Evaluator')
|
||||
channel.appendLine('Congratulations, your extension "vscode-factorio-rcon-evaluator" is now active!')
|
||||
|
||||
const disposable = commands.registerCommand('factorio-rcon-evaluator.test', () => evaluate(channel))
|
||||
|
||||
ctx.subscriptions.push(disposable)
|
||||
}
|
||||
|
||||
export function deactivate() {}
|
26
packages/vscode-factorio-rcon-evaluator/tsconfig.json
Normal file
26
packages/vscode-factorio-rcon-evaluator/tsconfig.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"ESNext"
|
||||
],
|
||||
"moduleDetection": "auto",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "./dist",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}
|
2450
pnpm-lock.yaml
generated
2450
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user