Giter Club home page Giter Club logo

parrot.nvim's Introduction

parrot.nvim ๐Ÿฆœ

This is parrot.nvim, the ultimate stochastic parrot to support your text editing inside Neovim.

Features โ€ข Demo โ€ข Getting Started โ€ข Commands โ€ข Configuration โ€ข Roadmap โ€ข FAQ

parrot.nvim logo

Warning

Version 0.4.x introduces breaking changes, including the removal of agents and modifications to some hook functions. Please review the updated documentation and adjust your configuration accordingly.

Note

This repository is still a work in progress, as large parts of the code are still being simplified and restructured. It is based on the brilliant work gp.nvim by https://github.com/Robitx.

I started this repository because a perplexity subscription provides $5 of API credits every month for free. Instead of letting them go to waste, I modified my favorite GPT plugin, gp.nvim, to meet my needs - a new Neovim plugin was born! ๐Ÿ”ฅ

Unlike gp.nvim, parrot.nvim prioritizes a seamless out-of-the-box experience by simplifying functionality and focusing solely on text generation, excluding the integration of DALL-E and Whisper.

Features

  • Persistent conversations as markdown files stored within the Neovim standard path or a user-defined location
  • Custom hooks for inline text editing and to start chats with predefined prompts
  • Support for multiple providers:
  • Flexible support for providing API credentials from various sources, such as environment variables, bash commands, and your favorite password manager CLI (lazy evaluation)
  • Provide repository-specific instructions with a .parrot.md file with the command PrtContext
  • No autocompletion and no hidden requests in the background to analyze your files

Demo

Seamlessly switch between providers and models.


Trigger code completions based on comments.


Let the parrot fix your bugs.


Rewrite a visual selection with `PrtRewrite`.

Append code with the visual selection as context with `PrtAppend`.

Add comments to a function with `PrtPrepend`.

Getting Started

Dependencies

lazy.nvim

{
  "frankroeder/parrot.nvim",
  tag = "v0.4.2",
  dependencies = { 'ibhagwan/fzf-lua', 'nvim-lua/plenary.nvim' },
  -- optionally include "rcarriga/nvim-notify" for beautiful notifications
  config = function()
    require("parrot").setup {
      -- Providers must be explicitly added to make them available.
      providers = {
        pplx = {
          api_key = os.getenv "PERPLEXITY_API_KEY",
          -- OPTIONAL
          -- gpg command
          -- api_key = { "gpg", "--decrypt", vim.fn.expand("$HOME") .. "/pplx_api_key.txt.gpg"  },
          -- macOS security tool
          -- api_key = { "/usr/bin/security", "find-generic-password", "-s pplx-api-key", "-w" },
        },
        openai = {
          api_key = os.getenv "OPENAI_API_KEY",
        },
        anthropic = {
          api_key = os.getenv "ANTHROPIC_API_KEY",
        },
        mistral = {
          api_key = os.getenv "MISTRAL_API_KEY",
        },
        gemini = {
          api_key = os.getenv "GEMINI_API_KEY",
        },
        groq = {
          api_key = os.getenv "GROQ_API_KEY",
        },
        ollama = {} -- provide an empty list to make provider available
      },
    }
  end,
}

Commands

Below are the available commands that can be configured as keybindings. These commands are included in the default setup. Additional useful commands are implemented through hooks (see my example configuration).

General

Command Description
PrtChatNew <target> open a new chat
PrtChatToggle <target> toggle chat (open last chat or new one)
PrtChatPaste <target> paste visual selection into the latest chat
PrtInfo print plugin config
PrtContext <target> edits the local context file
PrtChatFinder fuzzy search chat files using fzf
PrtChatDelete delete the current chat file
PrtChatRespond trigger chat respond (in chat file)
PrtStop interrupt ongoing respond
PrtProvider <provider> switch the provider (empty arg triggers fzf)
PrtModel <model> switch the model (empty arg triggers fzf)
Interactive
PrtRewrite Rewrites the visual selection based on a provided prompt
PrtAppend Append text to the visual selection based on a provided prompt
PrtPrepend Prepend text to the visual selection based on a provided prompt
PrtNew Prompt the model to respond in a new window
PrtEnew Prompt the model to respond in a new buffer
PrtVnew Prompt the model to respond in a vsplit
PrtTabnew Prompt the model to respond in a new tab
Example Hooks
PrtImplement takes the visual selection as prompt to generate code
PrtAsk Ask the model a question

