Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preserve files order in search #31

Open
basiliscos opened this issue Sep 13, 2017 · 8 comments
Open

preserve files order in search #31

basiliscos opened this issue Sep 13, 2017 · 8 comments

Comments

@basiliscos
Copy link

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...

@rgieseke
Copy link
Owner

Cool, I'll have a look!

@rgieseke
Copy link
Owner

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.

@basiliscos
Copy link
Author

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.

@rgieseke
Copy link
Owner

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?

@basiliscos
Copy link
Author

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...

@rgieseke
Copy link
Owner

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]

@basiliscos
Copy link
Author

Seems fine for me! Thanks!

@rgieseke
Copy link
Owner

Great, let me know if you discover any issues. Also not sure yet where and whether this should be default ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants