dotfiles

My personal shell configs and stuff
git clone git://git.alex.balgavy.eu/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

commit 22677e9b86fac102fa3ef8309bb4790dca1831a0
parent 623f647d9cf726fd9620e148a4f4c1d0d6792a02
Author: Alexander Balgavy <alexander.balgavy@spaceapplications.com>
Date:   Fri, 27 Oct 2023 20:19:46 +0200

nvim: llm access via ollama

Diffstat:
Mnvim/init.lua | 2++
Mnvim/lazy-lock.json | 46+++++++++++++++++++++++-----------------------
Anvim/lua/llm.lua | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 144 insertions(+), 23 deletions(-)

diff --git a/nvim/init.lua b/nvim/init.lua @@ -74,6 +74,8 @@ vim.keymap.set('n', 'i', function() end end, {expr = true}) +require('llm') + vim.cmd ([[ nnoremap <leader><C-e><C-u> :<c-u>exe "vsplit ~/.vim/snippets/"..&filetype..".snippets"<CR> ]]) diff --git a/nvim/lazy-lock.json b/nvim/lazy-lock.json @@ -1,30 +1,30 @@ { - "Comment.nvim": { "branch": "master", "commit": "d0cbbfb539898a275dc4398446ab0ae3b94819bf" }, - "LuaSnip": { "branch": "master", "commit": "99a94cc35ec99bf06263d0346128e908a204575c" }, - "cellular-automaton.nvim": { "branch": "main", "commit": "679943b8e1e5ef79aaeeaf4b00782c52eb4e928f" }, + "Comment.nvim": { "branch": "master", "commit": "0236521ea582747b58869cb72f70ccfa967d2e89" }, + "LuaSnip": { "branch": "master", "commit": "80a8528f084a97b624ae443a6f50ff8074ba486b" }, + "cellular-automaton.nvim": { "branch": "main", "commit": "b7d056dab963b5d3f2c560d92937cb51db61cb5b" }, "cmp-nvim-lsp": { "branch": "main", "commit": "44b16d11215dce86f253ce0c30949813c0a90765" }, - "cmp_luasnip": { "branch": "master", "commit": "18095520391186d634a0045dacaa346291096566" }, + "cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" }, "fidget.nvim": { "branch": "main", "commit": "89b633f3bd0b7187f070236b348697de176860e2" }, - "flash.nvim": { "branch": "main", "commit": "967117690bd677cb7b6a87f0bc0077d2c0be3a27" }, - "gitsigns.nvim": { "branch": "main", "commit": "31178496552584e84fa9e74e087dec1f6c347f5d" }, - "indent-blankline.nvim": { "branch": "master", "commit": "4541d690816cb99a7fc248f1486aa87f3abce91c" }, - "lazy.nvim": { "branch": "main", "commit": "dac844ed617dda4f9ec85eb88e9629ad2add5e05" }, + "flash.nvim": { "branch": "main", "commit": "48817af25f51c0590653bbc290866e4890fe1cbe" }, + "gitsigns.nvim": { "branch": "main", "commit": "5a9a6ac29a7805c4783cda21b80a1e361964b3f2" }, + "indent-blankline.nvim": { "branch": "master", "commit": "8a7b48f5823cc924f815129192288ec2e2b9288f" }, + "lazy.nvim": { "branch": "main", "commit": "4c75c8eeb957a99aa44ce8e526c04340ab358c5e" }, "lsp-inlayhints.nvim": { "branch": "main", "commit": "d981f65c9ae0b6062176f0accb9c151daeda6f16" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "e86a4c84ff35240639643ffed56ee1c4d55f538e" }, - "mason.nvim": { "branch": "main", "commit": "fe9e34a9ab4d64321cdc3ecab4ea1809239bb73f" }, - "neodev.nvim": { "branch": "main", "commit": "9f0205a08757711f57589a1dffa8abf525f4a23b" }, - "null-ls.nvim": { "branch": "main", "commit": "db09b6c691def0038c456551e4e2772186449f35" }, - "nvim-cmp": { "branch": "main", "commit": "c4e491a87eeacf0408902c32f031d802c7eafce8" }, - "nvim-dap": { "branch": "master", "commit": "1c63f37f95cd4fb54512898168138d9a75d1516a" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "e7b64c11035aa924f87385b72145e0ccf68a7e0a" }, + "mason.nvim": { "branch": "main", "commit": "cd7835b15f5a4204fc37e0aa739347472121a54c" }, + "neodev.nvim": { "branch": "main", "commit": "b094a663ccb71733543d8254b988e6bebdbdaca4" }, + "null-ls.nvim": { "branch": "main", "commit": "0010ea927ab7c09ef0ce9bf28c2b573fc302f5a7" }, + "nvim-cmp": { "branch": "main", "commit": "d3a3056204e1a9dbb7c7fe36c114dc43b681768c" }, + "nvim-dap": { "branch": "master", "commit": "92dc531eea2c9a3ef504a5c8ac0decd1fa59a6a3" }, "nvim-dap-python": { "branch": "master", "commit": "37b4cba02e337a95cb62ad1609b3d1dccb2e5d42" }, - "nvim-dap-ui": { "branch": "master", "commit": "85b16ac2309d85c88577cd8ee1733ce52be8227e" }, + "nvim-dap-ui": { "branch": "master", "commit": "34160a7ce6072ef332f350ae1d4a6a501daf0159" }, "nvim-dap-virtual-text": { "branch": "master", "commit": "57f1dbd0458dd84a286b27768c142e1567f3ce3b" }, - "nvim-lspconfig": { "branch": "master", "commit": "c0de180ddb3df36feef8ac3607670894d0e7497f" }, - "nvim-origami": { "branch": "main", "commit": "7bc3fd9e8cba3c3ccc64874b32568102eac7214e" }, - "nvim-treesitter": { "branch": "master", "commit": "8d5e5dc40a4c480483690777cefb8cf67e710702" }, - "nvim-treesitter-textobjects": { "branch": "master", "commit": "9e519b6146512c8e2e702faf8ac48420f4f5deec" }, - "plenary.nvim": { "branch": "master", "commit": "267282a9ce242bbb0c5dc31445b6d353bed978bb" }, - "telescope-fzf-native.nvim": { "branch": "main", "commit": "9bc8237565ded606e6c366a71c64c0af25cd7a50" }, - "telescope.nvim": { "branch": "master", "commit": "31b05ad3c313210039fae6958fb00449d72c259e" }, - "which-key.nvim": { "branch": "main", "commit": "7ccf476ebe0445a741b64e36c78a682c1c6118b7" } + "nvim-ghost.nvim": { "branch": "main", "commit": "a1ca0b2dac59881066d7ac9373cf64d59ba29d6a" }, + "nvim-lspconfig": { "branch": "master", "commit": "e49b1e90c1781ce372013de3fa93a91ea29fc34a" }, + "nvim-treesitter": { "branch": "master", "commit": "eb3faef3a44641e5875581e901b0a8df8da2bde4" }, + "nvim-treesitter-textobjects": { "branch": "master", "commit": "78c49ca7d2f7ccba2115c11422c037713c978ad1" }, + "plenary.nvim": { "branch": "master", "commit": "50012918b2fc8357b87cff2a7f7f0446e47da174" }, + "telescope-fzf-native.nvim": { "branch": "main", "commit": "6c921ca12321edaa773e324ef64ea301a1d0da62" }, + "telescope.nvim": { "branch": "master", "commit": "74ce793a60759e3db0d265174f137fb627430355" }, + "which-key.nvim": { "branch": "main", "commit": "ce741eb559c924d72e3a67d2189ad3771a231414" } } \ No newline at end of file diff --git a/nvim/lua/llm.lua b/nvim/lua/llm.lua @@ -0,0 +1,119 @@ +local ESC_FEEDKEY = vim.api.nvim_replace_termcodes("<ESC>", true, false, true) +local ollama = { + + --- @param model string + --- @param context string + --- @param prompt string + --- @param buf_nr number + --- @param max_width number + --- @return number + run = function(model, context, prompt, buf_nr, max_width) + local cmd = ("ollama run $model $prompt") + :gsub("$model", model) + :gsub("$prompt", vim.fn.shellescape(context .. "\n" .. prompt)) + local header = vim.split(prompt, "\n") + table.insert(header, "----------------------------------------") + vim.api.nvim_buf_set_lines(buf_nr, 0, -1, false, header) + local line = vim.tbl_count(header) + local line_char_count = 0 + local words = {} + return vim.fn.jobstart(cmd, { + on_stdout = function(_, data, _) + for i, token in ipairs(data) do + if i > 1 or (string.match(token, "^%s") and line_char_count > max_width) then -- if returned data array has more than one element, a line break occured. + line = line + 1 + words = {} + line_char_count = 0 + end + line_char_count = line_char_count + #token + table.insert(words, token) + vim.api.nvim_buf_set_lines(buf_nr, line, line + 1, false, { table.concat(words, "") }) + end + end, + }) + end, + + --- @return string + get_visual_lines = function(bufnr) + vim.api.nvim_feedkeys(ESC_FEEDKEY, "n", true) + vim.api.nvim_feedkeys("gv", "x", false) + vim.api.nvim_feedkeys(ESC_FEEDKEY, "n", true) + + local start_row, start_col = unpack(vim.api.nvim_buf_get_mark(bufnr, "<")) + local end_row, end_col = unpack(vim.api.nvim_buf_get_mark(bufnr, ">")) + local lines = vim.api.nvim_buf_get_lines(bufnr, start_row - 1, end_row, false) + + if start_row == 0 then + lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) + start_row = 1 + start_col = 0 + end_row = #lines + end_col = #lines[#lines] + end + + start_col = start_col + 1 + end_col = math.min(end_col, #lines[#lines] - 1) + 1 + + lines[#lines] = lines[#lines]:sub(1, end_col) + lines[1] = lines[1]:sub(start_col) + + return table.concat(lines, "\n") + end +} +local plen = require("plenary.window.float") +-- define some styles and spawn a scratch buffer +local win_options = { + winblend = 10, + border = "rounded", + bufnr = vim.api.nvim_create_buf(false, true) +} + +vim.keymap.set("n", "<leader>cc", function() + local prompt = vim.fn.input("Prompt: ") + if prompt == "" then + return + end + plen.clear(win_options.bufnr) + local float = plen.percentage_range_window(0.8, 0.8, win_options) + local win_width = vim.api.nvim_win_get_width(float.win_id) - 5 + ollama.run("mistral:instruct", "", prompt, float.bufnr, win_width) +end, { silent = true, desc = "Mistral" }) + +vim.keymap.set("v", "<leader>cp", function() + local prompt = ollama.get_visual_lines(0) + plen.clear(win_options.bufnr) + local float = plen.percentage_range_window(0.8, 0.8, win_options) + local win_width = vim.api.nvim_win_get_width(float.win_id) - 5 + ollama.run("mistral:instruct", "", prompt, float.bufnr, win_width) +end, { silent = true, desc = "Mistral" }) + +------------------------------------------------------------------ +-- coding +vim.keymap.set("v", "<leader>cc", function() + local prompt = ollama.get_visual_lines(0) + plen.clear(win_options.bufnr) + local float = plen.percentage_range_window(0.8, 0.8, win_options) + local win_width = vim.api.nvim_win_get_width(float.win_id) - 5 + ollama.run("codellama:7b", "", prompt, float.bufnr, win_width) +end, { silent = true, desc = "Codellama" }) + +------------------------------------------------------------------ +-- general purpose math & logic questions +vim.keymap.set("n", "<leader>cm", function() + local prompt = vim.fn.input("Prompt: ") + if prompt == "" then + return + end + plen.clear(win_options.bufnr) + local float = plen.percentage_range_window(0.8, 0.8, win_options) + local win_width = vim.api.nvim_win_get_width(float.win_id) - 5 + ollama.run("wizard-math", "", prompt, float.bufnr, win_width) +end, { silent = true, desc = "Math" }) + +vim.keymap.set("v", "<leader>cm", function() + local prompt = ollama.get_visual_lines(0) + plen.clear(win_options.bufnr) + local float = plen.percentage_range_window(0.8, 0.8, win_options) + local win_width = vim.api.nvim_win_get_width(float.win_id) - 5 + ollama.run("wizard-math", "", prompt, float.bufnr, win_width) +end, { silent = true, desc = "Math" })