1- local M = {}
2-
31local C = {}
42
3+ --- @class Sorter
4+ local Sorter = {}
5+
6+ function Sorter :new (opts )
7+ local o = {}
8+ setmetatable (o , self )
9+ self .__index = self
10+ o .config = vim .deepcopy (opts .sort )
11+
12+ if type (o .config .sorter ) == " function" then
13+ o .user = o .config .sorter
14+ end
15+ return o
16+ end
17+
518--- Predefined comparator, defaulting to name
619--- @param sorter string as per options
720--- @return function
8- local function get_comparator (sorter )
9- return C [sorter ] or C .name
21+ function Sorter :get_comparator (sorter )
22+ return function (a , b )
23+ return (C [sorter ] or C .name )(a , b , self .config )
24+ end
1025end
1126
1227--- Create a shallow copy of a portion of a list.
2742--- @param a Node
2843--- @param b Node
2944--- @return boolean | nil
30- local function folders_or_files_first (a , b )
31- if not (M . config . sort . folders_first or M . config . sort .files_first ) then
45+ local function folders_or_files_first (a , b , cfg )
46+ if not (cfg . folders_first or cfg .files_first ) then
3247 return
3348 end
3449
3550 if not a .nodes and b .nodes then
3651 -- file <> folder
37- return M . config . sort .files_first
52+ return cfg .files_first
3853 elseif a .nodes and not b .nodes then
3954 -- folder <> file
40- return not M . config . sort .files_first
55+ return not cfg .files_first
4156 end
4257end
4358
97112
98113--- Perform a merge sort using sorter option.
99114--- @param t table nodes
100- function M . sort (t )
101- if C .user then
115+ function Sorter : sort (t )
116+ if self .user then
102117 local t_user = {}
103118 local origin_index = {}
104119
@@ -115,9 +130,9 @@ function M.sort(t)
115130 table.insert (origin_index , n )
116131 end
117132
118- local predefined = C .user (t_user )
133+ local predefined = self .user (t_user )
119134 if predefined then
120- split_merge (t , 1 , # t , get_comparator (predefined ))
135+ split_merge (t , 1 , # t , self : get_comparator (predefined ))
121136 return
122137 end
123138
@@ -142,20 +157,20 @@ function M.sort(t)
142157
143158 split_merge (t , 1 , # t , mini_comparator ) -- sort by user order
144159 else
145- split_merge (t , 1 , # t , get_comparator (M .config . sort .sorter ))
160+ split_merge (t , 1 , # t , self : get_comparator (self .config .sorter ))
146161 end
147162end
148163
149164--- @param a Node
150165--- @param b Node
151166--- @param ignorecase boolean | nil
152167--- @return boolean
153- local function node_comparator_name_ignorecase_or_not (a , b , ignorecase )
168+ local function node_comparator_name_ignorecase_or_not (a , b , ignorecase , cfg )
154169 if not (a and b ) then
155170 return true
156171 end
157172
158- local early_return = folders_or_files_first (a , b )
173+ local early_return = folders_or_files_first (a , b , cfg )
159174 if early_return ~= nil then
160175 return early_return
161176 end
@@ -167,20 +182,20 @@ local function node_comparator_name_ignorecase_or_not(a, b, ignorecase)
167182 end
168183end
169184
170- function C .case_sensitive (a , b )
171- return node_comparator_name_ignorecase_or_not (a , b , false )
185+ function C .case_sensitive (a , b , cfg )
186+ return node_comparator_name_ignorecase_or_not (a , b , false , cfg )
172187end
173188
174- function C .name (a , b )
175- return node_comparator_name_ignorecase_or_not (a , b , true )
189+ function C .name (a , b , cfg )
190+ return node_comparator_name_ignorecase_or_not (a , b , true , cfg )
176191end
177192
178- function C .modification_time (a , b )
193+ function C .modification_time (a , b , cfg )
179194 if not (a and b ) then
180195 return true
181196 end
182197
183- local early_return = folders_or_files_first (a , b )
198+ local early_return = folders_or_files_first (a , b , cfg )
184199 if early_return ~= nil then
185200 return early_return
186201 end
@@ -199,17 +214,17 @@ function C.modification_time(a, b)
199214 return last_modified_b <= last_modified_a
200215end
201216
202- function C .suffix (a , b )
217+ function C .suffix (a , b , cfg )
203218 if not (a and b ) then
204219 return true
205220 end
206221
207222 -- directories go first
208- local early_return = folders_or_files_first (a , b )
223+ local early_return = folders_or_files_first (a , b , cfg )
209224 if early_return ~= nil then
210225 return early_return
211226 elseif a .nodes and b .nodes then
212- return C .name (a , b )
227+ return C .name (a , b , cfg )
213228 end
214229
215230 -- dotfiles go second
@@ -218,7 +233,7 @@ function C.suffix(a, b)
218233 elseif a .name :sub (1 , 1 ) ~= " ." and b .name :sub (1 , 1 ) == " ." then
219234 return false
220235 elseif a .name :sub (1 , 1 ) == " ." and b .name :sub (1 , 1 ) == " ." then
221- return C .name (a , b )
236+ return C .name (a , b , cfg )
222237 end
223238
224239 -- unsuffixed go third
@@ -230,7 +245,7 @@ function C.suffix(a, b)
230245 elseif a_suffix_ndx and not b_suffix_ndx then
231246 return false
232247 elseif not (a_suffix_ndx and b_suffix_ndx ) then
233- return C .name (a , b )
248+ return C .name (a , b , cfg )
234249 end
235250
236251 -- finally, compare by suffixes
@@ -242,18 +257,18 @@ function C.suffix(a, b)
242257 elseif not a_suffix and b_suffix then
243258 return false
244259 elseif a_suffix :lower () == b_suffix :lower () then
245- return C .name (a , b )
260+ return C .name (a , b , cfg )
246261 end
247262
248263 return a_suffix :lower () < b_suffix :lower ()
249264end
250265
251- function C .extension (a , b )
266+ function C .extension (a , b , cfg )
252267 if not (a and b ) then
253268 return true
254269 end
255270
256- local early_return = folders_or_files_first (a , b )
271+ local early_return = folders_or_files_first (a , b , cfg )
257272 if early_return ~= nil then
258273 return early_return
259274 end
@@ -267,18 +282,18 @@ function C.extension(a, b)
267282 local a_ext = (a .extension or " " ):lower ()
268283 local b_ext = (b .extension or " " ):lower ()
269284 if a_ext == b_ext then
270- return C .name (a , b )
285+ return C .name (a , b , cfg )
271286 end
272287
273288 return a_ext < b_ext
274289end
275290
276- function C .filetype (a , b )
291+ function C .filetype (a , b , cfg )
277292 local a_ft = vim .filetype .match { filename = a .name }
278293 local b_ft = vim .filetype .match { filename = b .name }
279294
280295 -- directories first
281- local early_return = folders_or_files_first (a , b )
296+ local early_return = folders_or_files_first (a , b , cfg )
282297 if early_return ~= nil then
283298 return early_return
284299 end
@@ -292,19 +307,10 @@ function C.filetype(a, b)
292307
293308 -- same filetype or both nil, sort by name
294309 if a_ft == b_ft then
295- return C .name (a , b )
310+ return C .name (a , b , cfg )
296311 end
297312
298313 return a_ft < b_ft
299314end
300315
301- function M .setup (opts )
302- M .config = {}
303- M .config .sort = opts .sort
304-
305- if type (M .config .sort .sorter ) == " function" then
306- C .user = M .config .sort .sorter
307- end
308- end
309-
310- return M
316+ return Sorter
0 commit comments