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(context): add a ui for selecting and adding files to the sidebar as context #912

Merged
merged 17 commits into from
Dec 11, 2024

Conversation

brewinski
Copy link
Contributor

I've been playing around with some tools to allow users to add other files as context in the sidebar. So far I have something that's relatively stable and seems to work.

I'm at a point where it would be good to have some feedback on the direction I'm going with this as I'd like to make sure my work aligns with the vision of the core maintainers. As always feedback and change requests are welcome.

So far this is what I have:

Opening the context menu from the sidebar with "c" by default
image

Searching for files be pressing "s" in the context window by default.
image

Displaying the context used in the chat and saving that as part of the chat history.
image

Search and Replace blocks in the current file and context files.
Example Output:

---

- Datetime: 2024-11-27 15:17:56

- Model: copilot/claude-3.5-sonnet

- Selected file: lua/avante/context.lua

- Context files:
  - ./lua/avante/providers/copilot.lua
  - ./lua/avante/providers/claude.lua


> Add a remove by index to context.lua. add a binary search function to the copilot.lua module and add a bubble sort function to the claude module. 
> 

I'll help add these functions. Let me make the changes one by one.

1. First, let's add the remove by index function to context.lua:

Filepath: lua/avante/context.lua
Replace lines: 294-305
```lua
---@return nil
function Context:remove_context()
  local current_string = self:get_full_string_under_cursor()
  for i, file_path in ipairs(self.context_files) do
    if vim.fs.basename(file_path) == current_string then
      table.remove(self.context_files, i)
      break
    end
  end
  self:update_file_cache()
  self:render()
end

---@param index integer
---@return nil
function Context:remove_by_index(index)
  if index > 0 and index <= #self.context_files then
    table.remove(self.context_files, index)
    self:update_file_cache()
    self:render()
  end
end
```

2. Let's add the binary search function to copilot.lua:

Filepath: lua/avante/providers/copilot.lua
Replace lines: 164-164
```lua
---@param arr number[] The sorted array to search in
---@param target number The value to find
---@return integer|nil index The found index or nil if not found
M.binary_search = function(arr, target)
  local left = 1
  local right = #arr
  
  while left <= right do
    local mid = math.floor((left + right) / 2)
    if arr[mid] == target then
      return mid
    elseif arr[mid] < target then
      left = mid + 1
    else
      right = mid - 1
    end
  end
  
  return nil
end

M.setup = function()
```

3. Let's add the bubble sort function to claude.lua:

Filepath: lua/avante/providers/claude.lua
Replace lines: 31-31
```lua
---@param arr number[] The array to sort
---@return number[] sorted The sorted array
M.bubble_sort = function(arr)
  local n = #arr
  for i = 1, n do
    for j = 1, n - i do
      if arr[j] > arr[j + 1] then
        arr[j], arr[j + 1] = arr[j + 1], arr[j]
      end
    end
  end
  return arr
end

M.parse_messages = function(opts)
```

These changes add:
1. A remove_by_index function to Context that removes a context file by its index
2. A binary search implementation to the copilot provider
3. A bubble sort implementation to the claude provider

The functions follow the existing code style and include type annotations where appropriate.

**Generation complete!** Please review the code suggestions above.

lua/avante/llm.lua Outdated Show resolved Hide resolved
@brewinski brewinski force-pushed the feat/context branch 3 times, most recently from dc661b9 to 6deb29f Compare November 27, 2024 06:11
@yetone
Copy link
Owner

yetone commented Nov 27, 2024

‌‌Perhaps @file is a good UX.

@radwo
Copy link
Contributor

radwo commented Nov 27, 2024

Great work!

When we have this context, maybe we can detach chat from the single file and operate on the context? The same thing as Cursor is working right now.

CleanShot 2024-11-27 at 18 21 20@2x

@yetone
Copy link
Owner

yetone commented Nov 29, 2024

@brewinski Hello, I will refactor this PR on a large scale to implement @files.

@brewinski
Copy link
Contributor Author

No problem @yetone, I haven't had time to action the feedback yet but I might have some time tonight :).

I think @file is a good approach.

@brewinski
Copy link
Contributor Author

@yetone I had some time last night so I spent it getting the @file menu working in the AvanteInput buffer. Still some work to be done getting it to actually provide the file as context.

image image

lua/avante/sidebar.lua Outdated Show resolved Hide resolved
lua/avante/llm.lua Outdated Show resolved Hide resolved
@yetone
Copy link
Owner

yetone commented Dec 1, 2024

image

This style is quite strange. Can we rely solely on markdown to render these contents? Similar to codecompanion:

image

Then parse the content before calling Llm.stream to extract the selected_files.

