Skip to content
Notifications
Clear all

TIL: You can use Copilot in Neovim. Here's my config and initial impressions.

14 Posts
13 Users
0 Reactions
9 Views
(@chrism)
Reputable Member
Joined: 3 months ago
Posts: 326
Topic starter   [#25983]

Alright, so I've been living in VS Code for Copilot since it launched, but my terminal heart has always belonged to Neovim for quick config edits and infra work. I just assumed a native-ish experience wasn't in the cards. Turns out I was wrong!

After some digging, I got the GitHub Copilot plugin running in Neovim, and the experience is surprisingly solid. It's not just a janky port. The suggestions pop up inline, and you can cycle through them with familiar keybindings. It feels like a natural part of the workflow, not a bolt-on.

Here's the snippet from my `lazy.nvim` config that made it happen:

```lua
return {
"github/copilot.vim",
config = function ()
-- Map Accept to something more vim-like
vim.keymap.set('i', '', 'copilot#Accept("")', { expr = true, silent = true })
vim.g.copilot_no_tab_map = true
end
}
```

The main thing I noticed is that context awareness is pretty good, even in my Terraform files and Helm charts. It's pulling from my project's other files effectively. For example, when I'm typing out a Kubernetes manifest, it'll suggest the correct `image:` based on a Deployment in another directory. Saves a lot of back-and-forth.

A couple of quick observations vs. the VS Code experience:
* The suggestions can feel a tiny bit slower, but not disruptive.
* You don't get the chat interface, but honestly, I mainly use the inline completions anyway.
* It works in splits and terminal buffers, which is a nice touch.

If you're a Neovim user who's been on the fence, I'd say it's definitely worth setting up. It bridges that last bit of tooling gap for me. Now if only I could get it to run my `kubectl` commands...

Has anyone else tried it? Found any clever mappings or tricks to improve the flow?

β€”Chris


K8s enthusiast


   
Quote
(@elliotk)
Reputable Member
Joined: 2 months ago
Posts: 323
 

Totally feel you on the context awareness! I had a similar moment writing some Ansible playbooks - it started suggesting module parameters I'd used in a totally different role directory, which was a nice surprise. The inline suggestion style feels more integrated than VS Code's ghost text to me.

Have you messed with the suggestion delay setting? I found the default a bit too eager for my old vim reflexes, especially in insert mode. Setting `vim.g.copilot_filetypes = { ["*"] = false, terraform = true, yaml = true }` helped me tame it to just the filetypes where I actually want it buzzing.

One thing I'm still curious about - have you noticed any difference in suggestion quality between the native Neovim LSP client with copilot-lsp and this standalone plugin approach? I tried both and couldn't decide.



   
ReplyQuote
(@cloud_migrate_tom)
Reputable Member
Joined: 6 months ago
Posts: 290
 

Oh, that's a neat trick with the context awareness across files. I've been hesitant to try Copilot in my main terminal editor because my team is right in the middle of a lift-and-shift to AWS, and I'm worried about introducing new tooling mid-stream. How long did it take you to feel like it wasn't disrupting your flow?

Your point about it suggesting the `image:` from another Deployment actually makes me wonder if it could help with our consistency problem across CloudFormation templates. We keep making small typos in property names. Do you find it picks up on those patterns in structured config files, or is it mostly for repeating exact strings?


One step at a time


   
ReplyQuote
(@docker_diver)
Honorable Member
Joined: 4 months ago
Posts: 496
 

Nice to see someone else diving into Neovim configs for infrastructure work. Your keymap snippet looks cleaner than what I cobbled together. 😅

When you say it pulls context from other project files, does that work across different types of configs in your experience? Like, if you're writing a Docker Compose file, does it ever suggest a port mapping or volume based on something in a nearby Dockerfile? I'm still getting mine tuned.


Containers are magic, but I want to know how the magic works.


   
ReplyQuote
(@emilyj)
Reputable Member
Joined: 3 months ago
Posts: 216
 

That's a good question. I've seen it pull from Dockerfiles, yeah, like suggesting a `COPY . .` line after seeing a similar pattern earlier. But I'm not sure how far the context reach goes. It feels strongest within the same file type.

Have you noticed if opening the related Dockerfile first improves those cross-config suggestions? I'm still trying to figure out the logic.



   
ReplyQuote
(@brianw)
Reputable Member
Joined: 3 months ago
Posts: 242
 

The cross-file context seems to depend heavily on the language server's workspace indexing. I've observed that for something like a `docker-compose.yml`, if the corresponding `Dockerfile` is in the same workspace folder and has been opened recently, the suggestions for `build: context:` or `target:` stages are significantly more accurate.

But I've done some informal testing with Terraform modules and AWS CloudFormation templates. The context appears to be segmented by both file type and project structure. Opening a related file first does seem to prime the model, but the effect is inconsistent. It might suggest a `Ref:` to a logical ID from another template, but only if that template is in the same directory. The moment you move to a different subdirectory in the same repo, the connection drops. It feels less like semantic understanding and more like a constrained lexical scope tied to the LSP's current view of the workspace.


Spreadsheets or it didn't happen.


   
ReplyQuote
(@integration_ian_2)
Honorable Member
Joined: 4 months ago
Posts: 525
 

That keymap tweak is a lifesaver. The default tab behavior felt really off until I set `copilot_no_tab_map = true`. It was stepping all over my completion triggers.

I've had a similar experience with the context pulling in Helm charts. It started suggesting the full `{{ .Values.image.repository }}:{{ .Values.image.tag }}` pattern after I'd typed it in one template, which saved me a ton of copy-pasting across subcharts. The cross-file stuff seems to work best when the files are in the same semantic "group" like you saw with your K8s manifests.

One hiccup I ran into - did you notice any delay or missed suggestions when working over a slower SSH connection? I had to tweak the suggestion delay a bit when I was editing configs on a remote jump host.


api first


   
ReplyQuote
(@hannahm)
Reputable Member
Joined: 3 months ago
Posts: 217
 

Yeah, the filetype filtering is such a good idea. I got so distracted by suggestions popping up in random log files I almost missed a real error. Your config snippet looks way simpler than what I was trying, thanks for sharing that!

> the suggestion delay setting?
I dropped mine to 500ms and it helped a lot. The default felt like it was jumping the gun before I even knew what I wanted to type next.

On your last question about copilot-lsp vs the plugin - I'm actually trying to decide the same thing right now. The standalone plugin seems faster to start up, but I saw someone mention the LSP version might get better context from other LSP-aware tools in the workspace. Have you noticed any difference in how they handle multi-line suggestions?


Just my two cents.


   
ReplyQuote
(@integration_ian_2)
Honorable Member
Joined: 4 months ago
Posts: 525
 

The multi-line suggestion difference is a good catch. I stuck with the standalone plugin after testing both because the LSP version kept breaking suggestions across lines for my Terraform blocks. The standalone one would suggest an entire aws_instance resource with all its curly braces, while the LSP client sometimes gave me just the first line and then stopped.

> better context from other LSP-aware tools
I haven't seen that materialize in practice, honestly. For something like a Python project, my pyright LSP is already handling completions, and Copilot just layers on top. The extra context from the LSP bridge felt negligible compared to the plugin just reading the buffer. The startup speed you noticed was the real clincher for me, especially when hopping between terminal windows.


api first


   
ReplyQuote
(@cost_optimizer_elle)
Reputable Member
Joined: 4 months ago
Posts: 370
 

The startup speed difference is huge when you're bouncing between tmux panes editing CloudFormation templates. That half-second delay on the LSP version felt like an eternity while the console errors pile up.

> the LSP client sometimes gave me just the first line and then stopped

I had the exact same issue with Azure Bicep modules. The standalone plugin would spit out a whole resource block, but the LSP version would choke after `param location string`. Made it useless for anything with a predictable pattern, which is most infra code.

One caveat on context - for pure cost files (like a `pricing.json` or a budget alert config), I've actually found the standalone plugin pulls less random nonsense from my Python scripts. The LSP version seemed to get confused by my billing calculation functions in another directory. Sometimes dumber is better.


- elle


   
ReplyQuote
(@crusty_pipeline)
Honorable Member
Joined: 5 months ago
Posts: 502
 

Half a second? Luxury. Try running the LSP bridge over a VPN to a staging environment while the ops team is hammering the same jump host. The standalone plugin is the only reason I didn't throw my laptop into a lake last month.

> The standalone plugin would spit out a whole resource block

That's the key for me with CloudFormation or Terraform. The pattern is the whole point. If it's only giving me the opening line of a `Properties:` block, I might as well just type it. The value is when it coughs up the entire, tedious 15-line security group ingress rule set after I've written one.

Your point about context noise with the LSP version rings true. I think it gets over-eager with its workspace scope. For a `costs.yaml` file, the last thing I need is a suggestion from a Python script three directories away that does some weird rounding on dollar amounts. The plugin's dumber, buffer-focused approach keeps it on topic for config work.



   
ReplyQuote
(@backend_builder)
Prominent Member
Joined: 6 months ago
Posts: 605
 

That keymap snippet is exactly what I needed. The default tab behavior was driving me nuts.

> when I'm typing out a Kubernetes manifest, it'll suggest the correct `image:` based on a Deployment in another directory.

I've had the same experience with Terraform modules. It started suggesting the correct `source = "../../modules/vpc"` path after I'd typed it once, which was a huge time-saver. The cross-file context feels strongest when the files share a similar structure, like K8s YAMLs or Terraform's HCL.

One minor gripe I ran into was suggestions popping up in random log files. Adding `ft = { "python", "go", "yaml", "tf", "json" }` to my plugin spec stopped that distraction cold.


Latency is the enemy, but consistency is the goal.


   
ReplyQuote
(@annas)
Honorable Member
Joined: 2 months ago
Posts: 542
 

The filetype filter is non-negotiable. I had to extend mine to exclude `Dockerfile` and `Jenkinsfile` from generic suggestions in log and config files because it kept trying to autocomplete random `RUN` commands in my `syslog` entries. It was absurd.

Your point about similar structure is key, but it's brittle. That `source` path suggestion works until you refactor your module layout. I've had it suggest an old, deprecated path for a Terraform module that I moved six months ago, which means it's pulling from cached context or old open buffers, not just the current workspace. Makes me question the "intelligence" part when it can't track a simple git mv.

The cross-directory suggestion for K8s images is useful until it suggests the dev image tag in a production manifest because you had both files open earlier in the week. I don't trust it for anything that has environment-specific values anymore.



   
ReplyQuote
(@code_weaver_anna)
Prominent Member
Joined: 7 months ago
Posts: 563
 

That keymap config is a good start, but you'll likely need to adjust the suggestion trigger delay. The default can feel too aggressive, especially in a terminal-based editor where you might be typing slower command sequences. I set mine to 75ms with `vim.g.copilot_suggestion_delay = 75`.

> context awareness is pretty good, even in my Terraform files and Helm charts

It's strong for repetitive, templated structures like those. I've found it excellent for suggesting entire Azure Bicep resource declarations after seeing a pattern once. However, the cross-file context seems to rely on recently opened buffers in the same Neovim instance, not the broader project workspace. If you haven't opened that referenced Deployment file in this session, the accuracy drops noticeably.


benchmark or bust


   
ReplyQuote