Coder Social home page Coder Social logo

claude.vim's Introduction

Claude for AI Pair Programming in Vim / Neovim: Or, a Hacker's Gateway to LLMs

This vim plugin integrates Claude deeply into your Vim workflow - rather than working in the clunky web Claude Chat, actually chat about and hack together on your currently opened vim buffers.

Claude is your pair programmer. You chat about what to build or how to debug problems, and Claude offers opinions while seeing your actual code, or goes ahead and proposes the modifications - high level, or just straight writes the code.

This plugin is NOT:

  • "code completion" like Github Copilot or Codeium. (You can use these together with claude.vim!) This plugin rather provides a chat / instruction centric interface.
  • CLI coding framework. It is much more optimized for human collaboration than e.g. aider or dravid. You may want to agree on design decisions before Claude writes code. And it is going to need feedback and change review in order to be helpful. This is why the access to chat history and the vimdiff interface are the killer features.

Chat buffer at the bottom, vimdiff at the top.

This plugin will give you a partner who will one-shot new features in your codebase:

chat-feature.mp4

You can let it refactor your code if it's a bit messy, and have an ongoing discussion about it:

chat-refactor.mp4

You can ask it to modify or extend just a selected piece of your code:

implement-blinking.mp4

It can use Claude Tools interface - it will open files and execute vim commands as needed.

Claude realizes it needs to open another file, opens it, and then executes a series of vim commands to uppercase its first line.

It can also (with your case-by-case consent) evaluate Python expression when figuring out what you asked:

When asked for refactoring suggestions, Claude evaluates short Python snippets to get basic source code stats, and even autonomously iterates the Python execution when one of the snippets fails.

And it can execute complex tasks by first reading documentation, then cloning git respositories, browsing the directory tree, etc.

Based on a short sentence, Claude reads documentation for another software project, clones the repo, installs dependencies etc.

Actually, the current version can execute also shell script. And it can help you also with sysadmin tasks, not just coding.

Claude is asked to diagnose a RAID1 after disk replacement, so it just runs the appropriate commands using the shell tool.

And ultimately, Claude.vim can act as pretty much a full text terminal replacement of Claude.ai or ChatGPT. And it will search the web if it doesn't know something.

Claude is asked for a simple medical advice. It searches the web for the germ, then summarizes the results.


Sonnet 3.5 is not yet good enough to completely autonomously perform complex tasks. This is why you can chat with it, review and reject its changes and tool execution attempts, etc. You still do the "hard thinking" and decide and tell it what to do.

That said, about 95% of the code of this plugin has been written by Claude Sonnet 3.5, and most of the time already "self-hosted" within the plugin.

NOTE: This is early alpha software. It is expected to rapidly evolve... and not just in backwards compatible way. Stay in touch with the maintainer if you are using it (pasky on libera IRC, or @xpasky on Twitter / X, or just via github issues or PRs).

Installation

First, install using your favourite package manager, or use Vim's built-in package support.

Vim:

mkdir -p ~/.vim/pack/pasky/start
cd ~/.vim/pack/pasky/start
git clone https://github.com/pasky/claude.vim.git

Neovim:

mkdir -p ~/.config/nvim/pack/pasky/start
cd ~/.config/nvim/pack/pasky/start
git clone https://github.com/pasky/claude.vim.git

To allow web access, install elinks or felinks (e.g. brew install felinks). To allow Google access, you first need to open elinks manually, navigate to https://www.google.com/search?q=lala and select and press one of the buttons in the cookie consent (then, quit it using q).

Configuration

Obtain your Claude API key by signing up at https://console.anthropic.com/ . Anthropic might give you a free $5 credit to get you started, which is plenty for many hours of hacking (depending on your mode of usage).

NOTE: This is a cloud service that costs actual money based on the amount of tokens consumed and produced. Be careful when working with big content, observe your usage / billing dashboard on Anthropic etc.

Set your Claude API key in your .vimrc:

let g:claude_api_key = 'your_api_key_here'

