From 79d688e5f6d5c554c8d30cd9ae1fa061c8381ef6 Mon Sep 17 00:00:00 2001 From: luozhiya Date: Tue, 4 Jun 2024 18:03:35 +0800 Subject: [PATCH] Handle default key maps properly --- README.md | 14 +++ lua/fittencode/{bindings.lua => commands.lua} | 76 +----------- lua/fittencode/config.lua | 19 +++ lua/fittencode/engines/actions/init.lua | 28 +++-- lua/fittencode/engines/inline/init.lua | 114 +++++++++++++++--- lua/fittencode/init.lua | 19 +-- lua/fittencode/views/chat.lua | 27 ++++- 7 files changed, 172 insertions(+), 125 deletions(-) rename lua/fittencode/{bindings.lua => commands.lua} (74%) diff --git a/README.md b/README.md index 8731977..a77a7d4 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,20 @@ use { }, -- Enable/Disable the default keymaps in inline completion. use_default_keymaps = true, + -- Default keymaps + keymaps = { + inline = { + [''] = 'accept_all_suggestions', + [''] = 'accept_line', + [''] = 'accept_word', + [''] = 'revoke_line', + [''] = 'revoke_word', + [''] = 'triggering_completion', + }, + chat = { + ['q'] = 'close' + } + }, -- Setting for source completion. source_completion = { -- Enable source completion. diff --git a/lua/fittencode/bindings.lua b/lua/fittencode/commands.lua similarity index 74% rename from lua/fittencode/bindings.lua rename to lua/fittencode/commands.lua index 0453097..5837d53 100644 --- a/lua/fittencode/bindings.lua +++ b/lua/fittencode/commands.lua @@ -1,52 +1,9 @@ -local api = vim.api - local API = require('fittencode.api').api local Base = require('fittencode.base') -local Config = require('fittencode.config') -local InlineEngine = require('fittencode.engines.inline') -local Lines = require('fittencode.views.lines') local Log = require('fittencode.log') local M = {} -function M.setup_autocmds() - api.nvim_create_autocmd({ 'CursorHoldI' }, { - group = Base.augroup('CursorHold'), - pattern = '*', - callback = function() - InlineEngine.on_cursor_hold() - end, - desc = 'On Cursor Hold', - }) - - api.nvim_create_autocmd({ 'CursorMovedI' }, { - group = Base.augroup('CursorMoved'), - pattern = '*', - callback = function() - InlineEngine.on_cursor_moved() - end, - desc = 'On Cursor Moved', - }) - - api.nvim_create_autocmd({ 'TextChangedI' }, { - group = Base.augroup('TextChanged'), - pattern = '*', - callback = function() - InlineEngine.on_text_changed() - end, - desc = 'On Text Changed', - }) - - api.nvim_create_autocmd({ 'BufLeave', 'InsertLeave' }, { - group = Base.augroup('Leave'), - pattern = '*', - callback = function() - InlineEngine.on_leave() - end, - desc = 'On Leave', - }) -end - ---@class FittenCommands ---@field login function ---@field logout function @@ -159,7 +116,7 @@ local function _summarize_text(...) return _action_apis_wrap_content(API.summarize_text, ...) end -function M.setup_commands() +function M.setup() ---@type FittenCommands local commands = { -- Arguments: Nop @@ -219,7 +176,7 @@ function M.setup_commands() table.remove(actions, 1) return cmd(unpack(actions)) end - Log.debug('Invalid command; fargs: {}', line.fargs) + Log.debug('Invalid command fargs: {}', line.fargs) end, { complete = function(_, line) local args = vim.split(vim.trim(line), '%s+') @@ -246,33 +203,4 @@ function M.setup_commands() }) end -local KEYMAPS = { - { '', API.accept_all_suggestions }, - { '', API.accept_line }, - { '', API.accept_word }, - { '', API.revoke_line }, - { '', API.revoke_word }, -} - -function M.setup_keymaps() - for _, keymap in ipairs(KEYMAPS) do - Base.map('i', keymap[1], function() - if API.has_suggestions() then - keymap[2]() - else - Lines.feedkeys(keymap[1]) - end - end) - end - Base.map('i', '', API.triggering_completion) -end - -function M.setup_keyfilters() - vim.on_key(function(key) - vim.schedule(function() - InlineEngine.on_key(key) - end) - end) -end - return M diff --git a/lua/fittencode/config.lua b/lua/fittencode/config.lua index 3d54542..1fe8ea1 100644 --- a/lua/fittencode/config.lua +++ b/lua/fittencode/config.lua @@ -73,6 +73,20 @@ local defaults = { }, -- Enable/Disable the default keymaps in inline completion. use_default_keymaps = true, + -- Default keymaps + keymaps = { + inline = { + [''] = 'accept_all_suggestions', + [''] = 'accept_line', + [''] = 'accept_word', + [''] = 'revoke_line', + [''] = 'revoke_word', + [''] = 'triggering_completion', + }, + chat = { + ['q'] = 'close' + } + }, -- Setting for source completion. ---@class SourceCompletionOptions source_completion = { @@ -128,7 +142,12 @@ M.internal = { ---@param opts? FittenCodeOptions function M.setup(opts) + ---@class FittenCodeOptions M.options = vim.tbl_deep_extend('force', defaults, opts or {}) + if M.options.use_default_keymaps == false then + M.options.keymaps.inline = {} + M.options.keymaps.chat = {} + end end return M diff --git a/lua/fittencode/engines/actions/init.lua b/lua/fittencode/engines/actions/init.lua index 65ac1b3..207c912 100644 --- a/lua/fittencode/engines/actions/init.lua +++ b/lua/fittencode/engines/actions/init.lua @@ -430,7 +430,9 @@ function ActionsEngine.start_action(action, opts) local window = api.nvim_get_current_win() local buffer = api.nvim_win_get_buf(window) - chat:create() + chat:create({ + keymaps = Config.options.keymaps.chat, + }) if not opts.headless then chat:show() fn.win_gotoid(window) @@ -665,18 +667,6 @@ local chat_callbacks = { end, } -function ActionsEngine.setup() - chat = Chat:new(chat_callbacks) - content = Content:new(chat) - tasks = TaskScheduler:new() - tasks:setup() - status = Status:new({ - tag = 'ActionsEngine', - ready_idle = true, - }) - setup_actions_menu() -end - ---@return integer function ActionsEngine.get_status() return status:get_current() @@ -698,4 +688,16 @@ function ActionsEngine.toggle_chat() end end +function ActionsEngine.setup() + chat = Chat:new(chat_callbacks) + content = Content:new(chat) + tasks = TaskScheduler:new() + tasks:setup() + status = Status:new({ + tag = 'ActionsEngine', + ready_idle = true, + }) + setup_actions_menu() +end + return ActionsEngine diff --git a/lua/fittencode/engines/inline/init.lua b/lua/fittencode/engines/inline/init.lua index 9e53eb3..c14804e 100644 --- a/lua/fittencode/engines/inline/init.lua +++ b/lua/fittencode/engines/inline/init.lua @@ -43,13 +43,6 @@ local CURSORMOVED_DEBOUNCE_TIME = 120 ---@type uv_timer_t local cursormoved_timer = nil -function M.setup() - model = Model:new() - tasks = TaskScheduler:new() - tasks:setup() - status = Status:new({ tag = 'InlineEngine' }) -end - local function suggestions_modify_enabled() return M.is_inline_enabled() and M.has_suggestions() end @@ -461,17 +454,21 @@ end, { '', }) -function M.on_key(key) - if api.nvim_get_mode().mode == 'i' then - if vim.tbl_contains(FILTERED_KEYS, key) then - M.reset() - if Config.options.inline_completion.disable_completion_when_delete then - ignore_event = true +local function setup_keyfilters() + vim.on_key(function(key) + vim.schedule(function() + if api.nvim_get_mode().mode == 'i' then + if vim.tbl_contains(FILTERED_KEYS, key) then + M.reset() + if Config.options.inline_completion.disable_completion_when_delete then + ignore_event = true + end + else + ignore_event = false + end end - else - ignore_event = false - end - end + end) + end) end function M.on_cursor_hold() @@ -510,4 +507,87 @@ function M.on_cursor_moved() end, CURSORMOVED_DEBOUNCE_TIME) end +local KEYS = { + accept_all_suggestions = { true }, + accept_char = { true }, + accept_word = { true }, + accept_line = { true }, + revoke_char = { true }, + revoke_word = { true }, + revoke_line = { true }, + triggering_completion = { false } +} + +local function setup_keymaps() + for key, value in pairs(Config.options.keymaps.inline) do + Base.map('i', key, function() + local v = KEYS[value] + if v == nil then + return + end + if v[1] then + if M.has_suggestions() then + M[value]() + else + Lines.feedkeys(key) + end + else + M[value]() + end + end) + end +end + +local function setup_autocmds() + api.nvim_create_autocmd({ 'CursorHoldI' }, { + group = Base.augroup('CursorHold'), + pattern = '*', + callback = function() + M.on_cursor_hold() + end, + desc = 'On Cursor Hold', + }) + + api.nvim_create_autocmd({ 'CursorMovedI' }, { + group = Base.augroup('CursorMoved'), + pattern = '*', + callback = function() + M.on_cursor_moved() + end, + desc = 'On Cursor Moved', + }) + + api.nvim_create_autocmd({ 'TextChangedI' }, { + group = Base.augroup('TextChanged'), + pattern = '*', + callback = function() + M.on_text_changed() + end, + desc = 'On Text Changed', + }) + + api.nvim_create_autocmd({ 'BufLeave', 'InsertLeave' }, { + group = Base.augroup('Leave'), + pattern = '*', + callback = function() + M.on_leave() + end, + desc = 'On Leave', + }) +end + +function M.setup() + model = Model:new() + tasks = TaskScheduler:new() + tasks:setup() + status = Status:new({ tag = 'InlineEngine' }) + if Config.options.completion_mode == 'inline' then + setup_keymaps() + setup_keyfilters() + setup_autocmds() + elseif Config.options.completion_mode == 'source' then + require('fittencode.sources').setup() + end +end + return M diff --git a/lua/fittencode/init.lua b/lua/fittencode/init.lua index f170f05..48839fa 100644 --- a/lua/fittencode/init.lua +++ b/lua/fittencode/init.lua @@ -13,24 +13,13 @@ function M.setup(opts) require('fittencode.log').setup() require('fittencode.rest.manager').setup() + local sessions = require('fittencode.sessions') + sessions.setup() require('fittencode.engines').setup() - require('fittencode.sessions').setup() require('fittencode.prompt_providers').setup() require('fittencode.color').setup_highlight() - local Bindings = require('fittencode.bindings') - Bindings.setup_commands() - - if Config.options.completion_mode == 'inline' then - Bindings.setup_autocmds() - Bindings.setup_keyfilters() - if Config.options.use_default_keymaps then - Bindings.setup_keymaps() - end - elseif Config.options.completion_mode == 'source' then - require('fittencode.sources').setup() - end - - require('fittencode.sessions').load_last_session() + require('fittencode.commands').setup() + sessions.load_last_session() end setmetatable(M, { diff --git a/lua/fittencode/views/chat.lua b/lua/fittencode/views/chat.lua index 6a0756c..1c17a31 100644 --- a/lua/fittencode/views/chat.lua +++ b/lua/fittencode/views/chat.lua @@ -76,7 +76,10 @@ local function set_option_value_win(window) -- api.nvim_set_option_value('scrolloff', 8, { win = window }) end -function M:create() +---@class ChatCreateOptions +---@field keymaps? table + +function M:create(opts) if self.buffer and api.nvim_buf_is_valid(self.buffer) then return end @@ -84,11 +87,23 @@ function M:create() self.buffer = api.nvim_create_buf(false, true) api.nvim_buf_set_name(self.buffer, 'FittenCodeChat') - Base.map('n', 'q', function() self:close() end, { buffer = self.buffer }) - Base.map('n', '[c', function() self:goto_prev_conversation() end, { buffer = self.buffer }) - Base.map('n', ']c', function() self:goto_next_conversation() end, { buffer = self.buffer }) - Base.map('n', 'c', function() self:copy_conversation() end, { buffer = self.buffer }) - Base.map('n', 'C', function() self:copy_all_conversations() end, { buffer = self.buffer }) + local FX = { + close = function() self:close() end, + } + + for key, value in pairs(opts.keymaps or {}) do + Base.map('n', key, function() + if FX[value] then + FX[value]() + end + end, { buffer = self.buffer }) + end + + -- Base.map('n', 'q', function() self:close() end, { buffer = self.buffer }) + -- Base.map('n', '[c', function() self:goto_prev_conversation() end, { buffer = self.buffer }) + -- Base.map('n', ']c', function() self:goto_next_conversation() end, { buffer = self.buffer }) + -- Base.map('n', 'c', function() self:copy_conversation() end, { buffer = self.buffer }) + -- Base.map('n', 'C', function() self:copy_all_conversations() end, { buffer = self.buffer }) -- Base.map('n', 'd', function() self:delete_conversation() end, { buffer = self.buffer }) -- Base.map('n', 'D', function() self:delete_all_conversations() end, { buffer = self.buffer })