From 7f2e13e034efb0ad9e6f782d395c4d5e876a3f0f Mon Sep 17 00:00:00 2001 From: sudacode Date: Fri, 12 Sep 2025 00:41:38 -0700 Subject: [PATCH] update nvim --- .config/nvim/init.lua | 2 +- .config/nvim/lua/core/highlights.lua | 79 +++++---- .config/nvim/lua/core/keymaps.lua | 28 +++ .config/nvim/lua/plugins/codecompanion.lua | 11 ++ .config/nvim/lua/plugins/dashboard.lua | 36 ---- .../nvim/lua/plugins/indent-blanklines.lua | 35 ---- .config/nvim/lua/plugins/mcphub.lua | 86 +++++++++ .config/nvim/lua/plugins/snacks.lua | 167 ++++++++++++++++++ .../utils/{ => functions}/git_paste/init.lua | 0 .config/nvim/lua/utils/functions/init.lua | 4 + .../functions/mkdir_under_cursor/init.lua | 24 +++ 11 files changed, 365 insertions(+), 107 deletions(-) delete mode 100644 .config/nvim/lua/plugins/dashboard.lua delete mode 100644 .config/nvim/lua/plugins/indent-blanklines.lua create mode 100644 .config/nvim/lua/plugins/mcphub.lua create mode 100644 .config/nvim/lua/plugins/snacks.lua rename .config/nvim/lua/utils/{ => functions}/git_paste/init.lua (100%) create mode 100644 .config/nvim/lua/utils/functions/init.lua create mode 100644 .config/nvim/lua/utils/functions/mkdir_under_cursor/init.lua diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua index fbf0cf0..87de84c 100644 --- a/.config/nvim/init.lua +++ b/.config/nvim/init.lua @@ -6,7 +6,7 @@ require("core.highlights") -- require("core.lsp-notifications") require("utils.extensions") require("utils.telescope_extra").setup() -require("utils.git_paste").setup({ telescope_key = "pg" }) +require("utils.functions.git_paste").setup({ telescope_key = "pg" }) require("utils.treesitter.parsers.hyprlang") require("utils.hyprland.lsp") -- vim.notify = function(msg, level, opts) diff --git a/.config/nvim/lua/core/highlights.lua b/.config/nvim/lua/core/highlights.lua index 624c3b7..5b7dac9 100644 --- a/.config/nvim/lua/core/highlights.lua +++ b/.config/nvim/lua/core/highlights.lua @@ -1,46 +1,55 @@ +local catppuccin = require("catppuccin.palettes").get_palette("macchiato") +local sethl = vim.api.nvim_set_hl -- Customization for Pmenu -vim.api.nvim_set_hl(0, "PmenuSel", { bg = "#282C34", fg = "NONE" }) -vim.api.nvim_set_hl(0, "Pmenu", { fg = "#C5CDD9", bg = "dodgerblue" }) +sethl(0, "PmenuSel", { bg = "#282C34", fg = "NONE" }) +sethl(0, "Pmenu", { fg = "#C5CDD9", bg = "dodgerblue" }) -vim.api.nvim_set_hl(0, "CmpItemAbbrDeprecated", { fg = "#7E8294", bg = "NONE", strikethrough = true }) -vim.api.nvim_set_hl(0, "CmpItemAbbrMatch", { fg = "#82AAFF", bg = "NONE", bold = true }) -vim.api.nvim_set_hl(0, "CmpItemAbbrMatchFuzzy", { fg = "#82AAFF", bg = "NONE", bold = true }) -vim.api.nvim_set_hl(0, "CmpItemMenu", { fg = "#C792EA", bg = "NONE", italic = true }) +sethl(0, "CmpItemAbbrDeprecated", { fg = "#7E8294", bg = "NONE", strikethrough = true }) +sethl(0, "CmpItemAbbrMatch", { fg = "#82AAFF", bg = "NONE", bold = true }) +sethl(0, "CmpItemAbbrMatchFuzzy", { fg = "#82AAFF", bg = "NONE", bold = true }) +sethl(0, "CmpItemMenu", { fg = "#C792EA", bg = "NONE", italic = true }) -vim.api.nvim_set_hl(0, "CmpItemKindField", { fg = "#EED8DA", bg = "#B5585F" }) -vim.api.nvim_set_hl(0, "CmpItemKindProperty", { fg = "#EED8DA", bg = "#B5585F" }) -vim.api.nvim_set_hl(0, "CmpItemKindEvent", { fg = "#EED8DA", bg = "#B5585F" }) +sethl(0, "CmpItemKindField", { fg = "#EED8DA", bg = "#B5585F" }) +sethl(0, "CmpItemKindProperty", { fg = "#EED8DA", bg = "#B5585F" }) +sethl(0, "CmpItemKindEvent", { fg = "#EED8DA", bg = "#B5585F" }) -vim.api.nvim_set_hl(0, "CmpItemKindText", { fg = "#C3E88D", bg = "#9FBD73" }) -vim.api.nvim_set_hl(0, "CmpItemKindEnum", { fg = "#C3E88D", bg = "#9FBD73" }) -vim.api.nvim_set_hl(0, "CmpItemKindKeyword", { fg = "#C3E88D", bg = "#9FBD73" }) +sethl(0, "CmpItemKindText", { fg = "#C3E88D", bg = "#9FBD73" }) +sethl(0, "CmpItemKindEnum", { fg = "#C3E88D", bg = "#9FBD73" }) +sethl(0, "CmpItemKindKeyword", { fg = "#C3E88D", bg = "#9FBD73" }) -vim.api.nvim_set_hl(0, "CmpItemKindConstant", { fg = "#FFE082", bg = "#D4BB6C" }) -vim.api.nvim_set_hl(0, "CmpItemKindConstructor", { fg = "#FFE082", bg = "#D4BB6C" }) -vim.api.nvim_set_hl(0, "CmpItemKindReference", { fg = "#FFE082", bg = "#D4BB6C" }) +sethl(0, "CmpItemKindConstant", { fg = "#FFE082", bg = "#D4BB6C" }) +sethl(0, "CmpItemKindConstructor", { fg = "#FFE082", bg = "#D4BB6C" }) +sethl(0, "CmpItemKindReference", { fg = "#FFE082", bg = "#D4BB6C" }) -vim.api.nvim_set_hl(0, "CmpItemKindFunction", { fg = "#EADFF0", bg = "#A377BF" }) -vim.api.nvim_set_hl(0, "CmpItemKindStruct", { fg = "#EADFF0", bg = "#A377BF" }) -vim.api.nvim_set_hl(0, "CmpItemKindClass", { fg = "#EADFF0", bg = "#A377BF" }) -vim.api.nvim_set_hl(0, "CmpItemKindModule", { fg = "#EADFF0", bg = "#A377BF" }) -vim.api.nvim_set_hl(0, "CmpItemKindOperator", { fg = "#EADFF0", bg = "#A377BF" }) +sethl(0, "CmpItemKindFunction", { fg = "#EADFF0", bg = "#A377BF" }) +sethl(0, "CmpItemKindStruct", { fg = "#EADFF0", bg = "#A377BF" }) +sethl(0, "CmpItemKindClass", { fg = "#EADFF0", bg = "#A377BF" }) +sethl(0, "CmpItemKindModule", { fg = "#EADFF0", bg = "#A377BF" }) +sethl(0, "CmpItemKindOperator", { fg = "#EADFF0", bg = "#A377BF" }) -vim.api.nvim_set_hl(0, "CmpItemKindVariable", { fg = "#C5CDD9", bg = "#7E8294" }) -vim.api.nvim_set_hl(0, "CmpItemKindFile", { fg = "#C5CDD9", bg = "#7E8294" }) +sethl(0, "CmpItemKindVariable", { fg = "#C5CDD9", bg = "#7E8294" }) +sethl(0, "CmpItemKindFile", { fg = "#C5CDD9", bg = "#7E8294" }) -vim.api.nvim_set_hl(0, "CmpItemKindUnit", { fg = "#F5EBD9", bg = "#D4A959" }) -vim.api.nvim_set_hl(0, "CmpItemKindSnippet", { fg = "#F5EBD9", bg = "#D4A959" }) -vim.api.nvim_set_hl(0, "CmpItemKindFolder", { fg = "#F5EBD9", bg = "#D4A959" }) +sethl(0, "CmpItemKindUnit", { fg = "#F5EBD9", bg = "#D4A959" }) +sethl(0, "CmpItemKindSnippet", { fg = "#F5EBD9", bg = "#D4A959" }) +sethl(0, "CmpItemKindFolder", { fg = "#F5EBD9", bg = "#D4A959" }) -vim.api.nvim_set_hl(0, "CmpItemKindMethod", { fg = "#DDE5F5", bg = "#6C8ED4" }) -vim.api.nvim_set_hl(0, "CmpItemKindValue", { fg = "#DDE5F5", bg = "#6C8ED4" }) -vim.api.nvim_set_hl(0, "CmpItemKindEnumMember", { fg = "#DDE5F5", bg = "#6C8ED4" }) +sethl(0, "CmpItemKindMethod", { fg = "#DDE5F5", bg = "#6C8ED4" }) +sethl(0, "CmpItemKindValue", { fg = "#DDE5F5", bg = "#6C8ED4" }) +sethl(0, "CmpItemKindEnumMember", { fg = "#DDE5F5", bg = "#6C8ED4" }) -vim.api.nvim_set_hl(0, "CmpItemKindInterface", { fg = "#D8EEEB", bg = "#58B5A8" }) -vim.api.nvim_set_hl(0, "CmpItemKindColor", { fg = "#D8EEEB", bg = "#58B5A8" }) -vim.api.nvim_set_hl(0, "CmpItemKindTypeParameter", { fg = "#D8EEEB", bg = "#58B5A8" }) +sethl(0, "CmpItemKindInterface", { fg = "#D8EEEB", bg = "#58B5A8" }) +sethl(0, "CmpItemKindColor", { fg = "#D8EEEB", bg = "#58B5A8" }) +sethl(0, "CmpItemKindTypeParameter", { fg = "#D8EEEB", bg = "#58B5A8" }) -vim.api.nvim_set_hl(0, "FloatBorder", { fg = "#8aadf4", bold = true }) -vim.api.nvim_set_hl(0, "LspSignatureActiveParameter", { fg = "#89b4fa", bg = "NONE", bold = true }) -vim.api.nvim_set_hl(0, "CmpBorder", { fg = "#8aadf4", bold = true }) -vim.api.nvim_set_hl(0, "CmpDocBorder", { fg = "#8aadf4", bold = true }) +sethl(0, "FloatBorder", { fg = "#8aadf4", bold = true }) +sethl(0, "LspSignatureActiveParameter", { fg = "#89b4fa", bg = "NONE", bold = true }) +sethl(0, "CmpBorder", { fg = "#8aadf4", bold = true }) +sethl(0, "CmpDocBorder", { fg = "#8aadf4", bold = true }) +sethl(0, "SnacksIndent1", { fg = catppuccin.red }) +sethl(0, "SnacksIndent3", { fg = catppuccin.peach }) +sethl(0, "SnacksIndent4", { fg = catppuccin.yellow }) +sethl(0, "SnacksIndent5", { fg = catppuccin.green }) +sethl(0, "SnacksIndent6", { fg = catppuccin.sky }) +sethl(0, "SnacksIndent7", { fg = catppuccin.blue }) +sethl(0, "SnacksIndent8", { fg = catppuccin.mauve }) diff --git a/.config/nvim/lua/core/keymaps.lua b/.config/nvim/lua/core/keymaps.lua index aaa7a76..a9e89f7 100644 --- a/.config/nvim/lua/core/keymaps.lua +++ b/.config/nvim/lua/core/keymaps.lua @@ -3,6 +3,7 @@ local term = require("utils.terminal") local map_from_table = require("utils.keymaps.converters.from_table").set_keybindings local add_to_whichkey = require("utils.keymaps.converters.whichkey").addToWhichKey local telescope_paste_img = require("utils.telescope_extra").find_and_paste_image +local mkdir_under_cursor = require("utils.functions.mkdir_under_cursor").setup() local term_factory = term.term_factory local term_toggle = term.term_toggle @@ -365,6 +366,25 @@ local telescope_mappings = { { mode = "n", key = "sF", cmd = ":Telescope fidget", group = "Fidget" }, { mode = "n", key = "sg", cmd = ":Telescope live_grep", group = "Live grep" }, { mode = "n", key = "sh", cmd = ":Telescope command_history", group = "Command history" }, + { + mode = "n", + key = "sn", + cmd = function() + Snacks.win({ + file = vim.api.nvim_get_runtime_file("doc/news.txt", false)[1], + width = 0.6, + height = 0.6, + wo = { + spell = false, + wrap = false, + signcolumn = "yes", + statuscolumn = " ", + conceallevel = 3, + }, + }) + end, + group = "News", + }, { mode = "n", key = "sm", cmd = ":Telescope man_pages", group = "Man pages" }, { mode = "n", key = "s/", cmd = ":Telescope search_history", group = "Search history" }, { mode = "n", key = "gc", cmd = ":Telescope git_commits", group = "Git commits" }, @@ -387,6 +407,14 @@ local misc_utilities_mappings = { { mode = "n", key = "y", cmd = '"+', group = "System Yank" }, { mode = "v", key = "y", cmd = '"+', group = "System Yank" }, { mode = "n", key = "sc", cmd = ":nohls", group = "Search" }, + { + mode = "n", + key = "m", + cmd = function() + mkdir_under_cursor() + end, + group = "mkdir under cursor", + }, } -- }}} diff --git a/.config/nvim/lua/plugins/codecompanion.lua b/.config/nvim/lua/plugins/codecompanion.lua index 444607d..034ab19 100644 --- a/.config/nvim/lua/plugins/codecompanion.lua +++ b/.config/nvim/lua/plugins/codecompanion.lua @@ -164,6 +164,17 @@ return { }, }, }, + opts = { + ---Decorate the user message before it's sent to the LLM + ---@param message string + ---@param adapter CodeCompanion.Adapter + ---@param context table + ---@return string + prompt_decorator = function(message, adapter, context) + return string.format([[%s]], message) + end, + completion_provider = "cmp", + }, }, inline = { adapter = "copilot", diff --git a/.config/nvim/lua/plugins/dashboard.lua b/.config/nvim/lua/plugins/dashboard.lua deleted file mode 100644 index 029b550..0000000 --- a/.config/nvim/lua/plugins/dashboard.lua +++ /dev/null @@ -1,36 +0,0 @@ -return { - "nvimdev/dashboard-nvim", - event = "VimEnter", - opts = { - theme = "hyper", - config = { - week_header = { - enable = true, - }, - shortcut = { - { desc = "󰊳 Update", group = "@property", action = "Lazy update", key = "u" }, - { - icon = " ", - icon_hl = "@variable", - desc = "Files", - group = "Label", - action = "Telescope find_files", - key = "f", - }, - { - desc = " Apps", - group = "DiagnosticHint", - action = "Telescope app", - key = "a", - }, - { - desc = " dotfiles", - group = "Number", - action = "Telescope ~/.config", - key = "d", - }, - }, - }, - }, - depends = { "nvim-tree/nvim-web-devicons" }, -} diff --git a/.config/nvim/lua/plugins/indent-blanklines.lua b/.config/nvim/lua/plugins/indent-blanklines.lua deleted file mode 100644 index e582d20..0000000 --- a/.config/nvim/lua/plugins/indent-blanklines.lua +++ /dev/null @@ -1,35 +0,0 @@ -return { - "lukas-reineke/indent-blankline.nvim", - config = function() - local highlight = { - "RainbowRed", - "RainbowYellow", - "RainbowBlue", - "RainbowOrange", - "RainbowGreen", - "RainbowViolet", - "RainbowCyan", - } - - local hooks = require("ibl.hooks") - -- create the highlight groups in the highlight setup hook, so they are reset - -- every time the colorscheme changes - hooks.register(hooks.type.HIGHLIGHT_SETUP, function() - vim.api.nvim_set_hl(0, "RainbowRed", { fg = "#ED8796" }) - vim.api.nvim_set_hl(0, "RainbowYellow", { fg = "#EED49F" }) - vim.api.nvim_set_hl(0, "RainbowBlue", { fg = "#8AADF4" }) - vim.api.nvim_set_hl(0, "RainbowOrange", { fg = "#F5A97F" }) - vim.api.nvim_set_hl(0, "RainbowGreen", { fg = "#A6DA95" }) - vim.api.nvim_set_hl(0, "RainbowViolet", { fg = "#C6A0F6" }) - vim.api.nvim_set_hl(0, "RainbowCyan", { fg = "#8BD5CA" }) - end) - - vim.g.rainbow_delimiters = { highlight = highlight } - require("ibl").setup({ - scope = { highlight = highlight }, - exclude = { filetypes = { "dashboard" } }, - }) - - hooks.register(hooks.type.SCOPE_HIGHLIGHT, hooks.builtin.scope_highlight_from_extmark) - end, -} diff --git a/.config/nvim/lua/plugins/mcphub.lua b/.config/nvim/lua/plugins/mcphub.lua new file mode 100644 index 0000000..65f3f58 --- /dev/null +++ b/.config/nvim/lua/plugins/mcphub.lua @@ -0,0 +1,86 @@ +return { + "ravitemer/mcphub.nvim", + dependencies = { + "nvim-lua/plenary.nvim", + }, + build = "npm install -g mcp-hub@latest", -- Installs `mcp-hub` node binary globally + config = function() + require("mcphub").setup({ + --- `mcp-hub` binary related options------------------- + config = vim.fn.expand("~/.config/mcphub/servers.json"), -- Absolute path to MCP Servers config file (will create if not exists) + port = 37373, -- The port `mcp-hub` server listens to + shutdown_delay = 5 * 60 * 000, -- Delay in ms before shutting down the server when last instance closes (default: 5 minutes) + use_bundled_binary = false, -- Use local `mcp-hub` binary (set this to true when using build = "bundled_build.lua") + mcp_request_timeout = 60000, --Max time allowed for a MCP tool or resource to execute in milliseconds, set longer for long running tasks + global_env = {}, -- Global environment variables available to all MCP servers (can be a table or a function returning a table) + workspace = { + enabled = true, -- Enable project-local configuration files + look_for = { ".mcphub/servers.json", ".vscode/mcp.json", ".cursor/mcp.json" }, -- Files to look for when detecting project boundaries (VS Code format supported) + reload_on_dir_changed = true, -- Automatically switch hubs on DirChanged event + port_range = { min = 40000, max = 41000 }, -- Port range for generating unique workspace ports + get_port = nil, -- Optional function returning custom port number. Called when generating ports to allow custom port assignment logic + }, + + ---Chat-plugin related options----------------- + auto_approve = false, -- Auto approve mcp tool calls + auto_toggle_mcp_servers = true, -- Let LLMs start and stop MCP servers automatically + extensions = { + avante = { + make_slash_commands = true, -- make /slash commands from MCP server prompts + }, + }, + + --- Plugin specific options------------------- + native_servers = {}, -- add your custom lua native servers here + builtin_tools = { + edit_file = { + parser = { + track_issues = true, + extract_inline_content = true, + }, + locator = { + fuzzy_threshold = 0.8, + enable_fuzzy_matching = true, + }, + ui = { + go_to_origin_on_complete = true, + keybindings = { + accept = ".", + reject = ",", + next = "n", + prev = "p", + accept_all = "ga", + reject_all = "gr", + }, + }, + }, + }, + ui = { + window = { + width = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number) + height = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number) + align = "center", -- "center", "top-left", "top-right", "bottom-left", "bottom-right", "top", "bottom", "left", "right" + relative = "editor", + zindex = 50, + border = "rounded", -- "none", "single", "double", "rounded", "solid", "shadow" + }, + wo = { -- window-scoped options (vim.wo) + winhl = "Normal:MCPHubNormal,FloatBorder:MCPHubBorder", + }, + }, + json_decode = nil, -- Custom JSON parser function (e.g., require('json5').parse for JSON5 support) + on_ready = function(hub) + -- Called when hub is ready + end, + on_error = function(err) + -- Called on errors + end, + log = { + level = vim.log.levels.WARN, + to_file = false, + file_path = nil, + prefix = "MCPHub", + }, + }) + end, +} diff --git a/.config/nvim/lua/plugins/snacks.lua b/.config/nvim/lua/plugins/snacks.lua new file mode 100644 index 0000000..e13c946 --- /dev/null +++ b/.config/nvim/lua/plugins/snacks.lua @@ -0,0 +1,167 @@ +return { + "folke/snacks.nvim", + priority = 1000, + lazy = false, + ---@type snacks.Config + opts = { + -- your configuration comes here + -- or leave it empty to use the default settings + -- refer to the configuration section below + bigfile = { enabled = true }, + dashboard = { enabled = true }, + explorer = { enabled = true }, + indent = { + priority = 1, + enabled = true, -- enable indent guides + char = "│", + only_scope = false, -- only show indent guides of the scope + only_current = false, -- only show indent guides in the current window + -- hl = "SnacksIndent", ---@type string|string[] hl groups for indent guides + -- can be a list of hl groups to cycle through + hl = { + "SnacksIndent1", + "SnacksIndent2", + "SnacksIndent3", + "SnacksIndent4", + "SnacksIndent5", + "SnacksIndent6", + "SnacksIndent7", + "SnacksIndent8", + }, + animate = { + -- enabled = vim.fn.has("nvim-0.10") == 1, + enabled = false, + style = "out", + easing = "linear", + duration = { + step = 20, -- ms per step + total = 500, -- maximum duration + }, + }, + filter = function(buf) + return vim.g.snacks_indent ~= false and vim.b[buf].snacks_indent ~= false and vim.bo[buf].buftype == "" + end, + }, + input = { + enabled = true, + icon = " ", + icon_hl = "SnacksInputIcon", + icon_pos = "left", + prompt_pos = "title", + win = { style = "input" }, + expand = true, + backdrop = true, + position = "float", + border = "rounded", + title_pos = "center", + height = 1, + width = 60, + relative = "editor", + noautocmd = true, + row = 2, + -- relative = "cursor", + -- row = -3, + -- col = 0, + wo = { + winhighlight = "NormalFloat:SnacksInputNormal,FloatBorder:SnacksInputBorder,FloatTitle:SnacksInputTitle", + cursorline = false, + }, + bo = { + filetype = "snacks_input", + buftype = "prompt", + }, + --- buffer local variables + b = { + completion = false, -- disable blink completions in input + }, + keys = { + n_esc = { "", { "cmp_close", "cancel" }, mode = "n", expr = true }, + i_esc = { "", { "cmp_close", "stopinsert" }, mode = "i", expr = true }, + i_cr = { "", { "cmp_accept", "confirm" }, mode = { "i", "n" }, expr = true }, + i_tab = { "", { "cmp_select_next", "cmp" }, mode = "i", expr = true }, + i_ctrl_w = { "", "", mode = "i", expr = true }, + i_up = { "", { "hist_up" }, mode = { "i", "n" } }, + i_down = { "", { "hist_down" }, mode = { "i", "n" } }, + q = "cancel", + }, + }, + lazygit = { enabled = true }, + picker = { enabled = true }, + notifier = { + enabled = true, + timeout = 3000, -- default timeout in ms + width = { min = 40, max = 0.4 }, + height = { min = 1, max = 0.6 }, + -- editor margin to keep free. tabline and statusline are taken into account automatically + margin = { top = 0, right = 1, bottom = 0 }, + padding = true, -- add 1 cell of left/right padding to the notification window + sort = { "level", "added" }, -- sort by level and time + -- minimum log level to display. TRACE is the lowest + -- all notifications are stored in history + level = vim.log.levels.TRACE, + icons = { + error = " ", + warn = " ", + info = " ", + debug = " ", + trace = " ", + }, + keep = function(notif) + return vim.fn.getcmdpos() > 0 + end, + ---@type snacks.notifier.style + style = "compact", + top_down = true, -- place notifications from top to bottom + date_format = "%R", -- time format for notifications + -- format for footer when more lines are available + -- `%d` is replaced with the number of lines. + -- only works for styles with a border + ---@type string|boolean + more_format = " ↓ %d lines ", + refresh = 50, -- refresh at most every 50ms + }, + quickfile = { enabled = true }, + scope = { enabled = true }, + scroll = { enabled = false }, + statuscolumn = { enabled = false }, + words = { enabled = false }, + terminal = { + enabled = true, + bo = { + filetype = "snacks_terminal", + }, + wo = {}, + keys = { + q = "hide", + gf = function(self) + local f = vim.fn.findfile(vim.fn.expand(""), "**") + if f == "" then + Snacks.notify.warn("No file under cursor") + else + self:hide() + vim.schedule(function() + vim.cmd("e " .. f) + end) + end + end, + term_normal = { + "", + function(self) + self.esc_timer = self.esc_timer or (vim.uv or vim.loop).new_timer() + if self.esc_timer:is_active() then + self.esc_timer:stop() + vim.cmd("stopinsert") + else + self.esc_timer:start(200, 0, function() end) + return "" + end + end, + mode = "t", + expr = true, + desc = "Double escape to normal mode", + }, + }, + }, + win = { enabled = true }, + }, +} diff --git a/.config/nvim/lua/utils/git_paste/init.lua b/.config/nvim/lua/utils/functions/git_paste/init.lua similarity index 100% rename from .config/nvim/lua/utils/git_paste/init.lua rename to .config/nvim/lua/utils/functions/git_paste/init.lua diff --git a/.config/nvim/lua/utils/functions/init.lua b/.config/nvim/lua/utils/functions/init.lua new file mode 100644 index 0000000..082a373 --- /dev/null +++ b/.config/nvim/lua/utils/functions/init.lua @@ -0,0 +1,4 @@ +return { + require("utils.functions.git_paste"), + require("utils.functions.mkdir_under_cursor"), +} diff --git a/.config/nvim/lua/utils/functions/mkdir_under_cursor/init.lua b/.config/nvim/lua/utils/functions/mkdir_under_cursor/init.lua new file mode 100644 index 0000000..b2b3486 --- /dev/null +++ b/.config/nvim/lua/utils/functions/mkdir_under_cursor/init.lua @@ -0,0 +1,24 @@ +local M = {} +vim.notify = require("notify") + +function M.mkdir_under_cursor() + -- Get the word under the cursor + local word = vim.fn.expand("") + -- Remove quotes if present + word = word:gsub("^[\"']", ""):gsub("[\"']$", "") + -- Check if directory exists + local stat = vim.loop.fs_stat(word) + if not stat then + -- Create directory (recursive) + vim.loop.fs_mkdir(word, 493) -- 493 = 0755 in decimal + vim.notify("Directory created: " .. word, vim.log.levels.INFO) + else + vim.notify("Directory already exists: " .. word, vim.log.levels.WARN) + end +end + +function M.setup(opts) + return M.mkdir_under_cursor +end + +return M