Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
swarn committed Nov 9, 2020
1 parent b2d90c0 commit 4382f69
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 23 deletions.
29 changes: 6 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,11 @@ fzy.positions("amuser", "app/models/customer.rb") -- { 1, 5, 13, 14, 18, 19 }
-- ^ ^ ^^ ^^
```

`fzy` is case-insensitive by default, which can be disabled:

``` lua
fzy.match("acE", "abcde") -- true
fzy.match("acE", "abcde", true) -- false
fzy.positions("ABC", "abcA*B*C") -- {1, 2, 3}
-- ^^^
fzy.positions("ABC", "abcA*B*C", true) -- {4, 6, 8}
-- ^ ^ ^
```

NB: `score` and `positions` must be called with a `needle` that is a
NB: `score` and `positions` should only be called with a `needle` that is a
subsequence of the `haystack`, which you can check with the `has_match`
function.

The `positions` function returns two values, the array shown above and the same
score that `score` returns. If you need both values, it's more efficient to use
`positions`.

There are two libraries, `fzy_lua` with the Lua implementation and `fzy_native`
with the C implementation. When you use `require'fzy'`, it attempts to load the
native module; if that fails, it automatically substitutes the Lua
implementation.
See [the docs](docs/fzy.md) for more information.

## Testing

Expand All @@ -77,9 +59,10 @@ busted test/test.lua

## Thanks

John Hawthorn wrote the original `fzy`, and this code is *very* similar to
his `fzy.js` implementation.
John Hawthorn wrote the original `fzy`. The native implementation here is
basically his code with a few tweaks, and the lua implementation is derived
from his `fzy.js` implementation.

[Rom Grk](https://github.com/romgrk) made several useful suggestions, and has a
a [lua C implemenation](https://github.com/romgrk/fzy-lua-native) using
[lua C implemenation](https://github.com/romgrk/fzy-lua-native) using
the luajit `ffi` library.
124 changes: 124 additions & 0 deletions docs/fzy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# fzy-lua

A Lua module for the [fzy][] fuzzy string matching algorithm.

[fzy]: https://github.com/jhawthorn/fzy


## Summary

| function | description |
|-------------------------------|---------------------------------------------------|
| `has_match(needle, haystack)` | Check if `needle` is a subsequence of `haystack`. |
| `score(needle, haystack)` | Compute a matching score. |
| `positions(needle, haystack)` | Compute the locations where fzy matches a string. |
| `filter(needle, haystacks)` | Match many strings at once. |


## Functions

### `fzy.has_match(needle, haystack[, case_sensitive])`

Check if `needle` is a subsequence of `haystack.`

``` lua
> fzy.has_match("ab", "acB")
true
> fzy.has_match("ab", "ac")
false
> fzy.has_match("ab", "acB", true)
false
```

**Parameters**
* **needle** (*string*)
* **haystack** (*string*)
* **case_sensitive** (*bool, optional*) – defaults to false

**Returns**
* *bool*


### `fzy.score(needle, haystack[, case_sensitive])`

**Parameters**
* **needle** (*string*)
* **haystack** (*string*)
* **case_sensitive** (*bool, optional*) – defaults to false

**Returns**
* *number*, where higher numbers indicate better matches.


### `fzy.positions(needle, haystack[, case_sensitive])`

Determine where each character of the `needle` is matched to the `haystack` in
the optimal match.

``` lua
> p, s = fzy.positions("ab", "*a*b*b")
> require'pl.pretty'.write(p, '')
{2,4}
```

**Parameters**
* **needle** (*string*)
* **haystack** (*string*)
* **case_sensitive** (*bool, optional*) – defaults to false

**Returns**
* **indices** (*{int, ...}*), where `indices[n]` is the location of the `n`th
character of `needle` in `haystack`.
* **score** (*number*): the same matching score returned by `score`


### `fzy.filter(needle, haystacks[, case_sensitive])`

Apply the `has_match` and `positions` functions to an array of `haystacks`.
For large numbers of haystacks, this will have better performance than
iterating over the `haystacks` and calling those functions for each string.

``` lua
> a = fzy.filter('ab', {'*ab', 'b', 'a*b'})
> require'pl.pretty'.write(a, '')
{{1,{2,3},0.995},{3,{1,3},0.89}}
```

**Parameters**
* **needle** (*string*)
* **haystack** (*{string, ...}*)
* **case_sensitive** (*bool, optional*) – defaults to false

**Returns**
* *{{idx, positions, score}, ...}*, an array with one entry per matching line
in `haystacks`, each entry giving the index of the line in `haystacks` as
well as the equivalent to the return value of `positions` for that line.


## Special Values

`fzy.get_score_min()`: The lowest value returned by `score`, which is only returned
for an empty `needle`, or `haystack` larger than than `get_max_length`.

`fzy.get_score_max()`: The score returned for exact matches. This is the
highest possible score.

`fzy.get_max_length()`: The maximum size for which `fzy` will evaluate scores.

`fzy.get_score_floor()`: For matches that don't return `get_score_min`, their
score will be greater than than this value.

`fzy.get_score_ceiling()`: For matches that don't return `get_score_max`, their
score will be less than this value.

`fzy.get_implementation_name()`: The name of the currently-running
implementation, "lua" or "native".


### Implementations

The lua implementation of fzy is in `fzy_lua`, and the C implementation is in
`fzy_native`. When you `require('fzy')`, it automatically loads the native
version. If that fails, it will fall back on the lua version. This is transparent;
in either case, all functions will be available as `fzy.*`.

0 comments on commit 4382f69

Please sign in to comment.