With <target>, we indicate the command to open the chat within one of the following target locations (defaults to toggle_target):

  • popup: open a popup window which can be configured via the options provided below
  • split: open the chat in a horizontal split
  • vsplit: open the chat in a vertical split
  • tabnew: open the chat in a new tab

All chat commands (PrtChatNew, PrtChatToggle) and custom hooks support the visual selection to appear in the chat when triggered. Interactive commands require the user to make use of the template placeholders to consider a visual selection within an API request.

Configuration

Options

{
    -- The provider definitions include endpoints, API keys, default parameters,
    -- and topic model arguments for chat summarization, with an example provided for Anthropic.
    providers = {
      anthropic = {
        api_key = os.getenv "ANTHROPIC_API_KEY",
        endpoint = "https://api.anthropic.com/v1/messages",
        topic_prompt = "You only respond with 3 to 4 words to summarize the past conversation.",
        topic = {
          model = "claude-3-haiku-20240307",
          params = { max_tokens = 32 },
        },
        params = {
          chat = { max_tokens = 4096 },
          command = { max_tokens = 4096 },
        },
      },
      ...
    }

    -- default system prompts used for the chat sessions and the command routines
    system_prompt = {
      chat = ...,
      command = ...
    },

    -- the prefix used for all commands
    cmd_prefix = "Prt",

    -- optional parameters for curl
    curl_params = {},

    -- The directory to store persisted state information like the
    -- current provider and the selected models
    state_dir = vim.fn.stdpath("data"):gsub("/$", "") .. "/parrot/persisted",

    -- The directory to store the chats (searched with PrtChatFinder)
    chat_dir = vim.fn.stdpath("data"):gsub("/$", "") .. "/parrot/chats",

    -- Chat user prompt prefix
    chat_user_prefix = "๐Ÿ—จ:",

    -- llm prompt prefix
    llm_prefix = "๐Ÿฆœ:",

    -- Explicitly confirm deletion of a chat file
    chat_confirm_delete = true,

    -- Local chat buffer shortcuts
    chat_shortcut_respond = { modes = { "n", "i", "v", "x" }, shortcut = "<C-g><C-g>" },
    chat_shortcut_delete = { modes = { "n", "i", "v", "x" }, shortcut = "<C-g>d" },
    chat_shortcut_stop = { modes = { "n", "i", "v", "x" }, shortcut = "<C-g>s" },
    chat_shortcut_new = { modes = { "n", "i", "v", "x" }, shortcut = "<C-g>c" },

    -- Option to move the chat to the end of the file after finished respond
    chat_free_cursor = false,

     -- use prompt buftype for chats (:h prompt-buffer)
    chat_prompt_buf_type = false,

    -- Default target for  PrtChatToggle, PrtChatNew, PrtContext and the chats opened from the ChatFinder
    -- values: popup / split / vsplit / tabnew
    toggle_target = "vsplit",

    -- The interactive user input appearing when can be "native" for
    -- vim.ui.input or "buffer" to query the input within a native nvim buffer
    -- (see video demonstrations below)
    user_input_ui = "native",

    -- Popup window layout
    -- border: "single", "double", "rounded", "solid", "shadow", "none"
    style_popup_border = "single",

    -- margins are number of characters or lines
    style_popup_margin_bottom = 8,
    style_popup_margin_left = 1,
    style_popup_margin_right = 2,
    style_popup_margin_top = 2,
    style_popup_max_width = 160

    -- Prompt used for interactive LLM calls like PrtRewrite where {{llm}} is
    -- a placeholder for the llm name
    command_prompt_prefix_template = "๐Ÿค– {{llm}} ~ ",

    -- auto select command response (easier chaining of commands)
    -- if false it also frees up the buffer cursor for further editing elsewhere
    command_auto_select_response = true,

    -- fzf_lua options for PrtModel and PrtChatFinder when plugin is installed
    fzf_lua_opts = {
        ["--ansi"] = true,
        ["--sort"] = "",
        ["--info"] = "inline",
        ["--layout"] = "reverse",
        ["--preview-window"] = "nohidden:right:75%",
    },

    -- Enables the query spinner animation 
    enable_spinner = true,
    -- Type of spinner animation to display while loading
    -- Available options: "dots", "line", "star", "bouncing_bar", "bouncing_ball"
    spinner_type = "star",
}

