1.1.1 优化自动补全和悬浮显示
This commit is contained in:
@@ -1,105 +0,0 @@
|
||||
# 代码错误检测功能修复报告
|
||||
|
||||
## 修复的问题
|
||||
|
||||
### 1. 字符串检测误报问题
|
||||
**原问题**: 只要使用引号就会报"检测未正确闭合的字符串"错误
|
||||
**修复方案**:
|
||||
- 重写了字符串检测逻辑,使用状态机方法进行精确解析
|
||||
- 正确处理转义字符(`\"`、`\'`)
|
||||
- 区分字符串内容和代码内容
|
||||
- 支持多行字符串检测
|
||||
- 正确处理注释中的引号(不会误报)
|
||||
- **新增**: 跳过被注释掉的代码行中的字符串检测
|
||||
|
||||
### 2. 括号检测误报问题
|
||||
**原问题**: 只要使用括号就会报"检测未正确闭合的括号"错误
|
||||
**修复方案**:
|
||||
- 重写了括号匹配算法,使用栈数据结构进行精确匹配
|
||||
- 正确处理字符串内的括号(不参与匹配)
|
||||
- 正确处理注释内的括号(不参与匹配)
|
||||
- 支持多行括号匹配
|
||||
- 提供具体的错误位置和类型(圆括号、方括号、花括号)
|
||||
- **新增**: 跳过被注释掉的代码行中的括号检测
|
||||
|
||||
### 3. 注释行误报问题 ⭐ **新修复**
|
||||
**原问题**: 被注释掉的代码(以`//`开头的行)也会被错误检测
|
||||
**修复方案**:
|
||||
- 智能识别整行注释(以`//`开头的行)
|
||||
- 跳过注释行中的所有错误检测
|
||||
- 正确处理块注释(`/* */`)中的内容
|
||||
- 区分行内注释和整行注释
|
||||
- 保持对正常代码的检测精度
|
||||
|
||||
### 4. 语法错误检测改进
|
||||
**改进内容**:
|
||||
- 更精确的拼写错误检测,减少误报
|
||||
- 改进的赋值操作符检查(避免误报合法赋值)
|
||||
- 跳过注释行的检查
|
||||
- 添加函数定义语法检查
|
||||
- 分号缺失检测
|
||||
|
||||
### 5. 拼写检查智能化
|
||||
**改进内容**:
|
||||
- 扩展了Squirrel关键字列表
|
||||
- 添加常见标识符模式识别,减少误报
|
||||
- 改进编辑距离算法的使用
|
||||
- 移除字符串和注释内容后再进行拼写检查
|
||||
- **新增**: 跳过注释行中的拼写检查
|
||||
|
||||
### 6. 快速修复功能增强
|
||||
**新增功能**:
|
||||
- 拼写错误的一键修复
|
||||
- 赋值操作符的快速修复
|
||||
- 缺失分号的自动添加
|
||||
- 更友好的修复建议描述
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 状态机解析
|
||||
使用状态机方法来跟踪:
|
||||
- 字符串状态(是否在字符串内)
|
||||
- 转义状态(是否被转义)
|
||||
- 注释状态(行注释/块注释)
|
||||
|
||||
### 栈结构匹配
|
||||
使用栈来跟踪:
|
||||
- 开括号的位置和类型
|
||||
- 括号的匹配状态
|
||||
- 错误位置的精确报告
|
||||
|
||||
### 上下文感知
|
||||
- 区分代码、字符串、注释的不同上下文
|
||||
- 在不同上下文中应用不同的检测规则
|
||||
- 避免跨上下文的误报
|
||||
|
||||
## 测试覆盖
|
||||
|
||||
创建了全面的测试用例:
|
||||
- 正常的字符串和括号使用
|
||||
- 各种拼写错误场景
|
||||
- 字符串中的特殊字符
|
||||
- 注释中的内容(行注释和块注释)
|
||||
- **新增**: 被注释掉的代码行测试
|
||||
- 多行结构
|
||||
- 转义字符处理
|
||||
- 混合场景(注释+正常代码)
|
||||
|
||||
## 使用说明
|
||||
|
||||
1. 修复后的错误检测会在您输入代码时实时运行
|
||||
2. 错误会以红色波浪线显示在编辑器中
|
||||
3. 将鼠标悬停在错误上可查看详细信息
|
||||
4. 点击灯泡图标或使用 `Ctrl+.` 可应用快速修复
|
||||
5. 支持的快速修复包括:拼写纠正、添加分号、修复操作符等
|
||||
6. **新功能**: 注释掉的代码不会被错误检测干扰
|
||||
|
||||
## 性能优化
|
||||
|
||||
- 使用高效的算法减少处理时间
|
||||
- 避免不必要的重复检查
|
||||
- 智能跳过注释和字符串内容的检查
|
||||
- 优化正则表达式的使用
|
||||
- **新优化**: 提前识别注释行,减少不必要的处理
|
||||
|
||||
修复完成后,代码错误检测功能应该能够准确、智能地识别真正的错误,同时避免之前存在的误报问题,包括对注释代码的错误检测。
|
||||
82
FEATURES.md
82
FEATURES.md
@@ -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. 编辑和保存文件时,相关缓存会自动更新
|
||||
@@ -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. 提供函数自动补全功能
|
||||
100
INSTALL_GUIDE.md
100
INSTALL_GUIDE.md
@@ -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 开发体验!** 🎉
|
||||
@@ -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 };
|
||||
49
dist/providers/apiParser.js
vendored
49
dist/providers/apiParser.js
vendored
@@ -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,7 +442,28 @@ class ApiParser {
|
||||
return this.constants.find(constant => constant.name === name);
|
||||
}
|
||||
// 生成函数签名
|
||||
generateFunctionSignature(func) {
|
||||
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 += ']';
|
||||
}
|
||||
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) {
|
||||
@@ -439,6 +477,7 @@ class ApiParser {
|
||||
}).join(', ');
|
||||
return `function ${func.name}(${params})${func.returns ? `: ${func.returns.type}` : ': void'}`;
|
||||
}
|
||||
}
|
||||
// 生成类签名
|
||||
generateClassSignature(cls) {
|
||||
return `class ${cls.name}`;
|
||||
|
||||
2
dist/providers/apiParser.js.map
vendored
2
dist/providers/apiParser.js.map
vendored
File diff suppressed because one or more lines are too long
33
dist/providers/completionProvider.js
vendored
33
dist/providers/completionProvider.js
vendored
@@ -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() {
|
||||
|
||||
2
dist/providers/completionProvider.js.map
vendored
2
dist/providers/completionProvider.js.map
vendored
File diff suppressed because one or more lines are too long
3
dist/providers/hoverProvider.js
vendored
3
dist/providers/hoverProvider.js
vendored
@@ -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) {
|
||||
|
||||
2
dist/providers/hoverProvider.js.map
vendored
2
dist/providers/hoverProvider.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -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.
@@ -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,7 +475,29 @@ export class ApiParser {
|
||||
}
|
||||
|
||||
// 生成函数签名
|
||||
public generateFunctionSignature(func: ApiFunction): string {
|
||||
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);
|
||||
|
||||
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) {
|
||||
@@ -471,6 +512,7 @@ export class ApiParser {
|
||||
|
||||
return `function ${func.name}(${params})${func.returns ? `: ${func.returns.type}` : ': void'}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 生成类签名
|
||||
public generateClassSignature(cls: ApiClass): string {
|
||||
|
||||
@@ -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类完成项
|
||||
|
||||
@@ -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
277
新库函数示范.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user