Summary:
Now we are running the tests in neovim we get some output printed to stderr.
This is not helpful in the test output, and obfuscate errors.
This throws any unneeded output to `/dev/null` so we can focus of the tests
that have failed. It also moves over to using TAP output for a more descriptive
out put in CI.
Test Plan:
CI, running the test will validate this
Summary:
Now the users configuration and the default configuration is separated. This
will make it easier to setup ivy with some defaults. Right now we only have the
backends configurable however, it looks like we will be making other components
of ivy configurable.
To use this you can now call `ivy.setup` with no parameters and you will get
the default config. You can also call it with a partial config and if the
option is not found in the users config it will fallback to the users config
value.
Test Plan:
Manual testing and with unit tests in CI
Summary:
Now when using ivy.nvim you will need to call the `setup` function. This will
need to register any backends you want to use. This is an example config, this
can be put into a plugin in `~/.config/nvim/plugin/ivy.lua` for example.
```lua
require('ivy').setup {
backends = {
"ivy.backends.buffers",
"ivy.backends.files",
},
}
```
If you are using Lazy you can use the `config` directly to call the setup
function.
```lua
return {
"AdeAttwood/ivy.nvim",
build = "cargo build --release",
config = {
backends = {
"ivy.backends.buffers",
"ivy.backends.files",
}
}
}
```
The `setup` function can only be called once, if its called a second time any
backends or config will not be used. The module does expose the
`register_backend` function, this can be used to load backends before or after
the setup function is called.
```lua
require('ivy').register_backend("ivy.backends.files")
```
As well as the `register_backend` the core `run`function is exposed. With this
exposed we should be able to build anything we want.
```lua
vim.ivy.run(
"Title",
function(input)
return {
{ content = "One" },
{ content = "Two" },
{ content = "Three" },
}
end,
function(result) vim.cmd("edit " .. result) end
)
```
Test Plan:
Not much to test in this one, it has been tested locally on my config that does
not use any plugin managers, also a sandbox Lazy env using `NVIM_APPNAME`
NVIM_APPNAME
Summary:
Split out the register backend function from being a private function. A
backend is a table that will define all of the attributes for a run function.
The attributes are as follows:
- **command** The name of the command that will be registered as a vim user command.
- **items** The callback function that will be passed to the run function that will gather the items for selection
- **callback** The callback function run when an item is selected
The following are optional:
- **keymap** The string passed to `nvim_set_keymap`, this will always be registered in normal mode
- **description** The text description that will be used in the user command
- **name** The name of the backend, this will fallback to the command if its not set
It will also allow to register a backend in a couple of different ways:
- With a backend module table
- With a backend module name
- With a backend module name and override options
This will look for for a lua module `ivy.backends.files`. The module will be
required and registered as a backend.
```lua
register_backend "ivy.backends.files"
```
This will do the same with the module string however, before the backend is
registered the keymap will be overridden
```lua
register_backend({ "ivy.backends.file", { keymap = "<C-p>" } })
```
Test Plan:
CI / Manual testing locally
Summary:
This runs the new tests in our existing CI. We will remove the old tests later
when we know everything runs together so we know everything works.
Test Plan:
CI
Summary:
Right now we are using a custom test runner. This move the suite over to
busted, this will make things much more maintainable going forward. The two
main reasons for moving are.
1) The custom runner as some bugs, when running assertions we are not getting
the correct results.
2) All of the busted mocking features. We can use spy and mock, this will allow
us to remove the nvim_mock. This file is not amazing and confuses the lsp
often.
Test Plan:
CI
Summary:
Fixes an issue where you could not open files that were already open with ivy.
If the file path contains a square brackets and that file is already loaded
into a buffer, ivy will throw an error when trying to open it via "files" or
"buffers".
This is an issue with the file escaping before we try and cal `buffer` passing
in the file path to go to the buffer rather than open a new buffer.
This is common with JS frameworks like next js for parameters in file based
routing.
Test Plan:
Test have been added for this change. I have also added tests for the dollar
that was previously handled.
Instead of doing two passes of all candidates using map then a filter,
this uses `filter_map` so we are only doing one pass for the candidates.
This alone is quite a significant improvement of ~7%
Output of `./scripts/bench 0.x`
Benchmark 1: 0.x
Time (mean ± σ): 2.373 s ± 0.138 s [User: 10.617 s, System: 1.697 s]
Range (min … max): 2.124 s … 2.577 s 10 runs
Benchmark 2: HEAD
Time (mean ± σ): 2.206 s ± 0.133 s [User: 10.061 s, System: 1.811 s]
Range (min … max): 1.940 s … 2.433 s 10 runs
Summary
HEAD ran
1.08 ± 0.09 times faster than 0.x
-------------------------------------
The percentage difference is -7.00%
-------------------------------------
Move some of the iteration in to loa and access the values by the index
to reduce the number of loops we need todo to get items into teh results
buffer.
Currently the flow is:
1) Filter and sort the candidates in rust
2) Convert to a string and pass to lua
3) Split the string and add them as lines in a buffer in lua
Now the flow is:
1) Filter and sort the candidates in rust
2) Loop over an iterator in lua
3) Pass each item to lua as a pointer by the index
This removes quite a bit of the work that is needed to get the data into
lua as a table. We are first removing the loop that will join the
results vector into one string. Then we will remove the copy of this
string into lua. We will then finally remove the loop to split the
string and create a table from it in lua. All of this ends up in a 12%
speed up.
Output for `./scripts/bench 0.x`
Benchmark 1: HEAD
Time (mean ± σ): 2.667 s ± 0.065 s [User: 8.537 s, System: 1.420 s]
Range (min … max): 2.588 s … 2.767 s 10 runs
Benchmark 2: 0.x
Time (mean ± σ): 2.337 s ± 0.150 s [User: 9.564 s, System: 1.648 s]
Range (min … max): 2.161 s … 2.529 s 10 runs
Summary
HEAD ran
1.14 ± 0.08 times faster than 0.x
-------------------------------------
The percentage difference is -12.00%
-------------------------------------
This will quickly benchmark your current commit against a commit you
pass in. This will output the percentage difference so you can quickly
get an idea in the performance changes in your current work
once_cell has now been merged into rust core. This removes the
lazy_static dependency and migrates over to the built in `OnceLock`.
Its always good to remove dependencies where possible, this also give us
a preference for the built in `OnceLock`
```
Benchmark 1: chore: add benchmark for `set_items`
Time (mean ± σ): 6.327 s ± 0.199 s [User: 15.316 s, System: 1.323 s]
Range (min … max): 6.087 s … 6.712 s 10 runs
Benchmark 2: refactor: remove lazy_static
Time (mean ± σ): 6.171 s ± 0.251 s [User: 15.223 s, System: 1.382 s]
Range (min … max): 5.910 s … 6.776 s 10 runs
Summary
'refactor: remove lazy_static' ran
1.03 ± 0.05 times faster than 'chore: add benchmark for `set_items`'
```
Now when you paste and you are in an ivy buffer the paste will be added
to the prompt not into the completion window. You can use your usual
paste key binding I.E. <SHIFT>+<INSERT> <CTRL>+<SHIFT>+<V>
Ref: #11
Now we are useing the package.searchpath to find the libivyrs.so or
libivyrs.dylib. This is so it will load the correct library or the OS
you are on. This fixes the issues with loading the library on macOS.
Ref: #57
`rg` will now be used over `ag` if it is available. This is because `rg`
is a faster alternative reduces lag when searching larger codebases.
`ag` is also now conditionally loaded if the command is available.
Now when trying to open files and buffers it will use the `buffer`
command when there is an existing buffer with the same name. This will
allow us to open non file buffers like terminals and log buffers.
By using the `bufnr` function to get the existing buffers, it will also
work for buffers that have been renamed with `title` command
Ref: #31
When reading the output of a command we are now reading the stream line
by line and building the table of results. This will save us a loop of
the results later, if we returned a string we need to split the string
before adding each line to the completion buffer because nvim only
supports replacing one line at a time.
This makes the terminal go really funkie and sometimes crash when
printing the error messages to the current process stdout where nvim is
running.
Now the error output is sent to the `popen` output and displayed in the
ivy completion buffer without messing with the current process io.
We now have a concept of a 'backend' this is the same as the current
sorters and finders but with added info like the keymap so they can all
be registered as one. This will allow us to split our backends into
modues so we can better maintain then.