feat(desktop): add right-click context menu to file editor with Monaco actions#631
Conversation
|
Warning Rate limit exceeded@Kitenite has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 17 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughIntroduces a pluggable editor context‑menu system and integrates it into diff and file editors: adds EditorContextMenu, FileEditorContextMenu, useEditorActions, editor action registration (copy path:line), and propagates pane/tab split and move handlers to file viewer panes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant Monaco as Monaco Editor
participant FileWrap as FileEditorContextMenu
participant Menu as EditorContextMenu
participant PaneCtrl as Pane Controller
Note over Monaco,FileWrap: Monaco native context menu disabled when custom menu is provided
User->>Monaco: Right-click in editor
Monaco->>FileWrap: emit contextmenu event
FileWrap->>Menu: open menu with editorActions & paneActions
Menu->>User: display custom context menu
alt Copy Path:Line
User->>Menu: Select "Copy Path:Line"
Menu->>FileWrap: invoke onCopyPathWithLine
FileWrap->>Monaco: query selection / position
FileWrap->>FileWrap: format "path:startLine:startCol"
FileWrap->>User: copy formatted string to clipboard
end
alt Split Pane Horizontal
User->>Menu: Select "Split Horizontally"
Menu->>FileWrap: invoke onSplitHorizontal
FileWrap->>PaneCtrl: splitPaneHorizontal(tabId, sourcePaneId, path?)
PaneCtrl->>PaneCtrl: create new pane and update layout
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (7)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsx (2)
31-162: Consider extracting a helper to reduce repetition in editor action handlers.All Monaco trigger handlers follow the same pattern: null-check editor, focus, trigger action. This could be DRY'd with a helper function.
🔎 Suggested helper extraction
+const triggerEditorAction = ( + editorRef: MutableRefObject<Monaco.editor.IStandaloneCodeEditor | null>, + actionId: string, +) => { + const editor = editorRef.current; + if (!editor) return; + editor.focus(); + editor.trigger("contextMenu", actionId, null); +}; const handleCut = () => { - const editor = editorRef.current; - if (!editor) return; - editor.focus(); - editor.trigger("contextMenu", "editor.action.clipboardCutAction", null); + triggerEditorAction(editorRef, "editor.action.clipboardCutAction"); };This pattern can then be applied to all other trigger-based handlers.
63-87: Clipboard write operations silently ignore failures.
navigator.clipboard.writeTextreturns a Promise that may reject. Consider adding error handling or using Electron's clipboard API for more reliability.🔎 Example with error handling
const handleCopyPath = () => { - navigator.clipboard.writeText(filePath); + navigator.clipboard.writeText(filePath).catch((err) => { + console.error("[FileEditorContextMenu/copyPath] Failed to copy:", err); + }); };apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx (1)
121-123: Inline arrow functions create new references on each render.The
onMoveToTabandonMoveToNewTabcallbacks are recreated on every render since they're defined inline. IfFileViewerPaneorTabPaneperform any memoization based on props, this would defeat it.🔎 Consider using useCallback if this causes performance issues
// If needed, memoize these at the component level const handleMoveToTab = useCallback( (paneId: string, targetTabId: string) => movePaneToTab(paneId, targetTabId), [movePaneToTab] ); // Then in renderPane: onMoveToTab={(targetTabId) => handleMoveToTab(paneId, targetTabId)}However, since
renderPaneitself is already memoized withuseCallback, the current approach is acceptable unless profiling shows issues.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsx (2)
158-207: Code duplication with FileEditorContextMenu action handlers.The
handleCopy,handleSelectAll,handleCopyPath,handleCopyPathWithLine, andhandleFindhandlers are nearly identical to those inFileEditorContextMenu.tsx. Consider extracting shared utilities to reduce duplication.🔎 Suggested approach
Extract common clipboard and editor action helpers to a shared utility module:
// e.g., in a shared editor-actions.ts utility export function copyPathToClipboard(filePath: string) { navigator.clipboard.writeText(filePath); } export function copyPathWithLineToClipboard( filePath: string, selection: Monaco.Selection | null ) { if (!selection) { navigator.clipboard.writeText(filePath); return; } const { startLineNumber, endLineNumber } = selection; const pathWithLine = startLineNumber === endLineNumber ? `${filePath}:${startLineNumber}` : `${filePath}:${startLineNumber}-${endLineNumber}`; navigator.clipboard.writeText(pathWithLine); }Both
FileEditorContextMenuandDiffViewercan then use these shared helpers.
250-258: Consider using shorthand property syntax.The
paneActionsobject could use shorthand syntax since the property names match thecontextMenuPropsproperties.🔎 Shorthand alternative
- const paneActions: PaneActions = { - onSplitHorizontal: contextMenuProps.onSplitHorizontal, - onSplitVertical: contextMenuProps.onSplitVertical, - onClosePane: contextMenuProps.onClosePane, - currentTabId: contextMenuProps.currentTabId, - availableTabs: contextMenuProps.availableTabs, - onMoveToTab: contextMenuProps.onMoveToTab, - onMoveToNewTab: contextMenuProps.onMoveToNewTab, - }; + const paneActions: PaneActions = { ...contextMenuProps };This works since
DiffViewerContextMenuPropsmatchesPaneActionsexactly.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsx (1)
41-67: Consider grouping related props to reduce interface complexity.The
FileViewerContentPropsinterface now has 24 properties. While this follows the object params guideline, grouping related props could improve readability and maintainability.🔎 Suggested grouping
interface ContextMenuProps { onSplitHorizontal: () => void; onSplitVertical: () => void; onClosePane: () => void; currentTabId: string; availableTabs: Tab[]; onMoveToTab: (tabId: string) => void; onMoveToNewTab: () => void; } interface FileViewerContentProps { // ... existing props ... contextMenuProps: ContextMenuProps; }This would also align with how
DiffVieweracceptscontextMenuProps.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx (1)
81-84: Consider using Electron's platform detection instead of deprecatednavigator.platform.The
navigator.platformAPI is deprecated. Since this is an Electron desktop app, consider usingprocess.platformfrom Node.js via the main process, or check if the platform information is already available through your app's context.Alternative approaches
Option 1: Use process.platform via tRPC (preferred for Electron)
// In main process tRPC router getPlatform: publicProcedure.query(() => { return process.platform; }); // In component const { data: platform } = trpc.getPlatform.useQuery(); const isMac = platform === 'darwin';Option 2: Use userAgent (browser fallback)
-const isMac = - typeof navigator !== "undefined" && - navigator.platform.toLowerCase().includes("mac"); +const isMac = + typeof navigator !== "undefined" && + /Mac|iPhone|iPad|iPod/.test(navigator.userAgent);As per coding guidelines, Electron IPC should use tRPC as defined in
src/lib/trpc.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid usinganytype - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Drizzle ORM for all database operations - never use raw SQL
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for formatting and linting - run at root level with
bun run lint:fixorbiome check --write
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
One component per file - do not create multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx
🧠 Learnings (3)
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/*/src/components/**/*.{ts,tsx} : Co-locate component dependencies: utils, hooks, constants, config, tests, stories in the same folder as the component using them
Applied to files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Applied to files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.ts
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/*/src/components/{ui,ai-elements,react-flow}/*.tsx : Use kebab-case single files for shadcn/ui components (e.g., button.tsx, base-node.tsx) in src/components/ui/, src/components/ai-elements, and src/components/react-flow/
Applied to files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsx
🧬 Code graph analysis (3)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsx (3)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsx (1)
FileEditorContextMenu(19-197)apps/desktop/src/shared/detect-language.ts (1)
detectLanguage(1-61)apps/desktop/src/renderer/contexts/MonacoProvider.tsx (1)
MONACO_EDITOR_OPTIONS(107-120)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx (1)
packages/ui/src/components/ui/context-menu.tsx (9)
ContextMenu(237-237)ContextMenuTrigger(238-238)ContextMenuContent(239-239)ContextMenuItem(240-240)ContextMenuShortcut(245-245)ContextMenuSub(248-248)ContextMenuSubTrigger(250-250)ContextMenuSubContent(249-249)ContextMenuSeparator(244-244)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx (1)
apps/desktop/src/renderer/stores/tabs/actions/move-pane.ts (2)
movePaneToTab(21-77)movePaneToNewTab(79-137)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (12)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.ts (1)
1-1: LGTM!Clean re-export for the FileEditorContextMenu component.
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.ts (1)
1-2: LGTM!Clean re-exports with proper
export typefor type-only exports.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts (1)
1-2: LGTM!Properly exposes EditorContextMenu and its types from the shared components surface.
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsx (1)
164-196: LGTM!Clean composition of EditorContextMenu with all editor and pane actions properly wired.
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx (1)
44-47: LGTM on workspace tabs filtering.The
workspaceTabsfilter correctly scopes available tabs to the current workspace for move-to-tab functionality.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsx (1)
239-242: Good: Monaco context menu correctly disabled when custom menu is active.The
contextmenu: !contextMenuPropsoption properly disables Monaco's native context menu only when the custom context menu is provided.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsx (2)
242-274: LGTM!Clean integration of
FileEditorContextMenuwrapper around the Monaco Editor with all props correctly forwarded and native context menu properly disabled.
185-194: LGTM!Context menu props correctly forwarded to
DiffViewerfor consistent context menu behavior across both raw and diff views.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx (3)
36-70: LGTM! Well-designed interfaces with appropriate optional/required properties.The interfaces provide good flexibility with
onCopyas a required baseline action and other editor actions as optional, allowing the component to adapt to different editor contexts.
265-303: LGTM! Well-structured pane management actions with good UX considerations.The pane actions section is well-implemented:
- Conditional separator (line 289) improves visual clarity
- "New Tab" is always available even when no other tabs exist
- Destructive variant appropriately applied to "Close File"
- Proper key prop on mapped tab items
119-261: Verify that displayed keyboard shortcuts match Monaco editor's actual keybindings and resolve shortcut conflicts.The menu displays keyboard shortcuts that conflict with or diverge from Monaco's defaults. Go to Definition shows
Cmd+F12but Monaco's actual default isF12(without modifier). Additionally,Shift+F12is used for both Go to References (line 130) and Peek References (line 160), creating a conflict. Other shortcuts like Go to Symbol (Cmd+Shift+O) and Change All Occurrences (Cmd+F2) also lack equivalent Monaco defaults. Verify all displayed shortcuts match Monaco's actual behavior, align with the application's actual keybindings, and resolve the duplicateShift+F12assignment.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx (1)
312-314: No action needed. The inline arrow functions are appropriate for this use case.
FileViewerContentis not memoized with React.memo, so the inline arrow functions at lines 312-314 create no performance issues. Without memoization, callback reference changes have no impact on component re-renders.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI Agents
In
@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx:
- Around line 81-84: Replace the deprecated navigator.platform logic in
EditorContextMenu: remove the navigator.platform checks and instead call
trpc.window.getPlatform.useQuery() (e.g., const { data: platform } =
trpc.window.getPlatform.useQuery()), then compute isMac as platform === "darwin"
and derive cmdKey from isMac; ensure you replace references to the old isMac and
cmdKey variables and remove any navigator.platform usage.
🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx (1)
56-64: Consider renaming to reflect mixed data and action properties.The
PaneActionsinterface contains both action callbacks (onSplitHorizontal, etc.) and data properties (currentTabId,availableTabs). Consider renaming toPaneActionsPropsor splitting into separate interfaces for clarity.🔎 Alternative structure
-export interface PaneActions { +export interface PaneActionsProps { onSplitHorizontal: () => void; onSplitVertical: () => void; onClosePane: () => void; currentTabId: string; availableTabs: Tab[]; onMoveToTab: (tabId: string) => void; onMoveToNewTab: () => void; }Or split into separate interfaces:
export interface PaneData { currentTabId: string; availableTabs: Tab[]; } export interface PaneActions { onSplitHorizontal: () => void; onSplitVertical: () => void; onClosePane: () => void; onMoveToTab: (tabId: string) => void; onMoveToNewTab: () => void; }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid usinganytype - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
One component per file - do not create multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Drizzle ORM for all database operations - never use raw SQL
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for formatting and linting - run at root level with
bun run lint:fixorbiome check --write
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (3)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx (3)
104-104: Review: Cut and Paste visibility are coupled.The
showCutPasteflag requires bothonCutandonPasteto be available. This means if only one is provided, neither will be shown. This is likely intentional for UI consistency, but verify this matches the desired behavior.Also applies to: 198-229
72-302: Well-structured component with good conditional rendering.The component implementation is clean and follows best practices:
- Proper conditional rendering prevents empty menu sections
- Tab filtering logic correctly excludes the current tab
- Consistent icon usage and keyboard shortcut display
- Type-safe implementation with no
anytypes- Follows coding guidelines (no Node.js imports, single component per file)
127-131: No action needed - shortcuts correctly reflect Monaco's default behavior.The keyboard shortcuts are correct as displayed. Monaco editor and VS Code both use
Shift+F12as the default shortcut for both "Go to References" and "Peek References" actions. This is intentional, not a duplicate or error.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.ts (1)
10-33: Add error handling for clipboard operations.The
navigator.clipboard.writeText()call can fail due to permissions, security context, or browser compatibility issues. Silent failures will leave users confused when the copy action appears to do nothing.🔎 Proposed fix with error handling
export function registerCopyPathLineAction( editor: Monaco.editor.IStandaloneCodeEditor, filePath: string, ) { editor.addAction({ id: "copy-path-line", label: "Copy Path:Line", keybindings: [ monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KeyC, ], - run: (ed) => { + run: async (ed) => { const selection = ed.getSelection(); if (!selection) return; const { startLineNumber, endLineNumber } = selection; const pathWithLine = startLineNumber === endLineNumber ? `${filePath}:${startLineNumber}` : `${filePath}:${startLineNumber}-${endLineNumber}`; - navigator.clipboard.writeText(pathWithLine); + try { + await navigator.clipboard.writeText(pathWithLine); + } catch (error) { + console.error("[editor-actions/copy-path-line] Failed to copy to clipboard:", error); + } }, }); }As per coding guidelines: "Never swallow errors silently - at minimum log them with context."
🤖 Fix all issues with AI Agents
In
@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.ts:
- Around line 53-77: Wrap every navigator.clipboard.writeText call in
handleCopyPath and handleCopyPathWithLine in a try/catch and log any caught
error with context (include the function name and the value attempted to copy,
e.g., filePath or pathWithLine); for handleCopyPathWithLine also log when editor
or selection is missing before returning. Use the existing console/error logging
mechanism (e.g., console.error) to record the error and the attempted text so
failures aren’t swallowed.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.ts
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsx
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid usinganytype - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Drizzle ORM for all database operations - never use raw SQL
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for formatting and linting - run at root level with
bun run lint:fixorbiome check --write
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
One component per file - do not create multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsx
🧠 Learnings (1)
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Applied to files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
🧬 Code graph analysis (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsx (4)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.ts (1)
registerCopyPathLineAction(3-3)apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsx (1)
FileEditorContextMenu(19-55)apps/desktop/src/shared/detect-language.ts (1)
detectLanguage(1-61)apps/desktop/src/renderer/contexts/MonacoProvider.tsx (1)
MONACO_EDITOR_OPTIONS(107-120)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (6)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts (1)
1-2: LGTM - Clean public API surface.The re-exports provide a clean component boundary for the EditorContextMenu module. This is an appropriate use of barrel files for defining public API surfaces.
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.ts (1)
16-171: Well-structured hook with consistent patterns.The hook is well-designed with:
- Proper use of
useCallbackfor memoization- Consistent pattern across all handlers (get editor → check → focus → trigger)
- Clean separation between clipboard, navigation, and editing actions
- Correct conditional inclusion of cut/paste based on
editableflagapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsx (2)
154-165: Good editor selection and action configuration.The
getEditorfallback logic correctly prioritizes the modified editor (where users typically make changes) and falls back to the original editor. Settingeditable: falseforuseEditorActionsis appropriate since diff viewers are read-only contexts where cut/paste operations should be handled by the underlying modified editor, not the diff viewer wrapper.
176-222: Clean conditional rendering with proper Monaco context menu handling.The implementation correctly:
- Extracts the
diffEditorJSX for reuse in both paths- Disables Monaco's native context menu when
contextMenuPropsis provided (line 197)- Uses early return pattern to avoid unnecessary nesting (lines 203-205)
- Wraps with
EditorContextMenuonly when context menu props are suppliedapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsx (2)
110-128: Correct editor initialization with copy-path action.The
handleEditorMountcallback properly registers both save and copy-path actions, and the dependency array correctly includesfilePathto ensure the copy-path action updates when the file changes.
250-284: Proper context menu integration with Monaco native menu disabled.The editor is correctly wrapped with
FileEditorContextMenuand Monaco's native context menu is properly disabled viacontextmenu: false(line 279) to prevent conflicts with the custom menu system.
- Add EditorContextMenu component with clipboard, file, and pane actions - Support Cut, Copy, Paste, Copy Path, Copy Path:Line - Add Change All Occurrences, Select All, Find actions - Include Split Horizontally/Vertically and Move to Tab options - Apply context menu to both file editor and diff viewer - Extract shared useEditorActions hook for reusability - Disable Monaco's native context menu when custom menu is active
5556789 to
8329148
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx:
- Around line 66-69: Replace the deprecated navigator.platform check in
EditorContextMenu with the app's tRPC window service: call the exposed platform
detection method (e.g. window.trpc.platform.isMac() or the equivalent used in
TopBar/StartTopBar) to set isMac, then derive cmdKey from that value and update
any surrounding logic to await or handle the service call if it’s asynchronous;
ensure you remove navigator.platform usage and mirror the same API shape the
other components use.
🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsx (1)
208-216: Consider simplifying the paneActions mapping.The
paneActionsobject is currently created by manually mapping each property fromcontextMenuProps. SinceDiffViewerContextMenuPropsandPaneActionshave identical structure, this can be simplified.🔎 Suggested simplification
- const paneActions: PaneActions = { - onSplitHorizontal: contextMenuProps.onSplitHorizontal, - onSplitVertical: contextMenuProps.onSplitVertical, - onClosePane: contextMenuProps.onClosePane, - currentTabId: contextMenuProps.currentTabId, - availableTabs: contextMenuProps.availableTabs, - onMoveToTab: contextMenuProps.onMoveToTab, - onMoveToNewTab: contextMenuProps.onMoveToNewTab, - }; + const paneActions: PaneActions = contextMenuProps;
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/useEditorActions.ts
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileViewerContent/FileViewerContent.tsx
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/editor-actions.ts
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/FileEditorContextMenu.tsx
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/FileViewerPane.tsx
- apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/FileEditorContextMenu/index.ts
🧰 Additional context used
📓 Path-based instructions (6)
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use object parameters for functions with 2+ parameters instead of positional arguments
Functions with 2+ parameters should accept a single params object with named properties for self-documentation and extensibility
Use prefixed console logging with context pattern: [domain/operation] message
Extract magic numbers and hardcoded values to named constants at module top
Use lookup objects/maps instead of repeated if (type === ...) conditionals
Avoid usinganytype - maintain type safety in TypeScript code
Never swallow errors silently - at minimum log them with context
Import from concrete files directly when possible - avoid barrel file abuse that creates circular dependencies
Avoid deep nesting (4+ levels) - use early returns, extract functions, and invert conditions
Use named properties in options objects instead of boolean parameters to avoid boolean blindness
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules (fs, path, os, net) in renderer process or shared code - they are externalized for browser compatibility
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
One component per file - do not create multi-component files
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
apps/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Drizzle ORM for all database operations - never use raw SQL
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for formatting and linting - run at root level with
bun run lint:fixorbiome check --write
Files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsxapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.tsapps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/index.ts
🧠 Learnings (3)
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/*/src/components/{ui,ai-elements,react-flow}/*.tsx : Use kebab-case single files for shadcn/ui components (e.g., button.tsx, base-node.tsx) in src/components/ui/, src/components/ai-elements, and src/components/react-flow/
Applied to files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`
Applied to files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx
📚 Learning: 2026-01-02T06:50:28.671Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-02T06:50:28.671Z
Learning: Applies to apps/*/src/components/**/*.{ts,tsx} : Co-locate component dependencies: utils, hooks, constants, config, tests, stories in the same folder as the component using them
Applied to files:
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/index.ts
🧬 Code graph analysis (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx (1)
packages/ui/src/components/ui/context-menu.tsx (9)
ContextMenu(237-237)ContextMenuTrigger(238-238)ContextMenuContent(239-239)ContextMenuItem(240-240)ContextMenuShortcut(245-245)ContextMenuSeparator(244-244)ContextMenuSub(248-248)ContextMenuSubTrigger(250-250)ContextMenuSubContent(249-249)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
🔇 Additional comments (4)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/ChangesContent/components/DiffViewer/DiffViewer.tsx (2)
154-165: LGTM! Clean integration of editor actions.The
getEditorcallback correctly prioritizes the modified editor and falls back to the original editor, and theuseEditorActionshook is properly configured witheditable: falsefor the diff viewer's read-only context.
197-197: LGTM! Correctly disables Monaco's native menu.The
contextmenuoption correctly disables Monaco's built-in context menu when custom context menu props are provided, preventing conflicting menus.apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx (2)
30-49: LGTM! Well-structured interface definitions.The
EditorActionsandPaneActionsinterfaces have clear separation of concerns. The required vs. optional distinction inEditorActions(e.g.,onCopyrequired butonCut/onPasteoptional) correctly reflects read-only contexts where clipboard modifications may not apply.
84-188: LGTM! Clean menu structure with good UX patterns.The context menu implementation has well-organized sections (clipboard, editor, pane actions) with appropriate conditional rendering. The
targetTabsfiltering correctly excludes the current tab, and the keyboard shortcuts match platform conventions using the computedcmdKey.
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
Summary
EditorContextMenucomponent for reuse across editor typesFeatures
Monaco Editor Actions:
Pane Management (matching terminal panes):
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.