#!/bin/bash # 设置错误时立即退出 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 日志函数 log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # 备份现有配置 backup_config() { log_info "备份现有配置..." if [ -d ~/.config/nvim ]; then mv ~/.config/nvim ~/.config/nvim.backup fi } # 安装NvChad install_nvchad() { log_info "安装NvChad..." # 克隆NvChad仓库 git clone https://github.com/NvChad/NvChad ~/.config/nvim --depth 1 # 创建自定义配置目录 mkdir -p ~/.config/nvim/lua/custom } # 配置NvChad configure_nvchad() { log_info "配置NvChad..." # 创建自定义配置 cat > ~/.config/nvim/lua/custom/init.lua << EOF local M = {} -- 自定义配置 M.config = { -- 设置主题 theme = "catppuccin", -- 设置字体 font = "MesloLGS NF", -- 设置终端 terminal = "kitty", -- 设置透明度 transparency = false, -- 设置行号 line_numbers = true, -- 设置相对行号 relative_line_numbers = true, -- 设置状态栏 statusline = { theme = "minimal", separator_style = "block", }, -- 设置标签栏 tabline = { theme = "minimal", separator_style = "block", }, -- 设置文件树 nvimtree = { side = "left", width = 30, }, -- 设置窗口 window = { border = "rounded", padding = 1, }, -- 设置补全 completion = { border = "rounded", padding = 1, }, -- 设置诊断 diagnostics = { virtual_text = true, signs = true, underline = true, }, -- 设置LSP lsp = { signature = true, virtual_text = true, signs = true, underline = true, }, -- 设置格式化 formatting = { timeout_ms = 500, async = true, quiet = false, }, -- 设置快捷键 keymaps = { -- 窗口管理 [""] = "h", [""] = "j", [""] = "k", [""] = "l", [""] = ":resize -2", [""] = ":resize +2", [""] = ":vertical resize -2", [""] = ":vertical resize +2", -- 标签页管理 [""] = ":bprevious", [""] = ":bnext", [""] = ":bdelete", -- 文件树 [""] = ":NvimTreeToggle", -- 终端 [""] = ":ToggleTerm", -- 查找 [""] = ":Telescope find_files", [""] = ":Telescope live_grep", [""] = ":Telescope buffers", [""] = ":Telescope help_tags", -- LSP ["gd"] = ":lua vim.lsp.buf.definition()", ["gr"] = ":lua vim.lsp.buf.references()", ["K"] = ":lua vim.lsp.buf.hover()", [""] = ":lua vim.lsp.buf.signature_help()", ["rn"] = ":lua vim.lsp.buf.rename()", ["ca"] = ":lua vim.lsp.buf.code_action()", ["d"] = ":lua vim.diagnostic.open_float()", ["f"] = ":lua vim.lsp.buf.formatting()", -- Git ["gs"] = ":Git", ["gc"] = ":Git commit", ["gp"] = ":Git push", ["gl"] = ":Git pull", ["gd"] = ":Git diff", ["gb"] = ":Git blame", }, } -- 自定义插件 M.plugins = { -- 主题 { "catppuccin/nvim", name = "catppuccin", priority = 1000, config = function() vim.cmd.colorscheme "catppuccin" end, }, -- 状态栏 { "nvim-lualine/lualine.nvim", config = function() require("custom.plugins.lualine") end, }, -- 标签栏 { "akinsho/bufferline.nvim", config = function() require("custom.plugins.bufferline") end, }, -- 文件树 { "nvim-tree/nvim-tree.lua", config = function() require("custom.plugins.nvimtree") end, }, -- 终端 { "akinsho/toggleterm.nvim", config = function() require("custom.plugins.toggleterm") end, }, -- 查找 { "nvim-telescope/telescope.nvim", config = function() require("custom.plugins.telescope") end, }, -- LSP { "neovim/nvim-lspconfig", config = function() require("custom.plugins.lspconfig") end, }, -- 补全 { "hrsh7th/nvim-cmp", config = function() require("custom.plugins.cmp") end, }, -- 语法高亮 { "nvim-treesitter/nvim-treesitter", config = function() require("custom.plugins.treesitter") end, }, -- Git { "lewis6991/gitsigns.nvim", config = function() require("custom.plugins.gitsigns") end, }, { "tpope/vim-fugitive", }, -- 注释 { "numToStr/Comment.nvim", config = function() require("custom.plugins.comment") end, }, -- 自动配对 { "windwp/nvim-autopairs", config = function() require("custom.plugins.autopairs") end, }, -- 代码片段 { "L3MON4D3/LuaSnip", config = function() require("custom.plugins.luasnip") end, }, -- 格式化 { "jose-elias-alvarez/null-ls.nvim", config = function() require("custom.plugins.null-ls") end, }, } return M EOF # 创建插件配置目录 mkdir -p ~/.config/nvim/lua/custom/plugins # 配置状态栏 cat > ~/.config/nvim/lua/custom/plugins/lualine.lua << EOF local M = {} function M.setup() require("lualine").setup({ options = { theme = "catppuccin", component_separators = { left = "", right = "" }, section_separators = { left = "", right = "" }, globalstatus = true, }, sections = { lualine_a = { { "mode", separator = { left = "" }, right_padding = 2 }, }, lualine_b = { "filename", "branch", "diff", "diagnostics", }, lualine_c = { "filetype", "progress", "location", }, lualine_x = { "encoding", "fileformat", "hostname", }, lualine_y = { "filesize", "filetype", }, lualine_z = { { "datetime", style = "%H:%M" }, }, }, }) end return M EOF # 配置标签栏 cat > ~/.config/nvim/lua/custom/plugins/bufferline.lua << EOF local M = {} function M.setup() require("bufferline").setup({ options = { theme = "catppuccin", separator_style = "block", always_show_bufferline = true, show_buffer_close_icons = true, show_close_icon = true, show_tab_indicators = true, show_duplicate_prefix = true, enforce_regular_tabs = true, view = "multiwindow", show_buffer_icons = true, show_tab_indicators = true, persist_buffer_sort = true, always_show_bufferline = true, sort_by = "extension", }, highlights = require("catppuccin.groups.integrations.bufferline").get(), }) end return M EOF # 配置文件树 cat > ~/.config/nvim/lua/custom/plugins/nvimtree.lua << EOF local M = {} function M.setup() require("nvim-tree").setup({ sort_by = "case_sensitive", view = { width = 30, }, renderer = { group_empty = true, }, filters = { dotfiles = false, }, }) end return M EOF # 配置终端 cat > ~/.config/nvim/lua/custom/plugins/toggleterm.lua << EOF local M = {} function M.setup() require("toggleterm").setup({ size = function(term) if term.direction == "horizontal" then return 15 elseif term.direction == "vertical" then return vim.o.columns * 0.4 end end, open_mapping = [[]], hide_numbers = true, shade_filetypes = {}, shade_terminals = true, shading_factor = 2, start_in_insert = true, insert_mappings = true, persist_size = true, direction = "float", close_on_exit = true, shell = vim.o.shell, float_opts = { border = "curved", winblend = 0, highlights = { border = "Normal", background = "Normal", }, }, }) end return M EOF # 配置查找 cat > ~/.config/nvim/lua/custom/plugins/telescope.lua << EOF local M = {} function M.setup() require("telescope").setup({ defaults = { prompt_prefix = "🔍 ", selection_caret = "➜ ", path_display = { "smart" }, file_ignore_patterns = { ".git/", "node_modules/", "venv/", "__pycache__/", ".pytest_cache/", ".mypy_cache/", }, }, pickers = { find_files = { theme = "dropdown", previewer = false, }, live_grep = { theme = "dropdown", previewer = false, }, buffers = { theme = "dropdown", previewer = false, }, help_tags = { theme = "dropdown", previewer = false, }, }, extensions = { fzf = { fuzzy = true, override_generic_sorter = true, override_file_sorter = true, case_mode = "smart_case", }, }, }) end return M EOF # 配置LSP cat > ~/.config/nvim/lua/custom/plugins/lspconfig.lua << EOF local M = {} function M.setup() local lspconfig = require("lspconfig") local capabilities = require("cmp_nvim_lsp").default_capabilities() local on_attach = function(client, bufnr) local opts = { noremap = true, silent = true, buffer = bufnr } vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) vim.keymap.set("n", "", vim.lsp.buf.signature_help, opts) vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) vim.keymap.set("n", "d", vim.diagnostic.open_float, opts) vim.keymap.set("n", "f", vim.lsp.buf.formatting, opts) end -- 配置各种语言的LSP服务器 local servers = { "tsserver", "html", "cssls", "jsonls", "eslint", "tailwindcss", "prismals", "graphql", "yamlls", "dockerls", "bashls", "pyright", "gopls", "rust_analyzer", "lua_ls", } for _, lsp in ipairs(servers) do lspconfig[lsp].setup({ capabilities = capabilities, on_attach = on_attach, }) end end return M EOF # 配置补全 cat > ~/.config/nvim/lua/custom/plugins/cmp.lua << EOF local M = {} function M.setup() local cmp = require("cmp") local luasnip = require("luasnip") cmp.setup({ snippet = { expand = function(args) luasnip.lsp_expand(args.body) end, }, mapping = { [""] = cmp.mapping.select_prev_item(), [""] = cmp.mapping.select_next_item(), [""] = cmp.mapping.scroll_docs(-4), [""] = cmp.mapping.scroll_docs(4), [""] = cmp.mapping.complete(), [""] = cmp.mapping.close(), [""] = cmp.mapping.confirm({ behavior = cmp.ConfirmBehavior.Replace, select = true, }), }, sources = { { name = "nvim_lsp" }, { name = "luasnip" }, { name = "buffer" }, { name = "path" }, }, }) end return M EOF # 配置语法高亮 cat > ~/.config/nvim/lua/custom/plugins/treesitter.lua << EOF local M = {} function M.setup() require("nvim-treesitter.configs").setup({ ensure_installed = { "lua", "vim", "vimdoc", "javascript", "typescript", "html", "css", "json", "yaml", "toml", "markdown", "bash", "python", "go", "rust", }, highlight = { enable = true, use_languagetree = true, }, indent = { enable = true, }, }) end return M EOF # 配置Git cat > ~/.config/nvim/lua/custom/plugins/gitsigns.lua << EOF local M = {} function M.setup() require("gitsigns").setup({ signs = { add = { text = "│" }, change = { text = "│" }, delete = { text = "_" }, topdelete = { text = "‾" }, changedelete = { text = "~" }, untracked = { text = "┆" }, }, signcolumn = true, numhl = true, linehl = false, word_diff = false, watch_gitdir = { interval = 1000, follow_files = true, }, attach_to_untracked = true, current_line_blame = false, current_line_blame_opts = { virt_text = true, virt_text_pos = "eol", hl_mode = "blend", }, current_line_blame_formatter_opts = { relative_time = false, }, sign_priority = 6, update_debounce = 100, status_formatter = nil, preview_config = { border = "rounded", style = "minimal", relative = "cursor", row = 0, col = 1, }, yadm = { enable = false, }, }) end return M EOF # 配置注释 cat > ~/.config/nvim/lua/custom/plugins/comment.lua << EOF local M = {} function M.setup() require("Comment").setup({ padding = true, sticky = true, ignore = nil, toggler = { line = "gcc", block = "gbc", }, opleader = { line = "gc", block = "gb", }, extra = { above = "gcO", below = "gco", eol = "gcA", }, mappings = { basic = true, extra = true, extended = false, }, pre_hook = nil, post_hook = nil, }) end return M EOF # 配置自动配对 cat > ~/.config/nvim/lua/custom/plugins/autopairs.lua << EOF local M = {} function M.setup() require("nvim-autopairs").setup({ check_ts = true, disable_filetype = { "TelescopePrompt", "spectre_panel" }, fast_wrap = { map = "", chars = { "{", "[", "(", '"', "'" }, pattern = string.gsub([[ [%'%"%)%>%]%)%}%,] ]]], "%s+", ""), offset = 0, end_key = "$", keys = "qwertyuiopzxcvbnmasdfghjkl", check_comma = true, highlight = "PmenuSel", highlight_grey = "LineNr", }, }) end return M EOF # 配置代码片段 cat > ~/.config/nvim/lua/custom/plugins/luasnip.lua << EOF local M = {} function M.setup() require("luasnip").setup({ region_check_events = "CursorMoved,InsertEnter", delete_check_events = "TextChanged,InsertLeave", }) end return M EOF # 配置格式化 cat > ~/.config/nvim/lua/custom/plugins/null-ls.lua << EOF local M = {} function M.setup() local null_ls = require("null-ls") null_ls.setup({ sources = { null_ls.builtins.formatting.prettier, null_ls.builtins.formatting.stylua, null_ls.builtins.formatting.black, null_ls.builtins.formatting.isort, null_ls.builtins.formatting.gofmt, null_ls.builtins.formatting.rustfmt, null_ls.builtins.diagnostics.eslint_d, null_ls.builtins.diagnostics.flake8, null_ls.builtins.diagnostics.mypy, null_ls.builtins.diagnostics.golangci_lint, null_ls.builtins.diagnostics.rustc, }, on_attach = function(client, bufnr) if client.supports_method("textDocument/formatting") then vim.api.nvim_clear_autocmds({ group = augroup, buffer = bufnr }) vim.api.nvim_create_autocmd("BufWritePre", { group = augroup, buffer = bufnr, callback = function() vim.lsp.buf.format({ bufnr = bufnr }) end, }) end end, }) end return M EOF } # 主函数 main() { log_info "开始配置NvChad..." # 备份现有配置 backup_config # 安装NvChad install_nvchad # 配置NvChad configure_nvchad log_info "NvChad配置完成!" log_info "请运行 nvim 来启动编辑器。" log_info "首次启动时会自动安装插件。" } # 执行主函数 main