@@ -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
89100class CompletionDialog {
0 commit comments