AI in Neovim
It took a lot of trial and error to get the CodeCompanion Neovim plugin to work. I thought maybe it would help replace quick google searches or help to provide quick code snippets so that I wouldn't have to go and look over as many samples before starting in on an unfamiliar task.
Instead it was really hit or miss. It was great at producing toy programs and translating them (more or less) between languages. And then it was able to produce nearly correct Nix package definitions for packaging up those toy programs.
However, it produced python with subtle, but common, bugs that took a long time to nail down.
It's sort of handy at producing sentences in foreign languages.
I still don't know how it picks which model it's going to use on the remote side. (Edit from the future: it uses the first available model, unless one is configured locally to be the default.)
the setup
NixOS for the host system and (coincidentally) where neovim is running. I didn't open a firewall port, so it only worked from the local system. So what follows will be the nix stanzas I put in my T383838configuration.nix file.
I put these snippets into T383838configuration.nix and ran a T383838nixos-rebuild switch. But I couldn't figure out how to pull a model from the open web ui, so I just did an T383838ollama pull codellama at the CLI.
Ollama
T282828
servicesTff7b72.Ta5d6ffollama Tff7b72= Tb4b4b4{
Ta5d6ffenable Tff7b72= Tff7b72trueTb4b4b4;
Ta5d6ffacceleration Tff7b72= Ta5d6ff"Ta5d6ffcudaTa5d6ff"Tb4b4b4; T8b949e# Or "rocm"
Tb4b4b4}Tb4b4b4;
systemdTff7b72.servicesTff7b72.ollamaTff7b72.Ta5d6ffserviceConfig Tff7b72= Tb4b4b4{
Ta5d6ffEnvironment Tff7b72= Tb4b4b4[ Ta5d6ff"Ta5d6ffOLLAMA_HOST=0.0.0.0:11434Ta5d6ff" Tb4b4b4]Tb4b4b4;
Tb4b4b4}Tb4b4b4;
Open Web UI
T282828
servicesTff7b72.Ta5d6ffopen-webui Tff7b72= Tb4b4b4{
Ta5d6ffenable Tff7b72= Tff7b72trueTb4b4b4;
Ta5d6ffport Tff7b72= T79c0ff3000Tb4b4b4;
T8b949e# note: add openFirewall = true; to share it with other hosts
T8b949e# also add host = "0.0.0.0"; or other appropriate value
Ta5d6ffenvironment Tff7b72= Tb4b4b4{
Ta5d6ffANONYMIZED_TELEMETRY Tff7b72= Ta5d6ff"Ta5d6ffFalseTa5d6ff"Tb4b4b4;
Ta5d6ffDO_NOT_TRACK Tff7b72= Ta5d6ff"Ta5d6ffTrueTa5d6ff"Tb4b4b4;
Ta5d6ffSCARF_NO_ANALYTICS Tff7b72= Ta5d6ff"Ta5d6ffTrueTa5d6ff"Tb4b4b4;
Ta5d6ffOLLAMA_API_BASE_URL Tff7b72= Ta5d6ff"Ta5d6ffhttp://127.0.0.1:11434/apiTa5d6ff"Tb4b4b4;
Ta5d6ffOLLAMA_BASE_URL Tff7b72= Ta5d6ff"Ta5d6ffhttp://127.0.0.1:11434Ta5d6ff"Tb4b4b4;
Tb4b4b4}Tb4b4b4;
Tb4b4b4}Tb4b4b4;
nixpkgsTff7b72.configTff7b72.Ta5d6ffallowUnfreePredicate Tff7b72= pkgTb4b4b4: Tffa657builtinsTff7b72.elem Tb4b4b4(libTff7b72.getName pkgTb4b4b4) Tb4b4b4[
Ta5d6ff"Ta5d6ffcuda_cudartTa5d6ff"
Ta5d6ff"Ta5d6ffcuda_nvccTa5d6ff"
Ta5d6ff"Ta5d6ffcuda_ccclTa5d6ff"
Ta5d6ff"Ta5d6fflibcublasTa5d6ff"
Ta5d6ff"Ta5d6ffopen-webuiTa5d6ff"
Tb4b4b4]Tb4b4b4;
Once the Web UI is running, API Keys must be enabled in Admin → Settings → Generarl, Enable API Keys.
Neovim
I think the sticking point here was realizing the T383838/api had to be in the connection url. While other transports had those settings baked in, I had to include that in the configuration.
I'm using Lazy, so here's the stanza I use inside my plugins:
T282828
Tb4b4b4{
Ta5d6ff"Ta5d6ffolimorris/codecompanion.nvimTa5d6ff"Tb4b4b4,
Te6edf3dependencies Tff7b72= Tb4b4b4{ Ta5d6ff"Ta5d6ffnvim-lua/plenary.nvimTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnvim-treesitter/nvim-treesitterTa5d6ff" Tb4b4b4},
Te6edf3config Tff7b72= Tff7b72functionTb4b4b4(Tb4b4b4)
Tffa657requireTb4b4b4(Ta5d6ff"Ta5d6ffcodecompanionTa5d6ff"Tb4b4b4).Td2a8ffsetupTb4b4b4({
Te6edf3adapters Tff7b72= Tb4b4b4{
Te6edf3http Tff7b72= Tb4b4b4{
Te6edf3hal900 Tff7b72= Tff7b72functionTb4b4b4(Tb4b4b4)
Tff7b72return Tffa657requireTb4b4b4(Ta5d6ff"Ta5d6ffcodecompanion.adaptersTa5d6ff"Tb4b4b4).Td2a8ffextendTb4b4b4(
Ta5d6ff"Ta5d6ffopenai_compatibleTa5d6ff"Tb4b4b4, Tb4b4b4{
Te6edf3env Tff7b72= Tb4b4b4{
Te6edf3url Tff7b72=
Ta5d6ff"Ta5d6ffhttp://127.0.0.1:3000/apiTa5d6ff"Tb4b4b4,
Te6edf3api_key Tff7b72= Te6edf3secretsTb4b4b4[Ta5d6ff'Ta5d6ffapi_keyTa5d6ff'Tb4b4b4],
Tb4b4b4},
Te6edf3headers Tff7b72= Tb4b4b4{
Tb4b4b4[Ta5d6ff"Ta5d6ffContent-TypeTa5d6ff"Tb4b4b4] Tff7b72=
Ta5d6ff"Ta5d6ffapplication/jsonTa5d6ff"Tb4b4b4,
Tb4b4b4[Ta5d6ff"Ta5d6ffAuthorizationTa5d6ff"Tb4b4b4] Tff7b72=
Ta5d6ff"Ta5d6ffBearer ${api_key}Ta5d6ff"Tb4b4b4,
Tb4b4b4},
Te6edf3parameters Tff7b72= Tb4b4b4{
Te6edf3sync Tff7b72= Tff7b72trueTb4b4b4,
Tb4b4b4},
Tb4b4b4})
Tff7b72endTb4b4b4,
Tb4b4b4},
Tb4b4b4},
Te6edf3strategies Tff7b72= Tb4b4b4{
Te6edf3chat Tff7b72= Tb4b4b4{
Te6edf3adapter Tff7b72= Ta5d6ff"Ta5d6ffhal900Ta5d6ff"Tb4b4b4,
Tb4b4b4},
Te6edf3inline Tff7b72= Tb4b4b4{
Te6edf3adapter Tff7b72= Ta5d6ff"Ta5d6ffhal900Ta5d6ff"Tb4b4b4,
Tb4b4b4},
Te6edf3cmd Tff7b72= Tb4b4b4{
Te6edf3adapter Tff7b72= Ta5d6ff"Ta5d6ffhal900Ta5d6ff"Tb4b4b4,
Tb4b4b4}
Tb4b4b4},
Te6edf3opts Tff7b72= Tb4b4b4{
Te6edf3log_level Tff7b72= Ta5d6ff"Ta5d6ffINFOTa5d6ff"Tb4b4b4,
Tb4b4b4},
Tb4b4b4}
Tb4b4b4)
Te6edf3vimTb4b4b4.Te6edf3keymapTb4b4b4.Td2a8ffsetTb4b4b4(Ta5d6ff"Ta5d6ffnTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff<Leader><Leader>Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff:CodeCompanionChat Toggle<cr>Ta5d6ff"Tb4b4b4,
Td2a8ffDESCTb4b4b4(Ta5d6ff"Ta5d6ffAI: ChatTa5d6ff"Tb4b4b4))
Tff7b72endTb4b4b4,
Tb4b4b4},
I made a table to hold secret values that I load from an external file, so the above could just as easily be:
api_key="sk-some-value-from-the-open-web-ui"
I load this up and then double tap the space bar to start a chat session. Enter key (from normal mode) sends.
(Note: JWT keys don't start with sk...)
keepers?
Nope. Neither free enough nor useful enough.
I'll try again in the future with other models, maybe.
Tags: index, nvim, ai
Tags
Navigation