ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Allegro Skill自定义菜单加载实战:从零部署可交付工具

Allegro Skill自定义菜单加载实战:从零部署可交付工具 1. 项目概述为什么Allegro Skill二次开发是PCB工程师的“第二把扳手”在Cadence Allegro PCB设计流程里菜单栏上那些灰掉的按钮、重复十遍的手动操作、每次改版都要重画的铜皮区域——它们不是软件缺陷而是你还没拿到那把真正的“定制化扳手”。这把扳手就是Skill语言。它不是什么高不可攀的编程黑魔法而是Allegro原生支持的、专为PCB工程师量身打造的脚本引擎。我从2013年开始用Allegro做高速背板设计前三年靠快捷键和模板硬扛直到某次被一个客户逼着48小时内完成37个相同结构的电源层分割修改才真正把Skill当成了日常工具。那天晚上写完第一个add_power_split.il脚本后我盯着屏幕里自动完成的216个分割线第一次觉得Allegro不是在拖我后腿而是在等我给它下指令。“Allegro Skill二次开发”这个关键词背后藏着三类真实需求第一类是高频重复操作自动化比如批量替换封装、自动生成测试点报告、一键导出多版本Gerber第二类是设计规则深度集成像把公司DRC检查逻辑直接嵌入菜单点击就跑结果带高亮定位第三类是跨平台数据桥接把Excel里的BOM参数实时映射到器件属性或者把仿真结果自动标注在Layout上。而“自定义菜单与命令加载”正是所有这些能力落地的第一道门槛——它不是炫技而是让脚本从命令行里走出来变成你右手边第三个图标、CtrlShiftP触发的快捷动作、甚至右键菜单里那个写着“按公司规范重排丝印”的选项。没有这一步再好的Skill脚本也只是一段躺在硬盘里的代码永远无法进入真实工作流。所以这篇攻略不讲语法基础不堆函数列表只聚焦一件事怎么让你写的脚本稳稳当当地长在Allegro界面上且能被团队里连Linux命令都不熟的同事一键调用。2. 整体设计思路菜单不是贴纸是系统级入口的重新编排很多人第一次尝试加菜单时会直接去改allegro.il文件或者把.il脚本扔进pcbenv目录就以为万事大吉。结果要么启动报错要么菜单一闪而过要么命令执行时报“undefined function”。这不是Skill语言的问题而是没理解Allegro菜单系统的底层逻辑——它本质上是一套分层加载的事件驱动架构菜单项只是触发器背后连着的是函数注册、环境初始化、上下文绑定三重机制。2.1 菜单加载的本质三个必须串联的环节Allegro的菜单不是静态配置而是运行时动态构建的。当你点击“File → Export → DXF”实际发生的是菜单项注册系统读取menu.def或menu.il中定义的Export DXF条目将其绑定到axlExportDXF()函数函数加载该函数必须已在内存中可用即axlExportDXF已被load或loadFromPath载入上下文校验执行前检查当前是否处于PCB编辑模式axlGetMode()返回pcb否则禁用该菜单项。Skill二次开发的菜单加载必须严格复现这三步。我见过太多人卡在第二步把my_script.il放在skill/目录下却忘了在allegro.il里用load(./skill/my_script.il)显式加载。Allegro不会自动扫描子目录它只认你明确告诉它要加载的文件。更隐蔽的坑是第三步——很多脚本写完发现菜单灰掉其实是没加axlSetMode(pcb)或axlSetMode(schematic)的模式判断导致Allegro认为当前环境不支持该命令。2.2 两种主流加载路径的取舍启动加载 vs 运行时加载加载方式触发时机适用场景风险点我的实际选择启动加载修改allegro.ilAllegro启动时一次性执行全局通用功能如自定义快捷键、基础工具集若脚本有语法错误Allegro直接启动失败需手动删allegro.il恢复仅放核心函数库如utils.il、drc_helper.il绝不放业务脚本运行时加载通过Tools → Skill → Load用户手动触发临时调试、项目专用脚本、未成熟功能每次重启需重载菜单项不持久开发阶段主力但最终交付必须转为启动加载我坚持一个铁律交付给客户的脚本必须能在Allegro启动后5秒内完成全部菜单注册且不依赖任何人工干预。这意味着所有依赖项包括第三方库、配置文件路径都必须在allegro.il中预声明。例如我的company_menu.il开头永远有这段; 预设公司路径避免相对路径失效 (setq *company-skill-path* (strcat (getShellEnvVar ALLEGRO_HOME) /skill/company/)) (load (strcat *company-skill-path* utils.il)) (load (strcat *company-skill-path* drc_rules.il))这样无论用户把Allegro装在C:\cadence\还是/opt/cadence/路径都能自动适配。而新手常犯的错误是直接写load(./skill/my_tool.il)结果换台电脑就报“file not found”。2.3 菜单层级设计原则别让工程师找菜单找到怀疑人生Allegro默认菜单已够复杂你的自定义菜单绝不能雪上加霜。我遵循三条物理法则视线距离法则常用功能必须在三级以内可达。比如“Tools → Company Tools → Power Split Generator”而不是“Tools → Advanced → Customization → PCB Utilities → Power Management → Split Generator”语义聚类法则同一类操作归入同一子菜单。把“生成测试点”、“导出钻孔表”、“检查焊盘间距”全塞进“Tools → My Tools”是灾难应该拆成“Tools → Company Tools → Manufacturing Output”和“Tools → Company Tools → DFM Check”视觉锚点法则关键菜单项加图标.bmp格式和分隔线。Allegro支持在menu.def中为菜单项指定图标路径虽然官方文档说“仅限Windows”但实测Linux下用X11图标也能显示。我在“Power Split Generator”前加了个闪电图标团队新人一眼就能认出这是处理电源层的工具。最后提醒一句菜单名别用英文缩写。曾有个客户把“BOM Sync”写成菜单名结果硬件工程师以为是“Bill of Materials”PCB工程师以为是“Board Outline Mask”最后发现是“Backplane Optimization Module”——这种命名灾难比脚本bug更难debug。3. 核心细节解析从零写出可加载的菜单项现在我们动手写第一个真正可用的自定义菜单。目标很具体在“Tools”菜单下新增一个子菜单“Company Tools”里面放两个命令“Generate Power Split Lines”和“Export Layer Stackup”。整个过程分四步走准备脚本文件、定义菜单结构、注册命令函数、验证加载流程。3.1 脚本文件组织目录结构决定维护成本Allegro对Skill文件位置极其敏感。我推荐的标准结构如下以Windows为例Linux路径仅需将\换成/C:\cadence\SPB_17.4\share\pcb\env\ ├── allegro.il ← 主入口只放load语句 ├── skill\ │ ├── company\ │ │ ├── utils.il ← 工具函数库字符串处理、文件IO │ │ ├── drc_rules.il← 公司DRC规则封装 │ │ ├── power_split.il ← 本次目标脚本 │ │ └── layer_stackup.il ← 本次目标脚本 │ └── menu\ │ └── company_menu.def ← 菜单定义文件关键点在于allegro.il必须是纯文本只包含load语句绝对不要在里面写业务逻辑。我见过最惨的案例是有人把整个功率分割算法写进allegro.il结果某天误删了其中一行括号导致全公司Allegro集体启动失败IT部门花了六小时逐行排查。power_split.il的内容框架如下先写骨架细节后续填充; power_split.il - 自动化电源层分割线生成 ; 作者XXX日期2024-06-15 ; 1. 函数声明必须否则菜单注册失败 (defun myPowerSplitGen () (printf 正在生成电源分割线...\n) ; TODO实际分割逻辑 t ) ; 2. 命令注册关键让Allegro认识这个函数 (axlCmdRegister myPowerSplitGen myPowerSplitGen ?cmdType interactive) ; 3. 可选设置快捷键提升效率 (axlBindKey Ctrl Shift P myPowerSplitGen interactive)注意axlCmdRegister的第三个参数?cmdType interactive——这是告诉Allegro这个命令需要用户交互比如选对象、输参数而不是后台静默执行。如果漏掉菜单项会显示但点击无反应。3.2 菜单定义文件menu.def的语法陷阱company_menu.def是纯文本文件用空格和制表符缩进定义层级。它的语法看着简单但有三个致命陷阱陷阱一缩进必须用Tab不能用空格Allegro解析器严格区分Tab和空格。用4个空格代替Tab菜单项会消失。我用Notepad时永远开启“显示所有字符”确保看到的是→而不是·。陷阱二菜单名中的空格必须用下划线Company Tools要写成Company_Tools否则解析失败。但显示时仍显示为“Company Tools”。这是Cadence的遗留设计忍着。陷阱三图标路径必须是绝对路径或相对ALLEGRO_HOMEicon: ./skill/company/icons/power.bmp是错的正确写法是icon: $ALLEGRO_HOME/skill/company/icons/power.bmp。完整的company_menu.def示例; Company Tools 主菜单 Company_Tools Company Tools Tools submenu ; 子菜单项1Power Split Generator Power_Split_Generator Generate Power Split Lines Company_Tools command cmd: myPowerSplitGen icon: $ALLEGRO_HOME/skill/company/icons/power.bmp ; 分隔线视觉锚点 Separator1 - Company_Tools separator ; 子菜单项2Layer Stackup Export Layer_Stackup_Export Export Layer Stackup Company_Tools command cmd: myLayerStackupExport icon: $ALLEGRO_HOME/skill/company/icons/stackup.bmp这里cmd:后面跟的是axlCmdRegister注册的命令名不是函数名。myPowerSplitGen是函数名myPowerSplitGen也是注册的命令名——两者一致是最佳实践避免混淆。3.3 命令函数编写不只是“能跑”更要“跑得稳”现在补全power_split.il的核心逻辑。重点不是算法多炫而是如何让脚本在各种边界条件下不崩溃(defun myPowerSplitGen () ; 1. 环境校验必须在PCB模式下 (unless (equal (axlGetMode) pcb) (axlUIConfirm 请在PCB编辑模式下运行此命令) (return nil) ) ; 2. 对象校验必须选中电源网络 (let ((nets (axlSelectSet-list (axlGetSelSet)))) (if (null nets) (progn (axlUIConfirm 请先选择一个电源网络如VCC、GND) (return nil) ) ; 3. 网络类型校验只处理power/ground net (unless (member (axlNetGetClass (car nets)) (power ground)) (axlUIConfirm 请选择电源或地网络) (return nil) ) ) ) ; 4. 实际分割逻辑简化版沿矩形区域画分割线 (printf 开始为网络 %s 生成分割线...\n (axlNetGetName (car nets))) ; TODO调用几何计算函数 (axlUIStatus 完成共生成12条分割线。) t )这段代码体现了三个实战经验防御性编程每一步都检查前置条件用axlUIConfirm弹窗提示而不是让脚本崩溃用户引导提示信息明确告诉用户“该做什么”而不是“错在哪”状态反馈用axlUIStatus在状态栏显示进度避免用户以为卡死。提示axlUIConfirm的返回值是t确认或nil取消所以unless后面直接return nil是安全的。千万别写(if (not (axlUIConfirm ...)) (return nil))因为axlUIConfirm返回t表示用户点了“确定”逻辑容易绕晕。3.4 加载与调试让菜单真正“活”起来把所有文件放好后启动Allegro打开Tools → Skill → Load加载company_menu.def。如果菜单没出现按以下顺序排查检查allegro.il是否加载了company_menu.def在allegro.il末尾加一行(load $ALLEGRO_HOME/skill/menu/company_menu.def)。注意路径必须准确$ALLEGRO_HOME是环境变量不是字面量。验证Skill文件语法在Allegro命令行输入load ./skill/company/power_split.il看是否报错。常见错误Error: unbound variable - axlGetSelSet说明axlGetSelSet函数未加载需确认utils.il已提前loadError: invalid command name - myPowerSplitGenaxlCmdRegister未执行检查函数是否在load前定义。查看菜单注册日志启动Allegro时加参数-log allegro.log日志里会记录菜单加载失败的具体原因。比如Failed to load menu file: company_menu.def, line 5就直接定位到第五行。我习惯在开发阶段用“三步验证法”第一步单独load脚本确认无语法错误第二步axlCmdRegister后在命令行直接输入myPowerSplitGen看是否执行第三步加载menu.def检查菜单是否出现且可点击。只有三步全通才算真正完成。4. 实操全流程从空白目录到可交付的菜单包现在把前面所有碎片组装成一个可立即部署的完整流程。我会以“为某通信设备公司定制电源分割工具”为案例展示从零开始到交付的每一步包括文件内容、路径、参数计算和现场问题记录。4.1 初始化环境创建标准技能包目录登录Allegro服务器执行以下命令创建标准结构Linux环境Windows类似# 进入Allegro环境目录 cd /opt/cadence/SPB_17.4/share/pcb/env/ # 创建skill目录树 mkdir -p skill/company/{icons,scripts} mkdir -p skill/menu # 创建核心文件 touch allegro.il touch skill/menu/company_menu.def touch skill/company/scripts/power_split.il touch skill/company/scripts/layer_stackup.il此时目录结构已就绪。接下来填充文件内容严格按顺序操作因为依赖关系是线性的。4.2 编写allegro.il启动加载的总开关allegro.il内容必须精简只做三件事设置路径、加载基础库、加载菜单。以下是实测有效的版本; allegro.il - 公司定制Skill主入口 ; 2024-06-15 v1.0 ; 1. 定义公司Skill根路径兼容Windows/Linux (setq *company-root* (cond ((string-match win (getShellEnvVar OS)) (strcat (getShellEnvVar ALLEGRO_HOME) \\skill\\company\\)) (t (strcat (getShellEnvVar ALLEGRO_HOME) /skill/company/)) ) ) ; 2. 加载基础工具库必须最先加载 (load (strcat *company-root* scripts/utils.il)) ; 3. 加载公司DRC规则库业务依赖 (load (strcat *company-root* scripts/drc_rules.il)) ; 4. 加载业务脚本按依赖顺序 (load (strcat *company-root* scripts/power_split.il)) (load (strcat *company-root* scripts/layer_stackup.il)) ; 5. 加载菜单定义最后一步确保所有函数已注册 (load (strcat (getShellEnvVar ALLEGRO_HOME) /skill/menu/company_menu.def))注意cond语句判断操作系统避免Windows用/路径导致加载失败。utils.il必须最先加载因为其他脚本都依赖它里面的file-exists-p、string-trim等函数。4.3 编写power_split.il带容错的真实业务脚本这次我们写一个真正可用的电源分割脚本目标选中VCC网络后自动在指定区域内画出等距分割线。核心参数来自公司设计规范分割线宽度0.2mm间距1.5mm区域边界为板框内缩2mm。; power_split.il - 电源分割线生成器 v1.0 ; 依据《XX公司高速PCB设计规范》第3.2节 ; 函数声明 (defun myPowerSplitGen () (let ((board-outline nil) (split-width 0.2) ; mm (split-gap 1.5) ; mm (inset 2.0) ; mm 板框内缩 (net-name nil) (net-obj nil) (lines-created 0) ) ; 1. 模式校验 (unless (equal (axlGetMode) pcb) (axlUIConfirm 请切换到PCB编辑模式) (return nil) ) ; 2. 获取选中的网络 (setq net-obj (axlSelectSet-list (axlGetSelSet))) (if (null net-obj) (progn (axlUIConfirm 请先选择一个电源网络) (return nil) ) (setq net-name (axlNetGetName (car net-obj))) ) ; 3. 网络类型校验 (unless (member (axlNetGetClass (car net-obj)) (power ground)) (axlUIConfirm (strcat 网络 net-name 不是电源或地网络)) (return nil) ) ; 4. 获取板框并计算内缩区域 (setq board-outline (axlDBGetBoardOutline)) (if (null board-outline) (progn (axlUIConfirm 未检测到板框请先绘制板框) (return nil) ) ; 计算内缩矩形简化取最小/最大XY (let ((min-x (apply min (mapcar car board-outline))) (max-x (apply max (mapcar car board-outline))) (min-y (apply min (mapcar cadr board-outline))) (max-y (apply max (mapcar cadr board-outline))) ) (setq min-x ( min-x inset)) (setq max-x (- max-x inset)) (setq min-y ( min-y inset)) (setq max-y (- max-y inset)) ; 5. 生成分割线水平方向等距 (setq lines-created (myGenerateSplitLines min-x max-x min-y max-y split-width split-gap net-name) ) ) ) ; 6. 结果反馈 (axlUIStatus (strcat 已完成为 net-name 生成 (numberToString lines-created) 条分割线。)) t ) ) ; 辅助函数生成分割线分离逻辑便于单元测试 (defun myGenerateSplitLines (x1 x2 y1 y2 width gap net-name) (let ((line-count 0) (y-pos y1) ) (while ( y-pos y2) (axlShapeCreate line (list (list x1 y-pos) (list x2 y-pos)) ?width width ?layer POWER ?net net-name ) (setq y-pos ( y-pos gap width)) (setq line-count ( line-count 1)) ) line-count ) ) ; 命令注册 (axlCmdRegister myPowerSplitGen myPowerSplitGen ?cmdType interactive) ; 快捷键绑定 (axlBindKey Ctrl Shift P myPowerSplitGen interactive)这段代码的关键改进参数外置化split-width、split-gap等硬编码参数后续可改为从配置文件读取几何计算健壮性用axlDBGetBoardOutline获取真实板框而非假设矩形辅助函数分离myGenerateSplitLines可单独测试降低主函数复杂度。4.4 编写company_menu.def生产环境就绪的菜单定义company_menu.def必须满足交付要求图标存在、路径正确、无语法错误。以下是最终版本; company_menu.def - 公司定制菜单定义 v1.0 ; 2024-06-15 ; 主菜单Company Tools Company_Tools Company Tools Tools submenu ; 子菜单1Power Split Generator Power_Split_Generator Generate Power Split Lines Company_Tools command cmd: myPowerSplitGen icon: $ALLEGRO_HOME/skill/company/icons/power.bmp ; 分隔线 Separator1 - Company_Tools separator ; 子菜单2Layer Stackup Export Layer_Stackup_Export Export Layer Stackup Company_Tools command cmd: myLayerStackupExport icon: $ALLEGRO_HOME/skill/company/icons/stackup.bmp ; 分隔线 Separator2 - Company_Tools separator ; 子菜单3DFM Rule Checker预留扩展位 DFM_Rule_Checker Run DFM Check Company_Tools command cmd: myDfmCheck icon: $ALLEGRO_HOME/skill/company/icons/dfm.bmp图标文件power.bmp需准备为24x24像素256色BMP格式Allegro旧版限制。我用GIMP导出时特意勾选“使用调色板”和“8-bit”否则图标显示为黑块。4.5 部署与验证一次成功的全流程记录部署过程全程录像以下是关键节点和耗时记录步骤操作耗时问题记录解决方案1创建目录结构2分钟Linux下mkdir -p权限不足切换到root用户执行2复制allegro.il30秒文件编码为UTF-8 with BOMAllegro报语法错误用Notepad转为ANSI编码3加载power_split.il1分钟报错Error: unbound variable - axlDBGetBoardOutline发现utils.il未加载检查allegro.il中load顺序4启动Allegro45秒菜单未出现日志显示Failed to load menu file: no such file路径中$ALLEGRO_HOME未被解析改用绝对路径/opt/cadence/...5执行命令10秒分割线画在板外axlDBGetBoardOutline返回空因板框未闭合手动用Edit → Shape → Complete修复最终成功画面Allegro启动后“Tools”菜单下清晰显示“Company Tools”点击“Generate Power Split Lines”选中VCC网络回车确认12条0.2mm宽的分割线精准落在内缩区域。整个流程从创建目录到成功运行耗时18分钟其中12分钟花在解决环境差异问题上——这恰恰是二次开发最真实的部分70%时间在适配环境30%时间写代码。5. 常见问题与排查技巧实录那些年踩过的坑在给12家客户部署Skill菜单的过程中我整理出一份高频问题速查表。这些问题90%以上都源于环境配置或路径细节而非Skill语法本身。下面按发生频率排序附带我的独家排查技巧。5.1 菜单项显示但点击无反应最经典的“幽灵菜单”现象菜单正常显示点击后状态栏闪一下“Ready”但无任何输出或操作。根本原因axlCmdRegister未执行或命令名与菜单定义不匹配。排查步骤在Allegro命令行输入(myPowerSplitGen)看是否执行如果报Error: undefined function说明函数未加载检查allegro.il中load语句是否执行如果函数可执行但菜单无效检查menu.def中cmd:后的名称是否与axlCmdRegister第一个参数完全一致大小写敏感独家技巧在allegro.il末尾加(printf Loaded company menu\n)启动时看控制台是否输出。没输出说明allegro.il根本没执行。注意Allegro启动时会加载allegro.il但如果该文件有语法错误后续所有load都会跳过。所以永远先验证allegro.il本身。5.2 菜单项灰色不可用上下文锁死现象菜单项始终灰色即使在PCB模式下。根本原因菜单项的?cmdType与实际函数不匹配或函数内部校验失败。排查步骤查看menu.def中该菜单项的?cmdType值interactive或background检查axlCmdRegister的?cmdType参数是否一致在函数开头加(printf myPowerSplitGen called\n)点击菜单看控制台是否输出独家技巧临时注释掉函数内所有校验代码unless块只留printf确认是否能触发。如果能问题就在校验逻辑。我遇到过最诡异的案例客户Allegro版本为17.2.1axlGetMode返回pcb但axlGetSelSet在某些情况下返回空列表导致校验失败。解决方案是加延时(axlDelay 100)单位毫秒让UI线程刷新后再获取选择集。5.3 图标不显示路径与格式的双重陷阱现象菜单项显示文字但图标为空白或黑块。根本原因BMP格式不兼容或路径解析失败。排查步骤用Allegro自带的File → Import → Image测试图标文件是否能加载检查图标尺寸是否为24x24像素Allegro硬性要求用十六进制编辑器查看BMP文件头确认是BM开头Windows BMP而非IITIFF独家技巧在menu.def中用绝对路径测试如icon: /home/user/allegro/skill/company/icons/power.bmp成功后再换回$ALLEGRO_HOME。提示Linux下BMP图标常因颜色深度问题显示异常。用GIMP导出时务必选择“索引颜色”→“最大颜色数256”并取消“透明度”选项。5.4 启动报错Allegro无法启动allegro.il的致命伤现象Allegro双击后闪退或弹出“Error in allegro.il”对话框。根本原因allegro.il语法错误或load的文件不存在。排查步骤用文本编辑器打开allegro.il检查括号是否匹配Lisp最常见错误将allegro.il重命名为allegro.il.bak启动Allegro确认是否正常逐行取消注释定位到哪一行引发错误独家技巧在allegro.il开头加(defun debug-load (file) (printf Loading %s\n file) (load file))然后用debug-load替代load启动时能看到每个文件的加载状态。我帮某汽车电子厂解决过一个经典问题他们的allegro.il里有一行(load ./skill/company/config.txt)而config.txt是文本文件非Skill脚本导致load失败。解决方案是改用axlReadFile读取配置。5.5 多用户环境冲突共享目录的权限雷区现象管理员部署成功普通用户启动报“Permission denied”。根本原因Skill文件权限不足或ALLEGRO_HOME环境变量指向只读目录。排查步骤普通用户终端执行echo $ALLEGRO_HOME确认路径ls -l $ALLEGRO_HOME/skill/company/检查文件权限是否为-rw-r--r--检查allegro.il中路径是否硬编码为管理员路径独家技巧在allegro.il中用(getShellEnvVar USER)获取用户名动态构造路径如(strcat /home/ (getShellEnvVar USER) /allegro/skill/company/)。最后分享一个血泪教训某次为客户部署我把所有Skill文件放在/opt/cadence/下结果IT部门每月自动清理/opt临时文件导致菜单消失。现在我的标准做法是所有客户定制Skill必须存放在用户家目录下的~/allegro_skill/并在allegro.il中用getShellEnvVar HOME动态加载彻底规避系统级清理风险。6. 进阶建议让菜单不止于“能用”更要“好用”完成基础菜单加载只是起点。真正让团队愿意用、持续用的Skill工具需要在三个维度深化易用性、可维护性、可扩展性。以下是我在多个项目中验证过的进阶实践。6.1 易用性升级从命令行到向导式交互原始脚本用axlUIConfirm弹窗但用户要手动输参数。升级为向导式对话框体验跃升(defun myPowerSplitGenWithWizard () ; 创建对话框 (let ((dialog (axlUIFormCreate ((Power Split Generator (Network Name: textInput VCC) (Split Width (mm): textInput 0.2) (Gap (mm): textInput 1.5) (Inset (mm): textInput 2.0) (OK button ok) (Cancel button cancel) ) ) ) (result nil) ) ; 显示对话框并获取输入 (setq result (axlUIFormDisplay dialog)) (if (equal result ok) (progn ; 解析输入值 (let ((net-name (axlUIFormGetField dialog 0)) (width (atof (axlUIFormGetField dialog 1))) (gap (atof (axlUIFormGetField dialog 2))) (inset (atof (axlUIFormGetField dialog 3))) ) ; 执行分割逻辑... ) ) (axlUIStatus 操作已取消。) ) ) )这样用户不再需要记参数界面直观且输入值可做校验如width 0。虽然开发量增加30%但培训成本降低70%。6.2 可维护性加固配置与代码分离把split-width等参数硬编码在脚本里每次改规范都要改代码。改为从JSON配置文件读取; config.json 示例 { power_split: { default_width: 0.2, default_gap: 1.5, min_inset: 1.0 } } ; 在power_split.il中 (defun myLoadConfig () (let ((config-file (strcat *company-root* config.json))) (if (file-exists-p config-file) (setq *config* (axlReadJson config-file)) (setq *config* ((power_split . ((
返回列表