Compare commits

...

10 Commits

Author SHA1 Message Date
睿 安
031b71c8a3 取出每次下方弹窗 2026-01-21 16:57:53 +08:00
睿 安
31475aa243 优化格式化功能中的自动换行 2025-10-22 10:55:24 +08:00
睿 安
9984dbc8e9 优化自动格式化,可关闭 2025-10-03 20:55:25 +08:00
睿 安
a26baaf66a 根据配置控制自动格式化功能
- 在onTypeFormattingProvider.ts中添加配置检查,根据squirrel.autoFormatOnType配置项决定是否执行输入时自动格式化
- 在documentFormattingProvider.ts中添加配置检查,根据squirrel.autoFormatOnType配置项决定是否执行文档格式化
- 保持配置项的默认值为false(禁用),用户需主动启用此功能

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 20:48:35 +08:00
睿 安
aaf84bc264 与C++联动,根据返回值才执行上传pvf 2025-10-03 20:41:57 +08:00
睿 安
859af05c7f 修改保存逻辑:在上传文件前先通过C++编译服务验证脚本
- 修改model.ts的saveFileContent方法,在上传文件前先通过C++服务验证脚本
- 如果C++服务可连接,则先发送脚本进行编译验证,只有在返回200状态码(编译通过)后才上传到服务器
- 如果C++服务返回非200状态码(编译失败),则不允许上传并提示错误
- 如果C++服务不可连接,则直接上传到服务器
- 简化extension.ts中的保存事件监听器,仅执行UI更新和缓存更新
- 保持原有错误处理机制,确保在C++服务故障时也能正常上传文件

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 20:34:01 +08:00
睿 安
95dfc4397e 修改保存逻辑:先检查C++服务连接性再决定上传流程
- 添加checkCppServiceConnection函数用于检查C++服务是否可连接
- 修改保存逻辑:如果C++服务可连接,先发送文件内容到C++服务,只有在收到200状态码后才继续保存到服务器
- 如果C++服务不可连接,则直接使用API函数保存到服务器
- 完善输出信息,帮助用户了解当前处理流程

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 19:54:53 +08:00
睿 安
8742b1d7d4 修改保存逻辑:先发送文件到本地C++服务,成功后再保存到服务器
- 调整文件保存流程:首先向本地C++服务发送文件内容
- 只有在收到C++服务返回200状态码后才继续执行保存到服务器操作
- 如果C++服务响应失败,则跳过服务器保存,并提供相应提示

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-03 19:32:02 +08:00
睿 安
32108d0d2b 开始修复的备份 2025-10-03 19:05:22 +08:00
睿 安
8f5ddd7dec 添加本地服务端口配置项,允许用户自定义发送JSON数据的端口号
- 在localClient.ts中实现从配置读取端口号,默认值为26000
- 在package.json中添加squirrel.localServicePort配置项
- 用户现在可以通过VS Code设置自定义本地C++服务端口

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 16:10:04 +08:00
28 changed files with 318 additions and 535 deletions

113
CLAUDE.md
View File

