From f17b5511c49e7cb5aab5e6afee6828fc129e145b Mon Sep 17 00:00:00 2001 From: PyDevC Date: Sun, 24 Aug 2025 05:23:12 -0400 Subject: [PATCH 1/8] UPDATED README: Warning message --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index af112f3..6e3de5a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ AI autocomplete plugin for neovim +**Warning:** things are pretty unstable right now since the newapi. + ## How to launch the server launch the llama-server on http://127.0.0.1:8080 From f4216563b6b82b3b716f3a669769d5218586bec9 Mon Sep 17 00:00:00 2001 From: PyDevC Date: Sun, 24 Aug 2025 05:27:02 -0400 Subject: [PATCH 2/8] Added api setup to init --- lua/model_cmp/commands.lua | 1 - lua/model_cmp/init.lua | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/model_cmp/commands.lua b/lua/model_cmp/commands.lua index 1fd1c73..e3be673 100644 --- a/lua/model_cmp/commands.lua +++ b/lua/model_cmp/commands.lua @@ -13,7 +13,6 @@ function M.create_autocmds(group) if file == "" or file:find 'oil:///' then return end - llama.text_changed() end }) diff --git a/lua/model_cmp/init.lua b/lua/model_cmp/init.lua index 9b4b5bd..243b0a3 100644 --- a/lua/model_cmp/init.lua +++ b/lua/model_cmp/init.lua @@ -1,7 +1,7 @@ local commands = require("model_cmp.commands") local mainconfig = require("model_cmp.config") local virtualtext = require("model_cmp.virtualtext") -local modelapi = require("model_cmp.modelapi.managekey") +local api = require("model_cmp.modelapi.common") local M = {} @@ -15,6 +15,7 @@ function M.setup(config) commands.create_autocmds(model_cmp_grp) commands.create_usercmds() virtualtext.setup(config) + api.setup(config) end return M From 563675cebc9367c758cf0cc2367ea8a0592eb3c9 Mon Sep 17 00:00:00 2001 From: PyDevC Date: Sun, 24 Aug 2025 05:57:56 -0400 Subject: [PATCH 3/8] fix: working suggestions --- lua/model_cmp/commands.lua | 3 ++- lua/model_cmp/init.lua | 1 + lua/model_cmp/modelapi/common.lua | 4 ++-- lua/model_cmp/modelapi/llama.lua | 2 +- lua/model_cmp/modelapi/prompt.lua | 13 +++++++++++++ lua/model_cmp/modelapi/request.lua | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lua/model_cmp/commands.lua b/lua/model_cmp/commands.lua index e3be673..d09fb7e 100644 --- a/lua/model_cmp/commands.lua +++ b/lua/model_cmp/commands.lua @@ -1,4 +1,4 @@ -local llama = require("model_cmp.modelapi.llama") +local api = require("model_cmp.modelapi.common") local virtualtext = require("model_cmp.virtualtext") local M = {} @@ -13,6 +13,7 @@ function M.create_autocmds(group) if file == "" or file:find 'oil:///' then return end + api.send_request() end }) diff --git a/lua/model_cmp/init.lua b/lua/model_cmp/init.lua index 243b0a3..cde1b3f 100644 --- a/lua/model_cmp/init.lua +++ b/lua/model_cmp/init.lua @@ -14,6 +14,7 @@ function M.setup(config) commands.create_autocmds(model_cmp_grp) commands.create_usercmds() + virtualtext.setup(config) api.setup(config) end diff --git a/lua/model_cmp/modelapi/common.lua b/lua/model_cmp/modelapi/common.lua index 4bb08f5..57ebbbb 100644 --- a/lua/model_cmp/modelapi/common.lua +++ b/lua/model_cmp/modelapi/common.lua @@ -82,10 +82,10 @@ function M.send_request() end end - if request ~= nil then + if request == nil then return end - if not check_already_requested(bufnr) then + if check_already_requested(bufnr) then return end diff --git a/lua/model_cmp/modelapi/llama.lua b/lua/model_cmp/modelapi/llama.lua index 7ca6234..3669bd8 100644 --- a/lua/model_cmp/modelapi/llama.lua +++ b/lua/model_cmp/modelapi/llama.lua @@ -30,7 +30,7 @@ function M.generate_request() local request = { "-s", "-X", "POST", - generate_url(), + generate_url(custom.custom_url), "-H", "Content-Type: application/json", "-d", vim.fn.json_encode({ diff --git a/lua/model_cmp/modelapi/prompt.lua b/lua/model_cmp/modelapi/prompt.lua index b81359e..1210a23 100644 --- a/lua/model_cmp/modelapi/prompt.lua +++ b/lua/model_cmp/modelapi/prompt.lua @@ -83,4 +83,17 @@ Instructions: ]] } +-- After this we are going to collect and send new data +M.closecall_suggestions = { + role = "user", + content = [[You almost got the right answer, try again with a different but similar result, +]] +} + +M.wrong_suggestion = { + role = "user", + content = [[You predicted wrong, try again with a completly new suggestion but with this code +]] +} + return M diff --git a/lua/model_cmp/modelapi/request.lua b/lua/model_cmp/modelapi/request.lua index f0197ba..c0faf20 100644 --- a/lua/model_cmp/modelapi/request.lua +++ b/lua/model_cmp/modelapi/request.lua @@ -3,7 +3,7 @@ local Job = require("plenary.job") local M = {} -function M.send(bufnr, request_args, callback) +function M.send(request_args, callback) local result = {} local job = Job:new({ command = "curl", From 6bb5db085c55f56ffe2225ea562fe400887dc195 Mon Sep 17 00:00:00 2001 From: PyDevC Date: Sun, 24 Aug 2025 06:43:47 -0400 Subject: [PATCH 4/8] fix: prompt aligned according to context The current line was missing in context Needed to delay the request frequency in common.lua --- lua/model_cmp/context.lua | 17 +++++++++++------ lua/model_cmp/modelapi/common.lua | 6 +++--- lua/model_cmp/modelapi/llama.lua | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/lua/model_cmp/context.lua b/lua/model_cmp/context.lua index 48bcfe4..3ac8071 100755 --- a/lua/model_cmp/context.lua +++ b/lua/model_cmp/context.lua @@ -8,13 +8,13 @@ end local function get_context_before(currentline) local start = 0 local stop = currentline - 1 - return vim.api.nvim_buf_get_lines(M.ContextEngine.bufnr, start, stop, false) + return vim.api.nvim_buf_get_lines(0, start, stop, false) end local function get_context_after(currentline) - local start = currentline + 1 + local start = currentline local stop = -1 - return vim.api.nvim_buf_get_lines(M.ContextEngine.bufnr, start, stop, false) + return vim.api.nvim_buf_get_lines(0, start, stop, false) end ---@class ModelCmp.ContextEngine @@ -24,7 +24,7 @@ end ---@field ctx table -- context ---@field currlang string -- current language eg: python, c, cpp, markdown M.ContextEngine = { - bufnr = 0, + bufnr = vim.api.nvim_get_current_buf(), id = 0, -- Need to think how to manipulate this this is imp to put the right virtual text for right context cursor = { 0, 0 }, ctx = { @@ -36,10 +36,11 @@ M.ContextEngine = { } function M.ContextEngine:get_ctx() + print(M.ContextEngine.bufnr) self.cursor = get_cursor() self.ctx.before = get_context_before(self.cursor[1]) self.ctx.after = get_context_after(self.cursor[1]) - self.ctx.current = vim.api.nvim_buf_get_lines(M.ContextEngine.bufnr, self.cursor[1], self.cursor[1] + 1, false) + self.ctx.current = vim.api.nvim_buf_get_lines(0, self.cursor[1] - 1, self.cursor[1] + 1, false) if not self.ctx.current then self.ctx.current = { "" } end @@ -72,7 +73,11 @@ function M.generate_context_text() local line = M.ContextEngine.ctx.current[1] local col = M.ContextEngine.cursor[2] - lines = lines .. line:sub(1, col) .. "" .. line:sub(col + 1) + if line == nil then + line = lines .. "\n\n" + else + lines = lines .. line:sub(1, col) .. "" .. line:sub(col + 1) + end -- after for idx, line in ipairs(M.ContextEngine.ctx.after) do diff --git a/lua/model_cmp/modelapi/common.lua b/lua/model_cmp/modelapi/common.lua index 57ebbbb..40d5a4f 100644 --- a/lua/model_cmp/modelapi/common.lua +++ b/lua/model_cmp/modelapi/common.lua @@ -58,7 +58,7 @@ end -- we will check if there is a request already made for the given buffer local function check_already_requested(bufnr) - for buffer in pairs(M.requests) do + for _,buffer in pairs(M.requests) do if bufnr == buffer then return true end @@ -89,13 +89,13 @@ function M.send_request() return end - add_request(bufnr) + local index = add_request(bufnr) req.send(request, function(response) vim.schedule(function() local text = utils.decode_response(response) virtualtext.VirtualText:update_preview(text) - remove_request(bufnr) + remove_request(index) end) end ) diff --git a/lua/model_cmp/modelapi/llama.lua b/lua/model_cmp/modelapi/llama.lua index 3669bd8..5d10db9 100644 --- a/lua/model_cmp/modelapi/llama.lua +++ b/lua/model_cmp/modelapi/llama.lua @@ -15,7 +15,7 @@ function M.generate_request() local bufnr = context.ContextEngine.bufnr local prompt = context.generate_context_text() local lang = context.ContextEngine:get_currlang() - local complete_prompt = "# language: " .. lang .. prompt + local complete_prompt = "# language: " .. lang .. "\n" .. prompt local few_shots = systemprompt.complete_few_shots From 1b6b0389df8daf6440253615f1fe6975a62cd9ab Mon Sep 17 00:00:00 2001 From: PyDevC Date: Sun, 24 Aug 2025 06:45:41 -0400 Subject: [PATCH 5/8] Added Todo From know on the new features or other commits other than bug fixes will be according the TODO.md this is to ensure consistent development of the plugin --- TODO.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..2ff3d38 --- /dev/null +++ b/TODO.md @@ -0,0 +1,18 @@ +# TODO + +- Load multiple lines of vitualtext even if not enough space. +- remove all the extmarks even. +- Capture single line virtual text +- Capture All line capture +- Treat the suggestions as a buffer and move through it for custom suggestions pickup +- manage response gracefully +- improve context engine +- improve modelapi +- setup openai and claude services +- Different prompt style +- Conversational few-shot prompt +- improve commands for different scenarios +- Lsp support +- nvim-cmp support +- Chat options +- more AI models From 9c0633d91799d0e7955be8a3619c2aea2c157452 Mon Sep 17 00:00:00 2001 From: PyDevC Date: Sun, 24 Aug 2025 06:53:48 -0400 Subject: [PATCH 6/8] Update README --- README.md | 46 ++++++++++++++++++++++++--------------- lua/model_cmp/context.lua | 1 - 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 6e3de5a..20665e4 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ AI autocomplete plugin for neovim -**Warning:** things are pretty unstable right now since the newapi. - ## How to launch the server -launch the llama-server on http://127.0.0.1:8080 +```bash +llama-server --no-mmap -hf bartowski/Llama-3.2-3B-Instruct-GGUF:Q8_0 +``` ## Installation @@ -14,20 +14,30 @@ launch the llama-server on http://127.0.0.1:8080 ```lua return { - "PyDevC/model-cmp.nvim", - config = function () - require("model_cmp").setup() - end + "PyDevC/model-cmp.nvim", + config = function() + require("model_cmp").setup({ + delay = 1, + + api = { + custom_url = { + url = "http://127.0.0.1", + port = "8080" + } + }, + + virtualtext = { + enable = false, + type = "inline", + + style = { -- This is just a highlight group + fg = "#b53a3a", + italic = false, + bold = false + } + + }, + }) + end, } ``` - -## What technique do we use? - -We actually use few shot prompting with self experimentation - -## Current Limitations - -- limited to the capabilities of the underlying LLM model. -- No configurations -- does not work well with markdown -- Output cpature does not work properly diff --git a/lua/model_cmp/context.lua b/lua/model_cmp/context.lua index 3ac8071..564945b 100755 --- a/lua/model_cmp/context.lua +++ b/lua/model_cmp/context.lua @@ -36,7 +36,6 @@ M.ContextEngine = { } function M.ContextEngine:get_ctx() - print(M.ContextEngine.bufnr) self.cursor = get_cursor() self.ctx.before = get_context_before(self.cursor[1]) self.ctx.after = get_context_after(self.cursor[1]) From aa0dea23775846707794aa9d2a44ea120dbf6c34 Mon Sep 17 00:00:00 2001 From: PyDevC Date: Fri, 29 Aug 2025 06:35:26 -0400 Subject: [PATCH 7/8] [feat]: adding extra lines to display AI Suggestions will add additional lines to display AI suggestions, for now user needs to move all the lines in order to reach the end of suggestions. In future we will use g[motion] to move betten suggested lines --- lua/model_cmp/commands.lua | 5 ++++ lua/model_cmp/utils.lua | 3 +++ lua/model_cmp/virtualtext.lua | 51 ++++++++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/lua/model_cmp/commands.lua b/lua/model_cmp/commands.lua index d09fb7e..81e4654 100644 --- a/lua/model_cmp/commands.lua +++ b/lua/model_cmp/commands.lua @@ -21,6 +21,11 @@ function M.create_autocmds(group) { group = group, callback = function(event) + local file = event["file"] + -- also Check for buffer editing in oil.nvim + if file == "" or file:find 'oil:///' then + return + end virtualtext.action.clear_preview() end }) diff --git a/lua/model_cmp/utils.lua b/lua/model_cmp/utils.lua index cd60d92..2f2aaf8 100644 --- a/lua/model_cmp/utils.lua +++ b/lua/model_cmp/utils.lua @@ -10,4 +10,7 @@ function M.decode_response(response) return response_table.choices[1].message.content end +function M.trim_codeblock_response(lines) +end + return M diff --git a/lua/model_cmp/virtualtext.lua b/lua/model_cmp/virtualtext.lua index 2549264..c4fc21b 100644 --- a/lua/model_cmp/virtualtext.lua +++ b/lua/model_cmp/virtualtext.lua @@ -17,15 +17,43 @@ M.VirtualText = { ext_ids = {}, } +local function remove_empty_lines() + local start_line = vim.b.start_line + local count = vim.b.count + if start_line and count and count > 0 then + vim.api.nvim_buf_set_lines(0, start_line - 1, start_line + count, false, {}) + vim.b.start_line = nil + vim.b.count = nil + end + vim.api.nvim_win_set_cursor(0,vim.b.cursor) +end + function M.VirtualText:clear_preview(ext_ids_arg) + if vim.b.start_line == nil then + return + end local ext_ids = ext_ids_arg or self.ext_ids for ext_id in pairs(ext_ids) do vim.api.nvim_buf_del_extmark(0, self.ns_id, ext_id) end + remove_empty_lines() +end + +local function insert_empty_lines(current_line, no_line) + local lines = {} + for i = 1, no_line do + table.insert(lines, "") + end + vim.b.start_line = current_line + vim.b.count = no_line + vim.api.nvim_buf_set_lines(0, current_line - 1, current_line - 1, false, lines) end function M.VirtualText:update_preview(text) - if text == nil then + if vim.b.count ~= nil or vim.b.start_line ~= nil then + return + end + if not vim.g.model_cmp_virtualtext_auto_trigger or text == nil then return end @@ -33,27 +61,24 @@ function M.VirtualText:update_preview(text) return end local cursor = context.ContextEngine.cursor + vim.b.cursor = cursor local lines = {} for line in text:gmatch("[^\r\n]+") do table.insert(lines, line) end + insert_empty_lines(cursor[1], #lines) local max_line = vim.api.nvim_buf_line_count(0) - cursor[1] + 1 local extmark = {} for idx, line in ipairs(lines) do - if not line:find "```" then - if idx == max_line then - return - end - table.insert(self.ext_ids, idx) - extmark = { - id = idx, - virt_text = { { line, "CustomVirttextHighlight" } }, - right_gravity = true, - } - vim.api.nvim_buf_set_extmark(0, self.ns_id, cursor[1] + idx - 2, 0, extmark) - end + table.insert(self.ext_ids, idx) + extmark = { + id = idx, + virt_text = { { line, "CustomVirttextHighlight" } }, + right_gravity = true, + } + vim.api.nvim_buf_set_extmark(0, self.ns_id, cursor[1] + idx - 2, 0, extmark) end M.CaptureText = lines end From ff3fd79e86762d1d88cb310f03ee81e349120c73 Mon Sep 17 00:00:00 2001 From: Anushk Sharma Date: Fri, 29 Aug 2025 21:57:22 +0530 Subject: [PATCH 8/8] added sponsor QR --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 20665e4..0e7cd8b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ AI autocomplete plugin for neovim +support me!!! it is difficult to develop open source while searching for jobs. scan and support +![IMG-20250829-WA0012](https://github.com/user-attachments/assets/e86526b6-6819-4ae5-a3b7-6698af3f03ee) + + ## How to launch the server ```bash