Demonstrations

With `user_input_ui = "native"`, use `vim.ui.input` as slim input interface.
With `user_input_ui = "buffer"`, your input is simply a buffer. All of the content is passed to the API when closed.
The spinner is a useful indicator for providers that take longer to respond.

Key Bindings

This plugin provides the following default key mappings:

Keymap Description
<C-g>c Opens a new chat via PrtChatNew
<C-g><C-g> Trigger the API to generate a response via PrtChatRespond
<C-g>s Stop the current text generation via PrtStop
<C-g>d Delete the current chat file via PrtChatDelete

Adding a new command

Ask a single-turn question and receive the answer in a popup window

require("parrot").setup {
    -- ...
    hooks = {
      Ask = function(parrot, params)
        local template = [[
          In light of your existing knowledge base, please generate a response that
          is succinct and directly addresses the question posed. Prioritize accuracy
          and relevance in your answer, drawing upon the most recent information
          available to you. Aim to deliver your response in a concise manner,
          focusing on the essence of the inquiry.
          Question: {{command}}
        ]]
        local model_obj = parrot.get_model("command")
        parrot.logger.info("Asking model: " .. model_obj.name)
        parrot.Prompt(params, parrot.ui.Target.popup, model_obj, "๐Ÿค– Ask ~ ", template)
      end,
    }
    -- ...
}

Start a chat with a predefined chat prompt to check your spelling.

require("parrot").setup {
    -- ...
    hooks = {
      SpellCheck = function(prt, params)
        local chat_prompt = [[
          Your task is to take the text provided and rewrite it into a clear,
          grammatically correct version while preserving the original meaning
          as closely as possible. Correct any spelling mistakes, punctuation
          errors, verb tense issues, word choice problems, and other
          grammatical mistakes.
        ]]
        prt.ChatNew(params, chat_prompt)
      end,
    }
    -- ...
}

Refer to my personal lazy.nvim setup for further hooks and key bindings: https://github.com/frankroeder/dotfiles/blob/master/nvim/lua/plugins/parrot.lua

Template Placeholders

Users can utilize the following placeholders in their templates to inject specific content into the user messages or custom system prompts:

Placeholder Content
{{selection}} Current visual selection
{{filetype}} Filetype of the current buffer
{{filepath}} Full path of the current file
{{filecontent}} Full content of the current buffer
{{multifilecontent}} Full content of all open buffers

Below is an example of how to use these placeholders in a completion hook, which receives the full file context and the selected code snippet as input.

require("parrot").setup {
    -- ...
    hooks = {
    	CompleteFullContext = function(prt, params)
          local template = [[
          I have the following code from {{filename}}:

          ```{{filetype}}
          {{filecontent}}
          ```

          Please look at the following section specifically:
          ```{{filetype}}
          {{selection}}
          ```

          Please finish the code above carefully and logically.
          Respond just with the snippet of code that should be inserted.
          ]]
          local model_obj = prt.get_model()
          prt.Prompt(params, prt.ui.Target.append, model_obj, nil, template)
        end,
    }
    -- ...
}

The placeholders {{filetype}} and {{filecontent}} can also be used in the chat_prompt when creating custom hooks calling prt.ChatNew(params, chat_prompt) to directly inject the whole file content.

require("parrot").setup {
    -- ...
      CodeConsultant = function(prt, params)
        local chat_prompt = [[
          Your task is to analyze the provided {{filetype}} code and suggest
          improvements to optimize its performance. Identify areas where the
          code can be made more efficient, faster, or less resource-intensive.
          Provide specific suggestions for optimization, along with explanations
          of how these changes can enhance the code's performance. The optimized
          code should maintain the same functionality as the original code while
          demonstrating improved efficiency.

          Here is the code
          ```{{filetype}}
          {{filecontent}}
          ```
        ]]
        prt.ChatNew(params, chat_prompt)
      end,
    }
    -- ...
}

Roadmap

  • Add status line integration/ notifications for summary of tokens used or money spent
  • Improve the documentation
  • Create a tutorial video
  • Reduce overall code complexity and improve robustness