(You can also use AWS Bedrock as your Claude provider instead - in that case, set let g:claude_use_bedrock = 1 instead.)

Usage

First, a couple of vim concepts you should be roughly familiar with:

  • Switching between windows (:help windows) - at least <C-W><C-W> to cycle between active windows
  • Diff mode (:help diff) - at least d o to accept the change under cursor
  • Folds (:help folding) - at least z o to open a fold (chat interaction) and z c to close it
  • Leader (:help leader) - if you are unsure, most likely \ is the key to press whenever <Leader> is mentioned (but on new keyboards, § or ± might be a nice leader to set)

Claude.vim currently offers two main interaction modes:

  1. Simple implementation assistant
  2. Chat interface

ClaudeImplement

In this mode, you select a block of code and ask Claude to modify it in some way; Claude proposes the change and lets you review and accept it.

  1. Select code block in visual mode. (Note that this selection is all Claude "sees", with no additional context! Therefore, select liberally, e.g. a whole function.)
  2. <Leader>ci - shortcut for :'<,'>ClaudeImplement ...
  3. Enter your instruction (e.g. "Fix typos" or "Factor out common code" or "Add error handling" or "There's some bug here") as a ClaudeImplement parameter in the command mode
  4. Review and accept proposed changes in diff mode
  5. Switch to the scratch window (<C-W>l) and :q it.

ClaudeChat

In this mode, you chat with Claude. You can chat about anything, really, but the twist is that Claude also sees the full content of all your buffers (listed in :buffers - roughly any files you currently have open in your vim).

  1. <Leader>cc - shortcut for opening Claude chat window
  2. Enter a message on the You: line (and/or indented(!) below it)
  3. <C-]> (in insert or normal mode) to send your message and get a reply
  4. Read the reply in the Claude window etc.
  5. If Claude proposes a code change, diff mode automatically pops up to apply it whenever possible.

You can e.g. ask Claude how to debug or fix a bug you observe, or ask it to propose implementation of even fairly complex new functionality. For example:

You: Can you write a short README.md for this plugin, please?
Claude:
    Here's a draft README.md for the Claude Vim plugin:

    ```markdown
    # Claude Vim Plugin

    A Vim plugin for integrating Claude, an AI assistant, directly into your Vim workflow.
    ...

Previous interactions are automatically folded for easy orientation (Claude can be a tad bit verbose), but the chat history is also visible to Claude when asking it something. However, you can simply edit the buffer to arbitrarily redact the history (or just delete it).

NOTE: For every single Claude Q&A roundtrip, full chat history and full content of all buffers is sent. This can consume tokens FAST. (Even if it is not too expensive, remember that Claude also imposes a total daily token limit.) Prune your chat history regularly.

claude.vim's People

Contributors

pasky avatar

Stargazers

Jeff Wu avatar kenzo avatar Wormhole Cowboy avatar Pablo Delgado avatar Andrea Boscolo Camiletto avatar Saskia Keil avatar Filip Harald avatar  avatar Mark JL (_jail) avatar Marwan Osman avatar hrqmonteiro avatar Aske Doerge avatar  avatar Jayson Rawlins avatar Tommy Falkowski avatar Su avatar Jay Sin avatar dxo  avatar Piotr Usewicz avatar Enno avatar Jorge Valdez avatar João Augusto  Sobral avatar Ivan avatar atori74 avatar  avatar William Ong avatar Denis Erfurt avatar ~nodreb-borrus avatar Andreas Thoelke avatar  avatar Max: avatar Ayodeji O. avatar Thomas Freiesleben avatar Tibor Schmidt avatar  avatar  avatar  avatar carlosfonseca avatar  avatar Anthony Flores avatar Settuba avatar Toby Slater avatar  avatar Fabien Penso avatar Zhuo Tao avatar Yurui Zhang avatar Carlos Castilla avatar Yi avatar bettabacon avatar Danyel Aristizabal avatar 0xheartcode avatar Jilles Soeters avatar Isaac Scarrott avatar h0pes avatar Dmitry Manannikov avatar Alberto Harres avatar Nathaniel Isaeff avatar Vaclav Kosar avatar wolfi3 avatar Arthur Tyukayev avatar Caio Ariede avatar Sip avatar lsCoco avatar Guðmundur Óli Norland avatar Janni Turunen avatar Igor Costa avatar Vincent Murphy avatar Tim Kersey avatar genix avatar Dean Rie avatar zetsukhun avatar 柴诗雨 avatar Byron J. Smith avatar Vladimir Sanchez avatar  avatar ramr avatar Benjamin Lundquist avatar Max Justus Spransy avatar Stepan Simsa avatar Hafiz  avatar Kevin Ridgway avatar Baolin avatar Daniel Kubec avatar Jan Kubalek avatar Miguel Morais avatar  avatar sarfrazkhan avatar Marek Sebera avatar O.S.H avatar Aymeric Beaumet avatar Dimas Aryo Prakoso avatar Ignacio El Kadre avatar Mario RC avatar Marek Ruttner avatar Stan Angeloff avatar Leo Tartari avatar Pedro Nascimento avatar Artyom Pertsovsky avatar KANATSU Minoru avatar Jocelyn Gaudette avatar

Watchers

 avatar Abhik Khanra avatar Denis Erfurt avatar  avatar Saabir avatar

Forkers

akshat6133 n13l

claude.vim's Issues

Can you please add better instructions for installing in NeoVim

Tried to install in NeoVim with Lazy package manager, but wasn't able to get it to work. I added this to my plugins.lua config

 {
    "pasky/claude.vim",
    config = function()
      -- Configure claude.vim here
      vim.g.claude_api_key = <anthropic_key>
    end,
  },

<leader>cc and <leader>ci do not work.
Typing :ClaudeChat or :ClaudeInsert in normal mode do not work either...

(I am not an NeoVim expert by a very long shot, so I may be missing some very obvious things)

claude is rate limiting

and the plugin is failing with error:
Unknown Claude protocol output: "{"type":"error","error":{"type":"rate_limit_error","message":"Number of request tokens has exceeded your per-minute rate limit (https://docs.anthropic.com/en/api/rate-limits); see the response headers for current usage. Please reduce the prompt length or the maximum tokens requested, or try again later. You may also contact sales at https://www.anthropic.com/contact-sales to discuss your options for a rate limit increase."}}"

Context: I was doing chat and it was browsing files, just 3 files was enough.

Claude does not seem to use the tool to create folders

First thanks a loooot for this tool, it's both extremly useful by itself (and I really mean it) and also as an example on how to plug claude to other tool

I use neovim

I opened it with no current buffer and here's our chat conversation

You: can you create a folder "test_zig" which boostrap a webservice written in zig ? 
Claude: Certainly! I'll create a folder named "test_zig" and set up a basic webservice written in Zig. Let's break this down into steps:
    
    <thinking>
    1. Do I have enough information?
       - We need to create a folder named "test_zig"
       - We need to bootstrap a webservice in Zig
       - This is enough information to get started, but we'll need to make some decisions about the structure and content.
    
    2. What is the biggest obstacle to achieve the goal?
       - Zig is a relatively new language, and web services aren't as common in Zig as in some other languages.
       - We'll need to create a basic HTTP server from scratch or use a minimal library.

    3. Alternatives and their pros/cons:
       - Use raw sockets: 
         Pro: No dependencies, educational
         Con: More complex, prone to errors
         Why: Raw sockets provide full control but require more low-level programming.
    
       - Use a minimal HTTP library:
         Pro: Easier to implement, more robust
         Con: Introduces a dependency
         Why: A library can handle HTTP parsing and other details, allowing us to focus on the service logic.
    
    4. Decision:
       Let's use a minimal HTTP library approach. The `std.http.Server` in Zig's standard library provides basic HTTP server functionality, which should be sufficient for our needs.
    
    5. Approach:
       - Create the "test_zig" folder
       - Create a `main.zig` file with a basic HTTP server
       - Create a `build.zig` file for building the project
       - Add a README.md with instructions
    
    6. Is it obvious to proceed?
       Yes, we can proceed with creating these files and then show them to the user for feedback.
    
    brm brm brm brm brm brm brm brm brm brm brm brm brm brm brm
    </thinking>
    
    Alright, let's create the folder and set up a basic Zig webservice. I'll use the available tools to create the necessary files and add the content.

   
    First, let's create the "test_zig" folder and the required files:
Tool use (toolu_0184pYqExAyaEhCT419GM3XB): new
    Input: {"path": "test_zig/main.zig"}
Tool result (toolu_0184pYqExAyaEhCT419GM3XB):
    test_zig/main.zig
Claude...: 
    
    Now, let's add the content for the `main.zig` file:
    
+--- 27 lines: ```zig test_zig/main.zig [APPLIED]·····························································································································································
    
    Now, let's create and add content to the `build.zig` file:
Tool use (toolu_01PKUHevJpsxfSaMPEWDxsK7): new
    Input: {"path": "test_zig/build.zig"}
Tool result (toolu_01PKUHevJpsxfSaMPEWDxsK7):
    test_zig/build.zig
Claude...: 
    
+--- 27 lines: ```zig test_zig/build.zig [APPLIED]·································································································································································
    
    Now that we have created the basic structure for a Zig webservice, here's a summary of what we've done:
    
    1. Created a folder named "test_zig".
    2. Added a `main.zig` file with a basic HTTP server using Zig's standard library.
    3. Added a `build.zig` file to manage the build process.
    
    The webservice is very simple and responds with "Hello from Zig!" to all requests. To run this webservice:
    
    1. Make sure you have Zig installed on your system.
    2. Navigate to the "test_zig" folder in your terminal.
    3. Run `zig build run` to compile and start the server.
    4. The server will listen on `http://127.0.0.1:8080`.
    
    You can test it by opening a web browser and navigating to `http://127.0.0.1:8080` or using a tool like curl: `curl http://127.0.0.1:8080`

I got some error appearing briefly, and then nothing except two scratch buffer opening with the main.zig and build.zig code, but no folder nor files were created

Ignoring the contents of invisible buffers

In keeping with the spirit of the original development, I asked Claude to update function! s:GetBufferContents() to only send buffers that are currently visible. This is very handy as anything that's quit and not attached to a window will get ignored. I'm a heavy user of tabs and I found that claude.vim was sending the contents of tabs I have long since quit.

I'm not sending as a PR as I find this change to be controversial and may affect current users of the plug-in. I'd be happy to refactor (or rather ask Claude to refactor) and put this behind a flag?

diff --git a/plugin/claude.vim b/plugin/claude.vim
index 6d66f10..df3c45e 100644
--- a/plugin/claude.vim
+++ b/plugin/claude.vim
@@ -441,9 +441,13 @@ function! s:GetBufferContents()
   let l:buffers = []
   for bufnr in range(1, bufnr('$'))
     if buflisted(bufnr) && bufname(bufnr) != 'Claude Chat'
-      let l:bufname = bufname(bufnr)
-      let l:contents = join(getbufline(bufnr, 1, '$'), "\n")
-      call add(l:buffers, {'name': l:bufname, 'contents': l:contents})
+      " Check if the buffer is attached to any window
+      let l:windows = win_findbuf(bufnr)
+      if !empty(l:windows)
+        let l:bufname = bufname(bufnr)
+        let l:contents = join(getbufline(bufnr, 1, '$'), "\n")
+        call add(l:buffers, {'name': l:bufname, 'contents': l:contents})
+      endif
     endif
   endfor
   return l:buffers

multi lllm providers?

first of all, thanks for this, I've been testing all the various coding ai assistants and I like this one the best so far as it fits with me and my current vim setup.
One longer term suggestion, claude is the best coder now, but I personally just keep switching out models as needed and I assume something will dethrone claude for programming soon, so maybe start to build in support for other llms later.

disable default keymaps

It would be nice to be disable the default keymaps in case they are in conflict with other keymaps.

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.