@@ -31,111 +31,138 @@ import {
3131 RustRoverIcon ,
3232 WebStormIcon ,
3333} from "../JetBrainsIcons" ;
34- import { isMacPlatform , isWindowsPlatform } from "~/lib/utils" ;
34+ import { cn , isMacPlatform , isWindowsPlatform } from "~/lib/utils" ;
3535import { shellEnvironment } from "~/state/shell" ;
3636import { useAtomCommand } from "~/state/use-atom-command" ;
3737
38+ type OpenInOption = {
39+ label : string ;
40+ Icon : Icon ;
41+ value : EditorId ;
42+ kind : "brand" | "generic" ;
43+ } ;
44+
3845const resolveOptions = ( platform : string , availableEditors : ReadonlyArray < EditorId > ) => {
39- const baseOptions : ReadonlyArray < { label : string ; Icon : Icon ; value : EditorId } > = [
46+ const baseOptions : ReadonlyArray < OpenInOption > = [
4047 {
4148 label : "Cursor" ,
4249 Icon : CursorIcon ,
4350 value : "cursor" ,
51+ kind : "brand" ,
4452 } ,
4553 {
4654 label : "Trae" ,
4755 Icon : TraeIcon ,
4856 value : "trae" ,
57+ kind : "brand" ,
4958 } ,
5059 {
5160 label : "Kiro" ,
5261 Icon : KiroIcon ,
5362 value : "kiro" ,
63+ kind : "brand" ,
5464 } ,
5565 {
5666 label : "VS Code" ,
5767 Icon : VisualStudioCode ,
5868 value : "vscode" ,
69+ kind : "brand" ,
5970 } ,
6071 {
6172 label : "VS Code Insiders" ,
6273 Icon : VisualStudioCodeInsiders ,
6374 value : "vscode-insiders" ,
75+ kind : "brand" ,
6476 } ,
6577 {
6678 label : "VSCodium" ,
6779 Icon : VSCodium ,
6880 value : "vscodium" ,
81+ kind : "brand" ,
6982 } ,
7083 {
7184 label : "Zed" ,
7285 Icon : Zed ,
7386 value : "zed" ,
87+ kind : "brand" ,
7488 } ,
7589 {
7690 label : "Antigravity" ,
7791 Icon : AntigravityIcon ,
7892 value : "antigravity" ,
93+ kind : "brand" ,
7994 } ,
8095 {
8196 label : "IntelliJ IDEA" ,
8297 Icon : IntelliJIdeaIcon ,
8398 value : "idea" ,
99+ kind : "brand" ,
84100 } ,
85101 {
86102 label : "Aqua" ,
87103 Icon : AquaIcon ,
88104 value : "aqua" ,
105+ kind : "brand" ,
89106 } ,
90107 {
91108 label : "CLion" ,
92109 Icon : CLionIcon ,
93110 value : "clion" ,
111+ kind : "brand" ,
94112 } ,
95113 {
96114 label : "DataGrip" ,
97115 Icon : DataGripIcon ,
98116 value : "datagrip" ,
117+ kind : "brand" ,
99118 } ,
100119 {
101120 label : "DataSpell" ,
102121 Icon : DataSpellIcon ,
103122 value : "dataspell" ,
123+ kind : "brand" ,
104124 } ,
105125 {
106126 label : "GoLand" ,
107127 Icon : GoLandIcon ,
108128 value : "goland" ,
129+ kind : "brand" ,
109130 } ,
110131 {
111132 label : "PhpStorm" ,
112133 Icon : PhpStormIcon ,
113134 value : "phpstorm" ,
135+ kind : "brand" ,
114136 } ,
115137 {
116138 label : "PyCharm" ,
117139 Icon : PyCharmIcon ,
118140 value : "pycharm" ,
141+ kind : "brand" ,
119142 } ,
120143 {
121144 label : "Rider" ,
122145 Icon : RiderIcon ,
123146 value : "rider" ,
147+ kind : "brand" ,
124148 } ,
125149 {
126150 label : "RubyMine" ,
127151 Icon : RubyMineIcon ,
128152 value : "rubymine" ,
153+ kind : "brand" ,
129154 } ,
130155 {
131156 label : "RustRover" ,
132157 Icon : RustRoverIcon ,
133158 value : "rustrover" ,
159+ kind : "brand" ,
134160 } ,
135161 {
136162 label : "WebStorm" ,
137163 Icon : WebStormIcon ,
138164 value : "webstorm" ,
165+ kind : "brand" ,
139166 } ,
140167 {
141168 label : isMacPlatform ( platform )
@@ -145,12 +172,17 @@ const resolveOptions = (platform: string, availableEditors: ReadonlyArray<Editor
145172 : "Files" ,
146173 Icon : FolderClosedIcon ,
147174 value : "file-manager" ,
175+ kind : "generic" ,
148176 } ,
149177 ] ;
150178 const availableEditorSet = new Set ( availableEditors ) ;
151179 return baseOptions . filter ( ( option ) => availableEditorSet . has ( option . value ) ) ;
152180} ;
153181
182+ function getOpenInIconClass ( kind : OpenInOption [ "kind" ] ) {
183+ return cn ( kind === "brand" ? "text-foreground opacity-100" : "text-muted-foreground" ) ;
184+ }
185+
154186export const OpenInPicker = memo ( function OpenInPicker ( {
155187 environmentId,
156188 keybindings,
@@ -233,7 +265,21 @@ export const OpenInPicker = memo(function OpenInPicker({
233265 disabled = { ! preferredEditor || ! openInCwd }
234266 onClick = { ( ) => openInEditor ( preferredEditor ) }
235267 >
236- { primaryOption ?. Icon && < primaryOption . Icon aria-hidden = "true" className = "size-3.5" /> }
268+ { primaryOption ?. Icon && (
269+ < primaryOption . Icon
270+ aria-hidden = "true"
271+ className = { cn ( "size-3.5" , getOpenInIconClass ( primaryOption . kind ) ) }
272+ />
273+ ) }
274+ < span
275+ className = {
276+ compact
277+ ? "sr-only"
278+ : "sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5"
279+ }
280+ >
281+ Open
282+ </ span >
237283 </ Button >
238284 < GroupSeparator { ...( ! compact ? { className : "hidden @3xl/header-actions:block" } : { } ) } />
239285 < Menu >
@@ -250,9 +296,9 @@ export const OpenInPicker = memo(function OpenInPicker({
250296 </ MenuTrigger >
251297 < MenuPopup align = "end" >
252298 { options . length === 0 && < MenuItem disabled > No installed editors found</ MenuItem > }
253- { options . map ( ( { label, Icon, value } ) => (
299+ { options . map ( ( { label, Icon, value, kind } ) => (
254300 < MenuItem key = { value } onClick = { ( ) => openInEditor ( value ) } >
255- < Icon aria-hidden = "true" className = "text-muted-foreground" />
301+ < Icon aria-hidden = "true" className = { getOpenInIconClass ( kind ) } />
256302 { label }
257303 { value === preferredEditor && openFavoriteEditorShortcutLabel && (
258304 < MenuShortcut > { openFavoriteEditorShortcutLabel } </ MenuShortcut >
0 commit comments