mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-04-13 17:30:40 +08:00
feat(fzf): add bundle telescope fzf extension
This commit is contained in:
parent
297f58477b
commit
237ec35fd7
@ -50,6 +50,7 @@ function! SpaceVim#layers#telescope#plugins() abort
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/telescope-menu', {'merged' : 0}])
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/telescope-ctags-outline.nvim', {'merged' : 0}])
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/neoyank.vim', { 'merged' : 0}])
|
||||
call add(plugins, [g:_spacevim_root_dir . 'bundle/telescope-fzf-native.nvim', { 'merged' : 0}])
|
||||
return plugins
|
||||
endfunction
|
||||
|
||||
|
7
bundle/telescope-fzf-native.nvim/.clang-format
vendored
Normal file
7
bundle/telescope-fzf-native.nvim/.clang-format
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
IndentCaseLabels: false
|
||||
SortIncludes: false
|
||||
ColumnLimit: 80
|
||||
IndentWidth: 2
|
1
bundle/telescope-fzf-native.nvim/.github/FUNDING.yml
vendored
Normal file
1
bundle/telescope-fzf-native.nvim/.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
github: Conni2461
|
88
bundle/telescope-fzf-native.nvim/.github/workflows/ci.yml
vendored
Normal file
88
bundle/telescope-fzf-native.nvim/.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
gcc:
|
||||
name: c build and tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
compiler: gcc
|
||||
- os: ubuntu-20.04
|
||||
compiler: clang
|
||||
- os: macos-10.15
|
||||
compiler: gcc
|
||||
- os: macos-10.15
|
||||
compiler: clang
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Prepare
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
run: |
|
||||
cc --version
|
||||
git clone https://github.com/Conni2461/examiner
|
||||
cd examiner
|
||||
make && sudo make install
|
||||
- name: Build
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
LD_LIBRARY_PATH: /usr/lib:/usr/local/lib
|
||||
run: make
|
||||
- name: Tests
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
LD_LIBRARY_PATH: /usr/lib:/usr/local/lib
|
||||
run: make test
|
||||
|
||||
windows:
|
||||
name: windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: lukka/get-cmake@latest
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build --config Release
|
||||
cmake --install build --prefix build
|
||||
|
||||
nvim-tests:
|
||||
name: nvim-tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-10.15]
|
||||
include:
|
||||
- os: ubuntu-20.04
|
||||
url: https://github.com/neovim/neovim/releases/download/nightly/nvim-linux64.tar.gz
|
||||
- os: macos-10.15
|
||||
url: https://github.com/neovim/neovim/releases/download/nightly/nvim-macos.tar.gz
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: date +%F > todays-date
|
||||
- name: Restore cache for today's nightly.
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: _neovim
|
||||
key: ${{ matrix.os }}-${{ hashFiles('todays-date') }}
|
||||
- name: Prepare
|
||||
run: |
|
||||
test -d _neovim || {
|
||||
mkdir -p _neovim
|
||||
curl -sL ${{ matrix.url }} | tar xzf - --strip-components=1 -C "${PWD}/_neovim"
|
||||
}
|
||||
mkdir -p ~/.local/share/nvim/site/pack/vendor/start
|
||||
git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim
|
||||
ln -s $(pwd) ~/.local/share/nvim/site/pack/vendor/start
|
||||
- name: Build
|
||||
run: make
|
||||
- name: Tests
|
||||
run: |
|
||||
export PATH="${PWD}/_neovim/bin:${PATH}"
|
||||
export VIM="${PWD}/_neovim/share/nvim/runtime"
|
||||
nvim --version
|
||||
make ntest
|
42
bundle/telescope-fzf-native.nvim/.github/workflows/lint.yml
vendored
Normal file
42
bundle/telescope-fzf-native.nvim/.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: Linting and style checking
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install luarocks
|
||||
sudo luarocks install luacheck
|
||||
|
||||
- name: Lint
|
||||
run: make lint
|
||||
|
||||
clangformat:
|
||||
name: clangformat
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Prepare clang-format
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-format
|
||||
- name: Format
|
||||
run: make format
|
||||
|
||||
stylua:
|
||||
name: stylua
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: JohnnyMorganz/stylua-action@1.0.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# CLI arguments
|
||||
args: --color always --check lua/
|
4
bundle/telescope-fzf-native.nvim/.gitignore
vendored
Normal file
4
bundle/telescope-fzf-native.nvim/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
build/
|
||||
.cache/
|
||||
|
||||
compile_commands.json
|
16
bundle/telescope-fzf-native.nvim/.luacheckrc
vendored
Normal file
16
bundle/telescope-fzf-native.nvim/.luacheckrc
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
-- cache false so i don't need sudo upstream
|
||||
cache = false
|
||||
std = luajit
|
||||
codes = true
|
||||
self = false
|
||||
|
||||
-- Glorious list of warnings: https://luacheck.readthedocs.io/en/stable/warnings.html
|
||||
ignore = {
|
||||
"212", -- Unused argument, In the case of callback function, _arg_name is easier to understand than _, so this option is set to off.
|
||||
"122", -- Indirectly setting a readonly global
|
||||
}
|
||||
|
||||
-- Global objects defined by the C code
|
||||
read_globals = {
|
||||
"vim",
|
||||
}
|
6
bundle/telescope-fzf-native.nvim/.stylua.toml
vendored
Normal file
6
bundle/telescope-fzf-native.nvim/.stylua.toml
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
column_width = 120
|
||||
line_endings = "Unix"
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
quote_style = "AutoPreferDouble"
|
||||
call_parentheses = "None"
|
20
bundle/telescope-fzf-native.nvim/CMakeLists.txt
vendored
Normal file
20
bundle/telescope-fzf-native.nvim/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(fzf C)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED "src/fzf.c")
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
PREFIX "lib"
|
||||
C_STANDARD 99
|
||||
WINDOWS_EXPORT_ALL_SYMBOLS ON
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /W4)
|
||||
else ()
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wall)
|
||||
endif ()
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_BINARY_DIR})
|
21
bundle/telescope-fzf-native.nvim/LICENSE
vendored
Normal file
21
bundle/telescope-fzf-native.nvim/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Simon Hauser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
40
bundle/telescope-fzf-native.nvim/Makefile
vendored
Normal file
40
bundle/telescope-fzf-native.nvim/Makefile
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
CFLAGS = -Wall -Werror -fpic -std=gnu99
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
MKD = -mkdir
|
||||
RM = cmd /C rmdir /Q /S
|
||||
CC = gcc
|
||||
TARGET := libfzf.dll
|
||||
else
|
||||
MKD = mkdir -p
|
||||
RM = rm -rf
|
||||
TARGET := libfzf.so
|
||||
endif
|
||||
|
||||
all: build/$(TARGET)
|
||||
|
||||
build/$(TARGET): src/fzf.c src/fzf.h
|
||||
$(MKD) build
|
||||
$(CC) -O3 $(CFLAGS) -shared src/fzf.c -o build/$(TARGET)
|
||||
|
||||
build/test: build/$(TARGET) test/test.c
|
||||
$(CC) -Og -ggdb3 $(CFLAGS) test/test.c -o build/test -I./src -L./build -lfzf -lexaminer
|
||||
|
||||
.PHONY: lint format clangdhappy clean test ntest
|
||||
lint:
|
||||
luacheck lua
|
||||
|
||||
format:
|
||||
clang-format --style=file --dry-run -Werror src/fzf.c src/fzf.h test/test.c
|
||||
|
||||
test: build/test
|
||||
@LD_LIBRARY_PATH=${PWD}/build:${PWD}/examiner/build:${LD_LIBRARY_PATH} ./build/test
|
||||
|
||||
ntest:
|
||||
nvim --headless --noplugin -u test/minrc.vim -c "PlenaryBustedDirectory test/ { minimal_init = './test/minrc.vim' }"
|
||||
|
||||
clangdhappy:
|
||||
compiledb make
|
||||
|
||||
clean:
|
||||
$(RM) build
|
167
bundle/telescope-fzf-native.nvim/README.md
vendored
Normal file
167
bundle/telescope-fzf-native.nvim/README.md
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
# telescope-fzf-native.nvim
|
||||
|
||||
**fzf-native** is a `c` port of **[fzf][fzf]**. It only covers the algorithm and
|
||||
implements few functions to support calculating the score.
|
||||
|
||||
This means that the [fzf syntax](https://github.com/junegunn/fzf#search-syntax)
|
||||
is supported:
|
||||
|
||||
| Token | Match type | Description |
|
||||
| --------- | -------------------------- | ------------------------------------ |
|
||||
| `sbtrkt` | fuzzy-match | Items that match `sbtrkt` |
|
||||
| `'wild` | exact-match (quoted) | Items that include `wild` |
|
||||
| `^music` | prefix-exact-match | Items that start with `music` |
|
||||
| `.mp3$` | suffix-exact-match | Items that end with `.mp3` |
|
||||
| `!fire` | inverse-exact-match | Items that do not include `fire` |
|
||||
| `!^music` | inverse-prefix-exact-match | Items that do not start with `music` |
|
||||
| `!.mp3$` | inverse-suffix-exact-match | Items that do not end with `.mp3` |
|
||||
|
||||
A single bar character term acts as an OR operator. For example, the following
|
||||
query matches entries that start with `core` and end with either `go`, `rb`,
|
||||
or `py`.
|
||||
|
||||
```
|
||||
^core go$ | rb$ | py$
|
||||
```
|
||||
|
||||
This is an advantage over the more simpler `fzy` algorithm, which is also
|
||||
available for telescope (as native component or as lua component).
|
||||
|
||||
## Installation
|
||||
|
||||
To get **fzf-native** working, you need to build it with either `cmake` or `make`. As of now, we do not ship binaries.
|
||||
Both install methods will be supported going forward.
|
||||
|
||||
### CMake (Windows, Linux, MacOS)
|
||||
|
||||
This requires:
|
||||
|
||||
- CMake, and the Microsoft C++ Build Tools on Windows
|
||||
- CMake, make, and GCC or Clang on Linux and MacOS
|
||||
|
||||
#### vim-plug
|
||||
|
||||
```viml
|
||||
Plug 'nvim-telescope/telescope-fzf-native.nvim', { 'do': 'cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build' }
|
||||
```
|
||||
|
||||
#### packer.nvim
|
||||
|
||||
```lua
|
||||
use {'nvim-telescope/telescope-fzf-native.nvim', run = 'cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build' }
|
||||
```
|
||||
|
||||
### Make (Linux, MacOS, Windows with MinGW)
|
||||
|
||||
This requires `gcc` or `clang` and `make`
|
||||
|
||||
#### vim-plug
|
||||
|
||||
```viml
|
||||
Plug 'nvim-telescope/telescope-fzf-native.nvim', { 'do': 'make' }
|
||||
```
|
||||
|
||||
#### packer.nvim
|
||||
|
||||
```lua
|
||||
use {'nvim-telescope/telescope-fzf-native.nvim', run = 'make' }
|
||||
```
|
||||
|
||||
## Telescope Setup and Configuration:
|
||||
|
||||
```lua
|
||||
-- You dont need to set any of these options. These are the default ones. Only
|
||||
-- the loading is important
|
||||
require('telescope').setup {
|
||||
extensions = {
|
||||
fzf = {
|
||||
fuzzy = true, -- false will only do exact matching
|
||||
override_generic_sorter = true, -- override the generic sorter
|
||||
override_file_sorter = true, -- override the file sorter
|
||||
case_mode = "smart_case", -- or "ignore_case" or "respect_case"
|
||||
-- the default case_mode is "smart_case"
|
||||
}
|
||||
}
|
||||
}
|
||||
-- To get fzf loaded and working with telescope, you need to call
|
||||
-- load_extension, somewhere after setup function:
|
||||
require('telescope').load_extension('fzf')
|
||||
```
|
||||
|
||||
## Developer Interface
|
||||
|
||||
This section is only addressed towards developers who plan to use the library
|
||||
(c or lua bindings).
|
||||
This section is not addressed towards users of the telescope extension.
|
||||
|
||||
### C Interface
|
||||
|
||||
```c
|
||||
fzf_slab_t *slab = fzf_make_default_slab();
|
||||
/* fzf_case_mode enum : CaseSmart = 0, CaseIgnore, CaseRespect
|
||||
* normalize bool : always set to false because its not implemented yet.
|
||||
* This is reserved for future use
|
||||
* pattern char* : pattern you want to match. e.g. "src | lua !.c$
|
||||
* fuzzy bool : enable or disable fuzzy matching
|
||||
*/
|
||||
fzf_pattern_t *pattern = fzf_parse_pattern(CaseSmart, false, "src | lua !.c$", true);
|
||||
|
||||
/* you can get the score/position for as many items as you want */
|
||||
int score = fzf_get_score(line, pattern, slab);
|
||||
fzf_position_t *pos = fzf_get_positions(line, pattern, slab);
|
||||
|
||||
fzf_free_positions(pos);
|
||||
fzf_free_pattern(pattern);
|
||||
fzf_free_slab(slab);
|
||||
```
|
||||
|
||||
### Lua Interface
|
||||
|
||||
```lua
|
||||
local fzf = require('fzf_lib')
|
||||
|
||||
local slab = fzf.allocate_slab()
|
||||
-- pattern: string
|
||||
-- case_mode: number with 0 = smart_case, 1 = ignore_case, 2 = respect_case
|
||||
-- fuzzy: enable or disable fuzzy matching. default true
|
||||
local pattern_obj = fzf.parse_pattern(pattern, case_mode, fuzzy)
|
||||
|
||||
-- you can get the score/position for as many items as you want
|
||||
-- line: string
|
||||
-- score: number
|
||||
local score = fzf.get_score(line, pattern_obj, slab)
|
||||
|
||||
-- table (does not have to be freed)
|
||||
local pos = fzf.get_pos(line, pattern_obj, slab)
|
||||
|
||||
fzf.free_pattern(pattern_obj)
|
||||
fzf.free_slab(slab)
|
||||
```
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This projects implements **[fzf][fzf]** algorithm in c. So there might be
|
||||
differences in matching. I don't guarantee completeness.
|
||||
|
||||
### TODO
|
||||
|
||||
Stuff still missing that is present in **[fzf][fzf]**.
|
||||
|
||||
- [ ] normalize
|
||||
- [ ] case for unicode (i don't think this works currently)
|
||||
|
||||
## Benchmark
|
||||
|
||||
Comparison with fzy-native and fzy-lua with a table containing 240201 file
|
||||
strings. It calculated the score and position (if score > 0) for each of these
|
||||
strings with the pattern that is listed below:
|
||||
|
||||

|
||||

|
||||
|
||||
## Credit
|
||||
|
||||
All credit for the algorithm goes to junegunn and his work on **[fzf][fzf]**.
|
||||
This is merely a c fork distributed under MIT for telescope.
|
||||
|
||||
[fzf]: https://github.com/junegunn/fzf
|
85
bundle/telescope-fzf-native.nvim/lua/fzf_lib.lua
vendored
Normal file
85
bundle/telescope-fzf-native.nvim/lua/fzf_lib.lua
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
local ffi = require "ffi"
|
||||
|
||||
local library_path = (function()
|
||||
local dirname = string.sub(debug.getinfo(1).source, 2, #"/fzf_lib.lua" * -1)
|
||||
if package.config:sub(1, 1) == "\\" then
|
||||
return dirname .. "../build/libfzf.dll"
|
||||
else
|
||||
return dirname .. "../build/libfzf.so"
|
||||
end
|
||||
end)()
|
||||
local native = ffi.load(library_path)
|
||||
|
||||
ffi.cdef [[
|
||||
typedef struct {} fzf_i16_t;
|
||||
typedef struct {} fzf_i32_t;
|
||||
typedef struct {
|
||||
fzf_i16_t I16;
|
||||
fzf_i32_t I32;
|
||||
} fzf_slab_t;
|
||||
|
||||
typedef struct {} fzf_term_set_t;
|
||||
typedef struct {
|
||||
fzf_term_set_t **ptr;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
} fzf_pattern_t;
|
||||
typedef struct {
|
||||
uint32_t *data;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
} fzf_position_t;
|
||||
|
||||
fzf_position_t *fzf_get_positions(const char *text, fzf_pattern_t *pattern, fzf_slab_t *slab);
|
||||
void fzf_free_positions(fzf_position_t *pos);
|
||||
int32_t fzf_get_score(const char *text, fzf_pattern_t *pattern, fzf_slab_t *slab);
|
||||
|
||||
fzf_pattern_t *fzf_parse_pattern(int32_t case_mode, bool normalize, char *pattern, bool fuzzy);
|
||||
void fzf_free_pattern(fzf_pattern_t *pattern);
|
||||
|
||||
fzf_slab_t *fzf_make_default_slab(void);
|
||||
void fzf_free_slab(fzf_slab_t *slab);
|
||||
]]
|
||||
|
||||
local fzf = {}
|
||||
|
||||
fzf.get_score = function(input, pattern_struct, slab)
|
||||
return native.fzf_get_score(input, pattern_struct, slab)
|
||||
end
|
||||
|
||||
fzf.get_pos = function(input, pattern_struct, slab)
|
||||
local pos = native.fzf_get_positions(input, pattern_struct, slab)
|
||||
if pos == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local res = {}
|
||||
for i = 1, tonumber(pos.size) do
|
||||
res[i] = pos.data[i - 1] + 1
|
||||
end
|
||||
native.fzf_free_positions(pos)
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
fzf.parse_pattern = function(pattern, case_mode, fuzzy)
|
||||
case_mode = case_mode == nil and 0 or case_mode
|
||||
fuzzy = fuzzy == nil and true or fuzzy
|
||||
local c_str = ffi.new("char[?]", #pattern + 1)
|
||||
ffi.copy(c_str, pattern)
|
||||
return native.fzf_parse_pattern(case_mode, false, c_str, fuzzy)
|
||||
end
|
||||
|
||||
fzf.free_pattern = function(p)
|
||||
native.fzf_free_pattern(p)
|
||||
end
|
||||
|
||||
fzf.allocate_slab = function()
|
||||
return native.fzf_make_default_slab()
|
||||
end
|
||||
|
||||
fzf.free_slab = function(s)
|
||||
native.fzf_free_slab(s)
|
||||
end
|
||||
|
||||
return fzf
|
148
bundle/telescope-fzf-native.nvim/lua/telescope/_extensions/fzf.lua
vendored
Normal file
148
bundle/telescope-fzf-native.nvim/lua/telescope/_extensions/fzf.lua
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
local fzf = require "fzf_lib"
|
||||
local sorters = require "telescope.sorters"
|
||||
|
||||
local case_enum = setmetatable({
|
||||
["smart_case"] = 0,
|
||||
["ignore_case"] = 1,
|
||||
["respect_case"] = 2,
|
||||
}, {
|
||||
__index = function(_, k)
|
||||
error(string.format("%s is not a valid case mode", k))
|
||||
end,
|
||||
__newindex = function()
|
||||
error "Don't set new things"
|
||||
end,
|
||||
})
|
||||
|
||||
local get_fzf_sorter = function(opts)
|
||||
local case_mode = case_enum[opts.case_mode]
|
||||
local fuzzy_mode = opts.fuzzy == nil and true or opts.fuzzy
|
||||
local post_or = false
|
||||
local post_inv = false
|
||||
local post_escape = false
|
||||
|
||||
local get_struct = function(self, prompt)
|
||||
local struct = self.state.prompt_cache[prompt]
|
||||
if not struct then
|
||||
struct = fzf.parse_pattern(prompt, case_mode, fuzzy_mode)
|
||||
self.state.prompt_cache[prompt] = struct
|
||||
end
|
||||
return struct
|
||||
end
|
||||
|
||||
local clear_filter_fun = function(self, prompt)
|
||||
local filter = "^(" .. self._delimiter .. "(%S+)" .. "[" .. self._delimiter .. "%s]" .. ")"
|
||||
local matched = prompt:match(filter)
|
||||
|
||||
if matched == nil then
|
||||
return prompt
|
||||
end
|
||||
return prompt:sub(#matched + 1, -1)
|
||||
end
|
||||
|
||||
return sorters.Sorter:new {
|
||||
init = function(self)
|
||||
self.state.slab = fzf.allocate_slab()
|
||||
self.state.prompt_cache = {}
|
||||
|
||||
if self.filter_function then
|
||||
self.__highlight_prefilter = clear_filter_fun
|
||||
end
|
||||
end,
|
||||
destroy = function(self)
|
||||
for _, v in pairs(self.state.prompt_cache) do
|
||||
fzf.free_pattern(v)
|
||||
end
|
||||
self.state.prompt_cache = {}
|
||||
if self.state.slab ~= nil then
|
||||
fzf.free_slab(self.state.slab)
|
||||
self.state.slab = nil
|
||||
end
|
||||
end,
|
||||
start = function(self, prompt)
|
||||
local last = prompt:sub(-1, -1)
|
||||
|
||||
if last == "|" then
|
||||
self._discard_state.filtered = {}
|
||||
post_or = true
|
||||
elseif last == " " and post_or then
|
||||
self._discard_state.filtered = {}
|
||||
elseif post_or then
|
||||
self._discard_state.filtered = {}
|
||||
post_or = false
|
||||
else
|
||||
post_or = false
|
||||
end
|
||||
|
||||
if last == "\\" and not post_escape then
|
||||
self._discard_state.filtered = {}
|
||||
post_escape = true
|
||||
else
|
||||
self._discard_state.filtered = {}
|
||||
post_escape = false
|
||||
end
|
||||
|
||||
if last == "!" and not post_inv then
|
||||
post_inv = true
|
||||
self._discard_state.filtered = {}
|
||||
elseif post_inv then
|
||||
self._discard_state.filtered = {}
|
||||
elseif post_inv and " " then
|
||||
post_inv = false
|
||||
end
|
||||
end,
|
||||
discard = true,
|
||||
scoring_function = function(self, prompt, line)
|
||||
local obj = get_struct(self, prompt)
|
||||
local score = fzf.get_score(line, obj, self.state.slab)
|
||||
if score == 0 then
|
||||
return -1
|
||||
else
|
||||
return 1 / score
|
||||
end
|
||||
end,
|
||||
highlighter = function(self, prompt, display)
|
||||
if self.__highlight_prefilter then
|
||||
prompt = self:__highlight_prefilter(prompt)
|
||||
end
|
||||
return fzf.get_pos(display, get_struct(self, prompt), self.state.slab)
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
local fast_extend = function(opts, conf)
|
||||
local ret = {}
|
||||
ret.case_mode = vim.F.if_nil(opts.case_mode, conf.case_mode)
|
||||
ret.fuzzy = vim.F.if_nil(opts.fuzzy, conf.fuzzy)
|
||||
return ret
|
||||
end
|
||||
|
||||
return require("telescope").register_extension {
|
||||
setup = function(ext_config, config)
|
||||
local override_file = vim.F.if_nil(ext_config.override_file_sorter, true)
|
||||
local override_generic = vim.F.if_nil(ext_config.override_generic_sorter, true)
|
||||
|
||||
local conf = {}
|
||||
conf.case_mode = vim.F.if_nil(ext_config.case_mode, "smart_case")
|
||||
conf.fuzzy = vim.F.if_nil(ext_config.fuzzy, true)
|
||||
|
||||
if override_file then
|
||||
config.file_sorter = function(opts)
|
||||
opts = opts or {}
|
||||
return get_fzf_sorter(fast_extend(opts, conf))
|
||||
end
|
||||
end
|
||||
|
||||
if override_generic then
|
||||
config.generic_sorter = function(opts)
|
||||
opts = opts or {}
|
||||
return get_fzf_sorter(fast_extend(opts, conf))
|
||||
end
|
||||
end
|
||||
end,
|
||||
exports = {
|
||||
native_fzf_sorter = function(opts)
|
||||
return get_fzf_sorter(opts or { case_mode = "smart_case", fuzzy = true })
|
||||
end,
|
||||
},
|
||||
}
|
1270
bundle/telescope-fzf-native.nvim/src/fzf.c
vendored
Normal file
1270
bundle/telescope-fzf-native.nvim/src/fzf.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
111
bundle/telescope-fzf-native.nvim/src/fzf.h
vendored
Normal file
111
bundle/telescope-fzf-native.nvim/src/fzf.h
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef FZF_H_
|
||||
#define FZF_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
int16_t *data;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
bool allocated;
|
||||
} fzf_i16_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t *data;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
bool allocated;
|
||||
} fzf_i32_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t *data;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
} fzf_position_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t start;
|
||||
int32_t end;
|
||||
int32_t score;
|
||||
} fzf_result_t;
|
||||
|
||||
typedef struct {
|
||||
fzf_i16_t I16;
|
||||
fzf_i32_t I32;
|
||||
} fzf_slab_t;
|
||||
|
||||
typedef struct {
|
||||
size_t size_16;
|
||||
size_t size_32;
|
||||
} fzf_slab_config_t;
|
||||
|
||||
typedef struct {
|
||||
const char *data;
|
||||
size_t size;
|
||||
} fzf_string_t;
|
||||
|
||||
typedef fzf_result_t (*fzf_algo_t)(bool, bool, fzf_string_t *, fzf_string_t *,
|
||||
fzf_position_t *, fzf_slab_t *);
|
||||
|
||||
typedef enum { CaseSmart = 0, CaseIgnore, CaseRespect } fzf_case_types;
|
||||
|
||||
typedef struct {
|
||||
fzf_algo_t fn;
|
||||
bool inv;
|
||||
char *ptr;
|
||||
void *text;
|
||||
bool case_sensitive;
|
||||
} fzf_term_t;
|
||||
|
||||
typedef struct {
|
||||
fzf_term_t *ptr;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
} fzf_term_set_t;
|
||||
|
||||
typedef struct {
|
||||
fzf_term_set_t **ptr;
|
||||
size_t size;
|
||||
size_t cap;
|
||||
bool only_inv;
|
||||
} fzf_pattern_t;
|
||||
|
||||
fzf_result_t fzf_fuzzy_match_v1(bool case_sensitive, bool normalize,
|
||||
fzf_string_t *text, fzf_string_t *pattern,
|
||||
fzf_position_t *pos, fzf_slab_t *slab);
|
||||
fzf_result_t fzf_fuzzy_match_v2(bool case_sensitive, bool normalize,
|
||||
fzf_string_t *text, fzf_string_t *pattern,
|
||||
fzf_position_t *pos, fzf_slab_t *slab);
|
||||
fzf_result_t fzf_exact_match_naive(bool case_sensitive, bool normalize,
|
||||
fzf_string_t *text, fzf_string_t *pattern,
|
||||
fzf_position_t *pos, fzf_slab_t *slab);
|
||||
fzf_result_t fzf_prefix_match(bool case_sensitive, bool normalize,
|
||||
fzf_string_t *text, fzf_string_t *pattern,
|
||||
fzf_position_t *pos, fzf_slab_t *slab);
|
||||
fzf_result_t fzf_suffix_match(bool case_sensitive, bool normalize,
|
||||
fzf_string_t *text, fzf_string_t *pattern,
|
||||
fzf_position_t *pos, fzf_slab_t *slab);
|
||||
fzf_result_t fzf_equal_match(bool case_sensitive, bool normalize,
|
||||
fzf_string_t *text, fzf_string_t *pattern,
|
||||
fzf_position_t *pos, fzf_slab_t *slab);
|
||||
|
||||
/* interface */
|
||||
fzf_pattern_t *fzf_parse_pattern(fzf_case_types case_mode, bool normalize,
|
||||
char *pattern, bool fuzzy);
|
||||
void fzf_free_pattern(fzf_pattern_t *pattern);
|
||||
|
||||
int32_t fzf_get_score(const char *text, fzf_pattern_t *pattern,
|
||||
fzf_slab_t *slab);
|
||||
|
||||
fzf_position_t *fzf_pos_array(size_t len);
|
||||
fzf_position_t *fzf_get_positions(const char *text, fzf_pattern_t *pattern,
|
||||
fzf_slab_t *slab);
|
||||
void fzf_free_positions(fzf_position_t *pos);
|
||||
|
||||
fzf_slab_t *fzf_make_slab(fzf_slab_config_t config);
|
||||
fzf_slab_t *fzf_make_default_slab(void);
|
||||
void fzf_free_slab(fzf_slab_t *slab);
|
||||
|
||||
#endif // FZF_H_
|
111
bundle/telescope-fzf-native.nvim/test/fzf_lib_spec.lua
vendored
Normal file
111
bundle/telescope-fzf-native.nvim/test/fzf_lib_spec.lua
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
local fzf = require "fzf_lib"
|
||||
local eq = assert.are.same
|
||||
local is_nil = assert.is_nil
|
||||
|
||||
describe("fzf", function()
|
||||
local slab = fzf.allocate_slab()
|
||||
it("can get the score for simple pattern", function()
|
||||
local p = fzf.parse_pattern("fzf", 0)
|
||||
eq(80, fzf.get_score("src/fzf", p, slab))
|
||||
eq(0, fzf.get_score("asdf", p, slab))
|
||||
eq(54, fzf.get_score("fasdzasdf", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the score for or pattern", function()
|
||||
local p = fzf.parse_pattern("lua | src | 'doc | ^asdfasdf | file$", 0)
|
||||
eq(80, fzf.get_score("src/fzf.c", p, slab))
|
||||
eq(0, fzf.get_score("build/libfzf", p, slab))
|
||||
eq(80, fzf.get_score("lua/fzf_lib.lua", p, slab))
|
||||
eq(80, fzf.get_score("doc/fzf.txt", p, slab))
|
||||
eq(0, fzf.get_score("daonc/fzf.txt", p, slab))
|
||||
eq(200, fzf.get_score("asdfasdf", p, slab))
|
||||
eq(0, fzf.get_score("noasdfasdf", p, slab))
|
||||
eq(104, fzf.get_score("not_file", p, slab))
|
||||
eq(0, fzf.get_score("not_file.txt", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the score for and pattern", function()
|
||||
local p = fzf.parse_pattern("fzf !lib", 0)
|
||||
eq(80, fzf.get_score("src/fzf.c", p, slab))
|
||||
eq(0, fzf.get_score("lua/fzf_lib.lua", p, slab))
|
||||
eq(0, fzf.get_score("build/libfzf", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
|
||||
local p = fzf.parse_pattern("fzf src c", 0)
|
||||
eq(192, fzf.get_score("src/fzf.c", p, slab))
|
||||
eq(0, fzf.get_score("lua/fzf_lib.lua", p, slab))
|
||||
eq(0, fzf.get_score("build/libfzf", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the score for patterns with escaped space", function()
|
||||
local p = fzf.parse_pattern("\\ ", 0)
|
||||
eq(32, fzf.get_score("src file", p, slab))
|
||||
eq(0, fzf.get_score("src_file", p, slab))
|
||||
eq(32, fzf.get_score("another another file", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the score for issue 11", function()
|
||||
local p = fzf.parse_pattern("feature/1337-some-times-i-have-a-lot-of-hyphens", 0)
|
||||
eq(1136, fzf.get_score("feature/1337-some-times-i-have-a-lot-of-hyphens", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the pos for simple pattern", function()
|
||||
local p = fzf.parse_pattern("fzf", 0)
|
||||
eq({ 7, 6, 5 }, fzf.get_pos("src/fzf", p, slab))
|
||||
is_nil(fzf.get_pos("asdf", p, slab))
|
||||
eq({ 9, 5, 1 }, fzf.get_pos("fasdzasdf", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the pos for or pattern", function()
|
||||
local p = fzf.parse_pattern("lua | src | 'doc | ^asdfasdf | file$", 0)
|
||||
eq({ 3, 2, 1 }, fzf.get_pos("src/fzf.c", p, slab))
|
||||
is_nil(fzf.get_pos("build/libfzf", p, slab))
|
||||
eq({ 3, 2, 1 }, fzf.get_pos("lua/fzf_lib.lua", p, slab))
|
||||
eq({ 1, 2, 3 }, fzf.get_pos("doc/fzf.txt", p, slab))
|
||||
is_nil(fzf.get_pos("daonc/fzf.txt", p, slab))
|
||||
eq({ 1, 2, 3, 4, 5, 6, 7, 8 }, fzf.get_pos("asdfasdf", p, slab))
|
||||
is_nil(fzf.get_pos("noasdfasdf", p, slab))
|
||||
eq({ 5, 6, 7, 8 }, fzf.get_pos("not_file", p, slab))
|
||||
is_nil(fzf.get_pos("not_file.txt", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the pos for and pattern", function()
|
||||
local p = fzf.parse_pattern("fzf !lib", 0)
|
||||
eq({ 7, 6, 5 }, fzf.get_pos("src/fzf.c", p, slab))
|
||||
is_nil(fzf.get_pos("lua/fzf_lib.lua", p, slab))
|
||||
is_nil(fzf.get_pos("build/libfzf", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
|
||||
p = fzf.parse_pattern("fzf src c", 0)
|
||||
eq({ 7, 6, 5, 3, 2, 1, 9 }, fzf.get_pos("src/fzf.c", p, slab))
|
||||
is_nil(fzf.get_pos("lua/fzf_lib.lua", p, slab))
|
||||
is_nil(fzf.get_pos("build/libfzf", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the pos for patterns with escaped space", function()
|
||||
local p = fzf.parse_pattern("\\ ", 0)
|
||||
eq({ 4 }, fzf.get_pos("src file", p, slab))
|
||||
is_nil(fzf.get_pos("src_file", p, slab))
|
||||
eq({ 8 }, fzf.get_pos("another another file", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
|
||||
it("can get the pos for issue 11", function()
|
||||
local p = fzf.parse_pattern("feature/1337-some-times-i-have-a-lot-of-hyphens", 0)
|
||||
local expected = {}
|
||||
for i = 47, 1, -1 do
|
||||
table.insert(expected, i)
|
||||
end
|
||||
eq(expected, fzf.get_pos("feature/1337-some-times-i-have-a-lot-of-hyphens", p, slab))
|
||||
fzf.free_pattern(p)
|
||||
end)
|
||||
fzf.free_slab(slab)
|
||||
end)
|
4
bundle/telescope-fzf-native.nvim/test/minrc.vim
vendored
Normal file
4
bundle/telescope-fzf-native.nvim/test/minrc.vim
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
set rtp+=.
|
||||
set rtp+=../plenary.nvim/
|
||||
|
||||
runtime! plugin/plenary.vim
|
771
bundle/telescope-fzf-native.nvim/test/test.c
vendored
Normal file
771
bundle/telescope-fzf-native.nvim/test/test.c
vendored
Normal file
@ -0,0 +1,771 @@
|
||||
#include "fzf.h"
|
||||
|
||||
#include <examiner.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum {
|
||||
ScoreMatch = 16,
|
||||
ScoreGapStart = -3,
|
||||
ScoreGapExtension = -1,
|
||||
BonusBoundary = ScoreMatch / 2,
|
||||
BonusNonWord = ScoreMatch / 2,
|
||||
BonusCamel123 = BonusBoundary + ScoreGapExtension,
|
||||
BonusConsecutive = -(ScoreGapStart + ScoreGapExtension),
|
||||
BonusFirstCharMultiplier = 2,
|
||||
} score_t;
|
||||
|
||||
#define call_alg(alg, case, txt, pat, assert_block) \
|
||||
{ \
|
||||
fzf_position_t *pos = fzf_pos_array(0); \
|
||||
fzf_result_t res = alg(case, false, txt, pat, pos, NULL); \
|
||||
assert_block; \
|
||||
fzf_free_positions(pos); \
|
||||
} \
|
||||
{ \
|
||||
fzf_position_t *pos = fzf_pos_array(0); \
|
||||
fzf_slab_t *slab = fzf_make_default_slab(); \
|
||||
fzf_result_t res = alg(case, false, txt, pat, pos, slab); \
|
||||
assert_block; \
|
||||
fzf_free_positions(pos); \
|
||||
fzf_free_slab(slab); \
|
||||
}
|
||||
|
||||
static int8_t max_i8(int8_t a, int8_t b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
#define MATCH_WRAPPER(nn, og) \
|
||||
fzf_result_t nn(bool case_sensitive, bool normalize, const char *text, \
|
||||
const char *pattern, fzf_position_t *pos, \
|
||||
fzf_slab_t *slab) { \
|
||||
fzf_string_t input = {.data = text, .size = strlen(text)}; \
|
||||
fzf_string_t pattern_wrap = {.data = pattern, .size = strlen(pattern)}; \
|
||||
return og(case_sensitive, normalize, &input, &pattern_wrap, pos, slab); \
|
||||
}
|
||||
|
||||
MATCH_WRAPPER(fuzzy_match_v2, fzf_fuzzy_match_v2);
|
||||
MATCH_WRAPPER(fuzzy_match_v1, fzf_fuzzy_match_v1);
|
||||
MATCH_WRAPPER(exact_match_naive, fzf_exact_match_naive);
|
||||
MATCH_WRAPPER(prefix_match, fzf_prefix_match);
|
||||
MATCH_WRAPPER(suffix_match, fzf_suffix_match);
|
||||
MATCH_WRAPPER(equal_match, fzf_equal_match);
|
||||
|
||||
// TODO(conni2461): Implement normalize and test it here
|
||||
TEST(FuzzyMatchV2, case1) {
|
||||
call_alg(fuzzy_match_v2, true, "So Danco Samba", "So", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(2, res.end);
|
||||
ASSERT_EQ(56, res.score);
|
||||
|
||||
ASSERT_EQ(2, pos->size);
|
||||
ASSERT_EQ(1, pos->data[0]);
|
||||
ASSERT_EQ(0, pos->data[1]);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case2) {
|
||||
call_alg(fuzzy_match_v2, false, "So Danco Samba", "sodc", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(7, res.end);
|
||||
ASSERT_EQ(89, res.score);
|
||||
|
||||
ASSERT_EQ(4, pos->size);
|
||||
ASSERT_EQ(6, pos->data[0]);
|
||||
ASSERT_EQ(3, pos->data[1]);
|
||||
ASSERT_EQ(1, pos->data[2]);
|
||||
ASSERT_EQ(0, pos->data[3]);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case3) {
|
||||
call_alg(fuzzy_match_v2, false, "Danco", "danco", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(5, res.end);
|
||||
ASSERT_EQ(128, res.score);
|
||||
|
||||
ASSERT_EQ(5, pos->size);
|
||||
ASSERT_EQ(4, pos->data[0]);
|
||||
ASSERT_EQ(3, pos->data[1]);
|
||||
ASSERT_EQ(2, pos->data[2]);
|
||||
ASSERT_EQ(1, pos->data[3]);
|
||||
ASSERT_EQ(0, pos->data[4]);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case4) {
|
||||
call_alg(fuzzy_match_v2, false, "fooBarbaz1", "obz", {
|
||||
ASSERT_EQ(2, res.start);
|
||||
ASSERT_EQ(9, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 3 + BonusCamel123 + ScoreGapStart + ScoreGapExtension * 3;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case5) {
|
||||
call_alg(fuzzy_match_v2, false, "foo bar baz", "fbb", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(9, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 3 + BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusBoundary * 2 + 2 * ScoreGapStart + 4 * ScoreGapExtension;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case6) {
|
||||
call_alg(fuzzy_match_v2, false, "/AutomatorDocument.icns", "rdoc", {
|
||||
ASSERT_EQ(9, res.start);
|
||||
ASSERT_EQ(13, res.end);
|
||||
int expected_score = ScoreMatch * 4 + BonusCamel123 + BonusConsecutive * 2;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case7) {
|
||||
call_alg(fuzzy_match_v2, false, "/man1/zshcompctl.1", "zshc", {
|
||||
ASSERT_EQ(6, res.start);
|
||||
ASSERT_EQ(10, res.end);
|
||||
int expected_score = ScoreMatch * 4 +
|
||||
BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusBoundary * 3;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case8) {
|
||||
call_alg(fuzzy_match_v2, false, "/.oh-my-zsh/cache", "zshc", {
|
||||
ASSERT_EQ(8, res.start);
|
||||
ASSERT_EQ(13, res.end);
|
||||
int expected_score = ScoreMatch * 4 +
|
||||
BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusBoundary * 3 + ScoreGapStart;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case9) {
|
||||
call_alg(fuzzy_match_v2, false, "ab0123 456", "12356", {
|
||||
ASSERT_EQ(3, res.start);
|
||||
ASSERT_EQ(10, res.end);
|
||||
int expected_score = ScoreMatch * 5 + BonusConsecutive * 3 + ScoreGapStart +
|
||||
ScoreGapExtension;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case10) {
|
||||
call_alg(fuzzy_match_v2, false, "abc123 456", "12356", {
|
||||
ASSERT_EQ(3, res.start);
|
||||
ASSERT_EQ(10, res.end);
|
||||
int expected_score = ScoreMatch * 5 +
|
||||
BonusCamel123 * BonusFirstCharMultiplier +
|
||||
BonusCamel123 * 2 + BonusConsecutive + ScoreGapStart +
|
||||
ScoreGapExtension;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case11) {
|
||||
call_alg(fuzzy_match_v2, false, "foo/bar/baz", "fbb", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(9, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 3 + BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusBoundary * 2 + 2 * ScoreGapStart + 4 * ScoreGapExtension;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case12) {
|
||||
call_alg(fuzzy_match_v2, false, "fooBarBaz", "fbb", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(7, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 3 + BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusCamel123 * 2 + 2 * ScoreGapStart + 2 * ScoreGapExtension;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case13) {
|
||||
call_alg(fuzzy_match_v2, false, "foo barbaz", "fbb", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(8, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 3 + BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusBoundary + ScoreGapStart * 2 + ScoreGapExtension * 3;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case14) {
|
||||
call_alg(fuzzy_match_v2, false, "fooBar Baz", "foob", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(4, res.end);
|
||||
int expected_score = ScoreMatch * 4 +
|
||||
BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusBoundary * 3;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case15) {
|
||||
call_alg(fuzzy_match_v2, false, "xFoo-Bar Baz", "foo-b", {
|
||||
ASSERT_EQ(1, res.start);
|
||||
ASSERT_EQ(6, res.end);
|
||||
int expected_score = ScoreMatch * 5 +
|
||||
BonusCamel123 * BonusFirstCharMultiplier +
|
||||
BonusCamel123 * 2 + BonusNonWord + BonusBoundary;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case16) {
|
||||
call_alg(fuzzy_match_v2, true, "fooBarbaz", "oBz", {
|
||||
ASSERT_EQ(2, res.start);
|
||||
ASSERT_EQ(9, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 3 + BonusCamel123 + ScoreGapStart + ScoreGapExtension * 3;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case17) {
|
||||
call_alg(fuzzy_match_v2, true, "Foo/Bar/Baz", "FBB", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(9, res.end);
|
||||
int expected_score = ScoreMatch * 3 +
|
||||
BonusBoundary * (BonusFirstCharMultiplier + 2) +
|
||||
ScoreGapStart * 2 + ScoreGapExtension * 4;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case18) {
|
||||
call_alg(fuzzy_match_v2, true, "FooBarBaz", "FBB", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(7, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 3 + BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusCamel123 * 2 + ScoreGapStart * 2 + ScoreGapExtension * 2;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case19) {
|
||||
call_alg(fuzzy_match_v2, true, "FooBar Baz", "FooB", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(4, res.end);
|
||||
int expected_score =
|
||||
ScoreMatch * 4 + BonusBoundary * BonusFirstCharMultiplier +
|
||||
BonusBoundary * 2 + max_i8(BonusCamel123, BonusBoundary);
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case20) {
|
||||
call_alg(fuzzy_match_v2, true, "foo-bar", "o-ba", {
|
||||
ASSERT_EQ(2, res.start);
|
||||
ASSERT_EQ(6, res.end);
|
||||
int expected_score = ScoreMatch * 4 + BonusBoundary * 3;
|
||||
ASSERT_EQ(expected_score, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case21) {
|
||||
call_alg(fuzzy_match_v2, true, "fooBarbaz", "oBZ", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case22) {
|
||||
call_alg(fuzzy_match_v2, true, "Foo Bar Baz", "fbb", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV2, case23) {
|
||||
call_alg(fuzzy_match_v2, true, "fooBarbaz", "fooBarbazz", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV1, case1) {
|
||||
call_alg(fuzzy_match_v1, true, "So Danco Samba", "So", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(2, res.end);
|
||||
ASSERT_EQ(56, res.score);
|
||||
|
||||
ASSERT_EQ(2, pos->size);
|
||||
ASSERT_EQ(0, pos->data[0]);
|
||||
ASSERT_EQ(1, pos->data[1]);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV1, case2) {
|
||||
call_alg(fuzzy_match_v1, false, "So Danco Samba", "sodc", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(7, res.end);
|
||||
ASSERT_EQ(89, res.score);
|
||||
|
||||
ASSERT_EQ(4, pos->size);
|
||||
ASSERT_EQ(0, pos->data[0]);
|
||||
ASSERT_EQ(1, pos->data[1]);
|
||||
ASSERT_EQ(3, pos->data[2]);
|
||||
ASSERT_EQ(6, pos->data[3]);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(FuzzyMatchV1, case3) {
|
||||
call_alg(fuzzy_match_v1, false, "Danco", "danco", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(5, res.end);
|
||||
ASSERT_EQ(128, res.score);
|
||||
|
||||
ASSERT_EQ(5, pos->size);
|
||||
ASSERT_EQ(0, pos->data[0]);
|
||||
ASSERT_EQ(1, pos->data[1]);
|
||||
ASSERT_EQ(2, pos->data[2]);
|
||||
ASSERT_EQ(3, pos->data[3]);
|
||||
ASSERT_EQ(4, pos->data[4]);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(ExactMatch, case1) {
|
||||
call_alg(exact_match_naive, true, "So Danco Samba", "So", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(2, res.end);
|
||||
ASSERT_EQ(56, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(ExactMatch, case2) {
|
||||
call_alg(exact_match_naive, false, "So Danco Samba", "sodc", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(ExactMatch, case3) {
|
||||
call_alg(exact_match_naive, false, "Danco", "danco", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(5, res.end);
|
||||
ASSERT_EQ(128, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(PrefixMatch, case1) {
|
||||
call_alg(prefix_match, true, "So Danco Samba", "So", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(2, res.end);
|
||||
ASSERT_EQ(56, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(PrefixMatch, case2) {
|
||||
call_alg(prefix_match, false, "So Danco Samba", "sodc", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(PrefixMatch, case3) {
|
||||
call_alg(prefix_match, false, "Danco", "danco", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(5, res.end);
|
||||
ASSERT_EQ(128, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(SuffixMatch, case1) {
|
||||
call_alg(suffix_match, true, "So Danco Samba", "So", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(SuffixMatch, case2) {
|
||||
call_alg(suffix_match, false, "So Danco Samba", "sodc", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(SuffixMatch, case3) {
|
||||
call_alg(suffix_match, false, "Danco", "danco", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(5, res.end);
|
||||
ASSERT_EQ(128, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(EqualMatch, case1) {
|
||||
call_alg(equal_match, true, "So Danco Samba", "So", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(EqualMatch, case2) {
|
||||
call_alg(equal_match, false, "So Danco Samba", "sodc", {
|
||||
ASSERT_EQ(-1, res.start);
|
||||
ASSERT_EQ(-1, res.end);
|
||||
ASSERT_EQ(0, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(EqualMatch, case3) {
|
||||
call_alg(equal_match, false, "Danco", "danco", {
|
||||
ASSERT_EQ(0, res.start);
|
||||
ASSERT_EQ(5, res.end);
|
||||
ASSERT_EQ(128, res.score);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(PatternParsing, empty) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "", true);
|
||||
ASSERT_EQ(0, pat->size);
|
||||
ASSERT_EQ(0, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, simple) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "lua", true);
|
||||
ASSERT_EQ(1, pat->size);
|
||||
ASSERT_EQ(1, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_fuzzy_match_v2, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("lua", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, withEscapedSpace) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "file\\ ", true);
|
||||
ASSERT_EQ(1, pat->size);
|
||||
ASSERT_EQ(1, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_fuzzy_match_v2, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("file ", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, withComplexEscapedSpace) {
|
||||
fzf_pattern_t *pat =
|
||||
fzf_parse_pattern(CaseSmart, false, "file\\ with\\ space", true);
|
||||
ASSERT_EQ(1, pat->size);
|
||||
ASSERT_EQ(1, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_fuzzy_match_v2, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("file with space",
|
||||
((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, withEscapedSpaceAndNormalSpace) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "file\\ new", true);
|
||||
ASSERT_EQ(2, pat->size);
|
||||
ASSERT_EQ(2, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
ASSERT_EQ(1, pat->ptr[1]->size);
|
||||
ASSERT_EQ(1, pat->ptr[1]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_fuzzy_match_v2, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("file ", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
|
||||
ASSERT_EQ((void *)fzf_fuzzy_match_v2, pat->ptr[1]->ptr[0].fn);
|
||||
ASSERT_EQ("new", ((fzf_string_t *)(pat->ptr[1]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[1]->ptr[0].case_sensitive);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, invert) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "!Lua", true);
|
||||
ASSERT_EQ(1, pat->size);
|
||||
ASSERT_EQ(1, pat->cap);
|
||||
ASSERT_TRUE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_exact_match_naive, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("Lua", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_TRUE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
ASSERT_TRUE(pat->ptr[0]->ptr[0].inv);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, invertMultiple) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "!fzf !test", true);
|
||||
ASSERT_EQ(2, pat->size);
|
||||
ASSERT_EQ(2, pat->cap);
|
||||
ASSERT_TRUE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
ASSERT_EQ(1, pat->ptr[1]->size);
|
||||
ASSERT_EQ(1, pat->ptr[1]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_exact_match_naive, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("fzf", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
ASSERT_TRUE(pat->ptr[0]->ptr[0].inv);
|
||||
|
||||
ASSERT_EQ((void *)fzf_exact_match_naive, pat->ptr[1]->ptr[0].fn);
|
||||
ASSERT_EQ("test", ((fzf_string_t *)(pat->ptr[1]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[1]->ptr[0].case_sensitive);
|
||||
ASSERT_TRUE(pat->ptr[1]->ptr[0].inv);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, smartCase) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "Lua", true);
|
||||
ASSERT_EQ(1, pat->size);
|
||||
ASSERT_EQ(1, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_fuzzy_match_v2, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("Lua", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_TRUE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, simpleOr) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, "'src | ^Lua", true);
|
||||
ASSERT_EQ(1, pat->size);
|
||||
ASSERT_EQ(1, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(2, pat->ptr[0]->size);
|
||||
ASSERT_EQ(2, pat->ptr[0]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_exact_match_naive, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ("src", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
|
||||
ASSERT_EQ((void *)fzf_prefix_match, pat->ptr[0]->ptr[1].fn);
|
||||
ASSERT_EQ("Lua", ((fzf_string_t *)(pat->ptr[0]->ptr[1].text))->data);
|
||||
ASSERT_TRUE(pat->ptr[0]->ptr[1].case_sensitive);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
TEST(PatternParsing, complexAnd) {
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false,
|
||||
".lua$ 'previewer !'term !asdf", true);
|
||||
ASSERT_EQ(4, pat->size);
|
||||
ASSERT_EQ(4, pat->cap);
|
||||
ASSERT_FALSE(pat->only_inv);
|
||||
|
||||
ASSERT_EQ(1, pat->ptr[0]->size);
|
||||
ASSERT_EQ(1, pat->ptr[0]->cap);
|
||||
ASSERT_EQ(1, pat->ptr[1]->size);
|
||||
ASSERT_EQ(1, pat->ptr[1]->cap);
|
||||
ASSERT_EQ(1, pat->ptr[2]->size);
|
||||
ASSERT_EQ(1, pat->ptr[2]->cap);
|
||||
ASSERT_EQ(1, pat->ptr[3]->size);
|
||||
ASSERT_EQ(1, pat->ptr[3]->cap);
|
||||
|
||||
ASSERT_EQ((void *)fzf_suffix_match, pat->ptr[0]->ptr[0].fn);
|
||||
ASSERT_EQ(".lua", ((fzf_string_t *)(pat->ptr[0]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[0]->ptr[0].case_sensitive);
|
||||
|
||||
ASSERT_EQ((void *)fzf_exact_match_naive, pat->ptr[1]->ptr[0].fn);
|
||||
ASSERT_EQ("previewer", ((fzf_string_t *)(pat->ptr[1]->ptr[0].text))->data);
|
||||
ASSERT_EQ(0, pat->ptr[1]->ptr[0].case_sensitive);
|
||||
|
||||
ASSERT_EQ((void *)fzf_fuzzy_match_v2, pat->ptr[2]->ptr[0].fn);
|
||||
ASSERT_EQ("term", ((fzf_string_t *)(pat->ptr[2]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[2]->ptr[0].case_sensitive);
|
||||
ASSERT_TRUE(pat->ptr[2]->ptr[0].inv);
|
||||
|
||||
ASSERT_EQ((void *)fzf_exact_match_naive, pat->ptr[3]->ptr[0].fn);
|
||||
ASSERT_EQ("asdf", ((fzf_string_t *)(pat->ptr[3]->ptr[0].text))->data);
|
||||
ASSERT_FALSE(pat->ptr[3]->ptr[0].case_sensitive);
|
||||
ASSERT_TRUE(pat->ptr[3]->ptr[0].inv);
|
||||
fzf_free_pattern(pat);
|
||||
}
|
||||
|
||||
static void score_wrapper(char *pattern, char **input, int *expected) {
|
||||
fzf_slab_t *slab = fzf_make_default_slab();
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, pattern, true);
|
||||
for (size_t i = 0; input[i] != NULL; ++i) {
|
||||
ASSERT_EQ(expected[i], fzf_get_score(input[i], pat, slab));
|
||||
}
|
||||
fzf_free_pattern(pat);
|
||||
fzf_free_slab(slab);
|
||||
}
|
||||
|
||||
TEST(ScoreIntegration, simple) {
|
||||
char *input[] = {"fzf", "main.c", "src/fzf", "fz/noooo", NULL};
|
||||
int expected[] = {0, 1, 0, 1};
|
||||
score_wrapper("!fzf", input, expected);
|
||||
}
|
||||
|
||||
TEST(ScoreIntegration, invertAnd) {
|
||||
char *input[] = {"src/fzf.c", "README.md", "lua/asdf", "test/test.c", NULL};
|
||||
int expected[] = {0, 1, 1, 0};
|
||||
score_wrapper("!fzf !test", input, expected);
|
||||
}
|
||||
|
||||
TEST(ScoreIntegration, withEscapedSpace) {
|
||||
char *input[] = {"file ", "file lua", "lua", NULL};
|
||||
int expected[] = {0, 200, 0};
|
||||
score_wrapper("file\\ lua", input, expected);
|
||||
}
|
||||
|
||||
TEST(ScoreIntegration, onlyEscapedSpace) {
|
||||
char *input[] = {"file with space", "file lua", "lua", "src", "test", NULL};
|
||||
int expected[] = {32, 32, 0, 0, 0};
|
||||
score_wrapper("\\ ", input, expected);
|
||||
}
|
||||
|
||||
TEST(ScoreIntegration, simpleOr) {
|
||||
char *input[] = {"src/fzf.h", "README.md", "build/fzf",
|
||||
"lua/fzf_lib.lua", "Lua/fzf_lib.lua", NULL};
|
||||
int expected[] = {80, 0, 0, 0, 80};
|
||||
score_wrapper("'src | ^Lua", input, expected);
|
||||
}
|
||||
|
||||
TEST(ScoreIntegration, complexTerm) {
|
||||
char *input[] = {"lua/random_previewer", "README.md",
|
||||
"previewers/utils.lua", "previewers/buffer.lua",
|
||||
"previewers/term.lua", NULL};
|
||||
int expected[] = {0, 0, 328, 328, 0};
|
||||
score_wrapper(".lua$ 'previewer !'term", input, expected);
|
||||
}
|
||||
|
||||
static void pos_wrapper(char *pattern, char **input, int **expected) {
|
||||
fzf_slab_t *slab = fzf_make_default_slab();
|
||||
fzf_pattern_t *pat = fzf_parse_pattern(CaseSmart, false, pattern, true);
|
||||
for (size_t i = 0; input[i] != NULL; ++i) {
|
||||
fzf_position_t *pos = fzf_get_positions(input[i], pat, slab);
|
||||
if (!pos) {
|
||||
ASSERT_EQ((void *)pos, expected[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Verify that the size is correct
|
||||
if (expected[i]) {
|
||||
ASSERT_EQ(-1, expected[i][pos->size]);
|
||||
} else {
|
||||
ASSERT_EQ(0, pos->size);
|
||||
}
|
||||
ASSERT_EQ_MEM(expected[i], pos->data, pos->size * sizeof(pos->data[0]));
|
||||
fzf_free_positions(pos);
|
||||
}
|
||||
fzf_free_pattern(pat);
|
||||
fzf_free_slab(slab);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, simple) {
|
||||
char *input[] = {"src/fzf.c", "src/fzf.h",
|
||||
"lua/fzf_lib.lua", "lua/telescope/_extensions/fzf.lua",
|
||||
"README.md", NULL};
|
||||
int match1[] = {6, 5, 4, -1};
|
||||
int match2[] = {6, 5, 4, -1};
|
||||
int match3[] = {6, 5, 4, -1};
|
||||
int match4[] = {28, 27, 26, -1};
|
||||
int *expected[] = {match1, match2, match3, match4, NULL};
|
||||
pos_wrapper("fzf", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, invert) {
|
||||
char *input[] = {"fzf", "main.c", "src/fzf", "fz/noooo", NULL};
|
||||
int *expected[] = {NULL, NULL, NULL, NULL, NULL};
|
||||
pos_wrapper("!fzf", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, andWithSecondInvert) {
|
||||
char *input[] = {"src/fzf.c", "lua/fzf_lib.lua", "build/libfzf", NULL};
|
||||
int match1[] = {6, 5, 4, -1};
|
||||
int *expected[] = {match1, NULL, NULL};
|
||||
pos_wrapper("fzf !lib", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, andAllInvert) {
|
||||
char *input[] = {"src/fzf.c", "README.md", "lua/asdf", "test/test.c", NULL};
|
||||
int *expected[] = {NULL, NULL, NULL, NULL};
|
||||
pos_wrapper("!fzf !test", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, withEscapedSpace) {
|
||||
char *input[] = {"file ", "file lua", "lua", NULL};
|
||||
int match1[] = {7, 6, 5, 4, 3, 2, 1, 0, -1};
|
||||
int *expected[] = {NULL, match1, NULL};
|
||||
pos_wrapper("file\\ lua", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, onlyEscapedSpace) {
|
||||
char *input[] = {"file with space", "lul lua", "lua", "src", "test", NULL};
|
||||
int match1[] = {4, -1};
|
||||
int match2[] = {3, -1};
|
||||
int *expected[] = {match1, match2, NULL, NULL, NULL};
|
||||
pos_wrapper("\\ ", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, simpleOr) {
|
||||
char *input[] = {"src/fzf.h", "README.md", "build/fzf",
|
||||
"lua/fzf_lib.lua", "Lua/fzf_lib.lua", NULL};
|
||||
int match1[] = {0, 1, 2, -1};
|
||||
int match2[] = {0, 1, 2, -1};
|
||||
int *expected[] = {match1, NULL, NULL, NULL, match2};
|
||||
pos_wrapper("'src | ^Lua", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, orMemLeak) {
|
||||
char *input[] = {"src/fzf.h", NULL};
|
||||
int match1[] = {2, 1, 0, -1};
|
||||
int *expected[] = {match1};
|
||||
pos_wrapper("src | src", input, expected);
|
||||
}
|
||||
|
||||
TEST(PosIntegration, complexTerm) {
|
||||
char *input[] = {"lua/random_previewer", "README.md",
|
||||
"previewers/utils.lua", "previewers/buffer.lua",
|
||||
"previewers/term.lua", NULL};
|
||||
int match1[] = {16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1};
|
||||
int match2[] = {17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1};
|
||||
int *expected[] = {NULL, NULL, match1, match2, NULL};
|
||||
pos_wrapper(".lua$ 'previewer !'term", input, expected);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
exam_init(argc, argv);
|
||||
return exam_run();
|
||||
}
|
@ -3,25 +3,29 @@ lua require('telescope').load_extension('messages')
|
||||
lua require('telescope').load_extension('project')
|
||||
lua require('telescope').load_extension('scriptnames')
|
||||
lua require('telescope').load_extension('neoyank')
|
||||
if filereadable(g:_spacevim_root_dir . 'bundle/telescope-fzf-native.nvim/build/libfzf.so')
|
||||
\ || filereadable(g:_spacevim_root_dir . 'bundle/telescope-fzf-native.nvim/build/libfzf.dll')
|
||||
lua require('telescope').load_extension('fzf')
|
||||
endif
|
||||
lua <<EOF
|
||||
local actions = require("telescope.actions")
|
||||
require("telescope").setup{
|
||||
defaults = {
|
||||
mappings = {
|
||||
i = {
|
||||
-- the default key binding should same as other fuzzy finder layer
|
||||
-- tab move to next
|
||||
["<C-j>"] = actions.move_selection_next,
|
||||
["<Tab>"] = actions.move_selection_next,
|
||||
["<C-k>"] = actions.move_selection_previous,
|
||||
["<S-Tab>"] = actions.move_selection_previous,
|
||||
["<Esc>"] = actions.close,
|
||||
["<C-h>"] = "which_key"
|
||||
defaults = {
|
||||
mappings = {
|
||||
i = {
|
||||
-- the default key binding should same as other fuzzy finder layer
|
||||
-- tab move to next
|
||||
["<C-j>"] = actions.move_selection_next,
|
||||
["<Tab>"] = actions.move_selection_next,
|
||||
["<C-k>"] = actions.move_selection_previous,
|
||||
["<S-Tab>"] = actions.move_selection_previous,
|
||||
["<Esc>"] = actions.close,
|
||||
["<C-h>"] = "which_key"
|
||||
},
|
||||
},
|
||||
sorting_strategy = "ascending",
|
||||
layout_config = {
|
||||
prompt_position = "bottom"
|
||||
layout_config = {
|
||||
prompt_position = "bottom"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user