@brewinski
Copy link
Contributor Author

brewinski commented Dec 2, 2024

Thanks for the feedback @yetone I looked at CodeCompanion and driving this via the markdown but couldn't get a consistent experience. This project was very helpful in working out how to get the @file callback working and integrating callbacks into mentions.lua

The best I've managed to come up with is slightly closer to the Cursor experience so hopefully this is reasonable intuitive.
image
image
image
image

lua/avante/llm.lua Outdated Show resolved Hide resolved
@yetone
Copy link
Owner

yetone commented Dec 3, 2024

Thanks for the feedback @yetone I looked at CodeCompanion and driving this via the markdown but couldn't get a consistent experience. This project was very helpful in working out how to get the @file callback working and integrating callbacks into mentions.lua

The best I've managed to come up with is slightly closer to the Cursor experience so hopefully this is reasonable intuitive. image image image image

Great, thank you for your work! It looks very elegant now. How do I delete a selected file in this situation?

@brewinski
Copy link
Contributor Author

brewinski commented Dec 3, 2024

Thanks for the feedback @yetone I looked at CodeCompanion and driving this via the markdown but couldn't get a consistent experience. This project was very helpful in working out how to get the @file callback working and integrating callbacks into mentions.lua
The best I've managed to come up with is slightly closer to the Cursor experience so hopefully this is reasonable intuitive. image image image image

Great, thank you for your work! It looks very elegant now. How do I delete a selected file in this situation?

Thank you! Currently if your cursor is over the file path you can press d to remove the file. This could be improved by adding some hint's / ext marks to make it clear. Also, adding these as configureable mappings would help too.

@brewinski
Copy link
Contributor Author

brewinski commented Dec 4, 2024

Added configurable mappings for deleting a context file & hints for updating the context from the ctx view.
image

commit adds support for code suggestions in multiple languages.
1cd0b2f
image

@aarnphm aarnphm changed the title feat (context) add a ui for selecting and adding files to the sidebar as context feat(context): add a ui for selecting and adding files to the sidebar as context Dec 6, 2024
@aarnphm
Copy link
Collaborator

aarnphm commented Dec 6, 2024

A small ask: can you make the choose modal as a side panel on non-float?

@brewinski
Copy link
Contributor Author

A small ask: can you make the choose modal as a side panel on non-float?

@aarnphm happy to look into it. Do you have an example of what you're looking for? If you do, I'll see if I can make it work.

@aarnphm
Copy link
Collaborator

aarnphm commented Dec 6, 2024

oh I was thinking to just append a panel on top of the input modal.

Sth like this

image

lua/avante/sidebar.lua Outdated Show resolved Hide resolved
lua/avante/sidebar.lua Outdated Show resolved Hide resolved
@brewinski
Copy link
Contributor Author

brewinski commented Dec 9, 2024

oh I was thinking to just append a panel on top of the input modal.

Sth like this

image

Thanks @aarnphm, I'm not quite sure how this would work but id be happy if you wanted to alter the input control.

I originally went with vim.ui.select because it makes it easy to extend in the future so that users can override it with their own file picker. (telescope/fzf-lua). I have a local branch where I'm able to configure telescope's builtin file picker.

An alternative to changing the UI could be to go back to using cmp as the file picker menu as seen in this comment?

lua/avante/sidebar.lua Outdated Show resolved Hide resolved
@yetone yetone force-pushed the feat/context branch 4 times, most recently from 2abbf98 to 55c17c4 Compare December 11, 2024 16:11
@yetone
Copy link
Owner

yetone commented Dec 11, 2024

@brewinski Hello, I just refactored and fixed some bugs. Now the code structure and UI/UX are more in line with my expectations. I'm ready to merge it now. Thank you so much for your hard work over the past two weeks, bringing such powerful features to avante.nvim!

image

@yetone yetone force-pushed the feat/context branch 5 times, most recently from 957db40 to fef350f Compare December 11, 2024 16:57
@yetone yetone merged commit 78dd9b0 into yetone:main Dec 11, 2024
5 checks passed
@dogonthehorizon
Copy link
Contributor

This is great, thanks for your work @brewinski and @yetone to get this merged. I've been testing this over the last few hours and it's working as described. The pattern of adding files w/ @ and switching to a file picker is really slick. What I'm longing for now is being able to add the currently focused buffer to the file list with a keybind.

I took a stab at implementing it here:
#941

I'm not married to the key binding, if there's one that makes more sense I'm happy to make that happen!

@brewinski
Copy link
Contributor Author

Thank you @yetone for all the time you spent providing feedback. The refactor is looking and working great.

@dogonthehorizon that's a cool idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants