Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve config #39

Merged
merged 6 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 117 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,129 @@ vim.call('plug#end')
require('magenta').setup()
```

# Usage
# Config

<details>
<summary>Default options</summary>

```lua
require('magenta').setup({
provider = "anthropic",
openai = {
model = "gpt-4o"
},
anthropic = {
model = "claude-3-5-sonnet-latest"
},
bedrock = {
model = "anthropic.claude-3-5-sonnet-20241022-v2:0",
prompt_caching = false
},
-- open chat sidebar on left or right side
sidebar_position = "left",
-- can be changed to "telescope"
picker = "fzf-lua",
-- enable default keymaps shown below
default_keymaps = true,
-- keymaps for the sidebar input buffer
sidebar_keymaps = {
normal = {
["<CR>"] = ":Magenta send<CR>",
}
},
-- keymaps for the inline edit input buffer
-- if keymap is set to function, it accpets a target_bufnr param
inline_keymaps = {
normal = {
["<CR>"] = function(target_bufnr)
vim.cmd("Magenta submit-inline-edit " .. target_bufnr)
end,
},
}
})
```

## keymaps
</details>

Global keymaps are set [here](https://github.com/dlants/magenta.nvim/blob/main/lua/magenta/init.lua#L12).
If `default_keymaps` is set to true, the plugin will configure the following global keymaps:

Input and display buffer keymaps are set [here](https://github.com/dlants/magenta.nvim/blob/main/node/sidebar.ts#L87).
<details>
<summary>Default keymaps</summary>

Commands are all nested under `:Magenta <cmd>`, and can be found [here](https://github.com/dlants/magenta.nvim/blob/main/node/magenta.ts#L54).
```lua
local Actions = require("magenta.actions")

vim.keymap.set(
"n",
"<leader>mc",
":Magenta clear<CR>",
{silent = true, noremap = true, desc = "Clear Magenta state"}
)

vim.keymap.set(
"n",
"<leader>ma",
":Magenta abort<CR>",
{silent = true, noremap = true, desc = "Abort current Magenta operation"}
)

vim.keymap.set(
"n",
"<leader>mt",
":Magenta toggle<CR>",
{silent = true, noremap = true, desc = "Toggle Magenta window"}
)

vim.keymap.set(
"n",
"<leader>mi",
":Magenta start-inline-edit<CR>",
{silent = true, noremap = true, desc = "Inline edit"}
)

vim.keymap.set(
"v",
"<leader>mi",
":Magenta start-inline-edit-selection<CR>",
{silent = true, noremap = true, desc = "Inline edit selection"}
)

vim.keymap.set(
"v",
"<leader>mp",
":Magenta paste-selection<CR>",
{silent = true, noremap = true, desc = "Send selection to Magenta"}
)

vim.keymap.set(
"n",
"<leader>mb", -- like "magenta buffer"?
Actions.add_buffer_to_context,
{ noremap = true, silent = true, desc = "Add current buffer to Magenta context" }
)

vim.keymap.set(
"n",
"<leader>mf",
Actions.pick_context_files,
{ noremap = true, silent = true, desc = "Select files to add to Magenta context" }
)

vim.keymap.set(
"n",
"<leader>mp",
Actions.pick_provider,
{ noremap = true, silent = true, desc = "Select provider and model" }
)
```

</details>

# Usage

TLDR:
### Chat

- `<leader>mt` is for `:Magenta toggle`, will toggle the sidebar on and off.
- `<leader>mp` is for `:Magenta paste-selection`. In visual mode it will take the current selection and paste it into the input buffer.
- `<leader>mb` is for `:Magenta context-files` with your _current_ file. It will pin the current file to your context.
- `<leader>mf` is for `:Magenta context-files` it allows you to select files via fzf-lua or telescope, and will pin those files to your context. This requires that fzf-lua or telescope are installed.
- `<leader>mc` is for `:Magenta clear`, which will clear the current chat.
- `<leader>ma` is for `:Magenta abort`, which will abort the current in-flight request.
- `<leader>mt` is for `:Magenta toggle`. This will open a sidebar where you can chat with the model. You can add files to the context with `Magenta context-files` (`<leader>mf`), or paste your current visual selection with `Magenta paste-selection` (`<leader>mp`)

### Inline edit

Expand Down
80 changes: 80 additions & 0 deletions lua/magenta/actions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
local M = {}

local Options = require("magenta.options")

local fzf_files = function()
local fzf = require("fzf-lua")
fzf.files(
{
raw = true, -- return just the raw path strings
actions = {
["default"] = function(selected)
local escaped_files = {}
for _, entry in ipairs(selected) do
table.insert(escaped_files, vim.fn.shellescape(fzf.path.entry_to_file(entry).path))
end
vim.cmd("Magenta context-files " .. table.concat(escaped_files, " "))
end
}
}
)
end

local telescope_files = function()
local builtin = require("telescope.builtin")
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
builtin.find_files({
prompt_title = "Select context files",
attach_mappings = function(prompt_bufnr)
actions.select_default:replace(function()
local picker = action_state.get_current_picker(prompt_bufnr)
local selected_entries = picker:get_multi_selection()
if vim.tbl_isempty(selected_entries) then
selected_entries = { action_state.get_selected_entry() }
end
actions.close(prompt_bufnr)
local escaped_files = {}
for _, entry in ipairs(selected_entries) do
table.insert(escaped_files, vim.fn.shellescape(entry.path))
end
if not vim.tbl_isempty(escaped_files) then
vim.cmd("Magenta context-files " .. table.concat(escaped_files, " "))
end
end)
return true
end,
})
end


M.pick_context_files = function()
if Options.options.picker == "fzf-lua" then
fzf_files()
elseif Options.options.picker == "telescope" then
telescope_files()
else
vim.notify("Neither fzf-lua nor telescope are installed!", vim.log.levels.ERROR)
end
end

M.pick_provider = function()
local items = {
'openai gpt-4o',
'openai o1',
'openai o1-mini',
'anthropic claude-3-5-sonnet-latest'
}
vim.ui.select(items, { prompt = "Select Model", }, function (choice)
if choice ~= nil then
vim.cmd("Magenta provider " .. choice )
end
end)
end

M.add_buffer_to_context = function()
local current_file = vim.fn.expand("%:p")
vim.cmd("Magenta context-files " .. vim.fn.shellescape(current_file))
end

return M
135 changes: 12 additions & 123 deletions lua/magenta/init.lua
Original file line number Diff line number Diff line change
@@ -1,130 +1,12 @@
local Utils = require("magenta.utils")
local Options = require("magenta.options")
local Actions = require("magenta.actions")
local M = {}

M.defaults = {
provider = "anthropic",
openai = {
model = "gpt-4o"
},
anthropic = {
model = "claude-3-5-sonnet-20241022"
},
bedrock = {
model = "anthropic.claude-3-5-sonnet-20241022-v2:0",
promptCaching = false
}
}

M.setup = function(opts)
M.options = vim.tbl_deep_extend("force", M.defaults, opts or {})
if (M.options.picker == nil) then
local success, _ = pcall(require, "fzf-lua")
if success then
M.options.picker = "fzf-lua"
else
success, _ = pcall(require, "telescope")
if success then
M.options.picker = "telescope"
end
end
end

Options.set_options(opts)
M.start(true)
vim.api.nvim_set_keymap(
"n",
"<leader>mc",
":Magenta clear<CR>",
{silent = true, noremap = true, desc = "Clear Magenta state"}
)
vim.api.nvim_set_keymap(
"n",
"<leader>ma",
":Magenta abort<CR>",
{silent = true, noremap = true, desc = "Abort current Magenta operation"}
)
vim.api.nvim_set_keymap(
"n",
"<leader>mt",
":Magenta toggle<CR>",
{silent = true, noremap = true, desc = "Toggle Magenta window"}
)
vim.api.nvim_set_keymap(
"n",
"<leader>mi",
":Magenta start-inline-edit<CR>",
{silent = true, noremap = true, desc = "Inline edit"}
)
vim.api.nvim_set_keymap(
"v",
"<leader>mi",
":Magenta start-inline-edit-selection<CR>",
{silent = true, noremap = true, desc = "Inline edit selection"}
)
vim.api.nvim_set_keymap(
"v",
"<leader>mp",
":Magenta paste-selection<CR>",
{silent = true, noremap = true, desc = "Send selection to Magenta"}
)
vim.api.nvim_set_keymap(
"n",
"<leader>mb", -- like "magenta buffer"?
"",
{
noremap = true,
silent = true,
desc = "Add current buffer to Magenta context",
callback = function()
local current_file = vim.fn.expand("%:p")
vim.cmd("Magenta context-files " .. vim.fn.shellescape(current_file))
end
}
)

vim.api.nvim_set_keymap(
"n",
"<leader>mf",
"",
{
noremap = true,
silent = true,
desc = "Select files to add to Magenta context",
callback = function()
if M.options.picker == "fzf-lua" then
Utils.fzf_files()
elseif M.options.picker == "telescope" then
Utils.telescope_files()
else
vim.notify("Neither fzf-lua nor telescope are installed!", vim.log.levels.ERROR)
end
end
}
)

vim.api.nvim_set_keymap(
"n",
"<leader>mp",
"",
{
noremap = true,
silent = true,
desc = "Select provider and model",
callback = function()
local items = {
'openai gpt-4o',
'openai o1',
'openai o1-mini',
'anthropic claude-3-5-sonnet-latest'
}
vim.ui.select(items, { prompt = "Select Model", }, function (choice)
if choice ~= nil then
vim.cmd("Magenta provider " .. choice )
end
end)
end
}
)

require("magenta.keymaps").default_keymaps()
end

M.testSetup = function()
Expand Down Expand Up @@ -207,7 +89,14 @@ M.bridge = function(channelId)
vim.rpcnotify(channelId, "magentaLspResponse", {requestId, response})
end

return M.options
local opts = Options.options
return {
provider = opts.provider,
anthropic = opts.anthropic,
openai = opts.openai,
bedrock = opts.bedrock,
sidebar_position = opts.sidebar_position
}
end

M.wait_for_lsp_attach = function(bufnr, capability, timeout_ms)
Expand Down
Loading
Loading