| ... | @@ -294,7 +294,10 @@ import { | ... | @@ -294,7 +294,10 @@ import { |
| 294 | import { cn, randomUUID } from "~/lib/utils"; | 294 | import { cn, randomUUID } from "~/lib/utils"; |
| 295 | import { COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS } from "~/workspaceTitlebar"; | 295 | import { COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS } from "~/workspaceTitlebar"; |
| 296 | import { stackedThreadToast, toastManager } from "./ui/toast"; | 296 | import { stackedThreadToast, toastManager } from "./ui/toast"; |
| 297 | import { decodeProjectScriptKeybindingRule } from "~/lib/projectScriptKeybindings"; | 297 | import { |
| | 298 | decodeProjectScriptKeybindingRule, |
| | 299 | keybindingValueForCommand, |
| | 300 | } from "~/lib/projectScriptKeybindings"; |
| 298 | import { type NewProjectScriptInput } from "./ProjectScriptsControl"; | 301 | import { type NewProjectScriptInput } from "./ProjectScriptsControl"; |
| 299 | import { | 302 | import { |
| 300 | buildProjectScript, | 303 | buildProjectScript, |
| ... | @@ -1534,6 +1537,9 @@ export default function ChatView(props: ChatViewProps) { | ... | @@ -1534,6 +1537,9 @@ export default function ChatView(props: ChatViewProps) { |
| 1534 | const upsertKeybinding = useAtomCommand(serverEnvironment.upsertKeybinding, { | 1537 | const upsertKeybinding = useAtomCommand(serverEnvironment.upsertKeybinding, { |
| 1535 | reportFailure: false, | 1538 | reportFailure: false, |
| 1536 | }); | 1539 | }); |
| | 1540 | const removeKeybinding = useAtomCommand(serverEnvironment.removeKeybinding, { |
| | 1541 | reportFailure: false, |
| | 1542 | }); |
| 1537 | const openTerminal = useAtomCommand(terminalEnvironment.open, "terminal open"); | 1543 | const openTerminal = useAtomCommand(terminalEnvironment.open, "terminal open"); |
| 1538 | const writeTerminal = useAtomCommand(terminalEnvironment.write, "terminal write"); | 1544 | const writeTerminal = useAtomCommand(terminalEnvironment.write, "terminal write"); |
| 1539 | const closeTerminalMutation = useAtomCommand(terminalEnvironment.close, "terminal close"); | 1545 | const closeTerminalMutation = useAtomCommand(terminalEnvironment.close, "terminal close"); |
| ... | @@ -4940,20 +4946,64 @@ export default function ChatView(props: ChatViewProps) { | ... | @@ -4940,20 +4946,64 @@ export default function ChatView(props: ChatViewProps) { |
| 4940 | command: input.keybindingCommand, | 4946 | command: input.keybindingCommand, |
| 4941 | }); | 4947 | }); |
| 4942 | | 4948 | |
| 4943 | if (isElectron && keybindingRule) { | 4949 | if (!isElectron) return updateResult; |
| 4944 | return mapAtomCommandResult( | 4950 | |
| 4945 | await upsertKeybinding({ | 4951 | const scriptId = input.keybindingCommand |
| 4946 | environmentId, | 4952 | ? projectScriptIdFromCommand(input.keybindingCommand) |
| 4947 | input: keybindingRule, | 4953 | : null; |
| 4948 | }), | 4954 | if (!keybindingRule && !input.previousScripts.some((script) => script.id === scriptId)) { |
| 4949 | () => undefined, | 4955 | return updateResult; |
| 4950 | ); | | |
| 4951 | } | 4956 | } |
| 4952 | return updateResult; | 4957 | const retainedElsewhere = |
| | 4958 | !input.nextScripts.some((script) => script.id === scriptId) && |
| | 4959 | (settings.defaultProjectScripts.some((script) => script.id === scriptId) || |
| | 4960 | Object.entries(settings.projectSettingsOverrides).some( |
| | 4961 | ([projectId, entry]) => |
| | 4962 | projectId !== input.projectId && |
| | 4963 | entry.defaultProjectScripts?.some((script) => script.id === scriptId), |
| | 4964 | ) || |
| | 4965 | allProjects.some( |
| | 4966 | (other) => |
| | 4967 | other.environmentId === environmentId && |
| | 4968 | other.id !== input.projectId && |
| | 4969 | resolveProjectScripts(settings, other).some((script) => script.id === scriptId), |
| | 4970 | )); |
| | 4971 | if (!keybindingRule && retainedElsewhere) return updateResult; |
| | 4972 | |
| | 4973 | const previousRules = ( |
| | 4974 | environmentById.get(environmentId)?.serverConfig?.keybindings ?? [] |
| | 4975 | ).flatMap((binding) => { |
| | 4976 | if (binding.command !== input.keybindingCommand || binding.whenAst) return []; |
| | 4977 | const previous = decodeProjectScriptKeybindingRule({ |
| | 4978 | keybinding: keybindingValueForCommand([binding], input.keybindingCommand), |
| | 4979 | command: input.keybindingCommand, |
| | 4980 | }); |
| | 4981 | return previous ? [previous] : []; |
| | 4982 | }); |
| | 4983 | const previous = previousRules.at(-1); |
| | 4984 | for (const rule of keybindingRule ? previousRules.slice(0, -1) : previousRules) { |
| | 4985 | const result = await removeKeybinding({ environmentId, input: rule }); |
| | 4986 | if (result._tag === "Failure") return mapAtomCommandResult(result, () => undefined); |
| | 4987 | } |
| | 4988 | return keybindingRule |
| | 4989 | ? mapAtomCommandResult( |
| | 4990 | await upsertKeybinding({ |
| | 4991 | environmentId, |
| | 4992 | input: |
| | 4993 | previous && previous.key !== keybindingRule.key |
| | 4994 | ? { ...keybindingRule, replace: previous } |
| | 4995 | : keybindingRule, |
| | 4996 | }), |
| | 4997 | () => undefined, |
| | 4998 | ) |
| | 4999 | : updateResult; |
| 4953 | }, | 5000 | }, |
| 4954 | [ | 5001 | [ |
| | 5002 | allProjects, |
| | 5003 | environmentById, |
| 4955 | environmentId, | 5004 | environmentId, |
| 4956 | settings.projectSettingsOverrides, | 5005 | removeKeybinding, |
| | 5006 | settings, |
| 4957 | supportsProjectSettingsOverrides, | 5007 | supportsProjectSettingsOverrides, |
| 4958 | updateProjectScriptSettings, | 5008 | updateProjectScriptSettings, |
| 4959 | upsertKeybinding, | 5009 | upsertKeybinding, |