textredux
textredux copied to clipboard
preserve files order in search
There files (sorted) :
$ ls -1 core
buffer.lua
filteredlist.lua
indicator.lua
init.lua
list.lua
style.lua
ui.lua
when I type lua
, I'd like to have all that files, keeping the original.
With the proposed patch:
diff --git a/util/matcher.lua b/util/matcher.lua
index ddb2fbf..ebcd36b 100644
--- a/util/matcher.lua
+++ b/util/matcher.lua
@@ -161,6 +161,17 @@ end
-- @return A table of matcher functions, each taking a line as parameter and
-- returning a score (or nil for no match).
function M:_matchers_for_search(search_string)
+ print(search_string);
+ return {
+ function(line)
+ local start_pos, end_pos = string.find(line, search_string, 1, true)
+ if start_pos then
+ return 1, start_pos, end_pos, search_string
+ end
+ end
+ }
+
+--[[
local fuzzy = self.search_fuzzy
local fuzzy_penalty = self.fuzzy_score_penalty
local groups = {}
@@ -184,6 +195,7 @@ function M:_matchers_for_search(search_string)
end
end
return matchers
+]]
end
I can achive the same.
The default behaviour is a bit crazy: it sorts files by filename length.
ui.lua
list.lua
init.lua
style.lua
buffer.lua
indicator.lua
filteredlist.lua
it's very confusing. I'm also not sure how the current patch can be integrated...
Cool, I'll have a look!
I think the reason for this behaviour is that a match with a large overlap is considered to be better (thus the sorting by length). One give less weight to matches in the extension etc. but I don't see an easy solution here.
I agree that simply filtering out non-matches would be better for lists of files ... Maybe there is a way to apply this in the fs
sub-module.
I think would be nice to have some switcheable matching policy. The one I proposed can be named "simple_matcher", and the original one "score_match" (or "fuzzy_matcher").
If it is OK for you, I can refactor fs.lua
to let it have some variable with default policy, and make it tuneable.
I wouldn't mind if a open dialog always kept the order (so no need for both options).
Maybe it needs to be an option in list
- which is then checked in the matching function or somewhere else.
So one creates a list and can define whether it should keep order or not.
So like in list.lua
:
--- Whether searches are case insensitive or not.
-- It's possible to override this for a specific list by assigning another
-- value to the instance itself. The default value is `true`.
list.search_case_insensitive = true
--- Whether fuzzy searching should be in addition to explicit matches.
-- It's possible to override this for a specific list by assigning another
-- value to the instance itself. The default value is `true`.
list.search_fuzzy = true
something like list.keep_order
?
I got an impression that keep order is exclusive to scores, which lead to the result above; and it seems by scores the shorter names pop up...
Maybe something like this might work:
diff --git a/core/list.lua b/core/list.lua
index 798a114..f65dff0 100644
--- a/core/list.lua
+++ b/core/list.lua
@@ -73,6 +73,8 @@ list.search_case_insensitive = true
-- value to the instance itself. The default value is `true`.
list.search_fuzzy = true
+list.keep_order = true
+
--- List instance fields.
-- These can be set only for a list instance, and not globally for the module.
-- @section instance
@@ -151,7 +153,8 @@ function list:show()
matcher = util_matcher.new(
self.items,
self.search_case_insensitive,
- self.search_fuzzy
+ self.search_fuzzy,
+ self.keep_order
),
list = self
}
diff --git a/util/matcher.lua b/util/matcher.lua
index ddb2fbf..fe53bcb 100644
--- a/util/matcher.lua
+++ b/util/matcher.lua
@@ -20,10 +20,11 @@ Defaults to `true`.
@param search_fuzzy Whether fuzzy searching should be used in addition to
explicit matching. Defaults to `true`.
]]
-function M.new(candidates, search_case_insensitive, search_fuzzy)
+function M.new(candidates, search_case_insensitive, search_fuzzy, keep_order)
local m = {
search_case_insensitive = search_case_insensitive,
- search_fuzzy = search_fuzzy
+ search_fuzzy = search_fuzzy,
+ keep_order = keep_order
}
setmetatable(m, { __index = M })
m:_set_candidates(candidates)
@@ -105,13 +106,17 @@ function M:match(search)
for i, line in ipairs(lines) do
local score = match_score(line.text, matchers)
if score then
- matches[#matches + 1] = { index = line.index, score = score }
+ matches[#matches + 1] = { index = line.index, score = score, text = line.text }
matching_lines[#matching_lines + 1] = line
end
end
cache.lines[search] = matching_lines
- table.sort(matches, function(a ,b) return a.score < b.score end)
+ if self.keep_order then
+ table.sort(matches, function(a ,b) return a.text < b.text end)
+ else
+ table.sort(matches, function(a ,b) return a.score < b.score end)
+ end
local matching_candidates = {}
for _, match in ipairs(matches) do
matching_candidates[#matching_candidates + 1] = self.candidates[match.index]
Seems fine for me! Thanks!
Great, let me know if you discover any issues. Also not sure yet where and whether this should be default ...