Skip to content

feat(macos): 完善类方法跳转、悬停提示与导航弹窗 - #1556

Closed
arkleselect wants to merge 8 commits into
previewfrom
codex/class-method-navigation
Closed

arkleselect wants to merge 8 commits into
previewfrom
codex/class-method-navigation

Conversation

@arkleselect

@arkleselect arkleselect commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

功能与行为

macOS 编辑器此前 Command 点击缺少可见链接反馈,同文件方法调用可能误入实现查询;导航选择器直接覆盖在编辑区上,缺少原生弹窗的关闭行为。本次完善类/方法的单目标跳转以及相关悬停、折叠和选择器体验。

  • Command 悬停通过现有语言服务只查询目标是否存在;解析成功显示链接色、下划线和小手,悬停本身不打开文件或结果面板。复用 Monaco ClickLinkGesture 处理修饰键、拖动和点击,保留原生文件/虚拟源及导航历史归属。
  • Command 点击/F12 使用原生导航;单目标直接打开文件并收起旧结果面板。同文件调用只有源位置确实落在返回声明范围内,才允许既有的实现回退,避免普通同文件方法调用误判为声明自身。
  • 普通说明延迟 500ms;Command 提示在解析完成后显示。松键仅关闭 Command 拥有的提示,已有普通说明不受影响;Esc、滚动、编辑、模型切换和失焦关闭提示,过期结果不得重开。移入提示仍能操作内容。
  • 说明面板使用共享 Lithe 主题的背景、文字、边框、圆角及阴影;Command 提示内边距对齐 IDEA。正文使用共享 Inter 字体、代码保留编程字体,既有只读 Fonts adapter 增加 OTF MIME/白名单支持与路径边界测试;没有运行时发行目录写入。
  • Java 导入区复用既有 Core structure 和 Monaco foldingImportsByDefault,至少两条 import/static import 在首次打开时默认收起,不等待语言服务准备完成;类与方法不默认折叠,手动展开状态随标签视图状态恢复。带版本/模型/位置保护。
  • 实现选择列表迁移至共享 litheDropdown 原生宿主,统一搜索框、列表行与外框;支持 Esc、外部点击、选择跳转、切换标签关闭,以及关闭后重开。按结果数收缩高度,上下键/回车选择,不截获输入法组合确认键;关闭同步重置旧导航操作。
  • 更新拥有该行为的 Agent Note 和两个功能矩阵条目;Windows 宿主与产品实现未修改。

审查结论与范围

审查范围:preview → codex/class-method-navigation 的 19 个变更文件及直接调用链。未发现需要阻塞合并的问题。提交前已移除误重复添加到终端页的弹窗锚点;悬停错误处理复用已有 languageRequest,不建立第二套异常逻辑。

已完成的是类/方法单目标导航及上述交互。既有“在声明自身上 Command 点击后回退到实现查询”的语义,与 IDEA 的声明/用法分流仍有差异;截图中的用法被标为实现的问题未在本 PR 宣称解决。Java 折叠沿用 Core 词法结构精度,并非新接入完整 LSP 语义折叠。完整产品的所有主题、JDK 外部源及所有导航来源未做穷举人工验收。

验证

  • 真实 WebKit workbench:102 项通过,包含链接/小手/点击、悬停显隐与取消、深浅主题面板、导入折叠及状态恢复。
  • Swift 相关导航、主题、字体路径、Core 折叠、共享弹窗:64 项、8 个 suite 通过;弹窗覆盖深浅主题、Esc、外部点击及关闭后重开。
  • 本地示例工程真实 JDT 查询已验证类、跨文件方法、同文件方法和接口声明目标;实际应用曾验证 OrderController 和 normalizeId 跳转。
  • service/editor boundaries、runtime bundle immutability、Agent Notes、i18n 生成一致性、test-stability、git diff --check 全部通过。
  • platform feature matrix 完整检查及相对实际 PR base/head 的 change gate 通过。

上游依据

  • IntelliJ Community:CtrlMouseHandler、EditorMouseHoverPopupManager、EditorSettingsExternalizable、GotoDeclarationOnlyHandler2、GotoTargetHandler;精确 revision 与取舍见拥有该行为的 Agent Note。
  • 固定 Monaco 0.55.1 的 ClickLinkGesture、ContentHoverController 和 foldingImportsByDefault。

慢查询光标稳定性补充

Command 命中候选词时立即在稳定的代码视图层显示 pointer;语义成功后才显示链接色和下划线。避免异步解析空档与文字 span 重绘时退回 I-beam。无目标/失败在同一手势内不重复查询,移出或松键后允许重试;取消时移除指针状态,迟到回复不能恢复它。

新增原生回复闸门的真实 WebKit 测试,覆盖慢服务、连续移动、重绘、负结果和松键后的迟到回复;102 项通过,边界、资源只读、Notes、测试稳定性和功能矩阵门禁通过。