@@ -1,113 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Squirrel NUT Explorer is a VS Code extension for browsing and editing NUT (Squirrel script) files through the pvfUtility API. The extension provides comprehensive language support features including code completion, hover information, definition jumping, function signature help, code formatting, and error detection.
## Build Commands
```bash
# Install dependencies
npm install
# Compile TypeScript
npm run compile
# Watch mode compilation
npm run watch
# Build project
npm run build
# VS Code pre-publish build
npm run vscode:prepublish
```
## High-Level Architecture
### Core Components
1. **Extension Entry Point** (`src/extension.ts`):
- Registers all providers and commands
- Initializes core services and manages extension lifecycle
2. **Data Model** (`src/model.ts`):
- `FileModel` class manages file state, content, and API communication
- Handles connection to pvfUtility API and file operations
- Manages file list and content caching
3. **Tree View Provider** (`src/provider.ts`):
- Implements `vscode.TreeDataProvider` for displaying files in the explorer view
- Manages UI representation of files and folders
4. **File System Provider** (`src/fileSystemProvider.ts`):
- Implements `vscode.FileSystemProvider` for virtual file handling
- Bridges VS Code file operations with pvfUtility API
### Language Feature Providers (`src/providers/`)
1. **Completion Provider** (`src/providers/completionProvider.ts`):
- Provides code completion for functions, keywords, constants, and variables
- Includes both basic completion and dot notation completion for object methods
2. **Hover Provider** (`src/providers/hoverProvider.ts`):
- Shows detailed information when hovering over code elements
- Displays function signatures, descriptions, and parameter details
3. **Definition Provider** (`src/providers/definitionProvider.ts`):
- Enables "Go to Definition" functionality for cross-file function references
4. **Signature Help Provider** (`src/providers/signatureHelpProvider.ts`):
- Shows function parameter information during typing
5. **Formatting Providers** (`src/providers/onTypeFormattingProvider.ts`, `src/providers/documentFormattingProvider.ts`):
- Handle code formatting on type and document formatting
6. **Code Error Provider** (`src/providers/codeErrorProvider.ts`):
- Implements code diagnostics and quick fixes
### Core Functionality Modules
1. **Function Extractor** (`src/functionExtractor.ts`):
- Parses NUT files to extract function definitions
- Manages function caching for performance
- Provides cross-file function reference capabilities
2. **API Client** (`src/apiClient.ts`):
- Handles all HTTP communication with pvfUtility API
- Manages file listing, content retrieval, and file saving
3. **API Parser** (`src/providers/apiParser.ts`):
- Provides built-in Squirrel language documentation
- Manages API functions, classes, and constants information
## Key Dependencies
- **VS Code API**: Foundation for extension development
- **TypeScript**: Development language
- **Node.js HTTP/HTTPS modules**: For API communication (no external HTTP libraries)
## Configuration Options
The extension provides these configuration options:
- `squirrel.api.baseUrl`: pvfUtility API base URL (default: http://localhost)
- `squirrel.api.port`: pvfUtility API port (default: 8080)
- `squirrel.defaultDirectory`: Default directory to browse (default: sqr)
- `squirrel.nutEncoding`: NUT file encoding type (default: UTF8)
## Development Notes
1. **Caching Mechanism**: FunctionExtractor uses caching to improve performance. File caches are updated when files are saved.
2. **Batch Processing**: Files are processed in batches to prevent memory overflow and blocking.
3. **Error Handling**: All API calls include exception handling to ensure extension stability.
4. **Chinese Support**: The project primarily uses Chinese for UI and comments, maintaining consistency in code documentation.
5. **Virtual File System**: The extension uses VS Code's virtual file system API to provide a seamless editing experience for remote files.
6. **Performance Monitoring**: Function extraction includes performance monitoring to track efficiency.

1
dist/apiClient.js vendored
View File

@@ -154,6 +154,7 @@ class ApiClient {
async uploadFileContent(filePath, content) { async uploadFileContent(filePath, content) {
try { try {
const url = this.getFullUrl(`/Api/PvfUtiltiy/ImportFile?filePath=${encodeURIComponent(filePath)}`); const url = this.getFullUrl(`/Api/PvfUtiltiy/ImportFile?filePath=${encodeURIComponent(filePath)}`);
console.log(`上传文件URL: ${url}`);
const result = await this.request(url, 'POST', content, { const result = await this.request(url, 'POST', content, {
'Content-Type': 'text/plain; charset=utf-8', 'Content-Type': 'text/plain; charset=utf-8',
}); });

File diff suppressed because one or more lines are too long

15
dist/extension.js vendored
View File

@@ -132,17 +132,12 @@ function activate(context) {
const saveListener = vscode.workspace.onDidSaveTextDocument(async (doc) => { const saveListener = vscode.workspace.onDidSaveTextDocument(async (doc) => {
if (doc.uri.scheme === 'squirrel') { if (doc.uri.scheme === 'squirrel') {
const filePath = doc.uri.path.substring(1); // 去掉开头的 '/' const filePath = doc.uri.path.substring(1); // 去掉开头的 '/'
const success = await model.saveFileContent(filePath, doc.getText()); // 当文件保存成功后执行UI更新和缓存更新
if (success) { output.appendLine(`[Squirrel] 文件 ${filePath} 已保存到服务器`);
output.appendLine(`[Squirrel] 文件 ${filePath} 保存成功`);
provider.refresh(); provider.refresh();
// 更新函数缓存 // 更新函数缓存
await functionExtractor.updateFileCache(model, filePath); await functionExtractor.updateFileCache(model, filePath);
} }
else {
output.appendLine(`[Squirrel] 文件 ${filePath} 保存失败`);
}
}
}); });
// 注册文件关闭事件以清理缓存 // 注册文件关闭事件以清理缓存
const closeListener = vscode.workspace.onDidCloseTextDocument((doc) => { const closeListener = vscode.workspace.onDidCloseTextDocument((doc) => {
@@ -151,10 +146,10 @@ function activate(context) {
} }
}); });
context.subscriptions.push(configChangeListener, saveListener, closeListener); context.subscriptions.push(configChangeListener, saveListener, closeListener);
output.appendLine('[Squirrel] 扩展激活完成'); //output.appendLine('[Squirrel] 扩展激活完成');
output.show(); // output.show(); // 不自动显示输出窗口
// 显示欢迎信息 // 显示欢迎信息
vscode.window.showInformationMessage('Squirrel NUT Explorer 已激活,请点击"连接到 pvfUtility API"开始使用'); // vscode.window.showInformationMessage('Squirrel NUT Explorer 已激活,请点击"连接到 pvfUtility API"开始使用');
} }
function deactivate() { function deactivate() {
console.log('Squirrel NUT Explorer 正在停用...'); console.log('Squirrel NUT Explorer 正在停用...');

View File

@@ -1 +1 @@
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"} {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}

48
dist/localClient.js vendored
View File

@@ -33,8 +33,51 @@ var __importStar = (this && this.__importStar) || (function () {
}; };
})(); })();
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.checkCppServiceConnection = checkCppServiceConnection;
exports.sendFileToCppService = sendFileToCppService; exports.sendFileToCppService = sendFileToCppService;
const http = __importStar(require("http")); const http = __importStar(require("http"));
const net = __importStar(require("net"));
const vscode = __importStar(require("vscode"));
/**
* 检查本地C++服务是否可连接
* @returns Promise<boolean> 是否可连接
*/
async function checkCppServiceConnection() {
// 从配置中获取端口号默认为26000
const config = vscode.workspace.getConfiguration('squirrel');
const localServicePort = config.get('localServicePort', 26000);
return new Promise((resolve) => {
const socket = new net.Socket();
let isResolved = false;
socket.setTimeout(3000); // 3秒超时
socket.connect(localServicePort, '127.0.0.1', () => {
// 连接成功,端口可达
socket.destroy();
resolve(true);
});
socket.on('error', (error) => {
// 连接失败
if (!isResolved) {
isResolved = true;
resolve(false);
}
});
socket.on('timeout', () => {
// 连接超时
socket.destroy();
if (!isResolved) {
isResolved = true;
resolve(false);
}
});
socket.on('close', () => {
if (!isResolved) {
isResolved = true;
resolve(false);
}
});
});
}
/** /**
* 构建JSON数据 * 构建JSON数据
* @param filePath 文件路径 * @param filePath 文件路径
@@ -53,12 +96,15 @@ function buildJsonData(filePath, content) {
* @returns Promise<boolean> 是否发送成功 * @returns Promise<boolean> 是否发送成功
*/ */
async function sendFileToCppService(filePath, content) { async function sendFileToCppService(filePath, content) {
// 从配置中获取端口号默认为26000
const config = vscode.workspace.getConfiguration('squirrel');
const localServicePort = config.get('localServicePort', 26000);
return new Promise((resolve) => { return new Promise((resolve) => {
const jsonData = buildJsonData(filePath, content); const jsonData = buildJsonData(filePath, content);
const postData = jsonData; const postData = jsonData;
const options = { const options = {
hostname: '127.0.0.1', hostname: '127.0.0.1',
port: 26000, port: localServicePort,
path: '/send_data', path: '/send_data',
method: 'POST', method: 'POST',
headers: { headers: {

View File

@@ -1 +1 @@
{"version":3,"file":"localClient.js","sourceRoot":"","sources":["../src/localClient.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,oDA0CC;AAhED,2CAA6B;AAG7B;;;;;GAKG;AACH,SAAS,aAAa,CAAC,QAAgB,EAAE,OAAe;IACpD,MAAM,IAAI,GAA8B,EAAE,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAEzB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,oBAAoB,CAAC,QAAgB,EAAE,OAAe;IACxE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC;QAE1B,MAAM,OAAO,GAAwB;YACjC,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;aAChD;SACJ,CAAC;QAEF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACtC,IAAI,IAAI,GAAG,EAAE,CAAC;YAEd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBACrB,IAAI,IAAI,KAAK,CAAC;YAClB,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACf,OAAO,CAAC,GAAG,CAAC,2BAA2B,QAAQ,UAAU,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;gBAC3E,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBACzB,OAAO,CAAC,IAAI,CAAC,CAAC;gBAClB,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,KAAK,CAAC,wBAAwB,GAAG,CAAC,UAAU,SAAS,IAAI,EAAE,CAAC,CAAC;oBACrE,OAAO,CAAC,KAAK,CAAC,CAAC;gBACnB,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACtB,OAAO,CAAC,KAAK,CAAC,4BAA4B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpB,GAAG,CAAC,GAAG,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;AACP,CAAC"} {"version":3,"file":"localClient.js","sourceRoot":"","sources":["../src/localClient.ts"],"names":[],"mappings":"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"}

42
dist/model.js vendored
View File

@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.FileModel = void 0; exports.FileModel = void 0;
const vscode = __importStar(require("vscode")); const vscode = __importStar(require("vscode"));
const apiClient_1 = require("./apiClient"); const apiClient_1 = require("./apiClient");
const localClient_1 = require("./localClient");
class FileModel { class FileModel {
constructor() { constructor() {
this.fileList = new Map(); this.fileList = new Map();
@@ -185,6 +186,46 @@ class FileModel {
} }
// 保存文件内容 // 保存文件内容
async saveFileContent(filePath, content) { async saveFileContent(filePath, content) {
// 先检查C++服务是否可连接
const isCppServiceConnected = await (0, localClient_1.checkCppServiceConnection)();
if (isCppServiceConnected) {
// C++服务可连接,先发送进行编译验证
try {
const sendSuccess = await (0, localClient_1.sendFileToCppService)(filePath, content);
if (sendSuccess) {
// C++编译服务返回200说明脚本编译通过允许上传
const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
return true;
}
}
else {
// C++编译服务返回非200说明脚本存在问题不允许上传
vscode.window.showErrorMessage(`脚本编译失败,无法保存文件 ${filePath}。请检查代码错误后再试。`);
return false;
}
}
catch (error) {
// 向C++服务发送文件过程中出现错误
vscode.window.showErrorMessage(`发送文件到编译服务时出错: ${error},但仍尝试直接保存文件`);
const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
return true;
}
}
}
else {
// C++服务不可连接,直接执行上传
try { try {
const success = await this.apiClient.uploadFileContent(filePath, content); const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) { if (success) {
@@ -199,6 +240,7 @@ class FileModel {
catch (error) { catch (error) {
vscode.window.showErrorMessage(`保存文件失败: ${error}`); vscode.window.showErrorMessage(`保存文件失败: ${error}`);
} }
}
return false; return false;
} }
// 刷新文件列表 // 刷新文件列表

2
dist/model.js.map vendored

File diff suppressed because one or more lines are too long

View File

@@ -44,6 +44,12 @@ class DocumentFormattingProvider {
* 提供整个文档的代码格式化功能 * 提供整个文档的代码格式化功能
*/ */
async provideDocumentFormattingEdits(document, options, token) { async provideDocumentFormattingEdits(document, options, token) {
// 检查配置项,如果未启用自动格式化则直接返回
const config = vscode.workspace.getConfiguration('squirrel');
const autoFormatOnType = config.get('autoFormatOnType', false);
if (!autoFormatOnType) {
return []; // 自动格式化未启用,返回空数组
}
const edits = []; const edits = [];
try { try {
// 获取文档全文 // 获取文档全文

View File

@@ -1 +1 @@
{"version":3,"file":"documentFormattingProvider.js","sourceRoot":"","sources":["../../src/providers/documentFormattingProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,4DAAuE;AAEvE;;GAEG;AACH,MAAa,0BAA0B;IACnC;;OAEG;IACH,KAAK,CAAC,8BAA8B,CAChC,QAA6B,EAC7B,OAAiC,EACjC,KAA+B;QAE/B,MAAM,KAAK,GAAsB,EAAE,CAAC;QAEpC,IAAI,CAAC;YACD,SAAS;YACT,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;YAEpC,oBAAoB;YACpB,IAAI,CAAC,IAAA,+BAAc,EAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,KAAK,CAAC,CAAC,0BAA0B;YAC5C,CAAC;YAED,uBAAuB;YACvB,MAAM,aAAa,GAAG,IAAA,6BAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEtD,wBAAwB;YACxB,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,gBAAgB;YAChB,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,KAAK,CAC9B,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EACtB,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CACvC,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;QAElE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACjC,0BAA0B;QAC9B,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AA3CD,gEA2CC"} {"version":3,"file":"documentFormattingProvider.js","sourceRoot":"","sources":["../../src/providers/documentFormattingProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,4DAAuE;AAEvE;;GAEG;AACH,MAAa,0BAA0B;IACnC;;OAEG;IACH,KAAK,CAAC,8BAA8B,CAChC,QAA6B,EAC7B,OAAiC,EACjC,KAA+B;QAE/B,wBAAwB;QACxB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC7D,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAU,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAExE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,iBAAiB;QAChC,CAAC;QAED,MAAM,KAAK,GAAsB,EAAE,CAAC;QAEpC,IAAI,CAAC;YACD,SAAS;YACT,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;YAEpC,oBAAoB;YACpB,IAAI,CAAC,IAAA,+BAAc,EAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,KAAK,CAAC,CAAC,0BAA0B;YAC5C,CAAC;YAED,uBAAuB;YACvB,MAAM,aAAa,GAAG,IAAA,6BAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEtD,wBAAwB;YACxB,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,gBAAgB;YAChB,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,KAAK,CAC9B,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EACtB,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CACvC,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;QAElE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACjC,0BAA0B;QAC9B,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AAnDD,gEAmDC"}

View File

@@ -44,6 +44,12 @@ class OnTypeFormattingProvider {
* 在用户输入特定字符时自动格式化代码 * 在用户输入特定字符时自动格式化代码
*/ */
async provideOnTypeFormattingEdits(document, position, ch, options, token) { async provideOnTypeFormattingEdits(document, position, ch, options, token) {
// 检查配置项,如果未启用自动格式化则直接返回
const config = vscode.workspace.getConfiguration('squirrel');
const autoFormatOnType = config.get('autoFormatOnType', false);
if (!autoFormatOnType) {
return []; // 自动格式化未启用,返回空数组
}
const edits = []; const edits = [];
try { try {
// 获取文档全文 // 获取文档全文

View File

@@ -1 +1 @@
{"version":3,"file":"onTypeFormattingProvider.js","sourceRoot":"","sources":["../../src/providers/onTypeFormattingProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,4DAAuE;AAEvE;;GAEG;AACH,MAAa,wBAAwB;IACjC;;OAEG;IACH,KAAK,CAAC,4BAA4B,CAC9B,QAA6B,EAC7B,QAAyB,EACzB,EAAU,EACV,OAAiC,EACjC,KAA+B;QAE/B,MAAM,KAAK,GAAsB,EAAE,CAAC;QAEpC,IAAI,CAAC;YACD,SAAS;YACT,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;YAEpC,oBAAoB;YACpB,IAAI,CAAC,IAAA,+BAAc,EAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,KAAK,CAAC,CAAC,0BAA0B;YAC5C,CAAC;YAED,uBAAuB;YACvB,MAAM,aAAa,GAAG,IAAA,6BAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEtD,wBAAwB;YACxB,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,gBAAgB;YAChB,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,KAAK,CAC9B,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EACtB,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CACvC,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;QAElE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAClC,0BAA0B;QAC9B,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AA7CD,4DA6CC"} {"version":3,"file":"onTypeFormattingProvider.js","sourceRoot":"","sources":["../../src/providers/onTypeFormattingProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,4DAAuE;AAEvE;;GAEG;AACH,MAAa,wBAAwB;IACjC;;OAEG;IACH,KAAK,CAAC,4BAA4B,CAC9B,QAA6B,EAC7B,QAAyB,EACzB,EAAU,EACV,OAAiC,EACjC,KAA+B;QAE/B,wBAAwB;QACxB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC7D,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAU,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAExE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,iBAAiB;QAChC,CAAC;QAED,MAAM,KAAK,GAAsB,EAAE,CAAC;QAEpC,IAAI,CAAC;YACD,SAAS;YACT,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;YAEpC,oBAAoB;YACpB,IAAI,CAAC,IAAA,+BAAc,EAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,KAAK,CAAC,CAAC,0BAA0B;YAC5C,CAAC;YAED,uBAAuB;YACvB,MAAM,aAAa,GAAG,IAAA,6BAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEtD,wBAAwB;YACxB,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,gBAAgB;YAChB,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,KAAK,CAC9B,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EACtB,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CACvC,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;QAElE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAClC,0BAA0B;QAC9B,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AArDD,4DAqDC"}

View File

@@ -1,8 +1,42 @@
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.getSquirrelBeautifyOptions = getSquirrelBeautifyOptions; exports.getSquirrelBeautifyOptions = getSquirrelBeautifyOptions;
exports.beautifyCode = beautifyCode; exports.beautifyCode = beautifyCode;
exports.isSquirrelCode = isSquirrelCode; exports.isSquirrelCode = isSquirrelCode;
const vscode = __importStar(require("vscode"));
// 由于 js-beautify.js 文件体积较大且复杂,我们将创建专门的存根函数 // 由于 js-beautify.js 文件体积较大且复杂,我们将创建专门的存根函数
// 将使用原生的 js-beautify 功能 // 将使用原生的 js-beautify 功能
let _jsBeauifyInstance = null; let _jsBeauifyInstance = null;
@@ -74,7 +108,7 @@ function createBasicJsBeautify() {
brace_style: 'collapse', brace_style: 'collapse',
space_before_conditional: true, space_before_conditional: true,
space_after_anon_function: false, space_after_anon_function: false,
wrap_line_length: 120, wrap_line_length: 0, // 默认禁用自动换行
end_with_newline: false end_with_newline: false
}; };
// 合并选项 // 合并选项
@@ -139,6 +173,9 @@ const jsBeautify = {
* Squirrel 语言的 js-beautify 选项配置 * Squirrel 语言的 js-beautify 选项配置
*/ */
function getSquirrelBeautifyOptions(options) { function getSquirrelBeautifyOptions(options) {
// 从用户配置中读取换行长度设置
const config = vscode.workspace.getConfiguration('squirrel.formatting');
const wrapLineLength = config.get('wrapLineLength', 0);
return { return {
indent_size: options.tabSize, indent_size: options.tabSize,
indent_char: options.insertSpaces ? ' ' : '\t', indent_char: options.insertSpaces ? ' ' : '\t',
@@ -149,7 +186,7 @@ function getSquirrelBeautifyOptions(options) {
space_before_conditional: true, space_before_conditional: true,
space_after_anon_function: false, space_after_anon_function: false,
unescape_strings: false, unescape_strings: false,
wrap_line_length: 120, wrap_line_length: wrapLineLength,
end_with_newline: false end_with_newline: false
}; };
} }

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
"name": "squirrel-nut-explorer", "name": "squirrel-nut-explorer",
"displayName": "Squirrel NUT Explorer", "displayName": "Squirrel NUT Explorer",
"description": "通过 pvfUtility API 浏览和编辑 NUT 文件", "description": "通过 pvfUtility API 浏览和编辑 NUT 文件",
"version": "1.1.1", "version": "1.1.5",
"publisher": "local", "publisher": "local",
"engines": { "engines": {
"vscode": "^1.99.0" "vscode": "^1.99.0"
@@ -122,6 +122,23 @@
"UTF-8", "UTF-8",
"Unicode" "Unicode"
] ]
},
"squirrel.localServicePort": {
"type": "number",
"default": 26000,
"description": "本地C++服务端口用于发送保存的NUT文件"
},
"squirrel.autoFormatOnType": {
"type": "boolean",
"default": false,
"description": "是否在编辑时自动格式化代码"
},
"squirrel.formatting.wrapLineLength": {
"type": "number",
"default": 0,
"description": "代码格式化时的最大行长度,超过此长度会自动换行。设置为 0 表示禁用自动换行",
"minimum": 0,
"maximum": 500
} }
} }
} }

Binary file not shown.

Binary file not shown.

View File

@@ -167,7 +167,7 @@ export class ApiClient {
async uploadFileContent(filePath: string, content: string): Promise<boolean> { async uploadFileContent(filePath: string, content: string): Promise<boolean> {
try { try {
const url = this.getFullUrl(`/Api/PvfUtiltiy/ImportFile?filePath=${encodeURIComponent(filePath)}`); const url = this.getFullUrl(`/Api/PvfUtiltiy/ImportFile?filePath=${encodeURIComponent(filePath)}`);
console.log(`上传文件URL: ${url}`);
const result = await this.request(url, 'POST', content, { const result = await this.request(url, 'POST', content, {
'Content-Type': 'text/plain; charset=utf-8', 'Content-Type': 'text/plain; charset=utf-8',
}); });

View File

@@ -12,7 +12,7 @@ import { OnTypeFormattingProvider } from './providers/onTypeFormattingProvider';
import { DocumentFormattingProvider } from './providers/documentFormattingProvider'; import { DocumentFormattingProvider } from './providers/documentFormattingProvider';
import { CodeErrorProvider } from './providers/codeErrorProvider'; import { CodeErrorProvider } from './providers/codeErrorProvider';
import { ApiParser } from './providers/apiParser'; import { ApiParser } from './providers/apiParser';
import { sendFileToCppService } from './localClient'; import { sendFileToCppService, checkCppServiceConnection } from './localClient';
export function activate(context: vscode.ExtensionContext) { export function activate(context: vscode.ExtensionContext) {
console.log('Squirrel NUT Explorer 正在激活...'); console.log('Squirrel NUT Explorer 正在激活...');
@@ -141,30 +141,13 @@ export function activate(context: vscode.ExtensionContext) {
const saveListener = vscode.workspace.onDidSaveTextDocument(async (doc) => { const saveListener = vscode.workspace.onDidSaveTextDocument(async (doc) => {
if (doc.uri.scheme === 'squirrel') { if (doc.uri.scheme === 'squirrel') {
const filePath = doc.uri.path.substring(1); // 去掉开头的 '/' const filePath = doc.uri.path.substring(1); // 去掉开头的 '/'
const fileContent = doc.getText();
const success = await model.saveFileContent(filePath, fileContent);
if (success) { // 当文件保存成功后执行UI更新和缓存更新
output.appendLine(`[Squirrel] 文件 ${filePath} 保存成功`); output.appendLine(`[Squirrel] 文件 ${filePath} 保存到服务器`);
provider.refresh(); provider.refresh();
// 更新函数缓存 // 更新函数缓存
await functionExtractor.updateFileCache(model, filePath); await functionExtractor.updateFileCache(model, filePath);
// 发送文件内容到本地C++服务
try {
const sendSuccess = await sendFileToCppService(filePath, fileContent);
if (sendSuccess) {
output.appendLine(`[Squirrel] 文件 ${filePath} 已发送到C++服务`);
} else {
output.appendLine(`[Squirrel] 文件 ${filePath} 发送到C++服务失败`);
}
} catch (error) {
output.appendLine(`[Squirrel] 发送文件到C++服务时发生错误: ${error}`);
}
} else {
output.appendLine(`[Squirrel] 文件 ${filePath} 保存失败`);
}
} }
}); });
@@ -177,11 +160,11 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(configChangeListener, saveListener, closeListener); context.subscriptions.push(configChangeListener, saveListener, closeListener);
output.appendLine('[Squirrel] 扩展激活完成'); //output.appendLine('[Squirrel] 扩展激活完成');
output.show(); // output.show(); // 不自动显示输出窗口
// 显示欢迎信息 // 显示欢迎信息
vscode.window.showInformationMessage('Squirrel NUT Explorer 已激活,请点击"连接到 pvfUtility API"开始使用'); // vscode.window.showInformationMessage('Squirrel NUT Explorer 已激活,请点击"连接到 pvfUtility API"开始使用');
} }
export function deactivate() { export function deactivate() {

View File

@@ -1,6 +1,54 @@
import * as http from 'http'; import * as http from 'http';
import * as net from 'net';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
/**
* 检查本地C++服务是否可连接
* @returns Promise<boolean> 是否可连接
*/
export async function checkCppServiceConnection(): Promise<boolean> {
// 从配置中获取端口号默认为26000
const config = vscode.workspace.getConfiguration('squirrel');
const localServicePort = config.get<number>('localServicePort', 26000);
return new Promise((resolve) => {
const socket = new net.Socket();
let isResolved = false;
socket.setTimeout(3000); // 3秒超时
socket.connect(localServicePort, '127.0.0.1', () => {
// 连接成功,端口可达
socket.destroy();
resolve(true);
});
socket.on('error', (error) => {
// 连接失败
if (!isResolved) {
isResolved = true;
resolve(false);
}
});
socket.on('timeout', () => {
// 连接超时
socket.destroy();
if (!isResolved) {
isResolved = true;
resolve(false);
}
});
socket.on('close', () => {
if (!isResolved) {
isResolved = true;
resolve(false);
}
});
});
}
/** /**
* 构建JSON数据 * 构建JSON数据
* @param filePath 文件路径 * @param filePath 文件路径
@@ -21,13 +69,17 @@ function buildJsonData(filePath: string, content: string): string {
* @returns Promise<boolean> 是否发送成功 * @returns Promise<boolean> 是否发送成功
*/ */
export async function sendFileToCppService(filePath: string, content: string): Promise<boolean> { export async function sendFileToCppService(filePath: string, content: string): Promise<boolean> {
// 从配置中获取端口号默认为26000
const config = vscode.workspace.getConfiguration('squirrel');
const localServicePort = config.get<number>('localServicePort', 26000);
return new Promise((resolve) => { return new Promise((resolve) => {
const jsonData = buildJsonData(filePath, content); const jsonData = buildJsonData(filePath, content);
const postData = jsonData; const postData = jsonData;
const options: http.RequestOptions = { const options: http.RequestOptions = {
hostname: '127.0.0.1', hostname: '127.0.0.1',
port: 26000, port: localServicePort,
path: '/send_data', path: '/send_data',
method: 'POST', method: 'POST',
headers: { headers: {

View File

@@ -1,5 +1,6 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { ApiClient } from './apiClient'; import { ApiClient } from './apiClient';
import { checkCppServiceConnection, sendFileToCppService } from './localClient';
export interface FileEntry { export interface FileEntry {
key: string; // 文件路径 key: string; // 文件路径
@@ -183,9 +184,46 @@ export class FileModel {
// 保存文件内容 // 保存文件内容
async saveFileContent(filePath: string, content: string): Promise<boolean> { async saveFileContent(filePath: string, content: string): Promise<boolean> {
// 先检查C++服务是否可连接
const isCppServiceConnected = await checkCppServiceConnection();
if (isCppServiceConnected) {
// C++服务可连接,先发送进行编译验证
try {
const sendSuccess = await sendFileToCppService(filePath, content);
if (sendSuccess) {
// C++编译服务返回200说明脚本编译通过允许上传
const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
return true;
}
} else {
// C++编译服务返回非200说明脚本存在问题不允许上传
vscode.window.showErrorMessage(`脚本编译失败,无法保存文件 ${filePath}。请检查代码错误后再试。`);
return false;
}
} catch (error) {
// 向C++服务发送文件过程中出现错误
vscode.window.showErrorMessage(`发送文件到编译服务时出错: ${error},但仍尝试直接保存文件`);
const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) {
const entry = this.fileList.get(filePath);
if (entry) {
entry.content = content;
entry.lastLoaded = new Date();
}
return true;
}
}
} else {
// C++服务不可连接,直接执行上传
try { try {
const success = await this.apiClient.uploadFileContent(filePath, content); const success = await this.apiClient.uploadFileContent(filePath, content);
if (success) { if (success) {
const entry = this.fileList.get(filePath); const entry = this.fileList.get(filePath);
if (entry) { if (entry) {
@@ -197,6 +235,7 @@ export class FileModel {
} catch (error) { } catch (error) {
vscode.window.showErrorMessage(`保存文件失败: ${error}`); vscode.window.showErrorMessage(`保存文件失败: ${error}`);
} }
}
return false; return false;
} }

View File

@@ -13,6 +13,14 @@ export class DocumentFormattingProvider implements vscode.DocumentFormattingEdit
options: vscode.FormattingOptions, options: vscode.FormattingOptions,
token: vscode.CancellationToken token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> { ): Promise<vscode.TextEdit[]> {
// 检查配置项,如果未启用自动格式化则直接返回
const config = vscode.workspace.getConfiguration('squirrel');
const autoFormatOnType = config.get<boolean>('autoFormatOnType', false);
if (!autoFormatOnType) {
return []; // 自动格式化未启用,返回空数组
}
const edits: vscode.TextEdit[] = []; const edits: vscode.TextEdit[] = [];
try { try {

View File

@@ -15,6 +15,14 @@ export class OnTypeFormattingProvider implements vscode.OnTypeFormattingEditProv
options: vscode.FormattingOptions, options: vscode.FormattingOptions,
token: vscode.CancellationToken token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> { ): Promise<vscode.TextEdit[]> {
// 检查配置项,如果未启用自动格式化则直接返回
const config = vscode.workspace.getConfiguration('squirrel');
const autoFormatOnType = config.get<boolean>('autoFormatOnType', false);
if (!autoFormatOnType) {
return []; // 自动格式化未启用,返回空数组
}
const edits: vscode.TextEdit[] = []; const edits: vscode.TextEdit[] = [];
try { try {

View File

@@ -78,7 +78,7 @@ function createBasicJsBeautify(): any {
brace_style: 'collapse', brace_style: 'collapse',
space_before_conditional: true, space_before_conditional: true,
space_after_anon_function: false, space_after_anon_function: false,
wrap_line_length: 120, wrap_line_length: 0, // 默认禁用自动换行
end_with_newline: false end_with_newline: false
}; };
@@ -158,6 +158,10 @@ const jsBeautify = {
* Squirrel 语言的 js-beautify 选项配置 * Squirrel 语言的 js-beautify 选项配置
*/ */
export function getSquirrelBeautifyOptions(options: vscode.FormattingOptions): any { export function getSquirrelBeautifyOptions(options: vscode.FormattingOptions): any {
// 从用户配置中读取换行长度设置
const config = vscode.workspace.getConfiguration('squirrel.formatting');
const wrapLineLength = config.get<number>('wrapLineLength', 0);
return { return {
indent_size: options.tabSize, indent_size: options.tabSize,
indent_char: options.insertSpaces ? ' ' : '\t', indent_char: options.insertSpaces ? ' ' : '\t',
@@ -168,7 +172,7 @@ export function getSquirrelBeautifyOptions(options: vscode.FormattingOptions): a
space_before_conditional: true, space_before_conditional: true,
space_after_anon_function: false, space_after_anon_function: false,
unescape_strings: false, unescape_strings: false,
wrap_line_length: 120, wrap_line_length: wrapLineLength,
end_with_newline: false end_with_newline: false
}; };
} }

View File

@@ -1,277 +0,0 @@
{
"functions": [
{
"name": "file",
"description": "",
"params": [],
"returns": {
"type": "void",
"description": ""
}
},
{
"name": "close",
"description": "关闭文件流",
"params": [],
"returns": {
"type": "void",
"description": ""
}
},
{
"name": "len",
"description": "获取数据长度",
"params": [
{
"name": "data",
"type": "object",
"description": "基本数据类型"
}
],
"returns": {
"type": "int",
"description": ""
}
}
],
"functionEx": [
{
"name": "sq_RGB",
"description": "颜色空间",
"params": [
{
"name": "R",
"type": "int",
"description": "红色0-255"
},
{
"name": "G",
"type": "int",
"description": "绿色0-255"
},
{
"name": "B",
"type": "int",
"description": "蓝色0-255"
}
],
"returns": {
"type": "object",
"description": "颜色对象"
}
},
{
"name": "sq_RGBA",
"description": "颜色空间",
"params": [
{
"name": "R",
"type": "int",
"description": "红色0-255"
},
{
"name": "G",
"type": "int",
"description": "绿色0-255"
},
{
"name": "B",
"type": "int",
"description": "蓝色0-255"
},
{
"name": "A",
"type": "int",
"description": "透明度0-255"
}
],
"returns": {
"type": "object",
"description": "颜色对象"
}
}
],
"classes": [
{
"name": "String",
"description": "字符串类,提供字符串操作方法",
"methods": [
{
"name": "len",
"description": "返回字符串长度",
"params": [],
"returns": {
"type": "integer",
"description": "字符串的长度"
}
},
{
"name": "slice",
"description": "返回字符串的子串",
"params": [
{
"name": "start",
"type": "integer",
"description": "起始位置"
},
{
"name": "end",
"type": "integer",
"description": "结束位置(可选)",
"optional": true
}
],
"returns": {
"type": "string",
"description": "子串"
}
},
{
"name": "find",
"description": "查找子串在字符串中的位置",
"params": [
{
"name": "substr",
"type": "string",
"description": "要查找的子串"
}
],
"returns": {
"type": "integer",
"description": "子串的位置,未找到返回-1"
}
}
],
"properties": [
{
"name": "length",
"type": "integer",
"description": "字符串的长度"
}
]
},
{
"name": "Array",
"description": "数组类,提供数组操作方法",
"methods": [
{
"name": "len",
"description": "返回数组长度",
"params": [],
"returns": {
"type": "integer",
"description": "数组的长度"
}
},
{
"name": "append",
"description": "向数组末尾添加元素",
"params": [
{
"name": "value",
"type": "any",
"description": "要添加的元素"
}
],
"returns": {
"type": "void",
"description": "无返回值"
}
},
{
"name": "pop",
"description": "移除并返回数组最后一个元素",
"params": [],
"returns": {
"type": "any",
"description": "被移除的元素"
}
}
],
"properties": [
{
"name": "length",
"type": "integer",
"description": "数组的长度"
}
]
},
{
"name": "Table",
"description": "表类,提供表操作方法",
"methods": [
{
"name": "len",
"description": "返回表中键值对的数量",
"params": [],
"returns": {
"type": "integer",
"description": "键值对的数量"
}
},
{
"name": "rawget",
"description": "获取指定键的值",
"params": [
{
"name": "key",
"type": "any",
"description": "键"
}
],
"returns": {
"type": "any",
"description": "键对应的值"
}
},
{
"name": "rawset",
"description": "设置指定键的值",
"params": [
{
"name": "key",
"type": "any",
"description": "键"
},
{
"name": "value",
"type": "any",
"description": "值"
}
],
"returns": {
"type": "void",
"description": "无返回值"
}
}
],
"properties": []
}
],
"constants": [
{
"name": "PI",
"value": "3.14159",
"description": "圆周率",
"category": "math"
},
{
"name": "true",
"value": "true",
"description": "布尔真值",
"category": "boolean"
},
{
"name": "false",
"value": "false",
"description": "布尔假值",
"category": "boolean"
},
{
"name": "null",
"value": "null",
"description": "空值",
"category": "general"
}
]
}

View File

@@ -1,71 +0,0 @@
pvfUtility WebApi
介绍
pvfUtility 2020开始 一项重大的更新就是提供了HTTP接口进行自动化操作
这使得第三方工具可以利用http rest api进行文件读写
只需在软件内打开pvf,就能通过第三方工具进行下一步的操作
获取pvfUtility版本号
插件作者可以以版本来来确定用户当前使用的pvfUtility是否适用某些API接口
请求类型GET
http://localhost:/Api/PvfUtiltiy/getVersion
返回结果
//注使用此接口pvfUtility版本号需大于2022.9.30.2
{"Data":"2022.9.30.3","IsError":false,"Msg":null}
获取nut文件列表
请求类型GET
http://localhost:/Api/PvfUtiltiy/GetFileList?dirName=sqr&returnType=0&fileType=nut
解释dirName=equipment(目录名称)
fileType=.equ(文件后缀名) 注使用fileType pvfUtility版本号必须大于2022.08.08.2
返回结果示例(returnType=1)
{
"Data": [
"sqr/arad_cashshop.nut",
"sqr/hair_avagacha.nut",
"sqr/neck_avagacha.nut",
"sqr/belt_avagacha.nut"
],
"IsError": false,
"Msg": null
}
批量获取nut文件内容
请求类型POST
http://localhost:/Api/PvfUtiltiy/GetFileContents
请求参数
{"FileList":["sqr/arad_cashshop.nut","sqr/neck_avagacha.nut"],"UseCompatibleDecompiler":false,"EncodingType":Null}
解释
UseCompatibleDecompiler=是否使用兼容性反编译器
使用encodingType参数 pvfUtility版本号需大于2022.12.3.1
//encodingType:仅适用于文本文件默认使用UTF8
//TW=中国台湾
//CN=中国大陆
//KR=韩国
//JP=日本
//UTF8
//Unicode
返回结果示例(注文件内容为utf-8编码)
{
{"Data":{"FileContentData":{"sqr/arad_cashshop.nut":"\r\nlocal a = 0;\r\n","sqr/neck_avagacha.nut":"\r\nlocal b = 1;\r\n"}},"IsError":false,"Msg":null}
上传新的文件内容
新增或覆盖文件内容
请求类型POST
http://localhost:/Api/PvfUtiltiy/ImportFile?filePath=[文件路径]
请求参数(文本内容)
文件内容
返回结果
{"IsError":false,"Msg":null}