neovim

a little llm experiementation

+175
+1
candy/lua/marshmallow/init.lua
··· 22 22 require("marshmallow.autocmd") 23 23 require("marshmallow.env") 24 24 require("marshmallow.git") 25 + require("marshmallow.llm")
+40
candy/lua/marshmallow/llm.lua
··· 1 + require("minuet").setup({ 2 + virtualtext = { 3 + auto_trigger_ft = { "lua" }, 4 + keymap = { 5 + -- accept whole completion 6 + accept = "<A-A>", 7 + -- accept one line 8 + accept_line = "<A-a>", 9 + -- accept n lines (prompts for number) 10 + -- e.g. "A-z 2 CR" will accept 2 lines 11 + accept_n_lines = "<A-z>", 12 + -- Cycle to prev completion item, or manually invoke completion 13 + prev = "<A-[>", 14 + -- Cycle to next completion item, or manually invoke completion 15 + next = "<A-]>", 16 + dismiss = "<A-e>", 17 + }, 18 + }, 19 + 20 + provider = "openai_compatible", 21 + request_timeout = 2.5, 22 + throttle = 1500, 23 + debounce = 600, 24 + provider_options = { 25 + openai_compatible = { 26 + api_key = "OPENROUTER_KEY", 27 + end_point = "https://openrouter.ai/api/v1/chat/completions", 28 + model = "deepseek/deepseek-chat-v3-0324", 29 + name = "Openrouter", 30 + optional = { 31 + max_tokens = 56, 32 + top_p = 0.9, 33 + provider = { 34 + -- Prioritize throughput for faster completion 35 + sort = "throughput", 36 + }, 37 + }, 38 + }, 39 + }, 40 + })
+133
candy/lua/marshmallow/usercommand.lua
··· 17 17 end, { 18 18 nargs = 1, 19 19 }) 20 + 21 + local namespace = vim.api.nvim_create_namespace("marsh-mods") 22 + local _window = nil 23 + 24 + local get_or_create_window = function() 25 + -- if _window == nil then 26 + vim.cmd.split({ mods = { vertical = true } }) 27 + _window = vim.api.nvim_get_current_win() 28 + -- end 29 + 30 + return _window 31 + end 32 + 33 + local mods_list = function() 34 + local window = get_or_create_window() 35 + local buf = vim.api.nvim_create_buf(false, true) 36 + -- vim.api.nvim_buf_set_name(buf, "mods://list") 37 + vim.api.nvim_win_set_buf(window, buf) 38 + vim.api.nvim_set_option_value("ft", "txt", { 39 + buf = buf, 40 + }) 41 + 42 + local obj = vim.system({ "mods", "--list" }, { 43 + text = true, 44 + }):wait() 45 + 46 + if obj.stdout == nil then 47 + return 48 + end 49 + 50 + local lines = vim.split(obj.stdout, "\n", { 51 + trimempty = true, 52 + }) 53 + 54 + vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) 55 + 56 + for key in pairs(lines) do 57 + vim.api.nvim_buf_set_extmark(0, namespace, key - 1, 0, { 58 + end_col = 7, 59 + hl_group = "Identifier", 60 + }) 61 + end 62 + 63 + vim.api.nvim_set_option_value("modifiable", false, { 64 + buf = buf, 65 + }) 66 + end 67 + 68 + local mods_prompt = function(context, arg) 69 + local window = get_or_create_window() 70 + 71 + local output = vim.fn.tempname() 72 + 73 + local buf = vim.api.nvim_create_buf(false, true) 74 + vim.api.nvim_win_set_buf(window, buf) 75 + vim.api.nvim_set_option_value("ft", "markdown", { 76 + buf = buf, 77 + }) 78 + -- vim.api.nvim_set_option_value("modifiable", false, { 79 + -- buf = buf, 80 + -- }) 81 + 82 + local obj = vim.system({ "mods", arg }, { 83 + stdin = context, 84 + text = true, 85 + detach = true, 86 + stdout = function(err, data) 87 + vim.schedule(function() 88 + -- if string.find(data, "\n") then 89 + -- local lines = vim.split(data, "\n") 90 + -- local last_line = vim.api.nvim_buf_line_count(buf) 91 + -- vim.api.nvim_buf_set_lines(buf, last_line, last_line, false, lines) 92 + -- else 93 + 94 + local lines = vim.split(data, "\n") 95 + 96 + local first = true 97 + 98 + for key, line in pairs(lines) do 99 + local length = vim.api.nvim_buf_line_count(buf) 100 + 101 + if not first then 102 + vim.api.nvim_buf_set_lines(buf, length, length, false, { "" }) 103 + length = length + 1 104 + end 105 + 106 + local col = vim.fn.col({ length, "$" }) - 1 107 + -- local existing_line = vim.api.nvim_buf_get_text(buf, length - 1, 0, length - 1, -1, {})[1] 108 + -- local new_line = existing_line .. data 109 + -- 110 + -- vim.api.nvim_buf_set_lines(buf, length - 1, length - 1, false, { 111 + -- new_line, 112 + -- }) 113 + vim.api.nvim_buf_set_text(buf, length - 1, col, length - 1, col, { 114 + line, 115 + }) 116 + 117 + first = false 118 + end 119 + 120 + -- if string.find(data, "\n") then 121 + -- vim.api.nvim_buf_set_lines(buf, length, length, false, { "" }) 122 + -- end 123 + 124 + -- vim.api.nvim_win_call(window, function() 125 + -- vim.cmd("normal! G") 126 + -- end) 127 + end) 128 + end, 129 + stderr = function(err, data) 130 + vim.schedule(function() 131 + vim.notify(data, vim.log.levels.ERROR) 132 + end) 133 + end, 134 + }) 135 + 136 + vim.print(obj) 137 + end 138 + 139 + vim.api.nvim_create_user_command("Mods", function(val) 140 + if val.args == "" then 141 + mods_list() 142 + return 143 + end 144 + 145 + local context = vim.api.nvim_buf_get_lines(0, val.line1, val.line2, false) 146 + 147 + mods_prompt(context, val.args) 148 + end, { 149 + nargs = "?", 150 + range = "%", 151 + bang = true, 152 + })
+1
flake.nix
··· 90 90 mini-nvim 91 91 colorizer 92 92 luasnip 93 + minuet-ai-nvim 93 94 (opt conform-nvim) 94 95 plenary-nvim 95 96 (pkgs.vimUtils.buildVimPlugin {