diff --git a/lua/codecompanion/init.lua b/lua/codecompanion/init.lua index b9186223..6c960d64 100644 --- a/lua/codecompanion/init.lua +++ b/lua/codecompanion/init.lua @@ -1,3 +1,4 @@ +local buf_utils = require("codecompanion.utils.buffers") local config = require("codecompanion.config") local context_utils = require("codecompanion.utils.context") local log = require("codecompanion.utils.log") @@ -265,26 +266,31 @@ M.setup = function(opts) local group = "codecompanion.syntax" api.nvim_create_augroup(group, { clear = true }) api.nvim_create_autocmd("FileType", { - pattern = "codecompanion", + pattern = "markdown", group = group, - callback = vim.schedule_wrap(function() - vim.iter(config.strategies.chat.variables):each(function(name, var) - vim.cmd.syntax('match CodeCompanionChatVariable "#' .. name .. '"') - if var.opts and var.opts.has_params then - vim.cmd.syntax('match CodeCompanionChatVariable "#' .. name .. ':\\d\\+-\\?\\d\\+"') - end - end) - vim.iter(config.strategies.agent.tools):each(function(name, _) - vim.cmd.syntax('match CodeCompanionChatTool "@' .. name .. '"') - end) - vim - .iter(config.strategies.agent) - :filter(function(name) - return name ~= "tools" + callback = vim.schedule_wrap(function(info) + if not api.nvim_buf_is_valid(info.buf) or not buf_utils.is_codecompanion_buffer(info.buf) then + return + end + api.nvim_buf_call(info.buf, function() + vim.iter(config.strategies.chat.variables):each(function(name, var) + vim.cmd.syntax('match CodeCompanionChatVariable "#' .. name .. '"') + if var.opts and var.opts.has_params then + vim.cmd.syntax('match CodeCompanionChatVariable "#' .. name .. ':\\d\\+-\\?\\d\\+"') + end end) - :each(function(name, _) - vim.cmd.syntax('match CodeCompanionChatAgent "@' .. name .. '"') + vim.iter(config.strategies.agent.tools):each(function(name, _) + vim.cmd.syntax('match CodeCompanionChatTool "@' .. name .. '"') end) + vim + .iter(config.strategies.agent) + :filter(function(name) + return name ~= "tools" + end) + :each(function(name, _) + vim.cmd.syntax('match CodeCompanionChatAgent "@' .. name .. '"') + end) + end) end), }) @@ -334,26 +340,35 @@ M.setup = function(opts) cmp.register_source("codecompanion_slash_commands", require(completion .. ".slash_commands").new(config)) cmp.register_source("codecompanion_tools", require(completion .. ".tools").new(config)) cmp.register_source("codecompanion_variables", require(completion .. ".variables").new()) - cmp.setup.filetype("codecompanion", { + cmp.setup.filetype("markdown", { enabled = true, - sources = { + sources = vim.list_extend({ { name = "codecompanion_models" }, { name = "codecompanion_slash_commands" }, { name = "codecompanion_tools" }, { name = "codecompanion_variables" }, - }, + }, cmp.get_config().sources), }) end -- Capture the last terminal buffer _G.codecompanion_last_terminal = nil + + ---Check if given buffer is a terminal buffer + ---and set `_G.codecompanion_last_terminal` if it is + ---@param buf number? when nil, the current buffer is used + local function check_terminal(buf) + local buf = buf ~= 0 and buf or api.nvim_get_current_buf() + if vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].buftype == "terminal" then + _G.codecompanion_last_terminal = buf + end + end + + check_terminal() api.nvim_create_autocmd("TermEnter", { desc = "Capture the last terminal buffer", - callback = function() - local bufnr = api.nvim_get_current_buf() - if vim.bo[bufnr].buftype == "terminal" then - _G.codecompanion_last_terminal = bufnr - end + callback = function(info) + check_terminal(info.buf) end, }) diff --git a/lua/codecompanion/keymaps.lua b/lua/codecompanion/keymaps.lua index 7ad7f460..8f6425b3 100644 --- a/lua/codecompanion/keymaps.lua +++ b/lua/codecompanion/keymaps.lua @@ -4,6 +4,7 @@ local config = require("codecompanion.config") local async = require("plenary.async") local ts = require("codecompanion.utils.treesitter") local ui = require("codecompanion.utils.ui") +local buf = require("codecompanion.utils.buffers") local util = require("codecompanion.utils") local api = vim.api @@ -33,7 +34,7 @@ local function open_float(lines, opts) local height = window.height > 1 and window.height or opts.height or 17 local bufnr = api.nvim_create_buf(false, true) - util.set_option(bufnr, "filetype", opts.filetype or "codecompanion") + buf.set_codecompanion_buffer(bufnr) local winnr = api.nvim_open_win(bufnr, true, { relative = opts.relative or "cursor", border = "single", diff --git a/lua/codecompanion/providers/completion/blink/init.lua b/lua/codecompanion/providers/completion/blink/init.lua index dd0a67e6..b1d208e0 100644 --- a/lua/codecompanion/providers/completion/blink/init.lua +++ b/lua/codecompanion/providers/completion/blink/init.lua @@ -1,4 +1,5 @@ local completion = require("codecompanion.completion") +local buf = require("codecompanion.utils.buffers") local slash_commands = completion.slash_commands() local tools = completion.tools() @@ -15,7 +16,7 @@ function M:get_trigger_characters() end function M:enabled() - return vim.bo.filetype == "codecompanion" + return buf.is_codecompanion_buffer() end function M:get_completions(ctx, callback) diff --git a/lua/codecompanion/providers/completion/cmp/models.lua b/lua/codecompanion/providers/completion/cmp/models.lua index b662d186..c14a40cb 100644 --- a/lua/codecompanion/providers/completion/cmp/models.lua +++ b/lua/codecompanion/providers/completion/cmp/models.lua @@ -1,3 +1,5 @@ +local buf = require("codecompanion.utils.buffers") + local source = {} ---@param config table @@ -8,7 +10,7 @@ function source.new(config) end function source:is_available() - return vim.bo.filetype == "codecompanion" and self.config.display.chat.show_settings + return buf.is_codecompanion_buffer() and self.config.display.chat.show_settings end source.get_position_encoding_kind = function() diff --git a/lua/codecompanion/providers/completion/cmp/slash_commands.lua b/lua/codecompanion/providers/completion/cmp/slash_commands.lua index f3608a34..4b7eeb5c 100644 --- a/lua/codecompanion/providers/completion/cmp/slash_commands.lua +++ b/lua/codecompanion/providers/completion/cmp/slash_commands.lua @@ -1,4 +1,5 @@ local SlashCommands = require("codecompanion.strategies.chat.slash_commands") +local buf = require("codecompanion.utils.buffers") local completion = require("codecompanion.completion") local strategy = require("codecompanion.strategies") @@ -9,7 +10,7 @@ function source.new(config) end function source:is_available() - return vim.bo.filetype == "codecompanion" + return buf.is_codecompanion_buffer() end function source:get_trigger_characters() diff --git a/lua/codecompanion/providers/completion/cmp/tools.lua b/lua/codecompanion/providers/completion/cmp/tools.lua index d793224c..b56f1def 100644 --- a/lua/codecompanion/providers/completion/cmp/tools.lua +++ b/lua/codecompanion/providers/completion/cmp/tools.lua @@ -1,3 +1,5 @@ +local buf = require("codecompanion.utils.buffers") + local source = {} function source.new(config) @@ -5,7 +7,7 @@ function source.new(config) end function source:is_available() - return vim.bo.filetype == "codecompanion" + return buf.is_codecompanion_buffer() end source.get_position_encoding_kind = function() diff --git a/lua/codecompanion/providers/completion/cmp/variables.lua b/lua/codecompanion/providers/completion/cmp/variables.lua index fdc2cb7a..21ebb6b9 100644 --- a/lua/codecompanion/providers/completion/cmp/variables.lua +++ b/lua/codecompanion/providers/completion/cmp/variables.lua @@ -1,3 +1,5 @@ +local buf = require("codecompanion.utils.buffers") + local source = {} function source.new() @@ -5,7 +7,7 @@ function source.new() end function source:is_available() - return vim.bo.filetype == "codecompanion" + return buf.is_codecompanion_buffer() end source.get_position_encoding_kind = function() diff --git a/lua/codecompanion/strategies/chat/init.lua b/lua/codecompanion/strategies/chat/init.lua index 210146ae..f5ca18ca 100644 --- a/lua/codecompanion/strategies/chat/init.lua +++ b/lua/codecompanion/strategies/chat/init.lua @@ -9,6 +9,7 @@ local keymaps = require("codecompanion.utils.keymaps") local log = require("codecompanion.utils.log") local util = require("codecompanion.utils") local yaml = require("codecompanion.utils.yaml") +local buf = require("codecompanion.utils.buffers") local api = vim.api @@ -227,7 +228,7 @@ function Chat.new(args) create_buf = function() local bufnr = api.nvim_create_buf(false, true) api.nvim_buf_set_name(bufnr, string.format("[CodeCompanion] %d", id)) - vim.bo[bufnr].filetype = "codecompanion" + buf.set_codecompanion_buffer(bufnr) return bufnr end, diff --git a/lua/codecompanion/utils/buffers.lua b/lua/codecompanion/utils/buffers.lua index 2925e13f..31ba537b 100644 --- a/lua/codecompanion/utils/buffers.lua +++ b/lua/codecompanion/utils/buffers.lua @@ -11,7 +11,7 @@ function M.get_visible_lines() for _, win in ipairs(wins) do local bufnr = vim.api.nvim_win_get_buf(win) - if vim.api.nvim_get_option_value("filetype", { buf = bufnr }) ~= "codecompanion" then + if not buf.is_codecompanion_buffer(bufnr) then local start_line = vim.api.nvim_win_call(win, function() return vim.fn.line("w0") end) @@ -145,4 +145,23 @@ function M.format(bufnr, range) ) end +---Check if a buffer is a codecompanion buffer +---@param bufnr integer? default to current buffer +---@return boolean? +function M.is_codecompanion_buffer(bufnr) + return vim.b[bufnr or 0].codecompanion +end + +---Set filetype and buffer-local variable to mark a buffer as a codecompanion +---buffer +--- +---Notice that we first set the buffer-local variable and then the filetype so +---that user can set autocmds on `FileType` event and check if the buffer is a +---codecompanion buffer by checking `vim.b.codecompanion` variable +---@param bufnr integer? default to current buffer +function M.set_codecompanion_buffer(bufnr) + vim.b[bufnr or 0].codecompanion = true + vim.bo[bufnr or 0].filetype = "markdown" +end + return M diff --git a/lua/legendary/extensions/codecompanion.lua b/lua/legendary/extensions/codecompanion.lua index b96ff092..ceb2a31f 100644 --- a/lua/legendary/extensions/codecompanion.lua +++ b/lua/legendary/extensions/codecompanion.lua @@ -1,10 +1,16 @@ +local buf = require("codecompanion.utils.buffers") + local function to_legendary_keymap(key, keymap) return { key, -- prefix makes it easier to search in legendary.nvim window desc = string.format("CodeCompanion: %s", require("legendary.util").get_desc(keymap)), -- keymaps are all for the chat buffer - filters = { filetype = "codecompanion" }, + filters = { + function(_, context) + return buf.is_codecompanion_buffer(context.buf) + end, + }, } end