FAQ

  • I am encountering errors related to the state.

    If the state is corrupted, simply delete the file ~/.local/share/nvim/parrot/persisted/state.json.

  • The completion feature is not functioning, and I am receiving errors.

    Ensure that you have an adequate amount of API credits and examine the log file ~/.local/state/nvim/parrot.nvim.log for any errors.

  • I have discovered a bug, have a feature suggestion, or possess a general idea to enhance this project.

    Everyone is invited to contribute to this project! If you have any suggestions, ideas, or bug reports, please feel free to submit an issue.

Related Projects

Star History

Star History Chart

parrot.nvim's People

Contributors

argshook avatar denismaciel avatar dioprz avatar dkuku avatar eltociear avatar eterps avatar frankroeder avatar github-actions[bot] avatar isak102 avatar jayeheffernan avatar judaew avatar lintaoamons avatar mindshade avatar mrgrinst avatar oliverchao avatar rob-3 avatar robitx avatar tarruda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

parrot.nvim's Issues

Restructure system promp Anthropic

          With respect to my earlier comment:

Are you referring to further cleanup or the planning of new features to add?

I think we still need to fix the system prompt issue with Anthropic (i.e. giving the provider configurations the same structure for end-users).

Because I just discovered a bug. If you activate a custom command using Anthropic provider and switch back to a general chat window, the system prompt keeps the value of the (previously activated) custom command (messing up the general chat system prompt).

Originally posted by @eterps in #23 (comment)

[sugestion] AI completion

How hard would it be to generate suggestions based on n-lines before and m-lines after? But I mean something that will work with LSP.

Just a thought

Hey Frank,
about a month ago I've got back to the active development of Gp.nvim - multi provider branch got merged, code base got split and cleaned up, whisper and imager are now in modules which can be completely disabled with single config option, etc.

So when I got around to "exploring the state of the competition" I thought it's a shame there are several projects converging on very similar target. On one hand yes, competition is good yadda yadda yadda, on the other hand instead of collaborating and getting to the target faster, we're fragmenting the user base and wasting available man power (since any meaningful improvement will be sooner than later absorbed by "competing projects").

If you have significant emotional attachment the the Parrot and it's a kid project you're unwilling to leave behind, then it's fine by me and by all means go ahead.

If you don't have any significant emotional attachment to it and your goal is to have AI integration Neovim users (including two of us) deserve and are satisfied with - did you notice any philosophical/design differences which would make collaboration impossible? If not, I'd give you maintainer access to Gp without blink of an eye.

Tibor

PS: There is a Gp's Discord in case you would want to talk in real time.

Deprecation warning for `vim.tbl_add_reverse_lookup`

I am getting this warning when loading parrot.nvim on NVIM v0.11.0-dev+d62d181.

vim.deprecated: require("vim.deprecated.health").check()

 ~
- WARNING vim.tbl_add_reverse_lookup is deprecated. Feature will be removed in Nvim 0.12
  - ADVICE:
    - stack traceback:
        /home/denis/.local/share/nvim/lazy/typescript-tools.nvim/lua/typescript-tools/protocol/module_mapper.lua:21
        [C]:-1
        /home/denis/.local/share/nvim/lazy/typescript-tools.nvim/lua/typescript-tools/tsserver.lua:6
        [C]:-1
        /home/denis/.local/share/nvim/lazy/typescript-tools.nvim/lua/typescript-tools/rpc.lua:3
        [C]:-1
        /home/denis/.local/share/nvim/lazy/typescript-tools.nvim/lua/typescript-tools/init.lua:4
        [C]:-1
        /home/denis/.config/nvim/lua/init.lua:1001
        /home/denis/.local/share/nvim/lazy/lazy.nvim/lua/lazy/core/loader.lua:366
        [C]:-1
        /home/denis/.local/share/nvim/lazy/lazy.nvim/lua/lazy/core/util.lua:113
        /home/denis/.local/share/nvim/lazy/lazy.nvim/lua/lazy/core/loader.lua:381
        /home/denis/.local/share/nvim/lazy/lazy.nvim/lua/lazy/core/loader.lua:348
        /home/denis/.local/share/nvim/lazy/lazy.nvim/lua/lazy/core/loader.lua:191
        /home/denis/.local/share/nvim/lazy/lazy.nvim/lua/lazy/core/handler/event.lua:83
        [C]:-1
        /home/denis/.local/share/nvim/lazy/parrot.nvim/lua/parrot/init.lua:856
        /home/denis/.local/share/nvim/lazy/parrot.nvim/lua/parrot/init.lua:964
        /home/denis/.local/share/nvim/lazy/parrot.nvim/lua/parrot/init.lua:203

