@@ -11,6 +11,7 @@ import * as result from 'result';
1111import * as search from 'dialog_search' ;
1212import * as launch from 'launcher_service' ;
1313import * as plugins from 'launcher_plugins' ;
14+ import * as levenshtein from 'levenshtein' ;
1415
1516import type { ShellWindow } from 'window' ;
1617import type { Ext } from 'extension' ;
@@ -90,15 +91,13 @@ export class Launcher extends search.Search {
9091 return needles . every ( ( n ) => hay . includes ( n ) ) ;
9192 } ;
9293
93- let apps : Array < launch . SearchOption > = new Array ( ) ;
94-
9594 // Filter matching windows
9695 for ( const window of ext . tab_list ( Meta . TabList . NORMAL , null ) ) {
9796 const retain = contains_pattern ( window . name ( ext ) , needles )
9897 || contains_pattern ( window . meta . get_title ( ) , needles ) ;
9998
10099 if ( retain ) {
101- apps . push ( window_selection ( ext , window , this . icon_size ( ) ) )
100+ this . options . push ( window_selection ( ext , window , this . icon_size ( ) ) )
102101 }
103102 }
104103
@@ -113,7 +112,7 @@ export class Launcher extends search.Search {
113112 if ( retain ) {
114113 const generic = app . generic_name ( ) ;
115114
116- apps . push ( new launch . SearchOption (
115+ this . options . push ( new launch . SearchOption (
117116 app . name ( ) ,
118117 generic ? generic + " — " + where : where ,
119118 'application-default-symbolic' ,
@@ -125,19 +124,26 @@ export class Launcher extends search.Search {
125124 }
126125
127126 // Sort the list of matched selections
128- apps . sort ( ( a , b ) => {
129- const a_name = a . title . toLowerCase ( ) ;
130- const b_name = b . title . toLowerCase ( ) ;
127+ this . options . sort ( ( a , b ) => {
128+ const a_name = a . title . toLowerCase ( )
129+ const b_name = b . title . toLowerCase ( )
131130
132131 const pattern_lower = pattern . toLowerCase ( )
133132
134- const a_includes = a_name . includes ( pattern_lower ) ;
135- const b_includes = b_name . includes ( pattern_lower ) ;
133+ let a_name_weight = levenshtein . compare ( pattern_lower , a_name )
136134
137- return ( ( a_includes && b_includes ) || ( ! a_includes && ! b_includes ) ) ? ( a_name > b_name ? 1 : 0 ) : a_includes ? - 1 : b_includes ? 1 : 0 ;
138- } ) ;
135+ let b_name_weight = levenshtein . compare ( pattern_lower , b_name )
136+
137+ if ( a . description ) {
138+ a_name_weight = Math . min ( a_name_weight , levenshtein . compare ( pattern_lower , a . description . toLowerCase ( ) ) )
139+ }
139140
140- for ( const app of apps ) this . options . push ( app )
141+ if ( b . description ) {
142+ b_name_weight = Math . min ( b_name_weight , levenshtein . compare ( pattern_lower , b . description . toLowerCase ( ) ) )
143+ }
144+
145+ return a_name_weight > b_name_weight ? 1 : 0
146+ } ) ;
141147
142148 // Truncate excess items from the list
143149 this . options . splice ( this . list_max ( ) ) ;
0 commit comments