Java 导入折叠首帧修复

  • 主编辑区及分屏在附加 Java 模型时,等待 Monaco 初始折叠与已保存视图状态恢复后才显示代码,避免先展开再收起的闪动。
  • 使用容器 opacity/inert 在计算期间隔离显示和输入,保留布局尺寸;finally 恢复原状态,完成后同步渲染。无固定延时,不重复实现 import 解析或折叠状态。
  • 保留用户手动展开状态;同一模型及非 Java 文件不增加此等待。
  • 新增真实 WebKit 受控 folding provider 测试,验证等待期间不可见、不可输入,完成后首个可见状态已经折叠。全套 103 项通过;平台矩阵、Agent Notes、服务/编辑器边界、运行时 bundle 只读及测试稳定性检查通过。
  • 代价:首次 Java 内容显示需等待已有折叠请求完成(沿用桥接超时),没有增加人为等待;产品实际项目打开体验仍需人工验收。

Command 悬停提示延迟

  • 按用户反馈,将 Command 提示从立即显示改为 Monaco Delayed 模式,沿用 macOS 既有 500ms hover 配置;定义可用性查询完成后进入延迟,手形和链接下划线独立即时反馈。
  • 移出符号/编辑区时取消尚未显示的提示,防止移走后迟到弹出;已显示面板保留 sticky 交互及链接点击。松键、滚动、编辑、切换、失焦继续取消。
  • 重新核对 Community 24bab9a438efb41bd197b295b87136bb98b0b40c 的 CtrlMouseHandler.kt / HoverPopupContext.kt:上游 Command 提示本身立即显示,Lithe 此处按用户要求有意采用普通文档延迟;紧凑 6/6/5/6 内边距与 Lithe 共享外观继续复用。
  • 真实 WebKit 全部 104 项通过;新增待显示提示移出取消检查(316ms),延迟/链接检查(323ms),完整显隐生命周期检查(3390ms,包含多次真实 500ms 延迟)。矩阵 change gate、服务/编辑器边界、bundle 只读、Agent Notes、测试稳定性检查通过。未进行完整 macOS 产品手工视觉验收。

Command 导航即时反馈

  • 候选词的小手、链接色和下划线同步应用,不再等待编辑同步和 native definitionHover 往返。真实目标仍由语言服务解析,点击流程不变。
  • 无目标或错误回复撤销候选装饰,同一候选内像素移动不反复启动;旧请求继续通过 generation / 文档快照拒绝。
  • 说明面板仍在确认可导航后使用既有 500ms 延迟,本次没有改变语言服务查询耗时,也不宣称语义解析变快。取舍:不可导航词可能短暂出现候选装饰,随后撤销。
  • WebKit 显式阻塞 native 回复,验证回复前已有实际下划线/手形、面板未出现,以及负结果撤销;全套 104 项通过。平台矩阵及 change gate、Agent Notes、服务/编辑器边界、bundle 只读、测试稳定性检查通过。实际项目手感仍需新构建人工验收。

注释候选误识别修复

  • Command 悬停和点击共用 Monaco/TextMate standard token type 过滤,注释、字符串及正则正文不进入候选导航。显式 F12 保留原语义。
  • 复用多行词法状态;只在 Monaco 判定低成本时同步刷新当前行 token,避免鼠标移动触发大段前缀解析。状态未准备好时暂不提示,不添加独立词法解析器。
  • 新增真实 WebKit 回归:行注释、多行注释、字符串既无指针/下划线,也不派发点击导航;原真实代码即时反馈测试继续通过。全套 105 项通过,矩阵 change gate、Agent Notes、服务/编辑器边界、bundle 只读及测试稳定性检查通过。

注释分隔符颜色

  • 修复 Java TextMate scope 映射把 punctuation.definition.comment 当作普通 delimiter 的问题,注释斜杠/星号与正文统一使用 comment 主题色和 token 类型。普通除法标点保持原分类,不增加 CSS 特例或硬编码颜色。
  • 真实 WebKit 深浅主题覆盖行注释、块注释、文档注释的分隔符前景色和类型,并验证除号不被分类为注释。全套 106 项通过;平台矩阵 change gate、Agent Notes、服务/编辑器边界、bundle 只读及测试稳定性检查通过。

@ghfind-review ghfind-review Bot added the review: medium ghfind author score; see https://ghfind.com label Oct 28, 2026
@lithe-code-review

lithe-code-review Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Lithe Review

结论: ⚠️ 有建议
范围: preview 分支 ← codex/class-method-navigation 分支 · head: f19da73

Scope Check

  • 关联 Issue 或需求是否完成:未找到可验证的关联 Issue;按 PR 描述审查所列功能范围。
  • 已完成范围:类/方法导航与 Command 悬停、Java 导入折叠、实现选择器弹窗及相关主题和字体适配均已纳入审查。
  • 未完成范围:PR 描述指出完整应用的主题、外部 JDK 源和所有导航来源未穷举验收。
  • 是否复用了已有上游能力,或对自研边界给出充分证据:导航复用 Monaco 手势、现有语言服务和原生导航;折叠复用 Core 结构与 Monaco 默认导入折叠。更新的 Agent Note 记录了选择依据和边界。
  • 每个 Finding 是否由本次变更引入或加剧:未发现需列入 Findings 的问题。
  • 是否属于本次变更职责范围:审查覆盖给定的完整 19 文件清单及其直接调用链。

Suggestions

  1. 请在 PR 描述或评论中补充受影响界面的截图;已有界面改动请提供前后对比。当前提供的上下文没有截图,因此视觉效果尚未验证。

Summary

静态检查未发现需要阻塞合并的问题。变更沿用现有平台导航和共享编辑器能力,并更新了相关 Agent Note 与功能矩阵。截图缺失是本次唯一审查建议。

Verification

  • 实际检查:给定 base...head 的 19 个文件差异、导航协调器与 AppModel 调用链、Monaco 请求与主题配置、共享弹窗实现、相关测试及 Agent Note。
  • 已提供的测试或 CI 结果:PR 描述报告 WebKit 101 项和 Swift 64 项测试通过;head 暂无 Check Run。以上测试结果未在本次审查中独立验证。
  • 本次未运行测试、构建或仓库代码。
  • 仍存在的非阻塞风险或平台验证缺口:视觉效果尚未通过截图检查;PR 描述所列的完整应用人工验收仍有未覆盖范围。

@xiaoyumuxi

Copy link
Copy Markdown
Collaborator

那个拆 Java Support 的 PR 没影响正常功能吧,我不是很确定哎

@arkleselect

Copy link
Copy Markdown
Collaborator Author

那个拆 Java Support 的 PR 没影响正常功能吧,我不是很确定哎

我还能用 就是突然不显示侧边栏的数据库按钮了

@xiaoyumuxi

Copy link
Copy Markdown
Collaborator

那个拆 Java Support 的 PR 没影响正常功能吧,我不是很确定哎

我还能用 就是突然不显示侧边栏的数据库按钮了

这个是 @1lck 给数据库拆到那个插件里面了哎,你可以看看插件内容

@xiaoyumuxi xiaoyumuxi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查基于 cb351ab,发现 2 处行为回归,具体见行内评论,建议合并前修复。

验证:现有 106 个 WebKit 逻辑集成用例全部通过;另用真实 WebKit 定向确认 Spring 字符串配置键的 Command-click 被拦截,并用原生 dropdown 生命周期定向 harness 确认选择后的关闭回调会回写 Binding(false)。后者只验证控件生命周期,未进行完整产品的 JDT 依赖源码跳转验收。平台矩阵、Agent Notes、架构边界及 runtime bundle 只读检查通过。未运行完整 Swift 测试及整机验收。

Color.clear.frame(width: 1, height: 1)
.litheDropdown(isPresented: Binding(
get: { model.isImplementationChooserVisible },
set: { if !$0 { model.closeLanguageNavigationResults() } }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 不要在选择完成后的关闭回调中重置新启动的导航

选择 jdt://… 等虚拟源码实现时,navigate(to:) 会先把 isImplementationChooserVisible 设为 false,随后启动异步 resolveVirtualDocument。SwiftUI 更新后,dropdown 的正常关闭流程仍会通过 onDismiss 回写 Binding(false);这里无条件调用 closeLanguageNavigationResults(),进而 reset() 导航 coordinator,使刚启动的 operationID 失效。只要虚拟源码响应晚于关闭回调,返回结果就会被 owns(operationID) 拦截,表现为弹窗关闭但目标源码没有打开。原生 dropdown 生命周期定向 harness 已确认“开始选择请求 -> 关闭回写 false -> reset”的顺序。请区分用户取消与选择完成后的关闭,避免关闭旧结果面板时取消新导航,并补一个延迟虚拟源码响应的选择回归测试。

if (!position || !tokens?.isCheapToTokenize(position.lineNumber)) return false;
tokens.forceTokenization(position.lineNumber);
const line = tokens.getLineTokens(position.lineNumber);
return line.getStandardTokenType(line.findTokenIndexAtOffset(position.column - 1)) === 0 /* Other (code) */;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 保留字符串内部已有的语义导航

这里只接受 Other token,而 isCodePosition() 也被用于 Command-click 的执行条件,因此会直接屏蔽合法的字符串导航。例如现有 Spring 功能支持从 @Value("${demo.retry-count}") 跳到配置文件,但该位置的 Java TextMate token 类型为 String,导航请求在到达 native 的 productNavigationLocations() 之前就被拦截。真实 WebKit 定向验证中,同一配置键的 Command-click 发出 0 次 definition 请求,F12 发出 1 次;普通代码位置两种方式均发出 1 次。这是已有交互回归,不只是缺少悬停效果。请保留可由产品功能或语言服务解析的字符串链接,不要仅凭字符串 token 全量拒绝,并补 Spring 配置键的点击导航测试。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: medium ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants