Repository navigation
fix(composer): an @ search stays open across spaces in a name #36337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
93ec082
6d46897
863cc11
3968727
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,8 @@ import { | |
| } from "../../state/use-composer-drafts"; | ||
| import { USAGE_LIMITS_COMMAND } from "@t3tools/shared/usageLimits"; | ||
| import { | ||
| composerItemAnswersTrigger, | ||
| continueComposerPathTrigger, | ||
| detectComposerTrigger, | ||
| replaceTextRange, | ||
| serializeComposerFileLink, | ||
|
|
@@ -329,19 +331,29 @@ export function useComposerCommandMenu({ | |
| setSelection(nextSelection); | ||
| }; | ||
|
|
||
| // The `@` search of the last render, which a space in this one continues. | ||
| const [carried, setCarried] = useState<{ | ||
| readonly ownerKey: string | null; | ||
| readonly trigger: ComposerTrigger | null; | ||
| }>({ ownerKey, trigger: null }); | ||
| const trigger = (() => { | ||
| if (!enabled || selection.start !== selection.end) { | ||
| return null; | ||
| } | ||
| return detectComposerTrigger(draftMessage, selection.end); | ||
| return continueComposerPathTrigger({ | ||
| text: draftMessage, | ||
| cursor: selection.end, | ||
| detected: detectComposerTrigger(draftMessage, selection.end), | ||
| previous: carried.ownerKey === ownerKey ? carried.trigger : null, | ||
| }); | ||
| })(); | ||
| const pathSearch = useComposerPathSearch({ | ||
| environmentId, | ||
| cwd: trigger?.kind === "path" ? projectCwd : null, | ||
| query: trigger?.kind === "path" ? trigger.query : null, | ||
| }); | ||
| // Mounts older settled threads matching the mention, which shells may leave out. | ||
| useThreadSearch( | ||
| const threadSearch = useThreadSearch( | ||
| trigger?.kind === "path" && environmentId ? [environmentId] : [], | ||
| trigger?.kind === "path" ? trigger.query : "", | ||
| { titlesOnly: true }, | ||
|
|
@@ -515,7 +527,7 @@ export function useComposerCommandMenu({ | |
| modelOptions && modelProviders | ||
| ? buildComposerModelItems(modelOptions, trigger.query, modelProviders) | ||
| : []; | ||
| return [ | ||
| const pathItems: ComposerCommandItem[] = [ | ||
| ...threadItems, | ||
| ...environmentItems, | ||
| ...modelItems, | ||
|
|
@@ -531,13 +543,35 @@ export function useComposerCommandMenu({ | |
| }; | ||
| }), | ||
| ]; | ||
| return pathItems.filter((item) => composerItemAnswersTrigger(item, trigger)); | ||
| } | ||
|
|
||
| return []; | ||
| })(); | ||
|
|
||
| // A query with a space ends once its search settles with nothing containing it, so prose | ||
| // after `@word` stops searching. A capped list waits for the next word instead. | ||
| const ruledOut = | ||
| trigger?.kind === "path" && | ||
| trigger.query.includes(" ") && | ||
| items.length === 0 && | ||
| !pathSearch.isPending && | ||
| !threadSearch.isPending && | ||
| !threadSearch.hasOlderRows && | ||
| !(pathSearch.truncated && trigger.query.endsWith(" ")); | ||
| const nextCarried = ruledOut ? null : trigger; | ||
|
Comment on lines
+559
to
+562
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clearing the carried trigger when the search settles drops older thread matches. When a spaced Keep the trigger until the matched rows reach the item source. Alternatively, build items from
|
||
| if ( | ||
| carried.ownerKey !== ownerKey || | ||
| carried.trigger?.kind !== nextCarried?.kind || | ||
| carried.trigger?.query !== nextCarried?.query || | ||
| carried.trigger?.rangeStart !== nextCarried?.rangeStart || | ||
| carried.trigger?.rangeEnd !== nextCarried?.rangeEnd | ||
| ) { | ||
| setCarried({ ownerKey, trigger: nextCarried }); | ||
| } | ||
|
|
||
| const onSelect = (item: ComposerCommandItem) => { | ||
| if (!trigger) return; | ||
| if (!trigger || !composerItemAnswersTrigger(item, trigger)) return; | ||
| if (item.type === "environment") { | ||
| if (!ownerKey || trigger.kind !== "path") return; | ||
| const record = environmentComposerContext(item.environmentId, item.label); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.