1.1.1 优化自动补全和悬浮显示

This commit is contained in:
睿 安
2025-09-17 22:31:31 +08:00
parent 7c838fa49c
commit fe15f52be5
17 changed files with 464 additions and 431 deletions

View File

@@ -1,105 +0,0 @@
# 代码错误检测功能修复报告
## 修复的问题
### 1. 字符串检测误报问题
**原问题**: 只要使用引号就会报"检测未正确闭合的字符串"错误
**修复方案**:
- 重写了字符串检测逻辑,使用状态机方法进行精确解析
- 正确处理转义字符(`\"``\'`
- 区分字符串内容和代码内容
- 支持多行字符串检测
- 正确处理注释中的引号(不会误报)
- **新增**: 跳过被注释掉的代码行中的字符串检测
### 2. 括号检测误报问题
**原问题**: 只要使用括号就会报"检测未正确闭合的括号"错误
**修复方案**:
- 重写了括号匹配算法,使用栈数据结构进行精确匹配
- 正确处理字符串内的括号(不参与匹配)
- 正确处理注释内的括号(不参与匹配)
- 支持多行括号匹配
- 提供具体的错误位置和类型(圆括号、方括号、花括号)
- **新增**: 跳过被注释掉的代码行中的括号检测
### 3. 注释行误报问题 ⭐ **新修复**
**原问题**: 被注释掉的代码(以`//`开头的行)也会被错误检测
**修复方案**:
- 智能识别整行注释(以`//`开头的行)
- 跳过注释行中的所有错误检测
- 正确处理块注释(`/* */`)中的内容
- 区分行内注释和整行注释
- 保持对正常代码的检测精度
### 4. 语法错误检测改进
**改进内容**:
- 更精确的拼写错误检测,减少误报
- 改进的赋值操作符检查(避免误报合法赋值)
- 跳过注释行的检查
- 添加函数定义语法检查
- 分号缺失检测
### 5. 拼写检查智能化
**改进内容**:
- 扩展了Squirrel关键字列表
- 添加常见标识符模式识别,减少误报
- 改进编辑距离算法的使用
- 移除字符串和注释内容后再进行拼写检查
- **新增**: 跳过注释行中的拼写检查
### 6. 快速修复功能增强
**新增功能**:
- 拼写错误的一键修复
- 赋值操作符的快速修复
- 缺失分号的自动添加
- 更友好的修复建议描述
## 技术实现
### 状态机解析
使用状态机方法来跟踪:
- 字符串状态(是否在字符串内)
- 转义状态(是否被转义)
- 注释状态(行注释/块注释)
### 栈结构匹配
使用栈来跟踪:
- 开括号的位置和类型
- 括号的匹配状态
- 错误位置的精确报告
### 上下文感知
- 区分代码、字符串、注释的不同上下文
- 在不同上下文中应用不同的检测规则
- 避免跨上下文的误报
## 测试覆盖
创建了全面的测试用例:
- 正常的字符串和括号使用
- 各种拼写错误场景
- 字符串中的特殊字符
- 注释中的内容(行注释和块注释)
- **新增**: 被注释掉的代码行测试
- 多行结构
- 转义字符处理
- 混合场景(注释+正常代码)
## 使用说明
1. 修复后的错误检测会在您输入代码时实时运行
2. 错误会以红色波浪线显示在编辑器中
3. 将鼠标悬停在错误上可查看详细信息
4. 点击灯泡图标或使用 `Ctrl+.` 可应用快速修复
5. 支持的快速修复包括:拼写纠正、添加分号、修复操作符等
6. **新功能**: 注释掉的代码不会被错误检测干扰
## 性能优化
- 使用高效的算法减少处理时间
- 避免不必要的重复检查
- 智能跳过注释和字符串内容的检查
- 优化正则表达式的使用
- **新优化**: 提前识别注释行,减少不必要的处理
修复完成后,代码错误检测功能应该能够准确、智能地识别真正的错误,同时避免之前存在的误报问题,包括对注释代码的错误检测。

View File

@@ -1,82 +0,0 @@
# Squirrel NUT Explorer 功能说明
## 已实现的功能
### 1. 基础功能
- 通过 pvfUtility API 浏览和编辑 NUT 文件
- 支持连接到本地运行的 pvfUtility 服务
- 自动加载所有 NUT 文件内容
- 支持文件保存和刷新
### 2. 代码自动完成功能
- **基础自动完成**提供关键字、API函数、类、常量的基本自动完成
- **跨文件完成**:能够识别其他已加载的 NUT 文件中定义的函数
- **变量完成**:提供当前文档中已声明的局部变量自动完成
- **点号完成**:支持对象属性和方法的自动完成(如 string.len, array.append 等)
### 3. 悬停信息功能
- **库函数信息显示**:显示内置函数的参数、返回值和描述
- **类信息显示**:显示内置类的方法和属性信息
- **常量信息显示**:显示内置常量的值和描述
- **跨文件自定义函数信息**:显示其他文件中定义的函数的参数和位置信息
### 4. 定义跳转功能
- **跨文件跳转**:支持在所有已加载的 NUT 文件中查找函数定义并跳转
- **多重定义支持**:当存在同名函数时,提供所有可能的定义位置供选择
### 5. 函数签名帮助
- **参数提示**:在函数调用时显示函数的参数列表
- **当前参数高亮**:高亮显示当前正在输入的参数
- **内置函数支持**:支持内置函数的签名帮助
- **自定义函数支持**:支持用户定义函数的签名帮助
### 6. 输入时格式化
- **括号触发格式化**:输入 ")" 时格式化当前行
- **分号触发格式化**:输入 ";" 时格式化当前行
- **大括号触发格式化**:输入 "}" 时格式化整个代码块
- **Squirrel语法优化**针对Squirrel语言特性进行格式化优化
### 7. 代码格式化
- **缩进标准化**:统一代码缩进风格
- **空格规范化**:在操作符周围添加适当空格
- **换行管理**:合理安排代码换行
- **括号处理**:自动调整大括号位置和缩进
### 8. 代码错误检测
- **语法错误检测**:检测常见的语法错误,如拼写错误的关键字
- **未闭合字符串检测**:检测未正确闭合的字符串
- **未闭合括号检测**:检测未正确闭合的括号
- **逻辑错误提示**:提示可能的逻辑错误,如在条件语句中使用赋值操作符
- **快速修复**:提供拼写错误的快速修复功能
### 9. API文档解析
- **内置函数文档**解析和管理Squirrel语言的内置函数文档
- **类文档**:解析和管理内置类的文档
- **常量文档**:解析和管理内置常量的文档
- **动态生成**:根据文档动态生成自动完成项和悬停信息
### 10. 语法定义支持
- **语法高亮**:支持关键字、字符串、注释、数字、操作符等的语法高亮
- **代码折叠**:支持基于大括号的代码折叠
- **自动闭合**:支持括号、引号的自动闭合
- **智能缩进**:根据代码结构自动调整缩进
## 缓存机制
- **函数缓存**:缓存所有已解析的函数信息,提高性能
- **持久化缓存**在整个VS Code会话期间保持缓存有效
- **增量更新**:在保存文件时自动更新对应文件的缓存
- **重复函数处理**:正确处理同名函数,提供所有定义位置供选择
## 性能优化
- **批量处理**:文件按批次处理,避免内存溢出
- **并行处理**:批次内的文件并行处理,提高效率
- **增量更新**:仅在文件保存时更新对应文件的缓存
- **防重复提取**:防止同时进行多次提取操作
- **性能监控**:监控提取性能,为优化提供数据支持
## 使用方法
1. 确保 pvfUtility 服务正在运行
2. 在 VS Code 中打开 Squirrel NUT Explorer
3. 点击"连接到 pvfUtility"按钮
4. 连接成功后,所有功能将自动启用
5. 编辑和保存文件时,相关缓存会自动更新

View File

@@ -1,67 +0,0 @@
# 函数提取和缓存功能说明
## 功能概述
本项目新增了函数提取和缓存功能用于从nut文件中提取函数信息并进行缓存为后续的函数跳转功能做准备。
## 主要组件
### 1. FunctionInfo 接口
定义了函数信息的数据结构:
- `name`: 函数名称
- `filePath`: 文件路径
- `lineNumber`: 行号
- `parameters`: 参数列表
- `signature`: 函数签名
### 2. FunctionCacheManager 类
负责管理函数信息的缓存:
- 缓存函数信息
- 提供函数查找功能
- 统计缓存信息
- 缓存在VS Code会话期间一直有效直到重新获取nut文件时重置
### 3. FunctionExtractor 类
负责从文件中提取函数信息:
- 解析Squirrel语言的函数定义
- 批量处理文件
- 防止重复提取
- 性能监控
### 4. PerformanceMonitor 类
监控函数提取的性能:
- 记录提取时间
- 计算平均处理时间
- 提供性能统计信息
## 工作流程
1. 用户点击"连接到 pvfUtility"时系统自动获取所有nut文件内容
2. 连接成功后,自动启动函数提取过程
3. FunctionExtractor逐个解析文件中的函数定义
4. 提取的函数信息被缓存到FunctionCacheManager中
5. 缓存在VS Code会话期间一直有效
6. 当用户保存nut文件时自动更新对应文件的函数缓存
7. 性能数据被记录用于优化
## 性能优化措施
1. **批量处理**: 文件按批次处理,避免内存溢出
2. **并行处理**: 批次内的文件并行处理,提高效率
3. **缓存机制**: 避免重复解析已处理的文件
4. **增量更新**: 仅在文件保存时更新对应文件的缓存
5. **防重复提取**: 防止同时进行多次提取操作
6. **性能监控**: 监控提取性能,为优化提供数据支持
## 使用方法
1. 函数提取功能在用户连接到pvfUtility后自动执行无需手动操作。
2. 当用户保存nut文件时对应的函数缓存会自动更新。
3. 缓存在整个VS Code会话期间一直有效直到重新获取nut文件时重置。
## 后续开发
当前实现为函数跳转功能奠定了基础,下一步可以:
1. 实现函数跳转到定义功能
2. 添加函数引用查找功能
3. 提供函数自动补全功能

View File

@@ -1,100 +0,0 @@
# 🚀 Squirrel NUT Explorer - 安装和使用指南
## 📦 已修复版本特性
**修复了所有代码错误检测的误报问题**
- 字符串检测不再误报
- 括号检测不再误报
- 智能语法检查
- 快速错误修复
**完整的功能支持**
- 代码自动完成
- 悬停信息显示
- 定义跳转
- 函数签名帮助
- 代码格式化
- 错误检测和修复
## 📋 安装步骤
### 方法一:通过 VSIX 文件安装 (推荐)
1. **打开 VS Code**
2. **打开扩展面板**
- 快捷键:`Ctrl+Shift+X`
- 或点击左侧活动栏的扩展图标
3. **安装扩展**
- 点击扩展面板右上角的 "..." 菜单
- 选择 "从 VSIX 安装..."
- 浏览并选择:`squirrel-nut-explorer-1.0.1.vsix`
4. **重启 VS Code**
- 安装完成后重启 VS Code 以确保扩展正常工作
### 方法二:命令行安装
```bash
code --install-extension squirrel-nut-explorer-1.0.1.vsix
```
## 🎯 使用方法
1. **激活扩展**
- 扩展会在 VS Code 启动时自动激活
- 在活动栏中会看到 "Squirrel" 图标
2. **连接到 pvfUtility**
- 确保 pvfUtility 服务正在运行
- 点击 Squirrel 面板中的"连接到 pvfUtility"按钮
- 连接成功后即可使用所有功能
3. **编辑 NUT 文件**
- 打开或创建 `.nut` 文件
- 享受完整的语言支持功能
## 🔧 功能说明
### 代码错误检测
- **实时检测**:输入时即时显示错误
- **智能识别**:不会误报正常的字符串和括号
- **快速修复**:点击灯泡图标或 `Ctrl+.` 应用修复
### 代码自动完成
- **关键字完成**Squirrel 语言关键字
- **函数完成**:内置和自定义函数
- **变量完成**:当前作用域的变量
- **跨文件完成**:其他 NUT 文件中的函数
### 悬停信息
- **函数说明**:显示参数、返回值和描述
- **类信息**:显示类的方法和属性
- **跨文件信息**:其他文件中的函数信息
### 其他功能
- **定义跳转**`F12``Ctrl+点击`
- **格式化代码**`Shift+Alt+F`
- **函数签名提示**:输入函数参数时显示
- **输入时格式化**:输入 `)``;``}` 时自动格式化
## 🐛 问题反馈
如果遇到任何问题,请检查:
1. VS Code 版本是否为 1.99.0 或更高
2. pvfUtility 服务是否正常运行
3. 文件扩展名是否为 `.nut`
## 📄 更新日志
### v1.0.1 (修复版)
- ✅ 完全修复字符串检测误报问题
- ✅ 完全修复括号检测误报问题
- ✅ 改进语法错误检测精度
- ✅ 增强快速修复功能
- ✅ 优化性能和稳定性
---
**享受无误报的 Squirrel 开发体验!** 🎉

View File

@@ -1,34 +0,0 @@
const fs = require('fs-extra');
const path = require('path');
// 复制 js-beautify 相关文件到 dist 目录
async function copyBeautifyFiles() {
const srcDir = path.join(__dirname);
const destDir = path.join(__dirname, 'dist');
// 确保目标目录存在
await fs.ensureDir(destDir);
// 复制 js-beautify.js 和包装器
const filesToCopy = [
'js-beautify.js',
'js-beautify-wrapper.js'
];
for (const file of filesToCopy) {
const srcPath = path.join(srcDir, file);
const destPath = path.join(destDir, file);
if (await fs.pathExists(srcPath)) {
await fs.copy(srcPath, destPath);
console.log(`已复制 ${file} 到 dist 目录`);
}
}
}
// 如果直接运行此脚本,则执行复制操作
if (require.main === module) {
copyBeautifyFiles().catch(console.error);
}
module.exports = { copyBeautifyFiles };

View File

@@ -40,7 +40,8 @@ const path = __importStar(require("path"));
// API文档解析器类
class ApiParser {
constructor() {
this.functions = [];
this.functions = []; // 普通函数,不自动填写第一个参数
this.functionEx = []; // 扩展函数,自动填写所有参数
this.classes = [];
this.constants = [];
// 获取扩展路径并设置JSON文件路径
@@ -65,6 +66,7 @@ class ApiParser {
const apiData = JSON.parse(jsonData);
// 加载函数数据
this.functions = apiData.functions || [];
this.functionEx = apiData.functionEx || [];
// 加载类数据
this.classes = apiData.classes || [];
// 加载常量数据
@@ -383,6 +385,7 @@ class ApiParser {
try {
const apiData = {
functions: this.functions,
functionEx: this.functionEx,
classes: this.classes,
constants: this.constants
};
@@ -396,13 +399,27 @@ class ApiParser {
reloadApiDocumentation() {
this.initializeApiDocumentation();
}
// 获取所有函数
// 获取所有普通函数
getFunctions() {
return this.functions;
}
// 根据名称获取函数
// 获取所有扩展函数
getFunctionEx() {
return this.functionEx;
}
// 根据名称获取函数(包括普通函数和扩展函数)
getFunctionByName(name) {
return this.functions.find(func => func.name === name);
// 先在普通函数中查找
let func = this.functions.find(func => func.name === name);
if (func) {
return func;
}
// 再在扩展函数中查找
return this.functionEx.find(func => func.name === name);
}
// 检查是否是扩展函数
isFunctionEx(name) {
return this.functionEx.some(func => func.name === name);
}
// 获取所有类
getClasses() {
@@ -425,19 +442,41 @@ class ApiParser {
return this.constants.find(constant => constant.name === name);
}
// 生成函数签名
generateFunctionSignature(func) {
const params = func.params.map(param => {
let paramStr = param.name;
if (param.optional) {
paramStr = `[${paramStr}`;
if (param.defaultValue) {
paramStr += `=${param.defaultValue}`;
generateFunctionSignature(func, isFunctionEx = false) {
// 检查是否是普通函数且有参数
if (!isFunctionEx && func.params.length > 0) {
// 对于普通函数,将第一个参数移到函数名前面
const firstParam = func.params[0];
const remainingParams = func.params.slice(1);
const params = remainingParams.map(param => {
let paramStr = param.name;
if (param.optional) {
paramStr = `[${paramStr}`;
if (param.defaultValue) {
paramStr += `=${param.defaultValue}`;
}
paramStr += ']';
}
paramStr += ']';
}
return paramStr;
}).join(', ');
return `function ${func.name}(${params})${func.returns ? `: ${func.returns.type}` : ': void'}`;
return paramStr;
}).join(', ');
const paramPart = params ? `(${params})` : '()';
return `function ${firstParam.name}.${func.name}${paramPart}${func.returns ? `: ${func.returns.type}` : ': void'}`;
}
else {
// 对于扩展函数或无参数的函数,保持原有格式
const params = func.params.map(param => {
let paramStr = param.name;
if (param.optional) {
paramStr = `[${paramStr}`;
if (param.defaultValue) {
paramStr += `=${param.defaultValue}`;
}
paramStr += ']';
}
return paramStr;
}).join(', ');
return `function ${func.name}(${params})${func.returns ? `: ${func.returns.type}` : ': void'}`;
}
}
// 生成类签名
generateClassSignature(cls) {

File diff suppressed because one or more lines are too long

View File

@@ -96,21 +96,50 @@ class CompletionProvider {
}
// 获取API函数完成项
getApiFunctionCompletions() {
const completions = [];
// 添加普通函数(不自动填写第一个参数)
const functions = this.apiParser.getFunctions();
return functions.map(func => {
functions.forEach(func => {
const item = new vscode.CompletionItem(func.name, vscode.CompletionItemKind.Function);
item.detail = '内置函数';
item.documentation = new vscode.MarkdownString(`\`\`\`squirrel\n${this.apiParser.generateFunctionSignature(func)}\n\`\`\`\n${func.description}`);
// 为函数创建带参数的插入文本
if (func.params.length > 0) {
// 普通函数不自动填写第一个参数,用户需要手动输入
if (func.params.length > 1) {
// 从第二个参数开始添加占位符
const remainingParams = func.params.slice(1);
const paramText = remainingParams.map((param, index) => `\${${index + 1}:${param.name}}`).join(', ');
item.insertText = new vscode.SnippetString(`${func.name}(${paramText})`);
}
else {
// 只有一个参数或无参数
item.insertText = new vscode.SnippetString(`${func.name}()`);
}
}
else {
item.insertText = new vscode.SnippetString(`${func.name}()`);
}
completions.push(item);
});
// 添加扩展函数(自动填写所有参数)
const functionEx = this.apiParser.getFunctionEx();
functionEx.forEach(func => {
const item = new vscode.CompletionItem(func.name, vscode.CompletionItemKind.Function);
item.detail = '扩展函数';
item.documentation = new vscode.MarkdownString(`\`\`\`squirrel\n${this.apiParser.generateFunctionSignature(func)}\n\`\`\`\n${func.description}`);
// 为函数创建带参数的插入文本
if (func.params.length > 0) {
// 扩展函数自动填写所有参数
const paramText = func.params.map((param, index) => `\${${index + 1}:${param.name}}`).join(', ');
item.insertText = new vscode.SnippetString(`${func.name}(${paramText})`);
}
else {
item.insertText = new vscode.SnippetString(`${func.name}()`);
}
return item;
completions.push(item);
});
return completions;
}
// 获取API类完成项
getApiClassCompletions() {

File diff suppressed because one or more lines are too long

View File

@@ -60,7 +60,8 @@ class HoverProvider {
// 首先检查是否是API函数
const apiFunction = this.apiParser.getFunctionByName(word);
if (apiFunction) {
const signature = this.apiParser.generateFunctionSignature(apiFunction);
const isFunctionEx = this.apiParser.isFunctionEx(apiFunction.name);
const signature = this.apiParser.generateFunctionSignature(apiFunction, isFunctionEx);
let hoverContent = `<span style="color:#4EC9B0;">★</span> <span style="color:#569CD6;">内置函数</span>: <code style="background-color:#2D2D30; color:#D4D4D4;">${signature}</code>\n\n`;
hoverContent += `<span style="color:#6A9955;">${apiFunction.description}</span>\n\n`;
if (apiFunction.params.length > 0) {

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
"name": "squirrel-nut-explorer",
"displayName": "Squirrel NUT Explorer",
"description": "通过 pvfUtility API 浏览和编辑 NUT 文件",
"version": "1.1.0",
"version": "1.1.1",
"publisher": "local",
"engines": {
"vscode": "^1.99.0"

Binary file not shown.

View File

@@ -52,7 +52,8 @@ export interface ApiConstant {
// API文档解析器类
export class ApiParser {
private static instance: ApiParser;
private functions: ApiFunction[] = [];
private functions: ApiFunction[] = []; // 普通函数,不自动填写第一个参数
private functionEx: ApiFunction[] = []; // 扩展函数,自动填写所有参数
private classes: ApiClass[] = [];
private constants: ApiConstant[] = [];
private jsonFilePath: string;
@@ -83,6 +84,7 @@ export class ApiParser {
// 加载函数数据
this.functions = apiData.functions || [];
this.functionEx = apiData.functionEx || [];
// 加载类数据
this.classes = apiData.classes || [];
@@ -405,6 +407,7 @@ export class ApiParser {
try {
const apiData = {
functions: this.functions,
functionEx: this.functionEx,
classes: this.classes,
constants: this.constants
};
@@ -420,14 +423,30 @@ export class ApiParser {
this.initializeApiDocumentation();
}
// 获取所有函数
// 获取所有普通函数
public getFunctions(): ApiFunction[] {
return this.functions;
}
// 根据名称获取函数
// 获取所有扩展函数
public getFunctionEx(): ApiFunction[] {
return this.functionEx;
}
// 根据名称获取函数(包括普通函数和扩展函数)
public getFunctionByName(name: string): ApiFunction | undefined {
return this.functions.find(func => func.name === name);
// 先在普通函数中查找
let func = this.functions.find(func => func.name === name);
if (func) {
return func;
}
// 再在扩展函数中查找
return this.functionEx.find(func => func.name === name);
}
// 检查是否是扩展函数
public isFunctionEx(name: string): boolean {
return this.functionEx.some(func => func.name === name);
}
// 获取所有类
@@ -456,20 +475,43 @@ export class ApiParser {
}
// 生成函数签名
public generateFunctionSignature(func: ApiFunction): string {
const params = func.params.map(param => {
let paramStr = param.name;
if (param.optional) {
paramStr = `[${paramStr}`;
if (param.defaultValue) {
paramStr += `=${param.defaultValue}`;
}
paramStr += ']';
}
return paramStr;
}).join(', ');
public generateFunctionSignature(func: ApiFunction, isFunctionEx: boolean = false): string {
// 检查是否是普通函数且有参数
if (!isFunctionEx && func.params.length > 0) {
// 对于普通函数,将第一个参数移到函数名前面
const firstParam = func.params[0];
const remainingParams = func.params.slice(1);
return `function ${func.name}(${params})${func.returns ? `: ${func.returns.type}` : ': void'}`;
const params = remainingParams.map(param => {
let paramStr = param.name;
if (param.optional) {
paramStr = `[${paramStr}`;
if (param.defaultValue) {
paramStr += `=${param.defaultValue}`;
}
paramStr += ']';
}
return paramStr;
}).join(', ');
const paramPart = params ? `(${params})` : '()';
return `function ${firstParam.name}.${func.name}${paramPart}${func.returns ? `: ${func.returns.type}` : ': void'}`;
} else {
// 对于扩展函数或无参数的函数,保持原有格式
const params = func.params.map(param => {
let paramStr = param.name;
if (param.optional) {
paramStr = `[${paramStr}`;
if (param.defaultValue) {
paramStr += `=${param.defaultValue}`;
}
paramStr += ']';
}
return paramStr;
}).join(', ');
return `function ${func.name}(${params})${func.returns ? `: ${func.returns.type}` : ': void'}`;
}
}
// 生成类签名

View File

@@ -93,22 +93,54 @@ export class CompletionProvider implements vscode.CompletionItemProvider {
// 获取API函数完成项
private getApiFunctionCompletions(): vscode.CompletionItem[] {
const completions: vscode.CompletionItem[] = [];
// 添加普通函数(不自动填写第一个参数)
const functions = this.apiParser.getFunctions();
return functions.map(func => {
functions.forEach(func => {
const item = new vscode.CompletionItem(func.name, vscode.CompletionItemKind.Function);
item.detail = '内置函数';
item.documentation = new vscode.MarkdownString(`\`\`\`squirrel\n${this.apiParser.generateFunctionSignature(func)}\n\`\`\`\n${func.description}`);
// 为函数创建带参数的插入文本
if (func.params.length > 0) {
// 普通函数不自动填写第一个参数,用户需要手动输入
if (func.params.length > 1) {
// 从第二个参数开始添加占位符
const remainingParams = func.params.slice(1);
const paramText = remainingParams.map((param, index) => `\${${index + 1}:${param.name}}`).join(', ');
item.insertText = new vscode.SnippetString(`${func.name}(${paramText})`);
} else {
// 只有一个参数或无参数
item.insertText = new vscode.SnippetString(`${func.name}()`);
}
} else {
item.insertText = new vscode.SnippetString(`${func.name}()`);
}
completions.push(item);
});
// 添加扩展函数(自动填写所有参数)
const functionEx = this.apiParser.getFunctionEx();
functionEx.forEach(func => {
const item = new vscode.CompletionItem(func.name, vscode.CompletionItemKind.Function);
item.detail = '扩展函数';
item.documentation = new vscode.MarkdownString(`\`\`\`squirrel\n${this.apiParser.generateFunctionSignature(func)}\n\`\`\`\n${func.description}`);
// 为函数创建带参数的插入文本
if (func.params.length > 0) {
// 扩展函数自动填写所有参数
const paramText = func.params.map((param, index) => `\${${index + 1}:${param.name}}`).join(', ');
item.insertText = new vscode.SnippetString(`${func.name}(${paramText})`);
} else {
item.insertText = new vscode.SnippetString(`${func.name}()`);
}
return item;
completions.push(item);
});
return completions;
}
// 获取API类完成项

View File

@@ -37,7 +37,8 @@ export class HoverProvider implements vscode.HoverProvider {
// 首先检查是否是API函数
const apiFunction = this.apiParser.getFunctionByName(word);
if (apiFunction) {
const signature = this.apiParser.generateFunctionSignature(apiFunction);
const isFunctionEx = this.apiParser.isFunctionEx(apiFunction.name);
const signature = this.apiParser.generateFunctionSignature(apiFunction, isFunctionEx);
let hoverContent = `<span style="color:#4EC9B0;">★</span> <span style="color:#569CD6;">内置函数</span>: <code style="background-color:#2D2D30; color:#D4D4D4;">${signature}</code>\n\n`;
hoverContent += `<span style="color:#6A9955;">${apiFunction.description}</span>\n\n`;

277
新库函数示范.json Normal file
View File

@@ -0,0 +1,277 @@
{
"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"
}
]
}