David-Kunz / gen.nvim

Neovim plugin to generate text using LLMs with customizable prompts
The Unlicense
992 stars 64 forks source link

Add Telescope Support and prepare for lasting Sessions #46

Closed cloud-wanderer closed 3 months ago

cloud-wanderer commented 7 months ago

Hello Everyone,

First of all thanks for the great plugin @David-Kunz.

I'd like to propose some new features. As I see this as a discussion, I'll not yet make separate topics for each, to not spam the issues list. The development of the plugin is very fast, so some things might be redundant now.

  1. Adding Support for Telescope
  2. No static model, either configure a model in the prompt or let the user select
  3. Option for vertical split for comparisons (also prep for chat) (Less focus on temporary floats)
  4. Multi-line prompts
  5. Selective prompts

Adding Support for Telescope

Currently, when selecting a prompt, you get the selector menu and type in a number. This is very fast, if you know exactly which prompt you want and the list is short.

However, this becomes unusable as soon as you define a larger number of prompts and/or your screen is smaller than the total set of prompts. Therefor i think adding Telescope as an (optional?) alternative might be better here, as it allows a fast selection even with a larger number of prompts.

I've made a quick poc to test this out and see if it's better and I think it is worth adding. I've forked your repo and made the necessary changes: https://github.com/cloud-wanderer/gen.nvim

I'm sorry about the code quality. It's my first time coding in lua, so i'm not familiar with the standards yet. Also my focus was on testing it fast, rather than making it perfect.

Once you use :Gen a telescope instance opens to select the prompt.

selectp selectedp

No static Model

Foundational Models are not compatible with every type of prompt / use case. Depending on the type of question I found that different models bring better results. Therefor I do think it is not advisable to have the concept of a default model.

I suggest to have the model as parameter/attribute inside the prompts.lua and if it is not set, a dialogue for available models opens. I've done this as well in the mentioned repository with telescope. (the default model can of course be a fallback in case of an empty list)

Side Remark: I've found some issues with the way the content is extracted from visual selection when using telescope, so I had to change the way this is done. However it's not compatible with replacing text.

selectmodel

``

Vertical Splits

Floating windows are nice visually. However if you want to keep the content and maybe extend it later for chat, these temporary windows are not ideal. Also most of the results i got from the models are not satisfactory enough to just replace as is. Sometimes they have security issues and other times it is simply wrong.

Especially when looking further into a future chat option, I suggest to focus on vertical splits (configurable). This way you can compare the output and take whatever you need. That buffer can then be extended with more answers from further chats.

In my poc I open a new buffer for every new prompt. If a vertical split exists (position 2), the output will be shown there. If not, a new vsplit will be created. This way it is easy to compare the results of the prompt with the original buffer. It would also allow for a new command to "Accept" the result as well as keeping a record / save answers for later.

As for chat, I thought about keeping the last buffer as well as the underlying data. The split window can then be extended with further chat answers, while the code can be applied in the other split if satisfactory.

split

Multi-line prompts

