-- === -- === map function -- === local function mapkey(mode, lhs, rhs) vim.keymap.set(mode, lhs, rhs, { silent = true, nowait = true }) end local function mapcmd(key, cmd) vim.keymap.set("n", key, "" .. cmd .. "", { silent = true }) end local function maplua(modes, key, action, desc) vim.keymap.set(modes, key, action, { silent = true, noremap = true, desc = desc }) end -- === -- === Basic Mappings -- === -- leader键设置为空格,; as : vim.g.mapleader = " " mapkey({ "n", "x", "o" }, ";", ":") -- 上/下一个搜索结果以及取消搜索结果高亮 mapkey({ "n", "x", "o" }, "=", "nzz") mapkey({ "n", "x", "o" }, "-", "Nzz") mapcmd("", "nohlsearch") -- 保存和退出 mapkey({ "n", "x", "o" }, "S", ":wall") mapkey({ "n", "x", "o" }, "Q", ":qall") -- 撤销与反撤销 mapkey({ "n", "x", "o" }, "l", "u") mapkey({ "n", "x", "o" }, "L", "") -- 插入 mapkey({ "n", "x", "o" }, "k", "i") mapkey({ "n", "x", "o" }, "K", "I") mapkey('n', '', '') -- 折叠 mapkey({ "n", "x", "o" }, "o", "za") mapkey("x", "o", "zf") -- 可视模式创造折叠 -- 读取保存的折叠 -- mapkey({ "n", "x", "o" }, "a", ":loadview") -- 以下两个映射默认了 -- make Y to copy till the end of the line -- mapkey('','Y','y$') -- make D to delete till the end of the line -- mapkey('','D','d$') -- 打开lazygit,已用fm-nvim插件 -- mapcmd('',':tabe:-tabmove:term lazygit') -- === -- === treesitter -- === -- 删除i键映射 vim.api.nvim_create_autocmd("VimEnter", { -- 所有启动脚本、默认脚本都加载完毕后的最后一个事件 callback = function() -- 使用 pcall 忽略如果键位不存在时的报错 pcall(vim.keymap.del, { "x", "o" }, "in") end, }) local function smart_select(ts_method, lsp_dir) return function() -- 如果当前不是普通文件(比如 Quickfix、帮助文档、终端等)那么我们直接发送一个原生的 按键并退出,恢复回车原本的功能 if lsp_dir == 1 and vim.bo.buftype ~= "" then local cr = vim.api.nvim_replace_termcodes("", true, false, true) vim.api.nvim_feedkeys(cr, "n", false) return end if vim.treesitter.get_parser(nil, nil, { error = false }) then require("vim.treesitter._select")[ts_method](vim.v.count1) else vim.lsp.buf.selection_range(lsp_dir * vim.v.count1) end end end -- 扩大范围 (回车键):不断向上寻找父节点 (等价于官方的 an) maplua({ "x", "o", "n" }, "", smart_select("select_parent", 1), "扩大 Treesitter/LSP 范围") -- 缩小范围 (退格键):不断向下寻找子节点 maplua({ "x", "o" }, "", smart_select("select_child", -1), "缩小 Treesitter/LSP 范围") -- === -- === Cursor Movement -- === -- New cursor movement (the default arrow keys are used for resizing windows) -- ^ -- u -- < n i > -- e -- v mapkey({ "n", "x", "o" }, "n", "h") mapkey({ "n", "x", "o" }, "u", "k") mapkey({ "n", "x", "o" }, "e", "j") mapkey({ "n", "x", "o" }, "i", "l") -- 更快的导航 mapkey({ "n", "x", "o" }, "U", "5k") mapkey({ "n", "x", "o" }, "E", "5j") mapkey({ "n", "x", "o" }, "N", "0") mapkey({ "n", "x", "o" }, "I", "$") -- 向下滚动半页,默认向上滚动半页 mapkey({ "n", "x", "o" }, "", "") -- 更快的行导航 mapkey({ "n", "x", "o" }, "W", "5W") mapkey({ "n", "x", "o" }, "B", "5B") -- === -- === Window management -- === -- 使用 + 新方向键 在分屏之间移动 mapkey({ "n", "x", "o" }, "w", "w") mapkey({ "n", "x", "o" }, "u", "k") mapkey({ "n", "x", "o" }, "e", "j") mapkey({ "n", "x", "o" }, "n", "h") mapkey({ "n", "x", "o" }, "i", "l") -- 使用s + 新方向键 进行分屏 mapcmd("su", "set nosplitbelow:split:set splitbelow") mapcmd("se", "set splitbelow:split") mapcmd("sn", "set nosplitright:vsplit:set splitright") mapcmd("si", "set splitright:vsplit") -- 使用方向键来调整窗口大小 mapcmd("", "res +5") mapcmd("", "res -5") mapcmd("", "vertical resize-5") mapcmd("", "vertical resize+5") -- 使分屏窗口上下分布 mapkey({ "n", "x", "o" }, "sh", "tK") -- 使分屏窗口左右分布 mapkey({ "n", "x", "o" }, "sv", "tH") -- 按 + q 关闭当前窗口下方的窗口 mapkey({ "n", "x", "o" }, "q", "j:q") -- === -- === Tab management -- === -- tu创建新标签,已用bufferline.nvim替代 -- mapcmd("tu", "tabe") -- 在标签之间移动 -- mapcmd('tn','-tabnext') -- mapcmd('ti','+tabnext') -- 移动标签的位置 -- mapcmd('tmn','-tabmove') -- mapcmd('tmi','+tabmove') -- 关闭当前标签,已用close-buffers替代 -- mapcmd('tq','tabc') -- === -- === 批量缩进方法 -- === -- 操作为,esc从编辑模式退到命令模式,将光标移到需要缩进的行的行首,然后按shift+v,可以看到该行已被选中,且左下角提示为“可视” -- 按键盘上的上下方向键,如这里按向下的箭头,选中所有需要批量缩进的行 -- 按shift+>,是向前缩进一个tab值,按shift+<,则是缩回一个tab值 mapkey("x", "<", "", ">gv") mapkey("x", "", "", ">gv") -- === -- === 批量替换 -- === -- 设置快捷键,替换所有文件内容 mapcmd("sa", "lua search_and_replace()") -- 设置快捷键,替换当前文件内容 mapcmd("sr", "lua search_and_replace_current_file()") -- 替换当前目录及子目录下所有文件内容 function search_and_replace() -- 获取用户输入的查找内容,使用 input() 函数动态输入替换内容 local search_text = vim.fn.input("Search for: ") -- 获取用户输入的替换内容 local replace_text = vim.fn.input("Replace with: ") -- 执行替换命令 if search_text ~= "" and replace_text ~= "" then local cmd = 'execute "!grep -rl \\"' .. search_text .. '\\" ./ | xargs sed -i \\"s/' .. search_text .. "/" .. replace_text .. '/g\\""' vim.cmd(cmd) print("Replaced all occurrences of '" .. search_text .. "' with '" .. replace_text .. "'") else print("Search or replace text cannot be empty.") end end -- 替换当前文件内容 function search_and_replace_current_file() -- 获取用户输入的查找内容 local search_text = vim.fn.input("Search for in current file: ") -- 获取用户输入的替换内容 local replace_text = vim.fn.input("Replace with: ") -- 执行替换命令 if search_text ~= "" and replace_text ~= "" then -- 使用 sed 替换当前文件中的匹配内容,并正确转义引号 local cmd = string.format("!sed -i 's/%s/%s/g' %%", search_text, replace_text) vim.cmd(cmd) print("Replaced all occurrences of '" .. search_text .. "' with '" .. replace_text .. "' in current file.") else print("Search or replace text cannot be empty.") end end -- === -- === 临时“存档”文件当前的版本,并与后续的修改进行 diff 对比 -- === -- 创建 :DiffOrig 自定义命令,这个命令会打开一个垂直分屏,加载当前文件存盘时的版本,并启动 diff 模式 vim.api.nvim_create_user_command( 'DiffOrig', function() -- 在创建新窗口前,先保存当前文件的 filetype local original_filetype = vim.bo.filetype -- 打开一个垂直分屏,并准备好临时缓冲区 vim.cmd('vert new | set buftype=nofile') -- 在新的临时缓冲区里,设置我们刚才保存的 filetype,这是确保语法高亮的关键! vim.bo.filetype = original_filetype -- 读取原始文件的磁盘内容,并启动 diff vim.cmd('read ++edit # | 0d_ | diffthis | wincmd p | diffthis') end, { force = true } ) -- dd 将会执行 :DiffOrig 命令 mapcmd('dd', 'DiffOrig') -- === -- === Other useful stuff -- === -- 打开一个终端窗口 mapcmd("/", "set splitbelow:split:res +10:term") -- 按两下空格跳转到占位符<++>,并进入插入模式 mapkey({ "n", "x", "o" }, "", "/<++>:nohlsearchc4l") -- 拼写检查 mapcmd("sc", "set spell!") -- === -- === 运行代码(该功能已经迁移到plugins/coderunner.lua) -- === -- vim.cmd([[ -- au filetype dart noremap r :wall:Telescope flutter commands -- au filetype python noremap r :wall:set splitbelow:sp:term uv run % -- au filetype go noremap r :wall:set splitbelow:sp:term go run % -- au filetype markdown noremap r :PeekClose:PeekOpen -- au filetype rust noremap r :wall:set splitbelow:sp:term cargo run -- ]]) -- === -- === map function external environment -- === -- 下面的函数给外部文件调用的 -- 使用示例如下 -- local map = require("core.keymap") -- map:cmd('p','PasteImg') local map = {} function map:key(mode, lhs, rhs) vim.keymap.set(mode, lhs, rhs, { silent = true }) end function map:cmd(key, cmd) vim.keymap.set("n", key, "" .. cmd .. "", { silent = true }) end function map:lua(key, txt_or_func) if type(txt_or_func) == "string" then vim.keymap.set("n", key, "lua " .. txt_or_func .. "", { silent = true }) else vim.keymap.set("n", key, txt_or_func, { silent = true }) end end return map