gen.nvim icon indicating copy to clipboard operation
gen.nvim copied to clipboard

Add before & after cursor as context

Open felixkreuk opened this issue 1 year ago • 5 comments

First, thanks a lot for this nifty plugin! :)

The use case would be to generate a code snippet at a specific line. In this scenario, it may be redundant to give the whole file as context, but a few lines before and after the current cursor line might help.

Edit: other helpful contexts can be passing the current function/class/scope and cursor location, etc.

Apologies if this is already implemented and I missed it. Thanks again!

felixkreuk avatar Sep 10 '24 12:09 felixkreuk

Hi @felixkreuk ,

Thank you for this feature suggestion. This is already possible as of today, for example to insert the lines before and after the cursor, you can do the following:

require('gen').prompts['Code_Completion'] = { 
  prompt = function()
    local buf = vim.api.nvim_get_current_buf()
    local row, col = unpack(vim.api.nvim_win_get_cursor(0))

    local before = vim.api.nvim_buf_get_text(0, 0, 0, row-1, col+1, {})
    local after = vim.api.nvim_buf_get_text(0, row-1, col+1, -1, -1, {})
    local prompt = '<|fim_prefix|>' .. table.concat(before, "\n") .. '<|fim_suffix|>' .. table.concat(after, "\n") .. '<|fim_middle|>only output the middle part, not the prefix/suffix, nothing else, just the missing code including the $filetype code fence ```$filetype\n<resulting code>\n``` for example ```$filetype\nconsole.log("hello")\n```'
    return prompt
  end,
  model = "qwen2.5-coder:7b-instruct",
  extract = "```$filetype\n(.-)```"
}
vim.keymap.set('i', '<c-]>', '<esc>:Gen Code_Completion<CR>')

Would that work for you?

Thanks and best regards, David

David-Kunz avatar Oct 03 '24 09:10 David-Kunz

having prompt be a function is pretty smart! your example doesnt work, i think buf is never used?

but i'm not sure how to write my own function, because i cant figure out how to debug lua code in nvim D: for example, how would i even check that before contains what i want

aep avatar Nov 26 '24 20:11 aep

Thanks, @aep . The following works for me:

require('gen').prompts['Code_Completion'] = { 
  prompt = function()
    local row, col = unpack(vim.api.nvim_win_get_cursor(0))
    local before = vim.api.nvim_buf_get_text(0, 0, 0, row-1, col+1, {})
    local after = vim.api.nvim_buf_get_text(0, row-1, col+1, -1, -1, {})
    local prompt = '<|fim_prefix|>' .. table.concat(before, "\n") .. '<|fim_suffix|>' .. table.concat(after, "\n") .. '<|fim_middle|>only output the middle part, not the prefix/suffix, nothing else, just the missing code in between, do not repeate the provided text, include the $filetype code fence ```$filetype\n<resulting code>\n``` for example ```$filetype\nconsole.log("hello")\n```'
    return prompt
  end,
  model = "qwen2.5-coder:32b",
  extract = "```$filetype\n(.-)```"
}
vim.keymap.set('i', '<c-]>', '<esc>:Gen Code_Completion<CR>')

Note: You have to accept it with ctrl-enter.

David-Kunz avatar Dec 05 '24 13:12 David-Kunz

i also tried it but it didn't work so i changed the show_prompt option to true

## Prompt:

> <|fim_prefix|>#!/usr/bin/env python3
> # Test
> # Version: 0.10.1
...

---

it seams to get the first few lines even though i was at line 552, so there might be an issue with getting the position NVIM v0.10.2

heema avatar Jan 27 '25 13:01 heema

the problem was that it was getting text from the beginning of the file (0, 0) to the cursor position

so honestly i am not good at lua so i used Claude AI to fix it and it gave me this code which works

require('gen').prompts['Code_Completion'] = {
  prompt = function()
    local row, col = unpack(vim.api.nvim_win_get_cursor(0))
    
    -- Get a few lines before the cursor for context
    local context_lines = 5
    local start_row = math.max(0, row - 1 - context_lines)
    
    -- Get text before cursor
    local before = vim.api.nvim_buf_get_text(0, start_row, 0, row-1, col+1, {})
    
    -- Get a few lines after cursor for context
    local buffer_line_count = vim.api.nvim_buf_line_count(0)
    local end_row = math.min(buffer_line_count - 1, row - 1 + context_lines)
    local after = vim.api.nvim_buf_get_text(0, row-1, col+1, end_row, -1, {})
    
    local prompt = string.format(
      '<|fim_prefix|>%s<|fim_suffix|>%s<|fim_middle|>'..
      'only output the middle part, not the prefix/suffix, nothing else, '..
      'just the missing code in between, do not repeat the provided text, '..
      'include the $filetype code fence ```$filetype\n<resulting code>\n```',
      table.concat(before, "\n"),
      table.concat(after, "\n")
    )
    
    return prompt
  end,
  model = "qwen2.5-coder:32b",
  extract = "```$filetype\n(.-)```"
}

vim.keymap.set('i', '<c-]>', '<esc>:Gen Code_Completion<CR>')

heema avatar Jan 28 '25 08:01 heema