[Bug] parrot.nvim: messages.0.role: Input should be 'user' or 'assistant'

Today, Anthropic API has changed to return the following error.

parrot.nvim: messages.0.role: Input should be 'user' or 'assistant'
Screenshot 2024-05-06 at 9 44 14

The log of the payload is here.

parrot.nvim: M.query(): payload: {
  max_tokens = 4096,
  messages = { {
      content = "",
      role = ""
    }, {
      content = "hello",
      role = "user"
    } },
  model = "claude-3-haiku-20240307",
  stream = true,
  system = "You are a versatile AI assistant with capabilities\nextending to general knowledge and coding support. Whe
n engaging\nwith users, please adhere to the following guidelines to ensure\nthe highest quality of interaction:\n\n-
Admit when unsure by saying 'I don't know.'\n- Ask for clarification when needed.\n- Use first principles thinking to
analyze queries.\n- Start with the big picture, then focus on details.\n- Apply the Socratic method to enhance underst
anding.\n- Include all necessary code in your responses.\n- Stay calm and confident with each task.\n"
}

I make it work with the following changes.

$ git diff
diff --git a/lua/parrot/init.lua b/lua/parrot/init.lua
index cf19ce0..8248c71 100644
--- a/lua/parrot/init.lua
+++ b/lua/parrot/init.lua
@@ -1155,6 +1155,13 @@ M.chat_respond = function(params)
     message.content = message.content:gsub("^%s*(.-)%s*$", "%1")
   end

+  -- remove a message if it's role is empty
+  for i = #messages, 1, -1 do
+    if messages[i].role == "" then
+      table.remove(messages, i)
+    end
+  end
+
   -- write assistant prompt
   local last_content_line = utils.last_content_line(buf)
   vim.api.nvim_buf_set_lines(buf, last_content_line, last_content_line, false, { "", agent_prefix .. agent_suffix, "" })

PrtProvider and PrtAgent doesn't accept args, always run fzf

After updating to the last version of parrot.nvim, I've encountered an error with PrtProvied and PrtAgent. I've defined custom shortcuts that were relying on both of those commands to accept parameters, but after the update the shortcuts stopped working. I've run the commands manually, and even when I did it like :PrtProvider openai it opened fzf window where I had to select provied, as if the "openai" argument was ignored. The same problem was with PrtAgent.

I've prepared simple fix for this on my fork: https://github.com/lzieniew/parrot.nvim and it works for my purposes.
If you are interested in merging it I can open a Pull request - but it's a quick fix and a bit messy, so you might want to rework it

Features compared to cursor editor

I've been evaluating the cursor editor to know what was usable and not and there are a couple of things (some are implemented and some are not).

Below is a table of some of the features I saw myself using either from time to time or often. Not sure if there are any plans to support these different features but thought I would add it anyway. Also, there might be a way to do this already with Parrot that I am just not aware of!

Feature Cursor Parrot
Visual select and ask question to change/implement โœ… cmd+k โœ…
Ask a question around the current file โœ… cmd+l Kinda (you have to copy the entire file content and ask with that context)
Full context search (uses the entire context of the project and ask a question) โœ… cmd+l then cmd+enter when asking โŒ

Increase visibility of this project

@frankroeder I'm really happy with parrot.nvim, I like that it is based on gp.nvim while allowing other providers as well.
I think it might be useful to let more users know that this project exists by announcing it at:

https://www.reddit.com/r/neovim/

r/neovim is a pretty active community and it will increase the visibility of this project.

Let me know what you think, I'd rather let you announce the project. But if you're actively avoiding Reddit let me know, I'd be happy to do it for you instead.

[suggestion] Ask for additional buffer context via user input

There are cases where it would be nice for the LLM to have the context of another file I have open. I don't have a good idea yet on the implementation specifics but I'm wondering if you would be open to a PR that prompts the user for additional buffers to include as context for the LLM.

a nil value

Whatever I do, I end up with the following issue:

 ๎ช‡  Error  03:14:26 notify.error lazy.nvim Failed to run `config` for parrot.nvim

/home/tofi/.config/lazy/lua/plugins/parrot.lua:12: attempt to call field 'setup' (a nil value)

# stacktrace:
  - parrot.lua:12 _in_ **config**

I have tried the default config, your config, but the result is the same - a nill value while calling config. I noticed that there is something about running without a user prompt inherited from gp.nvim, but I could not figure out an alternative value for it.

BTW, I use only perplexity API key; open AI is removed from my config.

PrtChatRespond results in ".... does not look like a chat file"

I've gone through the configuration and is using the following config.

	{
		"frankroeder/parrot.nvim",
		tag = "v0.3.7",
		dependencies = { "ibhagwan/fzf-lua", "nvim-lua/plenary.nvim" },
		-- optionally include "rcarriga/nvim-notify" for beautiful notifications
		config = function()
			require("parrot").setup({
				providers = {
					anthropic = {
						api_key = os.getenv "ANTHROPIC_API_KEY",
					},
				},
			})
		end,
	},

The chat file is named ~/.local/share/nvim/parrot/chats/2024-07-26.14-53-45.300.md, and opened through :PrtChatNew and tried to respond with :PrtChatRespond.

Am I missing something in the config?

Working configuration for lazyvim users

Just in case someone is using lazyvim, here is my configuration.

return {
  {
    "frankroeder/parrot.nvim",
    -- OPTIONAL dependency
    dependencies = { "fzf-lua" },
    -- OPTIONAL condition
    cond = os.getenv("OPENAI_API_KEY") ~= nil or os.getenv("PERPLEXITY_API_KEY") ~= nil,
    config = function()
      local cmd_prefix = "Prt"
      require("parrot").setup({
        providers = {
          pplx = {
            api_key = os.getenv("PERPLEXITY_API_KEY"),
            -- OPTIONAL
            -- gpg command
            -- api_key = { "gpg", "--decrypt", vim.fn.expand("$HOME") .. "/pplx_api_key.txt.gpg"  },
            -- macOS security tool
            -- api_key = { "/usr/bin/security", "find-generic-password", "-s pplx-api-key", "-w" },
          },
        },
        cmd_prefix = cmd_prefix,
        chat_conceal_model_params = false,
        hooks = {
          Complete = function(prt, params)
            local template = [[
        I have the following code from {{filename}}:

        ```{{filetype}}
        {{selection}}
        ```

        Please finish the code above carefully and logically.
        Respond just with the snippet of code that should be inserted."
        ]]
            local agent = prt.get_command_agent()
            prt.Prompt(params, prt.Target.append, nil, agent.model, template, agent.system_prompt, agent.provider)
          end,
          Explain = function(prt, params)
            local template = [[
        Explain the following code from {{filename}}:

        ```{{filetype}}
        {{selection}}
        ```

        Use the markdown format with codeblocks.
        A brief explanation of what the code above is doing:
        ]]
            local agent = prt.get_chat_agent()
            prt.logger.info("Explaining selection with agent: " .. agent.name)
            prt.Prompt(params, prt.Target.popup, nil, agent.model, template, agent.system_prompt, agent.provider)
          end,
          FixBugs = function(prt, params)
            local template = [[
        You are an expert in {{filetype}}.
        Fix bugs in the below code from {{filename}} carefully and logically:

        ```{{filetype}}
        {{selection}}
        ```

        Fixed code:
        ]]
            local agent = prt.get_command_agent()
            prt.logger.info("Fixing bugs in selection with agent: " .. agent.name)
            prt.Prompt(params, prt.Target.popup, nil, agent.model, template, agent.system_prompt, agent.provider)
          end,
          Optimize = function(prt, params)
            local template = [[
        You are an expert in {{filetype}}.
        Optimize the following code from {{filename}}:

        ```{{filetype}}
        {{selection}}
        ```

        Optimized code:
        ]]
            local agent = prt.get_command_agent()
            prt.logger.info("Optimizing selection with agent: " .. agent.name)
            prt.Prompt(params, prt.Target.popup, nil, agent.model, template, agent.system_prompt, agent.provider)
          end,
          UnitTests = function(prt, params)
            local template = [[
        I have the following code from {{filename}}:

        ```{{filetype}}
        {{selection}}
        ```

        Please respond by writing table driven unit tests for the code above.
        ]]
            local agent = prt.get_command_agent()
            prt.logger.info("Creating unit tests for selection with agent: " .. agent.name)
            prt.Prompt(params, prt.Target.enew, nil, agent.model, template, agent.system_prompt, agent.provider)
          end,
          ProofReader = function(prt, params)
            local chat_system_prompt = [[
        I want you to act as a proofreader. I will provide you with texts and
        I would like you to review them for any spelling, grammar, or
        punctuation errors. Once you have finished reviewing the text,
        provide me with any necessary corrections or suggestions to improve the
        text. Highlight the corrections with markdown bold or italics style.
        ]]
            local agent = prt.get_chat_agent()
            prt.logger.info("Proofreading selection with agent: " .. agent.name)
            prt.cmd.ChatNew(params, agent.model, chat_system_prompt)
          end,
          Debug = function(prt, params)
            local template = [[
        I want you to act as {{filetype}} expert.
        Review the following code, carefully examine it, and report potential
        bugs and edge cases alongside solutions to resolve them.
        Keep your explanation short and to the point:

        ```{{filetype}}
        {{selection}}
        ```
        ]]
            local agent = prt.get_chat_agent()
            prt.logger.info("Debugging selection with agent: " .. agent.name)
            prt.Prompt(params, prt.Target.enew, nil, agent.model, template, agent.system_prompt, agent.provider)
          end,
        },
      })
    end,
    keys = {
      -- Normal and Insert mode mappings
      { "<C-g>c", "<cmd>PrtChatNew<cr>", mode = { "n", "i" }, desc = "New Chat" },
      { "<C-g>t", "<cmd>PrtChatToggle tabnew<cr>", mode = { "n", "i" }, desc = "Toggle Popup Chat" },
      { "<C-g>f", "<cmd>PrtChatFinder<cr>", mode = { "n", "i" }, desc = "Chat Finder" },
      { "<C-g>r", "<cmd>PrtRewrite<cr>", mode = { "n", "i" }, desc = "Inline Rewrite" },
      { "<C-g>a", "<cmd>PrtAppend<cr>", mode = { "n", "i" }, desc = "Append" },
      { "<C-g>o", "<cmd>PrtPrepend<cr>", mode = { "n", "i" }, desc = "Prepend" },

      -- Visual mode mappings
      { "<C-g>c", "<cmd>PrtChatNew<cr>", mode = "v", desc = "Visual Chat New" },
      { "<C-g>r", "<cmd>PrtRewrite<cr>", mode = "v", desc = "Visual Rewrite" },
      { "<C-g>a", "<cmd>PrtAppend<cr>", mode = "v", desc = "Visual Append" },
      { "<C-g>o", "<cmd>PrtPrepend<cr>", mode = "v", desc = "Visual Prepend" },
      { "<C-g>e", "<cmd>PrtEnew<cr>", mode = "v", desc = "Visual Enew" },

      -- Additional mappings
      { "<C-g>s", "<cmd>PrtStop<cr>", mode = { "n", "i", "v", "x" }, desc = "Stop" },
      { "<C-g>i", "<cmd>PrtComplete<cr>", mode = { "n", "i", "v", "x" }, desc = "Complete the visual selection" },

      -- Context and agent/provider selection mappings
      { "<C-g>x", "<cmd>PrtContext<cr>", mode = "n", desc = "Open file with custom context" },
      { "<C-g>n", "<cmd>PrtAgent<cr>", mode = "n", desc = "Select agent or show info" },
      { "<C-g>p", "<cmd>PrtProvider<cr>", mode = "n", desc = "Select provider or show info" },
    },
  },
}


P.S. I get rid of refactoring the keymap as it obscures readability. This should be a human-readable config file, not an efficient code.

bug: Gemini sometimes doesn't provide the full answer

Hi @frankroeder! Hope you are well.

I have been using Gemini a lot, and while most of the time it works incredibly well, sometimes it doesn't give me the full response.

While I could like to give you a way to reproduce the error, I'm still unable to find it. However, I have one conversation with the same error three times in a row. The responses are bash scripts where they don't write the code block close string (```), and they also feel kind of incomplete.

I email you with the details in case that could help. Also let me know if you need another API key.

Thanks for all your work man. It has been a pleasure to work with such variety of models directly in Neovim.

Docs regarding templates with `ChatToggle`

There is no clear documentation in how to add in hooks with a new / toggle chat but only with popups.

For example in the cursor editor you would do <cmd>+l which would have the context of the current file and put you into chat mode, tapping it again would close and then open with a new chat instance with the current file context. If you would open a new file it would do the same with that as the current file context.

Often times it doesn't get it right the first time and you would have to do additional prompting to get into a good state, so a popup without chat doesn't really cut it most of the time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.