Skip to content

Commit e4e1f4d

Browse files
authored
Merge pull request #3 from overleaf/mj-unfiltered-at-end
Avoid re-arranging list of options when unfiltered results come in
2 parents 62d864f + 52f3f3c commit e4e1f4d

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

src/config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export interface CompletionConfig {
9090
/// displaying results from faster sources. Defaults to 100
9191
/// milliseconds.
9292
updateSyncTime?: number
93+
/// overleaf: Move unfiltered results after the filtered ones
94+
unfilteredResultsAtEnd?: boolean
9395
}
9496

9597
export const completionConfig = Facet.define<CompletionConfig, Required<CompletionConfig>>({
@@ -112,7 +114,9 @@ export const completionConfig = Facet.define<CompletionConfig, Required<Completi
112114
filterStrict: false,
113115
compareCompletions: (a, b) => a.label.localeCompare(b.label),
114116
interactionDelay: 75,
115-
updateSyncTime: 100
117+
updateSyncTime: 100,
118+
// overleaf: default to at top which is default CM6 behaviour
119+
unfilteredResultsAtEnd: false
116120
}, {
117121
defaultKeymap: (a, b) => a && b,
118122
closeOnBlur: (a, b) => a && b,

src/state.ts

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ function sortOptions(active: readonly ActiveSource[], state: EditorState) {
3333
let getMatch = a.result.getMatch
3434
if (a.result.filter === false) {
3535
for (let option of a.result.options) {
36-
addOption(new Option(option, a.source, getMatch ? getMatch(option) : [], 1e9 - options.length))
36+
let defaultScore = conf.unfilteredResultsAtEnd ? -1e9 : 1e9
37+
addOption(new Option(option, a.source, getMatch ? getMatch(option) : [], defaultScore - options.length))
3738
}
3839
} else {
3940
let pattern = state.sliceDoc(a.from, a.to), match
@@ -59,31 +60,41 @@ function sortOptions(active: readonly ActiveSource[], state: EditorState) {
5960
}
6061

6162
let result = [], prev = null
63+
const priorityIndices = new Map<string, number>()
6264
let compare = conf.compareCompletions
6365
for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
66+
// overleaf: Deduplicate results with dedup options
67+
// The goal is to keep only the highest priority option, in the
68+
// highest scoring position.
69+
const key = opt.completion.deduplicate?.key
70+
if (key) {
71+
// Handle merging specifically for deduplicated items item
72+
const currentOptionIndex = priorityIndices.get(key)
73+
if (currentOptionIndex === undefined) {
74+
priorityIndices.set(key, result.length)
75+
result.push(opt)
76+
prev = opt.completion
77+
} else {
78+
if (result[currentOptionIndex].completion.deduplicate.priority < opt.completion.deduplicate.priority) {
79+
result[currentOptionIndex] = opt
80+
if (currentOptionIndex === result.length - 1) {
81+
prev = opt.completion
82+
}
83+
}
84+
}
85+
continue
86+
}
87+
// overleaf: end
6488
let cur = opt.completion
6589
if (!prev || prev.label != cur.label) result.push(opt)
90+
// overleaf: we're already handling deduplication, so skip extra merges
91+
else if (prev.deduplicate) result.push(opt)
6692
else if (score(opt.completion) > score(prev)) result[result.length - 1] = opt
6793
else if (opt.completion.info) result[result.length - 1] = opt
6894
prev = opt.completion
6995
}
70-
// overleaf: Deduplicate results with dedup options
71-
const topPriorities = new Map<string, number>()
72-
for (const opt of result) {
73-
const key = opt.completion.deduplicate?.key
74-
if (!key) continue
75-
const currentPriority = topPriorities.get(key)
76-
if (currentPriority === undefined) {
77-
topPriorities.set(key, opt.completion.deduplicate.priority)
78-
} else {
79-
if (currentPriority < opt.completion.deduplicate.priority) {
80-
topPriorities.set(key, opt.completion.deduplicate.priority)
81-
}
82-
}
83-
}
84-
return result.filter(opt => opt.completion.deduplicate
85-
? topPriorities.get(opt.completion.deduplicate.key) === opt.completion.deduplicate.priority
86-
: true)
96+
97+
return result
8798
}
8899

89100
class CompletionDialog {

0 commit comments

Comments
 (0)