fix(tui): keep slash completion alive after a leading command
Typing a second slash command went dead whenever the message started with one: `/work /cle` offered nothing while `do /work then /cle` completed fine, which reads as an intermittent glitch rather than a rule. Only the first slash can be an invocation, so detect the inline shape first. The leading-command branch claimed the whole line and handed it to the backend's completer, which has nothing to say about a slash sitting in a command's argument tail. The inline trigger requires a whitespace-preceded slash at the caret, so ordinary argument completion (`/cron ad`, `/personality alic`) is untouched — it fires only where completion was already dead.
This commit is contained in:
parent
609cd28b17
commit
40ec9834b2
|
|
@ -64,6 +64,28 @@ describe('completionRequestForInput — inline skill references', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('completes a second slash in a line that starts with a command', () => {
|
||||
// Only the first slash is an invocation. Routing the whole line to the
|
||||
// completer offered nothing, so `/work /cle` went dead while
|
||||
// `do /work then /cle` completed fine.
|
||||
expect(completionRequestForInput('/work /cle')).toMatchObject({
|
||||
method: 'complete.slash',
|
||||
params: { text: '/cle' },
|
||||
replaceFrom: 7,
|
||||
skillsOnly: true
|
||||
})
|
||||
})
|
||||
|
||||
it('leaves a command own arguments to the command', () => {
|
||||
for (const input of ['/personality alic', '/cron ad', '/details ']) {
|
||||
expect(completionRequestForInput(input)).toEqual({
|
||||
method: 'complete.slash',
|
||||
params: { text: input },
|
||||
replaceFrom: 1
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('routes a real mid-message path to path completion, not skills', () => {
|
||||
expect(completionRequestForInput('open src/foo/ba')).toMatchObject({ method: 'complete.path' })
|
||||
expect(completionRequestForInput('open /usr/lo')).toMatchObject({ method: 'complete.path' })
|
||||
|
|
|
|||
|
|
@ -41,15 +41,13 @@ export function completionRequestForInput(
|
|||
return null
|
||||
}
|
||||
|
||||
if (isSlashCommand) {
|
||||
return { method: 'complete.slash', params: { text: input }, replaceFrom: 1 }
|
||||
}
|
||||
|
||||
// A `/token` mid-message is a skill reference dropped into prose. It's only
|
||||
// reachable here because the path branch below would otherwise claim it: a
|
||||
// bare `/cle` matches TAB_PATH_RE as an absolute path. Skills win that tie —
|
||||
// the moment a second `/` is typed the inline trigger stops matching and
|
||||
// path completion takes back over.
|
||||
// A `/token` mid-message is a skill reference dropped into prose. Detected
|
||||
// BEFORE the leading-command shape because only the first slash can be an
|
||||
// invocation — `/help /cle` is a command whose argument names a skill, and
|
||||
// routing the whole line to the backend's completer offered nothing at all.
|
||||
// It only matches a whitespace-preceded slash sitting at the caret, so
|
||||
// ordinary argument completion (`/cron ad`, `/personality alic`) is
|
||||
// untouched.
|
||||
const inline = inlineSlashTrigger(input)
|
||||
|
||||
if (inline) {
|
||||
|
|
@ -61,6 +59,10 @@ export function completionRequestForInput(
|
|||
}
|
||||
}
|
||||
|
||||
if (isSlashCommand) {
|
||||
return { method: 'complete.slash', params: { text: input }, replaceFrom: 1 }
|
||||
}
|
||||
|
||||
if (!pathWord) {
|
||||
return null
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue