Skip to content

Commit 109ca46

Browse files
committed
feat: support fig deprecated flag
1 parent 5c8f32e commit 109ca46

File tree

4 files changed

+43
-40
lines changed

4 files changed

+43
-40
lines changed

src/main/utils/completion.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,25 @@ function getFigSuggestionType(spec: Fig.Suggestion): CommandCompletion['type'] {
102102
}
103103
}
104104

105-
function transformFigSuggestion(raw: string | Fig.Suggestion, query: string) {
105+
function transformFigSuggestion(raw: string | Fig.Suggestion, query: string, strict?: boolean) {
106106
const spec = typeof raw === 'string' ? { name: raw } : raw
107-
const values = getFigValues(spec)
107+
if (spec.hidden) return []
108+
let values = getFigValues(spec)
109+
if (strict) {
110+
values = values.filter(value => value.startsWith(query))
111+
}
108112
return values.map<CommandCompletion>(value => ({
109113
type: getFigSuggestionType(spec),
110114
query: spec._internal?.commasCompletionQuery as string | undefined ?? query,
111115
value,
112116
label: spec.displayName,
113117
description: spec.description,
118+
deprecated: Boolean(spec.deprecated),
114119
}))
115120
}
116121

117122
function transformFigSubcommand(spec: Fig.Subcommand, query: string) {
123+
if (spec.hidden) return []
118124
const values = getFigValues(spec)
119125
return values.map<CommandCompletion>(value => ({
120126
type: 'command',
@@ -124,10 +130,12 @@ function transformFigSubcommand(spec: Fig.Subcommand, query: string) {
124130
spec.insertValue ? undefined : getFigArgsLabel(spec, value)
125131
),
126132
description: spec.description,
133+
deprecated: Boolean(spec.deprecated),
127134
}))
128135
}
129136

130137
function transformFigOption(spec: Fig.Option, query: string) {
138+
if (spec.hidden) return []
131139
const values = getFigValues(spec)
132140
return values.map<CommandCompletion>(value => ({
133141
type: 'command',
@@ -137,6 +145,7 @@ function transformFigOption(spec: Fig.Option, query: string) {
137145
spec.insertValue ? undefined : getFigArgsLabel(spec, value)
138146
),
139147
description: spec.description,
148+
deprecated: Boolean(spec.deprecated),
140149
}))
141150
}
142151

@@ -164,16 +173,16 @@ async function getFigCompletions(
164173
if (!('name' in spec)) return []
165174
const asyncCompletions: (CommandCompletion[] | Promise<CommandCompletion[]>)[] = []
166175
const options = spec.options ?? []
167-
// Suggestions or args (suggestions if no argv, args else)
168-
if (!args.length || args.length === 1 && args[0] === '') {
169-
const suggestions = [
170-
...normalizeArray(spec.args).flatMap(arg => arg.suggestions ?? []),
171-
...(spec.additionalSuggestions ?? []),
172-
]
173-
asyncCompletions.push(
174-
suggestions.flatMap(suggestion => transformFigSuggestion(suggestion, query)),
175-
)
176-
} else {
176+
// Suggestions
177+
const suggestions = [
178+
...normalizeArray(spec.args).flatMap(arg => arg.suggestions ?? []),
179+
...(spec.additionalSuggestions ?? []),
180+
]
181+
asyncCompletions.push(
182+
suggestions.flatMap(suggestion => transformFigSuggestion(suggestion, query, true)),
183+
)
184+
// Option args
185+
if (args.length > 1) {
177186
// Option args since option spec will not pass to `getFigCompletions`
178187
const previousArg = args[args.length - 2]
179188
const inputtingOption = options.find(item => {

src/renderer/components/TerminalTeletype.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ function scrollToStickyCommand() {
218218
</span>
219219
<span
220220
v-else
221-
:class="['completion-item-label', { 'is-pending': item.state === 'pending' }]"
221+
class="completion-item-label"
222222
>
223223
<span
224224
v-if="item.value"
225-
class="completion-item-value"
225+
:class="['completion-item-value', { 'is-deprecated': item.deprecated }]"
226226
v-html="highlight(item.value, item.query)"
227227
></span>
228228
<span v-if="item.label" class="completion-item-suffix">{{ suffix(item.label, item.value) }}</span>
@@ -424,6 +424,11 @@ function scrollToStickyCommand() {
424424
text-overflow: ellipsis;
425425
overflow: hidden;
426426
}
427+
.completion-item-value {
428+
&.is-deprecated {
429+
text-decoration: line-through;
430+
}
431+
}
427432
.completion-item-suffix {
428433
flex: 1;
429434
min-width: 0;

src/renderer/utils/shell-integration.ts

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -80,29 +80,15 @@ function updateDecorationElement(decoration: IDecoration, callback: (el: HTMLEle
8080
}
8181
}
8282

83-
const completionTypePriority: Record<NonNullable<CommandCompletion['type']>, number> = {
84-
'third-party': 0,
85-
recommendation: 1,
86-
history: 2,
87-
directory: 3,
88-
file: 4,
89-
command: 5,
90-
default: Infinity,
91-
}
92-
93-
const completionTypeOrder = Object.entries(completionTypePriority)
94-
.sort((a, b) => a[1] - b[1])
95-
.map(([type, priority]) => type)
96-
97-
function determineCompletionType(
98-
a: CommandCompletion['type'],
99-
b: CommandCompletion['type'],
100-
): NonNullable<CommandCompletion['type']> {
101-
for (const type of completionTypeOrder) {
102-
if (a === type || b === type) return type
103-
}
104-
return 'default'
105-
}
83+
const orderedCompletionTypes = [
84+
'third-party',
85+
'recommendation',
86+
'history',
87+
'directory',
88+
'file',
89+
'command',
90+
'default',
91+
] as const
10692

10793
function filterAndSortCompletions(completions: CommandCompletion[]) {
10894
const duplicatedTimes: (Pick<CommandCompletion, 'value' | 'query'> & { times: number })[] = []
@@ -132,10 +118,12 @@ function filterAndSortCompletions(completions: CommandCompletion[]) {
132118
})
133119
}
134120
const existingItem = deduplicatedCompletions[existingIndex]
135-
const replacement = {
121+
const replacement: CommandCompletion = {
136122
...existingItem,
137-
type: determineCompletionType(existingItem.type, completion.type),
138-
description: existingItem.description || completion.description,
123+
type: orderedCompletionTypes.find(type => (existingItem.type === type || completion.type === type)) ?? 'default',
124+
label: existingItem.label ?? completion.label,
125+
description: existingItem.description ?? completion.description,
126+
deprecated: existingItem.deprecated ?? completion.deprecated,
139127
}
140128
deduplicatedCompletions.splice(existingIndex, 1, replacement)
141129
}

src/types/terminal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export interface CommandCompletion {
8888
description?: string,
8989
state?: 'pending' | 'loading',
9090
key?: string,
91+
deprecated?: boolean,
9192
}
9293

9394
export interface TerminalTabPosition {

0 commit comments

Comments
 (0)