Skip to content

Commit

Permalink
Merge pull request #15 from S1M0N38/dev
Browse files Browse the repository at this point in the history
Refactor: split init.lua into callbacks/utils/init
  • Loading branch information
S1M0N38 authored Sep 14, 2024
2 parents 78f4b1e + 1971d5e commit 86d253b
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 185 deletions.
31 changes: 13 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
______________________________________________________________________

> [!IMPORTANT]
> This is a heavily refactored version of the original dante.nvim plugin. If you want
> use the previous version, stick to the `a6955468391665d6465b371e81d1a80eac4cf0f1` commit.
> **Note on Version Compatibility**: This is a heavily refactored version of the original dante.nvim plugin. If you want to use the previous version, stick to the `a6955468391665d6465b371e81d1a80eac4cf0f1` commit.
## ⚡️ Requirements

Expand All @@ -29,11 +28,15 @@ ______________________________________________________________________

## 📦 Installation

You can install dante.nvim using your preferred plugin manager. Here's an example configuration for lazy.nvim:

```lua
-- using lazy.nvim
{
"S1M0N38/dante.nvim",
lazy = true,
cmd = "Dante",
version = "*",
opts = {
presets = {
["default"] = {
Expand All @@ -54,27 +57,19 @@ For a more complex configuration, check [my own config](https://github.com/S1M0N

## 🚀 Usage

Read the documentation with [`:help dante`](https://github.com/S1M0N38/dante.nvim/blob/main/doc/dante.txt)
To get started with dante.nvim, read the documentation with [`:help dante`](https://github.com/S1M0N38/dante.nvim/blob/main/doc/dante.txt). This will provide you with a comprehensive overview of the plugin's features and usage.

> [!NOTE]
> Vim/Neovim plugins are usually shipped with :help documentation. Learning how
> to navigate it is a valuable skill. If you are not familiar with it,
> start with `:help` and read the first 20 lines.
> **Learning Vim/Neovim Documentation**: Vim/Neovim plugins are usually shipped with :help documentation. Learning how to navigate it is a valuable skill. If you are not familiar with it, start with `:help` and read the first 20 lines.
> [!TIP]
> This plugin ships with a bare minimum configuration. The idea is that the
> user can define their own presets to interact with different LLM providers
> and customize the requests down to the last LLM parameter. The downside is
> that the opts table could become quite large and verbose, but in Neovim,
> configuration == code, so you can simplify it with utility functions.
> **Customizing Configuration**: This plugin ships with a bare minimum configuration. The idea is that the user can define their own presets to interact with different LLM providers and customize the requests down to the last LLM parameter. The downside is that the opts table could become quite large and verbose, but in Neovim, configuration == code, so you can simplify it with utility functions.
## 🙏 Acknowledgments

This plugin was inspired by:

- [jackMort/ChatGPT.nvim](https://github.com/jackMort/ChatGPT.nvim)
- [David-Kunz/gen.nvim](https://github.com/David-Kunz/gen.nvim)
- [Bryley/neoai.nvim](https://github.com/Bryley/neoai.nvim)
- [olimorris/codecompanion.nvim](https://github.com/olimorris/codecompanion.nvim)
This plugin was inspired by the following projects:

This README is a copycat of [lazy.nvim](https://github.com/folke/lazy.nvim)'s README.
* [jackMort/ChatGPT.nvim](https://github.com/jackMort/ChatGPT.nvim)
* [David-Kunz/gen.nvim](https://github.com/David-Kunz/gen.nvim)
* [Bryley/neoai.nvim](https://github.com/Bryley/neoai.nvim)
* [olimorris/codecompanion.nvim](https://github.com/olimorris/codecompanion.nvim)
62 changes: 29 additions & 33 deletions doc/dante.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ example, using `lazy.nvim`:
"S1M0N38/dante.nvim",
lazy = true,
cmd = "Dante",
version = "*",
opts = {
presets = {
["default"] = {
Expand All @@ -31,10 +32,7 @@ example, using `lazy.nvim`:
}
}
dependencies = {
{
"S1M0N38/ai.nvim",
version=">=1.1.0",
},
{ "S1M0N38/ai.nvim", version=">=1.1.0" },
}
}
<
Expand All @@ -43,11 +41,11 @@ Usually, in the installation example, the plugin author provides the bare
minimum setup. However, dante.nvim has very few options, so it makes sense to
discuss them here. Here is a breakdown of the previous example:

- `S1M0N38/dante.nvim`: Where to download the plugin hosted on GitHub.
- `S1M0N38/dante.nvim`: The plugin's GitHub repository.
- `cmd`: Load this plugin only when the `:Dante` command is called.
- `opts`: A table with plugin options. See |dante.setup()|.

So, with this configuration, when the command `:Dante` is called:
When the `:Dante` command is called:

1. The `dante.nvim` plugin is loaded
2. |dante.setup()| is called with the `opts` table
Expand All @@ -57,16 +55,16 @@ So, with this configuration, when the command `:Dante` is called:
*dante.setup()*
dante.setup({opts}) ~

The `dante.setup()` function is a convention used by many plugins to set up
options provided by the user. It's so common that `lazy.nvim` automatically
calls the `dante.setup()` function using the `opts` table.
The `dante.setup()` function sets up options provided by the user. It's so
common that `lazy.nvim` automatically calls the `dante.setup()` function
using the `opts` table.

The table `opts` that you specify will be merged with the default options,
which are:

>lua
{
-- Notify with extra information
-- Enable verbose notifications
verbose = false,

presets = {
Expand Down Expand Up @@ -108,50 +106,48 @@ dante.setup({opts}) ~
- `verbose`: If `true`, the plugin will notify you with extra information on
completion.

- `presets`: This is a list of presets. The preset `default` is the only
preset available at the moment. The idea is that you can craft various
presets for various situations (e.g., just fix typos, refine an email, add
emojis to a readme, reformat a doc, etc.). Presets can differ in provider,
model, generation parameters, stream and messages.
- `presets`: A list of presets. The preset `default` is the only preset
available at the moment. You can craft various presets for various
situations (e.g., just fix typos, refine an email, add emojis to a readme,
reformat a doc, etc.). Presets can differ in provider, model, generation
parameters, stream, and messages.

- `client`: The client options are used to connect to the provider's API.
- `client`: Client options for connecting to the provider's API.
- `base_url`: The base URL to connect to the provider's API
- `api_key`: The API key to authenticate with the provider's API.

- `request`: This is a request object which follows the same schema as the
OpenAI request object
- `request`: A request object following the OpenAI request object schema
(https://platform.openai.com/docs/api-reference/chat). OpenAI implements
plenty of options, but not all compatible APIs support all of them, only
the most common.

================================================================================
PLACEHOLDERS *dante-placeholders*

Placeholders are used to inject context in request messages. They have the
form `{{PLACEHOLDER_NAME}}`. The following placeholders are supported:
Placeholders inject context into request messages and have the form
`{{PLACEHOLDER_NAME}}`. The following placeholders are supported:

- `{{SELECTED_LINES}}`: The selected lines in the buffer. This selection is
obtained from the range given while using the `Dante` command. See
|dante-commands|.
- `{{SELECTED_LINES}}`: The selected lines in the buffer, obtained from the
range given while using the `Dante` command. See |dante-commands|.

- `{{NOW}}`: It will be replaced by the current date and time. For example:
"Today is Wed, 04 Sep 2024 08:22:32 +0200"
- `{{NOW}}`: Replaced by the current date and time, e.g., "Today is Wed, 04
Sep 2024 08:22:32 +0200"

The placeholders are processed as such only if they are defined in the preset.
If valid placeholders are present in the selected lines, they are not
processed and kept as they are. This choice helps keep the plugin simple and
avoid infinite loops.
Placeholders are processed only if defined in the preset. If valid
placeholders are present in the selected lines, they are not processed and
kept as they are. This choice keeps the plugin simple and avoids infinite
loops.

================================================================================
COMMANDS *dante-commands*

There is only one command provided by the plugin:

:{range}Dante [preset] ~
The `Dante` command requires a range to work. It will substitute the
placeholder `{{SELECTED_LINES}}` with the selected lines in the buffer and
query the LLM provider with the specified preset. If no preset is given, it
will use the default preset.
The `Dante` command requires a range to work. It substitutes the placeholder
`{{SELECTED_LINES}}` with the selected lines in the buffer and queries the
LLM provider with the specified preset. If no preset is given, it uses the
default preset.

The range can be specified in the following ways:
- `:'<,'>Dante` Run the command in visual mode to use the selected lines.
Expand Down
64 changes: 64 additions & 0 deletions lua/dante/callbacks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
local M = {}

---Callback function to handle the completion of a chat request.
---@param res table
---@param opts Options
---@return function
M.on_chat_completion = function(res, opts)
return function(obj)
local finish_reason = obj.choices[1].finish_reason
local content = obj.choices[1].message.content
if finish_reason == "stop" then
local lines = vim.split(content, "\n", { plain = true, trimempty = false })
vim.api.nvim_buf_set_lines(res.buf, -2, -1, true, lines)
if opts.verbose and obj.usage then
vim.notify("usage = " .. vim.inspect(obj.usage), vim.log.levels.INFO)
end
vim.notify("Done.", vim.log.levels.INFO)
else
vim.notify("An error occured during text genereation.", vim.log.levels.ERROR)
end
end
end

---Callback function to handle the completion chunk of a chat request.
---@param res table
---@param opts Options
---@return function
M.on_chat_completion_chunk = function(res, opts)
return function(obj)
local finish_reason = obj.choices[1].finish_reason
local content = obj.choices[1].delta.content
if finish_reason == vim.NIL then
local lines = vim.split(content, "\n", { plain = true, trimempty = false })
local last_line, last_column = require("dante.utils").last(res.buf)
vim.api.nvim_buf_set_text(res.buf, last_line, last_column, last_line, last_column, lines)
if opts.verbose and obj.usage then
vim.notify("usage = " .. vim.inspect(obj.usage), vim.log.levels.INFO)
end
elseif finish_reason == "stop" then
vim.notify("Done.", vim.log.levels.INFO)
else
vim.notify("An error occured during text genereation.", vim.log.levels.ERROR)
end
end
end

---Callback function to handle the exit of a chat request.
---@param res table
---@param req table
---@param opts Options
---@param after_lines string[]
---@return function
---@diagnostic disable-next-line: unused-local
M.on_exit = function(res, req, opts, after_lines)
return function()
vim.api.nvim_buf_set_lines(res.buf, -1, -1, true, after_lines)
vim.api.nvim_set_current_win(res.win)
vim.cmd("diffthis")
vim.api.nvim_set_current_win(req.win)
vim.cmd("diffthis")
end
end

return M
Loading

0 comments on commit 86d253b

Please sign in to comment.