3 ms·
How are you highlighting the matching characters in the fuzzy search results? http://www.chris-granger.com/images/030/navigate.png http://www.chris-granger.com
by scottjad 14y ago
How are you highlighting the matching characters in the fuzzy search results?
http://www.chris-granger.com/images/030/navigate.png http://www.chris-granger.com/images/030/navigate.png
It looks like the same method I'm using in emacs/ido, which is to turn "la/clj" into
"(l).*?(a).*?(/).*?(c).*?(l).*?(j).*?"
I've found this technique gives inferior results to whatever SublimeText is doing. For example, in your hits with "langs", such as "lt/objs/langs/js.cljs" I think "lt/objs/langs/js.cljs" is more intuitive than the result you give of "lt/objs/langs/js.cljs". (Sorry for the hard to read italics)
For another example, on a search of "completions" I think your technique will highlight "hacks-completions" as "hacks-completions" instead of "hacks-completions".
Does anyone know if there's an easy way to modify the regex (not LightTable) and get the user-friendly results of Sublime Text?
- ibdknox 14y agoit's not currently configurable, but I agree that the highlighting should be more like that. Filed an issue to track it: https://github.com/Kodowa/Light-Table-Playground/issues/277 https://github.com/Kodowa/Light-Table-Playground/issues/277
- jules 14y agoTurn slashes into .*?(/).*? and leave the rest alone? If you don't want to treat slashes specially and want to allow "ab" to match "aqqqb" then I don't think you can do it without creating a giant regex. You can go for a modified longest common subsequence algorithm. Edit: here's how you can do it: // gives one point for each letter matched // plus an extra point if the next letter is also a match let rec scorematch = function | true::true::r -> 2 + scorematch (true::r) | true::r -> 1 + scorematch r | false::r -> scorematch r | [] -> 0 // find the match with best score let rec search xs ys = match (xs,ys) with | (x::xr, y::yr) -> let matches = [false::search xr ys; false::search xs yr] let matches = if x=y then (true::search xr yr)::matches else matches matches |> List.maxBy scorematch | _,ys -> List.map (fun _ -> false) ys let underline xs ys = search (List.ofSeq xs) (List.ofSeq ys) |> List.map (fun b -> if b then "-" else " ") |> String.Concat for x in ["foobarbaz"; "foobaXrbaz"; "foobXaXrbaz"; "foobXaXrbazr"] do Console.WriteLine x Console.WriteLine (underline "bar" x) For search term "bar" this outputs: foobarbaz --- foobaXrbaz -- - foobXaXrbaz - - - foobXaXrbazr -- - You'll want to memoize this or apply dynamic programming.
- scottjad 14y agoThank you!
- deleted 14y ago[deleted]
- martinced 14y ago"I've found this technique gives inferior results to whatever SublimeText is doing." Oh boy this one we're going to hear for a long time ain't we!?