ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Visual Studio Code 会话布局控制器 D1–D11 规则解析:桌面端 side pane(辅助栏)行为规格与实现指南

Visual Studio Code 会话布局控制器 D1–D11 规则解析:桌面端 side pane(辅助栏)行为规格与实现指南 Visual Studio Code 会话布局控制器 D1–D11 规则解析桌面端 side pane辅助栏行为规格与实现指南【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode本文以 desktopSessionLayoutController.md 规格文档为骨架系统讲解 VS Code 中LayoutController桌面端与 Web 桌面布局共用如何为每个会话记住并恢复side pane辅助栏 / auxiliary bar的开合状态与展示视图Files 或 Changes。读者将掌握 D1–D11 规则的含义、配置项sessions.layout.autoCollapseSessionsSidebar的用途以及这些规则在 desktopSessionLayoutController.ts 与测试中的落地位置。一、背景控制器家族与“规格 规则”文档模式在引入会话级工作区Sessions / Agents布局管理之前VS Code 的编辑器、侧边栏、面板布局是全局共享的。会话布局控制器则让每个会话拥有自己的布局记忆切换会话时恢复该会话此前打开/关闭的编辑器集合、底部面板与辅助栏状态。LayoutController是其中的桌面实现位于 desktopSessionLayoutController.ts导出类LayoutController代码中注释直接引用了 D1–D11。完整的分层结构见 LAYOUT_CONTROLLER.md控制器文件规格文档规则标签BaseLayoutController抽象基类平台无关baseSessionLayoutController.mdB1–B6LayoutController桌面 / Web 桌面本文档D1–D11MobileLayoutControllerWeb 手机布局mobileSessionLayoutController.mdM1–M2SinglePaneLayoutController单窗格细节面板模式策略测试见 singlePaneStrategies.test.ts场景文档关键事实规格文档的“规则Rules”描述用户可见行为规则标签D*、B*、M*同时被代码注释与测试用例引用作为稳定的行为契约文档头部的 “Specification change gate” 明确指出——恢复既有规则的 bug 修复应写入回归测试只有控制器预期行为改变时才更新本文档。实现层面信息放在独立的 “Implementation notes” 小节仅在修改代码时需要阅读。本文档仅覆盖经典桌面布局aux bar 作为工作台栅格独立列当实验性设置sessions.layout.singlePaneDetailPanel开启时单窗格细节面板模式aux bar 被停靠进编辑器内部由SinglePaneLayoutController与 singlePane/ 目录下的策略/协调器接管D 规则不适用。二、核心概念side pane / auxiliary bar整个文档中反复出现的“side pane” 指的是 auxiliary bar辅助栏即二次侧边栏位于编辑器区右侧的栅格部分它只会显示两种视图Files 视图会话工作区文件Changes 视图多文件 diff 编辑器对应的变更视图。在文档语境中 “side pane” 还有另一种用法D9 等规则指“编辑器区 辅助栏”整体。区分两种含义是读懂规则的关键——D8/D9 讨论“关闭整个 side pane”时是把编辑器与辅助栏作为一个可整体收起/展开的面。辅助栏在代码中的常量与识别方式部件 ID 为Parts.AUXILIARYBAR_PART见 desktopSessionLayoutController.ts 中对onDidChangePartVisibility的监听两个视图容器 IDFiles 为SESSIONS_FILES_CONTAINER_ID来自 files.contribution.tsChanges 容器与视图 ID 为CHANGES_VIEW_CONTAINER_ID/CHANGES_VIEW_ID来自 changes.ts。三、记忆 side pane捕获D1、D2场景记住 side pane。side pane 的开/关状态以及它显示哪个视图Files 或 Changes会按会话被记住以便稍后恢复。D1 — 切走时捕获当离开某个会话时其当前 side pane 状态被为该会话捕获。实现上是_captureViewState(previousSession)记录两个字段auxiliaryBarVisible辅助栏当前是否可见auxiliaryBarActiveViewContainerId当前活跃的视图容器Files 还是 Changes。在切换 autorun 中通过比较previousSessionResource与当前 active 会话的 resource 判断“是否真的发生了切换”命中即调用_captureViewState保存即将离场会话的状态desktopSessionLayoutController.ts。该方法也被基类保存钩子复用——桌面控制器重写_captureActiveSessionViewState委托给它对应基类规则 B4关闭/重载时保存所有会话布局见 baseSessionLayoutController.md。D2 — 切换时立即捕获打开或关闭 side pane 会立即被记录而不是等到切换会话才记录。底层是监听AUXILIARYBAR_PART的onDidChangePartVisibility事件desktopSessionLayoutController.ts。以下情形会**挂起suspended**记录保证不会把非用户意图的可见性变化误记为用户的“新选择”多个会话同时可见多会话网格视图此时没有单一“active”布局可记录编辑器处于最大化状态对应 D5强制的 Changes 视图不应写入会话偏好控制器为恢复会话记忆状态而主动隐藏 side pane 时——通过_hidingAuxiliaryBarForRestore标志_hideAuxiliaryBarForRestore同步置位跳过避免“恢复驱动的隐藏”被当成用户选择整个 side pane 被一次性收起对应 D9_togglingSidePane置位期间跳过所有中间态。记录目标根据当前 active 会话是否已创建区分未创建untitled 草稿会话更新共享的_newSessionViewState已创建会话写入该会话的 view state。对“从隐藏态被恢复显示”的已创建会话D2 捕获前先通过_restoreSavedAuxiliaryBarContainerOnReveal恢复其保存的或默认的活跃容器避免只记录“可见”而丢失“显示哪个视图”。四、打开 Changes 编辑器D8、D9、D9b场景打开 Changes 编辑器。会话标题栏上的Changes按钮会在编辑器区打开多文件 diff 编辑器。D8 — 首次打开 Changes 编辑器会展示 side pane当一个 Changes 编辑器为某已存在会话打开时side pane 会打开到Changes视图——条件是“第一次”尚无任何记忆的选择或“整个 side pane 曾被关闭D9之后”包含 reload 之后的情形此时 pane 被恢复为关闭但打开 Changes 会重新揭示它。但以下情况不会自动打开用户只显式关闭了side pane辅助栏本身编辑器仍开着——则后续打开 Changes含跨 reload保持关闭已经打开的 side pane 停留在用户自选的视图上不被强制切换编辑器处于最大化D5、多会话可见、或单窗格细节面板模式由其他规则接管。实现要点desktopSessionLayoutController.ts_revealChangesViewOnFirstOpen同时注册在onDidActiveEditorChange和EDITOR_PART变为可见的onDidChangePartVisibility上——后者覆盖“整个 side pane 被关闭后再次点击 Changes 按钮”的场景此时 Changes 编辑器仍是 active editor只是被隐藏重新打开只触发 editor part 可见不会触发 active-editor 变化通过ISessionChangesService.getSessionResource多 diff 源 URI 的反查识别 Changes 编辑器打开前必须满足该会话是 active 的 titled 会话、编辑器部件可见reload 恢复的 Changes 编辑器可能在编辑器部件仍隐藏时成为 active此时不得自动揭示 side pane、非最大化、非多会话模式例外若会话 view state 记录的是显式辅助栏隐藏auxiliaryBarVisible: false且无auxiliaryBarHiddenByCollapse标记或辅助栏已经可见则不揭示揭示动作流经 D2 监听器从而把{ auxiliaryBarVisible: true }记录为一次真实选择。测试覆盖见 desktopSessionLayoutController.test.ts例如 “untitled sessions are governed by D3b/D4, not D8”断言切换不会打开CHANGES_VIEW_ID。D9 — 关闭整个 side pane 不算一次辅助栏“选择”这里的 “side pane” 编辑器区 辅助栏。关闭它例如从 side panel 的 toggle会同时隐藏两者。对已创建会话这不被视为“选择隐藏辅助栏”因此重新打开 Changes 编辑器会再次显示它D8即使在 reload 之后也成立——pane 恢复为关闭但被标记为collapsedauxiliaryBarHiddenByCollapse: true而非显式隐藏所以打开 Changes 会重新揭示只有单独隐藏辅助栏编辑器保持打开才被记为显式的 “closed” 选择。实现细节side-pane toggle 的用户界面入口Toggle Side Panel动作的菜单项、键绑定、命令面板项、切换图标由基类控制器注册但其 handler 直接调用工作台布局服务的toggleSidePane()。工作台记忆/恢复原始的 editor/aux 可见性并发出onWillToggleSidePane/onDidToggleSidePane携带{ editor, auxiliaryBar }状态_onSidePaneToggled(collapsed, previousAuxiliaryBarVisible)在完成后记录结果完整收起先前可见的辅助栏时为该会话写入带auxiliaryBarHiddenByCollapse: true的 view state。该标记因此只作用于真正被收起的那个会话_captureViewState保存时、切走时、关闭时在辅助栏保持隐藏期间只保留已有标记从不凭空捏造因此别的会话的显式隐藏绝不会被误认为 collapse。D9b — 新会话上关闭整个 side pane 会被记住对**新未创建**会话关闭或打开整个 side pane会被记录为“所有新会话共享的 side pane 选择”见 D3b。这意味着你在起草新会话时关掉了 side pane它保持关闭同一新会话后续重新同步时例如获得了工作区、取消最大化、或从多会话视图收回不会重新打开也不会在创建下一条新会话时被重新打开多会话可见或编辑器最大化时挂起。实现上_onSidePaneToggled在桌面控制器被重写未创建会话通过_setNewSessionViewState记录结果可见性已创建会话只有在“完整收起先前可见的辅助栏”时才打 collapse 标记其余情形重新打开、或收起一个本就 editor-only 的状态只捕获结果状态确保显式隐藏永远不会被转写成 collapse。五、返回会话时的恢复优先级D3场景返回到某会话。聚焦一个会话时会依据上述记忆状态恢复其 side pane。_syncAuxiliaryBarVisibility(resource, hasWorkspace, isCreated)按严格优先级执行恢复D3a — 无会话 / 无工作区→ 什么都不做。D3b — 新未创建会话→ 所有新会话共享同一个被记住的 side pane 状态_newSessionViewState持久化在 workspace 存储键sessions.newSessionViewState下。若你显式关闭过 side pane它就保持关闭跨切换和reload否则打开到默认视图D3d。这是 side pane 唯一会自行打开的正常时机——新会话默认打开让用户一开始就能看到 Files。D3c — 已创建会话→ 恢复时绝不会自动打开side pane。若它是关闭的或没有记忆状态保持关闭若它是打开的且该视图仍然存在则重新打开若该视图已消失回退到默认视图D3d。D3d — 默认视图→ 在该会话任意 chat产出至少一个文件变更之前默认显示Files之后默认显示Changes。变更状态在 side pane 打开的那一刻读取untracked 读取因此更晚到达的变更不会切换你正在看的视图与 D6 呼应。若 Files 面板已被用户 unpin固定解除则回退到 Changes。测试证据desktopSessionLayoutController.test.ts覆盖了各分支[D3c] hides side pane for existing session without saved state[D3b] shows files view for untitled session[D3d] defaults to Files while the session has no changes/defaults to Changes once one of the session chats has a change[D3a] does not open views when session has no workspace[D3b] ignores malformed persisted new-session state损坏的持久化数据被防御性丢弃六、覆盖记忆状态的特殊场景D4、D5场景有意忽略上述记忆状态的少数过渡。D4 — 提交新会话当新会话在保持 active 的情况下变为“已创建”同一资源上isCreated从 false 变 true或 provider 用已提交资源替换草稿时side pane完全保持你离开时的样子若它是打开的 → 保持打开停留其当前视图若它是关闭的 → 保持关闭且不为它记录任何视图因此以后打开时按当时会话的变更状态显示默认视图D3d。实现上切换 autorun 检测isSubmit同资源、非切换、previousIsCreatedfalse 且isCreatedtrue后走_onNewSessionSubmitted_onSessionReplaced在 provider 提交草稿时执行相同的状态迁移复制草稿的可见容器隐藏时容器为空留给揭示时按默认选择。该状态会被持久化保证后续 sync 不回退到“隐藏”。提交过渡发生在_withSessionLayoutRestore包裹内因此不会与恢复逻辑冲突。D5 — 最大化编辑器当编辑器区被最大化时side pane总是显示 Changes忽略会话保存的或先前的任何状态。这个被强制的状态不会被记住D2 在此期间挂起因此取消最大化会恢复该会话真实的 side pane 状态且编辑器恢复到之前的尺寸——强制的 Changes 视图永远不会把编辑器永久压缩。实现上切换 autorun 首先读editorMaximizedObsIAgentWorkbenchLayoutService.isEditorMaximized()命中即openView(CHANGES_VIEW_ID)后 return会话工作台setEditorMaximized会在最大化时快照编辑器部件尺寸与周边部件可见性取消最大化时恢复。七、新变更到达与“无可展示内容”D6、D10、D11D6 — 新变更从不自动打开 side pane当一次 chat 回合产出新文件变更时side pane不会被自动打开当前活跃视图也不会被自动切换——一切保持你离开时的状态。只有新会话会打开它D3b。第一个变更确实会让Changes成为默认视图D3d但那只在 side pane 下一次打开时才生效。sync 逻辑autorun从不因文件变更打开 side pane 或切换容器测试[D3d] does not switch a side pane that is already showing Files when a change lands正是该行为的回归防护。D10 — 空的辅助栏保持隐藏某些会话把辅助栏的所有视图容器都 gate 掉了——例如没有工作区的 quick chatChanges 与 Files 容器因when条件隐藏——此时辅助栏会是一条空列。规则是当辅助栏没有任何 active view container没有可展示内容时其部件保持隐藏而非显示空列聊天区占据该空间。该规则是响应式的随 active 会话切换更新容器被 gate 掉→隐藏部件容器重新 active→交给 D3/D8 的正常恢复规则揭示当部件自身变为可见但没有任何 container/descriptor 变化信号触发时也会重新检查——例如“先显示空列、容器稍后才打开”的裸 detail toggle或恢复时容器仍被 gate 住——确保 detail toggle 永远不会在一张空白面板上读到 “on”收掉空列在suppressEditorPartAutoVisibility()下执行因此不会作为副作用“复活”编辑器编辑器可见性始终归 D3/D8 管控制器只隐藏空的辅助栏从不主动揭示它。对称地停靠宿主setAuxiliaryBarHidden在辅助栏显示时绝不强制打开一个没有 active view 的hideIfEmpty容器因此一次 show 永远不可能呈现空白停靠面板Toggle Side Panel只影响“有内容”的部件编辑器有编辑器时揭示编辑器、辅助栏空时只对编辑器生效且从不揭示空辅助栏两侧都无内容时 toggle-open 是 no-op。这些共同保证了不变式partVisibility.auxiliaryBar⇒AuxiliaryBarVisibleContext⇒ detail toggle为真当且仅当停靠的 detail 面板确实渲染了某个 active view container。对于quick chat——它根本没有 side pane无工作区辅助栏保持隐藏、聊天区全宽——Toggle Side Panel 命令被直接禁用命令携带precondition: IsQuickChatSessionContext.negate()因此其菜单项、键绑定与命令面板条目全部失效。实现要点desktopSessionLayoutController.ts_registerAuxiliaryBarPartVisibility在以下事件上重新挂线并检查_hasActiveAuxViewContainers()容器增删onDidChangeViewContainers、容器位置移动、每个辅助栏容器 model 的onDidChangeActiveViewDescriptors即when-gating 信号、aux 容器可见性变化、以及 aux-bar 部件自身可见_syncAuxiliaryBarPartVisibility只在确认为 quick chat 时隐藏activeSession?.isQuickChat?.get() true避免把工作区会话启动/激活的瞬时空容器态误判成空列导致“reload 闪烁 / Files 不显示”。D11 — 单窗格模式的新会话视图仅显示 Files仅在单窗格 detail-panel 模式下当未创建untitled的工作区会话视图处于 active 时编辑器内容默认隐藏使编辑器标签栏与 Files detail 面板保持显示而不展示编辑器内容。隐藏是过渡触发的_registerNewSessionRules是基类中的 no-op 钩子由SinglePaneLayoutController重写另见 singlePaneLayoutController.ts当编辑器部件刚变为可见或刚进入新会话视图且编辑器已经可见继承自上一会话的可见编辑器时隐藏编辑器部件——且仅当 active editor 不是真实内容受管的空标签或 none时一旦真实文件/浏览器编辑器成为 active就不再动编辑器编辑器已经可见时切换到受管标签如 Files 占位符不会隐藏它——只有可见性过渡或进入视图才会显式揭示会“粘住”打开文件会在文件成为 active editor 之前揭示编辑器Task 4关闭 detail 面板会揭示空编辑器以免 side pane 消失Task 2进入视图总是重置为 editor-closed因此旧的跨会话显式揭示不会残留瞬时基于宽度的揭示如 sash 拖拽会被同一规则重新隐藏。共享的 D3b/D9b 新会话 side-pane 可见性状态不变一旦用户为新会话隐藏了 side pane它对后续新会话保持隐藏。八、小窗口下的响应式布局D7场景狭窄窗口。小窗口没有空间同时容纳会话侧边栏、编辑器与 side pane。D7 — 响应式会话侧边栏当窗口很窄主容器宽度 ≤ 1800pxSMALL_WINDOW_MAX_WIDTH且编辑器与 side pane辅助栏同时打开时会话侧边栏自动隐藏。两者中任一关闭或窗口重新变宽时侧边栏恢复显示。若用户自己关闭过侧边栏则它保持关闭——自动显示被抑制直到用户手动重新打开。规则在以下情形挂起编辑器最大化时D5多个会话同时可见时切换会话从不自动隐藏侧边栏会话切换恢复了新会话保存的 side pane 时会重新基线化响应式状态而非作出反应因此只有会话内的布局变化驱动自动隐藏。整个行为由实验性设置sessions.layout.autoCollapseSessionsSidebar门控其在非稳定构建Insiders/探索渠道默认开启、稳定版默认关闭。该设置在 sessions.layout.contribution.ts 中注册其default由product.quality ! stable决定// 注册于 sessions.layout.contribution.tsConfigurationRegistry { id: sessions, properties: { sessions.layout.autoCollapseSessionsSidebar: { type: boolean, // 窄 Agents 窗口中当编辑器与 side panel 同时打开时是否自动收起会话侧边栏 // 并在任一者关闭时再次显示。 default: /* product.quality ! stable即稳定版关闭 */, tags: [experimental], experiment: { mode: auto } } } }实现要点desktopSessionLayoutController.ts_registerResponsiveSidebar从四个可观察源 设置派生出spaceConstrainedenabled small editor visible aux-bar visible !multipleSessionsVisible其中small由onDidLayoutMainContainer提供宽度 1800autorun 只在派生值的真实过渡上动作用_previousSpaceConstrained比较且编辑器最大化期间跳过受约束时仅当_setSidebarAutoHidden(true)真的隐藏了一个可见侧边栏才置位_sidebarAutoHidden解除约束时仅当_sidebarAutoHidden为真即确实是控制器隐藏的才恢复显示一个独立的SIDEBAR_PART可见性监听器在任何手动toggle 时清除_sidebarAutoHidden受_applyingAutoSidebar保护避免把控制器自己的 toggle 当成用户意图最大化自身的侧边栏进出 toggle 会经此监听器自我抵消因为只有控制器驱动的隐藏才会自动回滚reload 前就已关闭的侧边栏内存中_sidebarAutoHidden重置为 false绝不会被自动重新揭示恢复会话布局期间autorun 重新基线化而非反应恢复纪元_withSessionLayoutRestore/_isRestoringSessionLayout由基类持有同时包裹桌面 D3 的 aux-bar 恢复与基类 B2 的编辑器 working-set 应用并保持_restoringSessionLayoutDepth 0直到工作沉降同步的 void 工作立即结束异步工作等 promise 落定——从而把_applyWorkingSet在await之后执行的编辑器部件揭示、以及落在更晚 autorun run 里的 aux-bar 揭示吸收掉避免导航时触发自动隐藏。单窗格覆盖在单窗格 detail-panel 模式下_registerResponsiveSidebar被替换为显式 details 规则——会话侧边栏仅当用户通过Toggle Details动作workbench.action.toggleAuxiliaryBar打开详情窗格时才自动隐藏为编辑器区腾出横向空间并在通过同一动作关闭详情窗格时恢复。它不受窗口尺寸驱动、忽略自动详情打开提交、会话恢复、多会话可见时挂起一旦用户手动重新打开会话侧边栏即交还控制权。九、注册与配置入口谁在使用这些规则控制器装配在 sessions.layout.contribution.tsSessionsLayoutContributionWorkbenchPhase.BlockRestore若启用了单窗格布局layoutService.isSinglePaneLayoutEnabled→SinglePaneLayoutController否则若是isWeb isMobileWeb 手机布局→MobileLayoutController否则 →LayoutController桌面与 Web 桌面本文档的主角。该 contribution 同时注册两个实验性配置项均由导入方 sessions.desktop.main.ts 与 sessions.web.main.ts 以副作用导入方式挂载配置项类型默认值用途sessions.layout.autoCollapseSessionsSidebarbooleanproduct.quality ! stable实验默认 auto门控 D7 响应式侧边栏sessions.layout.singlePaneDetailPanelbooleantrueexperiment: { mode: startup }是否启用单窗格 detail 面板停靠细节面板进编辑器需要重载生效启用后由 SinglePane 控制器接管十、持久化与状态模型横向视图虽然 D 规则聚焦可见行为理解状态落点有助于排查问题。LayoutController与基类按会话资源URI为键持久化以下状态细节见 LAYOUT_CONTROLLER.md状态存储映射说明辅助栏可见性 活跃容器_viewStateBySession含auxiliaryBarHiddenByCollapse标记经典布局序列化到 workspace 键sessions.layoutState底部面板可见性_panelVisibilityBySession经典布局B1单窗格改由工作台级别持有编辑器 working set_workingSets各会话的已打开编辑器集合B2新会话共享选择_newSessionViewState键sessions.newSessionViewStateD3b/D9b切换时立即写入而非关机时才写持久化走StorageScope.WORKSPACEStorageTarget.MACHINE损坏数据被防御性丢弃_loadNewSessionViewState对 JSON 解析失败/字段非法会直接 remove并有一性迁移逻辑从旧键sessions.workingSets升级。十一、变更与测试给维护者的指引规格文档本身写明了变更纪律修复既有 D 规则的 bug 应写成回归测试而不是改规格只有桌面控制器预期行为变化才更新本文档。桌面控制器的行为测试集中在 desktopSessionLayoutController.test.ts约 3888 行其中用例标题直接用规则标签命名[D3a]、[D3b]、[D3c]、[D3d]、[D9b]…是理解每条规则的“可执行规格”。测试通过测试 harness 模拟toggleSidePane()调用、toggleSidePaneCalls计数、openedViews断言等可精确复现“打开 Changes 是否揭示 aux bar”“新会话收起 side pane 后 re-sync 是否保持关闭”等行为。因此向 D 规则添加或修改行为时标准流程是先在这份 spec 中修订规则 → 在LayoutController中实现 → 在测试文件中添加带同一标签的用例。三个文件通过标签形成闭环desktopSessionLayoutController.md中对应的代码与测试引用均以此为锚点。结语LayoutController的 D1–D11 规则刻画了一套细致的“记忆—恢复—例外”状态机D1/D2/D3 负责把用户的选择按会话记住并恢复D4/D5 处理提交与最大化这两个绕开记忆的过渡D6 保证运行中的变更绝不打扰用户当前视野D8/D9/D9b 精确区分“显式隐藏辅助栏”与“整体收起 side pane”这两种看似相同却语义相反的操作D7 与 D10/D11 则分别应对小窗口与“无内容可展示”的空间极端情况。理解这套规则无论是排查布局恢复问题、扩展新的布局策略还是撰写新的回归测试都能在 desktopSessionLayoutController.md 与 desktopSessionLayoutController.ts 之间找到一一对应的证据链。【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表