Currently the input selector is not ideal for adding more content or longer prompt - especially of pasted from another source. I suggest to add multi-line prompts as the default (maybe via a temporary buffer and a command to send the content of this buffer as a prompt, while adding """before and after.

Selective Prompts

Not every prompt is applicable to all filetypes. I suggest to preselect the list of available prompts depending on the current filetype, to narrow it down. For example Create a markdown table from this input should only pop up for a list of filetypes like *.md.

I suggest a new optional attribute for a list of fileendings. If not set, the prompt will apply to all.

kjjuno commented 7 months ago

Vertical splits and extended chat with remembered context was recently merged.

https://github.com/David-Kunz/gen.nvim/pull/36

David-Kunz commented 7 months ago

Hi @cloud-wanderer ,

Thank you for this extensive list, very appreciated!

Adding Support for Telescope

This already works as of today if you install https://github.com/nvim-telescope/telescope-ui-select.nvim

No static model, either configure a model in the prompt or let the user select

Already possible today, users can specify model per prompt. With require('gen').select_model(), they can also set it dynamically.

Multi-line prompts

That's correct, this is not ideal. I like how Mini.Files does it, you just modify the buffer and press a command for it to have an effect. That's something we can think of.

Selective Prompts

Interesting suggestion! Maybe we can add an option to each prompt... I'll need to think about it.

cloud-wanderer commented 7 months ago

Hi @David-Kunz, @kjjuno

Thanks for the quick answers and recommendations.

Telescope Ui Select Neovim Bug

I've immediately tested it out and it appears the with using telescope ui select, you run into the same issue as i had: no content in the var content from the visual selection.

here's a pic, i made also a video but i think it's better to just try it out:

empty

Steps to reproduce:

  1. Install https://github.com/nvim-telescope/telescope-ui-select.nvim. I left the config the same as the repo suggested.
  2. Visually select text and hit cmd Gen. I made a screenshot to showcase that so far it worked all fine. Note that the visual selection in the background vanished

[

telescope

](url)

  1. Select a prompt (i used review code)
  2. See that the visual selection code is empty.

Reason from my previous attempts at using telescope, the following command all return 0's :

        end_pos = vim.fn.getpos("'>")

One possible fix:

local function buf_vtext()
  print("Visual selection")
  local a_orig = vim.fn.getreg('a')
  vim.cmd([[normal! gv]])
  vim.cmd([[silent! normal! "aygv]])
  local text = vim.fn.getreg('a')
  vim.fn.setreg('a', a_orig)
  return text
end

-- get content whole file
local function buf_text()
  print("Whole File")
  local bufnr = vim.api.nvim_win_get_buf(0)
  local lines = vim.api.nvim_buf_get_lines(bufnr, 0, vim.api.nvim_buf_line_count(bufnr), true)
  local text = ''
  for _, line in ipairs(lines) do
    text = text .. line .. '\n'
  end
  return text
end

-- get content
local function buf_text_or_vtext()
  print(M.mode)
  if M.mode == 'v' or M.mode == 'V' then
    return buf_vtext()
  end
  return buf_text()
end

Issue: Not compatible with replace, as you still do not have the pos for start and end (still nil). Same issue with marks etc.

Selective Prompts

I suggest something like this:

Review_Code = {
        prompt = "Review the following code and make concise suggestions:\n```$filetype\n$text\n```",
    },

Applies to all files and buffers

    Review_Code = {
        prompt = "Review the following code and make concise suggestions:\n```$filetype\n$text\n```",
        filetypes = { "go", "lua"},
    },

Only applies to the listed filetypes, here go and lua.

I'd add a filter function before showing the select menu. It would filter the table and make a subset. Ideally it would be cashed / table kept until the next run of Gen. There i would check whether the filetype is still the same to save on processing. Meaning you'd store 2 more vars, the subtable and the last filetype. If the filetype changed, you rerun the filter.

What do you think?

EDIT: @David-Kunz It seems the bug, assumed cause was telescope, it not caused by it. I've reversed the telescope ui select change to the normal ui select and it still does not retrieve the visual selection. The code is directly from github, no fork.

## Prompt:

> Review the following code and make concise suggestions:
> ```lua
> 
...

---
Without any provided code, it's difficult to offer specific suggestions. Please share the Lua code so I can provide concise recommendations for improvement or optimization.

here's the version from Lazy:

    ● gen.nvim 6.29ms 🗝 <leader>o (v)
        dir    /Users/martin/.local/share/nvim/lazy/gen.nvim
        url    https://github.com/David-Kunz/gen.nvim
        branch main
        commit 780fb41
        readme README.md
        cmd    ⌘ Gen 
        keys   🗝 <leader>o (v) 🗝 <leader>o 

EDIT II: I tried finding the commit that broke it, and fix it myself with the time i had, but i was not successful. It seems to be either already broken since a while (since i only either encountered the issue or unrelated errors from previous versions when testing old commits.) or it's something only on my own local env.

Can you confirm whether it's working for you to visually select and then "Review Code", with the prompt having the visually selected text?

David-Kunz commented 7 months ago

Hey @cloud-wanderer ,

Thank you so much for your write up! The filetype proposal is great, I think we can support this!

Regarding Telescope: I already use the telescope vim.ui.select extension and it works without problems. I'm not sure how your setup differs, do you have any custom configurations?