diff --git a/nvim/.claude/settings.local.json b/nvim/.claude/settings.local.json new file mode 100644 index 0000000..0a37a01 --- /dev/null +++ b/nvim/.claude/settings.local.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [ + "WebSearch" + ] + } +} diff --git a/nvim/.gitignore b/nvim/.gitignore deleted file mode 100644 index cc5457a..0000000 --- a/nvim/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -tt.* -.tests -doc/tags -debug -.repro -foo.* -*.log -data diff --git a/nvim/.neoconf.json b/nvim/.neoconf.json deleted file mode 100644 index 7c48087..0000000 --- a/nvim/.neoconf.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "neodev": { - "library": { - "enabled": true, - "plugins": true - } - }, - "neoconf": { - "plugins": { - "lua_ls": { - "enabled": true - } - } - } -} diff --git a/nvim/LICENSE b/nvim/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/nvim/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/nvim/README.md b/nvim/README.md index 185280b..cb31a88 100644 --- a/nvim/README.md +++ b/nvim/README.md @@ -1,4 +1,172 @@ -# 💤 LazyVim +# Neovim 配置 -A starter template for [LazyVim](https://github.com/LazyVim/LazyVim). -Refer to the [documentation](https://lazyvim.github.io/installation) to get started. +这是一个基于 lazy.nvim 的 Neovim 配置,专注于 Python 和 Go 开发,提供现代化的编辑体验和高效的开发环境。 + +## 功能特点 + +- 🚀 基于 lazy.nvim 的插件管理 +- 💻 完善的 LSP 支持,包括代码补全、诊断和代码操作 +- 🔍 强大的语法高亮和代码分析 (Treesitter) +- 🧩 针对 Python 和 Go 开发的专业配置 +- 🔧 内置调试支持 (DAP) +- 🎨 美观的 UI 和主题 + +## 目录结构 + +``` +nvim/ +├── init.lua # 主配置入口 +├── lua/ +│ ├── core/ # 核心配置 +│ │ ├── autocmds.lua # 自动命令 +│ │ ├── keymaps.lua # 键位映射 +│ │ ├── lazy.lua # 插件管理器配置 +│ │ └── options.lua # 编辑器选项 +│ └── plugins/ # 插件配置 +│ ├── coding.lua # 编码相关插件 (LSP, 补全) +│ ├── colorscheme.lua # 主题配置 +│ ├── editor.lua # 编辑器增强插件 +│ ├── go.lua # Go 开发专用插件 +│ ├── python.lua # Python 开发专用插件 +│ ├── ui.lua # UI 相关插件 +│ └── utils.lua # 实用工具插件 +``` + +## 安装步骤 + +1. 备份现有配置(如果有) + +```bash +mv ~/.config/nvim ~/.config/nvim.bak +``` + +2. 克隆此配置 + +```bash +git clone https://github.com/yourusername/nvim-config.git ~/.config/nvim +``` + +3. 启动 Neovim + +```bash +nvim +``` + +首次启动时,lazy.nvim 将自动安装所有插件。 + +## 语言支持 + +### Python + +- 语言服务器: Pyright 和 Ruff-LSP +- 代码格式化: Black 和 isort +- 调试: debugpy +- 虚拟环境管理: venv-selector +- 测试支持: pytest + +### Go + +- 语言服务器: gopls +- 代码格式化: gofumpt 和 goimports +- 调试: delve +- 工具集成: go.nvim +- 测试支持: Go 测试工具 + +## 主要快捷键 + +> 所有快捷键都基于 `` 作为 leader 键 + +### 通用 + +| 快捷键 | 功能 | +|--------|------| +| `ff` | 查找文件 | +| `fg` | 全局搜索 | +| `fb` | 浏览缓冲区 | +| `e` | 切换文件浏览器 | +| `w` | 保存文件 | +| `q` | 退出 | +| `h` | 清除搜索高亮 | +| `bd` | 删除缓冲区 | + +### LSP 相关 + +| 快捷键 | 功能 | +|--------|------| +| `gd` | 转到定义 | +| `gr` | 查找引用 | +| `K` | 显示悬停信息 | +| `ca` | 代码操作 | +| `cr` | 重命名 | +| `cf` | 格式化代码 | +| `]d` | 下一个诊断 | +| `[d` | 上一个诊断 | + +### Python 专用 + +| 快捷键 | 功能 | +|--------|------| +| `pv` | 选择 Python 虚拟环境 | +| `pt` | 运行最近的测试 | +| `pT` | 运行文件中的测试 | +| `pd` | 调试最近的测试 | + +### Go 专用 + +| 快捷键 | 功能 | +|--------|------| +| `gtt` | 运行包测试 | +| `gtf` | 测试函数 | +| `gfs` | 填充结构体 | +| `gfa` | 添加标签 | +| `ge` | 生成错误处理 | +| `gr` | 运行 Go 程序 | + +### 调试 + +| 快捷键 | 功能 | +|--------|------| +| `db` | 切换断点 | +| `dc` | 继续执行 | +| `di` | 单步进入 | +| `do` | 单步跳出 | +| `dO` | 单步跳过 | +| `dt` | 终止调试 | + +## 自定义配置 + +您可以通过编辑以下文件来自定义配置: + +- `lua/core/options.lua`: 修改编辑器选项 +- `lua/core/keymaps.lua`: 添加或修改键位映射 +- `lua/core/autocmds.lua`: 修改自动命令 + +## 疑难解答 + +如果遇到问题: + +1. 确保 Neovim 版本 >= 0.9.0 +2. 更新所有插件: `:Lazy update` +3. 检查健康状态: `:checkhealth` + +## 依赖项 + +- Neovim >= 0.9.0 +- Git +- 一个支持连字的 Nerd 字体 (推荐 JetBrainsMono Nerd Font) +- Node.js (用于某些 LSP 服务器) +- Python 3 (用于 Python 开发) +- Go (用于 Go 开发) +- ripgrep (用于全局搜索) + +## 灵感来源 + +这个配置受到以下项目的启发: + +- [LazyVim](https://github.com/LazyVim/LazyVim) +- [AstroNvim](https://github.com/AstroNvim/AstroNvim) +- [NvChad](https://github.com/NvChad/NvChad) + +## 许可证 + +MIT \ No newline at end of file diff --git a/nvim/init.lua b/nvim/init.lua index 2514f9e..2aa8aad 100644 --- a/nvim/init.lua +++ b/nvim/init.lua @@ -1,2 +1,11 @@ --- bootstrap lazy.nvim, LazyVim and your plugins -require("config.lazy") +-- 设置 mapleader 必须在加载插件前 +vim.g.mapleader = " " +vim.g.maplocalleader = "\\" + +-- 加载基础配置 +require("config.options") -- 基本设置 +require("config.keymaps") -- 键位映射 +require("config.autocmds") -- 自动命令 + +-- 加载插件管理器 +require("config.lazy") \ No newline at end of file diff --git a/nvim/lazy-lock.json b/nvim/lazy-lock.json index 2c73136..564e526 100644 --- a/nvim/lazy-lock.json +++ b/nvim/lazy-lock.json @@ -1,35 +1,76 @@ { - "LazyVim": { "branch": "main", "commit": "ec5981dfb1222c3bf246d9bcaa713d5cfa486fbd" }, - "blink.cmp": { "branch": "main", "commit": "dcda20d3aa345025699a920c45b0a0603551f41d" }, + "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, + "LuaSnip": { "branch": "master", "commit": "776a29c3e1ac61029ac3f57ac6b5937df2340162" }, + "alpha-nvim": { "branch": "main", "commit": "a35468cd72645dbd52c0624ceead5f301c566dff" }, + "animation.nvim": { "branch": "main", "commit": "fb77091ab72ec9971aee0562e7081182527aaa6a" }, + "avante.nvim": { "branch": "main", "commit": "d80b7966c0505809e83e408353bbe8cb3394936d" }, "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, - "catppuccin": { "branch": "main", "commit": "5b5e3aef9ad7af84f463d17b5479f06b87d5c429" }, - "conform.nvim": { "branch": "master", "commit": "a6f5bdb78caa305496357d17e962bbc4c0b392e2" }, + "catppuccin": { "branch": "main", "commit": "a0c769bc7cd04bbbf258b3d5f01e2bdce744108d" }, + "cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" }, + "cmp-cmdline": { "branch": "main", "commit": "d126061b624e0af6c3a556428712dd4d4194ec6d" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "a8912b88ce488f411177fc8aed358b04dc246d7b" }, + "cmp-path": { "branch": "main", "commit": "c6635aae33a50d6010bf1aa756ac2398a2d54c32" }, + "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, + "conform.nvim": { "branch": "master", "commit": "b529dd4897c85c3188cc787084089a9d55843093" }, + "copilot.lua": { "branch": "master", "commit": "5f726c8e6bbcd7461ee0b870d4e6c8a973b55b64" }, + "dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" }, + "fidget.nvim": { "branch": "main", "commit": "d9ba6b7bfe29b3119a610892af67602641da778e" }, "flash.nvim": { "branch": "main", "commit": "3c942666f115e2811e959eabbdd361a025db8b63" }, - "friendly-snippets": { "branch": "main", "commit": "efff286dd74c22f731cdec26a70b46e5b203c619" }, - "gitsigns.nvim": { "branch": "main", "commit": "4c40357994f386e72be92a46f41fc1664c84c87d" }, - "grug-far.nvim": { "branch": "main", "commit": "3d39dc8b31d4ab7aad1b9ffdba136eafc6c7c360" }, + "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, + "gitsigns.nvim": { "branch": "main", "commit": "d0f90ef51d4be86b824b012ec52ed715b5622e51" }, + "go.nvim": { "branch": "master", "commit": "a3455f48cff718a86275115523dcc735535a13aa" }, + "guihua.lua": { "branch": "master", "commit": "87bea7b98429405caf2a0ce4d029b027bb017c70" }, + "img-clip.nvim": { "branch": "main", "commit": "b6ddfb97b5600d99afe3452d707444afda658aca" }, + "indent-blankline.nvim": { "branch": "master", "commit": "005b56001b2cb30bfa61b7986bc50657816ba4ba" }, "lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" }, - "lazydev.nvim": { "branch": "main", "commit": "2367a6c0a01eb9edb0464731cc0fb61ed9ab9d2c" }, - "lualine.nvim": { "branch": "master", "commit": "f4f791f67e70d378a754d02da068231d2352e5bc" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "1a31f824b9cd5bc6f342fc29e9a53b60d74af245" }, - "mason.nvim": { "branch": "main", "commit": "fc98833b6da5de5a9c5b1446ac541577059555be" }, - "mini.ai": { "branch": "main", "commit": "6e01c0e5a15554852546fac9853960780ac52ed4" }, - "mini.icons": { "branch": "main", "commit": "ec61af6e606fc89ee3b1d8f2f20166a3ca917a36" }, - "mini.pairs": { "branch": "main", "commit": "1a3e73649c0eaef2f6c48ce1e761c6f0a7c11918" }, + "lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" }, + "legendary.nvim": { "branch": "master", "commit": "6de819bc285eb8c420e49e82c21d5bb696b5a727" }, + "lualine.nvim": { "branch": "master", "commit": "0c6cca9f2c63dadeb9225c45bc92bb95a151d4af" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "c2682b0d9732bf52cbc34862056f143e71dc4a6d" }, + "mason-null-ls.nvim": { "branch": "main", "commit": "de19726de7260c68d94691afb057fa73d3cc53e7" }, + "mason-tool-installer.nvim": { "branch": "main", "commit": "93a9ff9b34c91c0cb0f7de8d5f7e4abce51d8903" }, + "mason.nvim": { "branch": "main", "commit": "8024d64e1330b86044fed4c8494ef3dcd483a67c" }, + "middleclass": { "branch": "master", "commit": "9fab4d5bca67262614960960ca35c4740eb2be2c" }, + "mini.bufremove": { "branch": "main", "commit": "66019ecebdc5bc0759e04747586994e2e3f98416" }, + "neo-tree.nvim": { "branch": "v3.x", "commit": "f481de16a0eb59c985abac8985e3f2e2f75b4875" }, + "neodev.nvim": { "branch": "main", "commit": "46aa467dca16cf3dfe27098042402066d2ae242d" }, "noice.nvim": { "branch": "main", "commit": "0427460c2d7f673ad60eb02b35f5e9926cf67c59" }, - "nui.nvim": { "branch": "main", "commit": "53e907ffe5eedebdca1cd503b00aa8692068ca46" }, - "nvim-lint": { "branch": "master", "commit": "6e9dd545a1af204c4022a8fcd99727ea41ffdcc8" }, - "nvim-lspconfig": { "branch": "master", "commit": "919f83ef8169d11eabd921a4cbda4fc1ba12f123" }, - "nvim-treesitter": { "branch": "master", "commit": "1adcd5711929e44d1bc9e59fbf7d94656cf6d389" }, - "nvim-treesitter-textobjects": { "branch": "master", "commit": "8b2d4d519f3516d09910f5baf48d1a47b594f0ce" }, - "nvim-ts-autotag": { "branch": "main", "commit": "a1d526af391f6aebb25a8795cbc05351ed3620b5" }, + "none-ls.nvim": { "branch": "main", "commit": "db2a48b79cfcdab8baa5d3f37f21c78b6705c62e" }, + "nui.nvim": { "branch": "main", "commit": "7cd18e73cfbd70e1546931b7268b3eebaeff9391" }, + "nvim-autopairs": { "branch": "master", "commit": "4d74e75913832866aa7de35e4202463ddf6efd1b" }, + "nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" }, + "nvim-dap": { "branch": "master", "commit": "e771e86a69a8ba60cffb16609773522eafb9f41a" }, + "nvim-dap-go": { "branch": "main", "commit": "8763ced35b19c8dc526e04a70ab07c34e11ad064" }, + "nvim-dap-python": { "branch": "master", "commit": "261ce649d05bc455a29f9636dc03f8cdaa7e0e2c" }, + "nvim-dap-ui": { "branch": "master", "commit": "73a26abf4941aa27da59820fd6b028ebcdbcf932" }, + "nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" }, + "nvim-lint": { "branch": "master", "commit": "bcd1a44edbea8cd473af7e7582d3f7ffc60d8e81" }, + "nvim-lspconfig": { "branch": "master", "commit": "8adb3b5938f6074a1bcc36d3c3916f497d2e8ec4" }, + "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, + "nvim-notify": { "branch": "master", "commit": "b5825cf9ee881dd8e43309c93374ed5b87b7a896" }, + "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, + "nvim-treesitter-textobjects": { "branch": "master", "commit": "0f051e9813a36481f48ca1f833897210dbcfffde" }, + "nvim-ufo": { "branch": "main", "commit": "3c7a3570e9c9dc198a2ad4491b0b0e51c4d4ba08" }, + "nvim-web-devicons": { "branch": "master", "commit": "1fb58cca9aebbc4fd32b086cb413548ce132c127" }, + "oil.nvim": { "branch": "master", "commit": "5b6068aad7d2057dd399fac73b7fb2cdf23ccd6e" }, "persistence.nvim": { "branch": "main", "commit": "166a79a55bfa7a4db3e26fc031b4d92af71d0b51" }, "plenary.nvim": { "branch": "master", "commit": "857c5ac632080dba10aae49dba902ce3abf91b35" }, + "project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" }, + "promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" }, + "rainbow-delimiters.nvim": { "branch": "master", "commit": "55ad4fb76ab68460f700599b7449385f0c4e858e" }, "snacks.nvim": { "branch": "main", "commit": "bc0630e43be5699bb94dadc302c0d21615421d93" }, + "sniprun": { "branch": "master", "commit": "a90c65846c3c18efc3f799d8b6dc26af9d4a69ed" }, + "statuscol.nvim": { "branch": "main", "commit": "c46172d0911aa5d49ba5f39f4351d1bb7aa289cc" }, + "telescope-fzf-native.nvim": { "branch": "main", "commit": "1f08ed60cafc8f6168b72b80be2b2ea149813e55" }, + "telescope.nvim": { "branch": "master", "commit": "b4da76be54691e854d3e0e02c36b0245f945c2c7" }, "todo-comments.nvim": { "branch": "main", "commit": "304a8d204ee787d2544d8bc23cd38d2f929e7cc5" }, + "toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" }, "tokyonight.nvim": { "branch": "main", "commit": "057ef5d260c1931f1dffd0f052c685dcd14100a3" }, "trouble.nvim": { "branch": "main", "commit": "85bedb7eb7fa331a2ccbecb9202d8abba64d37b3" }, "ts-comments.nvim": { "branch": "main", "commit": "1bd9d0ba1d8b336c3db50692ffd0955fe1bb9f0c" }, - "vim-wakatime": { "branch": "master", "commit": "e46d7c4f98ee0f40782008dd60cb2a79c377fb1d" }, - "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" } + "venv-selector.nvim": { "branch": "main", "commit": "f212a424fb29949cb5e683928bdd4038bbe0062d" }, + "vim-illuminate": { "branch": "master", "commit": "0d1e93684da00ab7c057410fecfc24f434698898" }, + "vim-visual-multi": { "branch": "master", "commit": "a6975e7c1ee157615bbc80fc25e4392f71c344d4" }, + "which-key.nvim": { "branch": "main", "commit": "370ec46f710e058c9c1646273e6b225acf47cbed" }, + "windows.nvim": { "branch": "main", "commit": "c7492552b23d0ab30325e90b56066ec51242adc8" } } diff --git a/nvim/lazyvim.json b/nvim/lazyvim.json deleted file mode 100644 index 6206f7e..0000000 --- a/nvim/lazyvim.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extras": [ - - ], - "install_version": 8, - "news": { - "NEWS.md": "10960" - }, - "version": 8 -} \ No newline at end of file diff --git a/nvim/lua/config/autocmds.lua b/nvim/lua/config/autocmds.lua index ab19c6a..872ad56 100644 --- a/nvim/lua/config/autocmds.lua +++ b/nvim/lua/config/autocmds.lua @@ -1,26 +1,116 @@ --- Autocmds are automatically loaded on the VeryLazy event --- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua --- --- Add any additional autocmds here --- with `vim.api.nvim_create_autocmd` --- --- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults) --- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell") +-- autocmds.lua - 自动命令配置 -vim.cmd('filetype plugin indent on') +-- 创建自动命令组 +local augroup = vim.api.nvim_create_augroup("MyCustomGroup", { clear = true }) --- Create a group for our autocommands -local augroup = vim.api.nvim_create_augroup("CustomSettings", { clear = true }) +-- 自动设置光标行 +vim.api.nvim_create_autocmd({ "InsertLeave", "WinEnter" }, { + pattern = "*", + group = augroup, + callback = function() + if vim.bo.buftype ~= "terminal" then + vim.opt_local.cursorline = true + end + end, +}) --- FileType autocommands +vim.api.nvim_create_autocmd({ "InsertEnter", "WinLeave" }, { + pattern = "*", + group = augroup, + callback = function() + if vim.bo.buftype ~= "terminal" then + vim.opt_local.cursorline = false + end + end, +}) + +-- 高亮复制文本 +vim.api.nvim_create_autocmd("TextYankPost", { + pattern = "*", + group = augroup, + callback = function() + vim.highlight.on_yank({ higroup = "IncSearch", timeout = 200 }) + end, +}) + +-- 自动切换工作目录 +vim.api.nvim_create_autocmd({ "BufEnter" }, { + pattern = "*", + group = augroup, + desc = "自动切换到文件所在目录", + callback = function() + local buftype = vim.bo.buftype + if buftype ~= "terminal" and buftype ~= "nofile" and buftype ~= "prompt" then + vim.cmd("silent! lcd %:p:h") + end + end, +}) + +-- 自动恢复光标位置 +vim.api.nvim_create_autocmd("BufReadPost", { + group = augroup, + desc = "恢复光标位置", + callback = function() + local mark = vim.api.nvim_buf_get_mark(0, '"') + local lcount = vim.api.nvim_buf_line_count(0) + if mark[1] > 0 and mark[1] <= lcount then + pcall(vim.api.nvim_win_set_cursor, 0, mark) + end + end, +}) + +-- 自动关闭某些窗口的 q 键 +vim.api.nvim_create_autocmd("FileType", { + pattern = { + "qf", + "help", + "man", + "notify", + "lspinfo", + "startuptime", + "tsplayground", + "spectre_panel", + "PlenaryTestPopup", + }, + group = augroup, + callback = function(event) + vim.bo[event.buf].buflisted = false + vim.keymap.set("n", "q", "close", { buffer = event.buf, silent = true }) + end, +}) + +-- 在保存时自动删除行尾空白字符 +vim.api.nvim_create_autocmd("BufWritePre", { + pattern = "*", + group = augroup, + desc = "删除行尾空白字符", + callback = function() + -- 保存当前位置 + local cursor_pos = vim.api.nvim_win_get_cursor(0) + -- 保存搜索寄存器 + local search = vim.fn.getreg("/") + + -- 替换所有行尾空白字符 + vim.cmd([[%s/\s\+$//e]]) + + -- 恢复搜索寄存器 + vim.fn.setreg("/", search) + -- 恢复光标位置 + vim.api.nvim_win_set_cursor(0, cursor_pos) + end, +}) + +-- 自动设置文件类型的选项 vim.api.nvim_create_autocmd("FileType", { pattern = "python", group = augroup, callback = function() - vim.opt_local.tabstop = 4 + vim.opt_local.expandtab = true vim.opt_local.shiftwidth = 4 + vim.opt_local.tabstop = 4 vim.opt_local.softtabstop = 4 - vim.opt_local.textwidth = 120 + vim.opt_local.textwidth = 88 -- 符合 black 格式化 + vim.opt_local.colorcolumn = "88" end, }) @@ -28,112 +118,20 @@ vim.api.nvim_create_autocmd("FileType", { pattern = "go", group = augroup, callback = function() - vim.opt_local.tabstop = 4 - vim.opt_local.shiftwidth = 4 - vim.opt_local.softtabstop = 4 - vim.opt_local.textwidth = 120 vim.opt_local.expandtab = false + vim.opt_local.shiftwidth = 4 + vim.opt_local.tabstop = 4 end, }) vim.api.nvim_create_autocmd("FileType", { - pattern = { "json", "jsonnet" }, + pattern = { "javascript", "typescript", "javascriptreact", "typescriptreact", "json", "html", "css", "yaml", "markdown" }, group = augroup, callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 vim.opt_local.expandtab = true - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "yaml", - group = augroup, - callback = function() - vim.opt_local.tabstop = 2 vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 - vim.opt_local.textwidth = 0 - vim.opt_local.expandtab = true - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "gotmpl", - group = augroup, - callback = function() vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 vim.opt_local.softtabstop = 2 - vim.opt_local.textwidth = 0 - vim.opt_local.expandtab = true - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "php", - group = augroup, - callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 - vim.opt_local.textwidth = 120 - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = { "html", "htmldjango", "xhtml", "haml" }, - group = augroup, - callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 - vim.opt_local.textwidth = 0 - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "ruby", - group = augroup, - callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 - vim.opt_local.textwidth = 120 - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = { "less", "sass", "scss", "css" }, - group = augroup, - callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 - vim.opt_local.textwidth = 120 - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = { "javascript", "javascript.jsx", "javascriptreact", "typescript", "typescriptreact" }, - group = augroup, - callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 - vim.opt_local.expandtab = true - end, -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "NvimTree", - group = augroup, - callback = function() - vim.opt_local.tabstop = 2 - vim.opt_local.shiftwidth = 2 - vim.opt_local.softtabstop = 2 - vim.opt_local.textwidth = 0 end, }) @@ -142,23 +140,73 @@ vim.api.nvim_create_autocmd("FileType", { group = augroup, callback = function() vim.opt_local.expandtab = false - vim.opt_local.shiftwidth = 8 - vim.opt_local.softtabstop = 0 end, }) --- File pattern autocommands -vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { - pattern = "*.proto", - group = augroup, - command = "setfiletype proto", -}) - -vim.api.nvim_create_autocmd("FileType", { - pattern = "proto", +-- 为新文件创建模板 +vim.api.nvim_create_autocmd("BufNewFile", { + pattern = "*.py", group = augroup, callback = function() - vim.opt_local.shiftwidth = 2 - vim.opt_local.expandtab = true + local lines = { + "#!/usr/bin/env python3", + "# -*- coding: utf-8 -*-", + "\"\"\"", + "Description: ", + "\"\"\"", + "", + "", + "def main():", + " pass", + "", + "", + "if __name__ == \"__main__\":", + " main()", + "", + } + vim.api.nvim_buf_set_lines(0, 0, 0, false, lines) + vim.api.nvim_win_set_cursor(0, { 4, 13 }) end, -}) \ No newline at end of file +}) + +vim.api.nvim_create_autocmd("BufNewFile", { + pattern = "*.go", + group = augroup, + callback = function() + local package_name = vim.fn.fnamemodify(vim.fn.expand("%:p:h:t"), ":r") + + local lines = { + "package " .. package_name, + "", + "import (", + "\t\"fmt\"", + ")", + "", + "// TODO: Add description here", + "", + "", + } + vim.api.nvim_buf_set_lines(0, 0, 0, false, lines) + vim.api.nvim_win_set_cursor(0, { 7, 27 }) + end, +}) + +-- 在外部更改时自动重新加载文件 +vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold", "CursorHoldI" }, { + pattern = "*", + group = augroup, + callback = function() + if vim.fn.mode() ~= "c" and not vim.bo.readonly then + vim.cmd("checktime") + end + end, +}) + +-- 当 checktime 检测到文件已更改时通知 +vim.api.nvim_create_autocmd("FileChangedShellPost", { + pattern = "*", + group = augroup, + callback = function() + vim.notify("File changed on disk. Buffer reloaded!", vim.log.levels.WARN) + end, +}) \ No newline at end of file diff --git a/nvim/lua/config/keymaps.lua b/nvim/lua/config/keymaps.lua index 2c134f7..f893706 100644 --- a/nvim/lua/config/keymaps.lua +++ b/nvim/lua/config/keymaps.lua @@ -1,3 +1,117 @@ --- Keymaps are automatically loaded on the VeryLazy event --- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua --- Add any additional keymaps here +-- keymaps.lua - 键位映射配置 + +-- 设置局部变量 +local map = vim.keymap.set +local opts = { noremap = true, silent = true } + +--[[ +模式说明: + n: 普通模式 + i: 插入模式 + v: 可视模式 + x: 可视块模式 + t: 终端模式 + c: 命令行模式 +]]-- + +----------------- +-- 基础键位映射 -- +----------------- + +-- 使用 jk 从插入模式返回普通模式 +map("i", "jk", "", opts) + +-- 保存和退出 +map("n", "w", "w", { desc = "保存文件" }) +map("n", "q", "q", { desc = "退出" }) +map("n", "Q", "qa", { desc = "退出全部" }) + +-- 清除搜索高亮 +map("n", "h", "nohlsearch", { desc = "清除搜索高亮" }) + +-- 更好的缩进 +map("v", "<", "", ">gv", opts) + +-- 上下移动选中的文本 +map("v", "J", ":m '>+1gv=gv", { desc = "向下移动选中文本" }) +map("v", "K", ":m '<-2gv=gv", { desc = "向上移动选中文本" }) + +-- 保持复制内容在粘贴后 +map("x", "p", [["_dP]], { desc = "粘贴不覆盖寄存器" }) + +-- 删除到黑洞寄存器 +map({ "n", "v" }, "d", [["_d]], { desc = "删除到黑洞寄存器" }) + +-- 快速移动 +map("n", "J", "mzJ`z", { desc = "连接行保持光标位置" }) +map("n", "", "zz", { desc = "向下移动保持光标居中" }) +map("n", "", "zz", { desc = "向上移动保持光标居中" }) +map("n", "n", "nzzzv", { desc = "下一个搜索结果并居中" }) +map("n", "N", "Nzzzv", { desc = "上一个搜索结果并居中" }) + +------------------------- +-- 窗口和缓冲区管理 -- +------------------------- + +-- 窗口间导航 +map("n", "", "h", { desc = "移动到左窗口" }) +map("n", "", "j", { desc = "移动到下窗口" }) +map("n", "", "k", { desc = "移动到上窗口" }) +map("n", "", "l", { desc = "移动到右窗口" }) + +-- 缓冲区导航 +map("n", "", "bprevious", { desc = "上一个缓冲区" }) +map("n", "", "bnext", { desc = "下一个缓冲区" }) +map("n", "bd", "bdelete", { desc = "关闭当前缓冲区" }) +map("n", "ba", "bufdo bd", { desc = "关闭所有缓冲区" }) + +-- 窗口分割 +map("n", "sv", "vsplit", { desc = "垂直分割" }) +map("n", "sh", "split", { desc = "水平分割" }) +map("n", "se", "=", { desc = "使所有窗口等宽" }) +map("n", "sx", "close", { desc = "关闭当前窗口" }) + +-- 调整窗口大小 +map("n", "", "resize +2", { desc = "增加窗口高度" }) +map("n", "", "resize -2", { desc = "减小窗口高度" }) +map("n", "", "vertical resize -2", { desc = "减小窗口宽度" }) +map("n", "", "vertical resize +2", { desc = "增加窗口宽度" }) + +------------------------- +-- 终端模式映射 -- +------------------------- + +-- 退出终端模式 +map("t", "", "", { desc = "退出终端模式" }) +map("t", "jk", "", { desc = "退出终端模式" }) + +-- 终端窗口导航 +map("t", "", "h", { desc = "终端模式下向左移动" }) +map("t", "", "j", { desc = "终端模式下向下移动" }) +map("t", "", "k", { desc = "终端模式下向上移动" }) +map("t", "", "l", { desc = "终端模式下向右移动" }) + +------------------------- +-- 实用功能 -- +------------------------- + +-- 全文快速替换当前单词 +map("n", "r", [[:%s/\<\>//gI]], { desc = "替换当前单词" }) + +-- 使当前文件可执行 +map("n", "x", "!chmod +x %", { desc = "使当前文件可执行", silent = true }) + +-- 打开一个新的终端 +map("n", "t", "terminal", { desc = "打开终端" }) + +-- 快速编辑配置文件 +map("n", "ev", "e $MYVIMRC", { desc = "编辑init.lua" }) +map("n", "sv", "source $MYVIMRC", { desc = "重新加载配置" }) + +-- 更简单的命令行历史导航 +map("c", "", "", { desc = "下一个命令历史" }) +map("c", "", "", { desc = "上一个命令历史" }) + +-- 更好的搜索 +map("n", "g/", "/\\<\\>", { desc = "搜索单词" }) \ No newline at end of file diff --git a/nvim/lua/config/lazy.lua b/nvim/lua/config/lazy.lua index d73bfa1..13d8ce8 100644 --- a/nvim/lua/config/lazy.lua +++ b/nvim/lua/config/lazy.lua @@ -1,3 +1,6 @@ +-- lazy.lua - lazy.nvim 插件管理器配置 + +-- Bootstrap lazy.nvim local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or vim.loop).fs_stat(lazypath) then local lazyrepo = "https://github.com/folke/lazy.nvim.git" @@ -14,40 +17,75 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then end vim.opt.rtp:prepend(lazypath) +-- 配置 lazy.nvim require("lazy").setup({ + -- 插件列表 spec = { - -- add LazyVim and import its plugins - { "LazyVim/LazyVim", import = "lazyvim.plugins" }, - -- import/override with your plugins + -- 导入插件模块 { import = "plugins" }, }, + + -- 默认配置 defaults = { - -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. - -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. - lazy = false, - -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, - -- have outdated releases, which may break your Neovim install. - version = false, -- always use the latest git commit - -- version = "*", -- try installing the latest stable version for plugins that support semver + lazy = false, -- 默认不延迟加载 + version = false, -- 使用最新版本 }, - install = { colorscheme = { "tokyonight", "habamax" } }, - checker = { - enabled = true, -- check for plugin updates periodically - notify = false, -- notify on update - }, -- automatically check for plugin updates + + -- 安装配置 + install = { + colorscheme = { "tokyonight", "habamax" }, -- 安装时使用的主题 + missing = true, -- 自动安装缺失的插件 + }, + + -- 性能配置 performance = { rtp = { - -- disable some rtp plugins + -- 禁用一些内置插件 disabled_plugins = { - "gzip", - -- "matchit", - -- "matchparen", - -- "netrwPlugin", - "tarPlugin", - "tohtml", - "tutor", - "zipPlugin", + "gzip", -- 不需要在编辑器内处理 gzip 文件 + "matchit", -- 使用 treesitter 代替 + "matchparen", -- 使用 treesitter 代替 + "netrwPlugin", -- 使用 nvim-tree 代替 + "tarPlugin", -- 不需要在编辑器内处理 tar 文件 + "tohtml", -- 不需要转换为 HTML + "tutor", -- 不需要内置教程 + "zipPlugin", -- 不需要在编辑器内处理 zip 文件 }, }, }, -}) + + -- UI 配置 + ui = { + -- 自定义图标 + icons = { + cmd = "⌘", + config = "🛠", + event = "📅", + ft = "📂", + init = "⚙", + keys = "🔑", + plugin = "🔌", + runtime = "💻", + source = "📄", + start = "🚀", + task = "📌", + lazy = "💤 ", + }, + size = { width = 0.8, height = 0.8 }, -- 窗口大小 + wrap = true, -- 自动换行 + border = "rounded", -- 边框样式 + }, + + -- 检查更新配置 + checker = { + enabled = true, -- 启用自动检查更新 + frequency = 3600, -- 检查频率(秒) + notify = false, -- 禁用更新通知 + }, + + -- 更新配置 + change_detection = { + enabled = true, -- 启用自动重载 + notify = false, -- 禁用更改通知 + }, +}) \ No newline at end of file diff --git a/nvim/lua/config/options.lua b/nvim/lua/config/options.lua index d28623a..a98409f 100644 --- a/nvim/lua/config/options.lua +++ b/nvim/lua/config/options.lua @@ -1,55 +1,89 @@ --- Options are automatically loaded before lazy.nvim startup --- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua --- Add any additional options here +-- options.lua - 基本编辑器选项设置 + local opt = vim.opt -local o = vim.o local g = vim.g -g.loaded_netrw = 1 -g.loaded_netrwPlugin = 1 -o.termguicolors = true +-- UI设置 +opt.termguicolors = true -- 使用终端真彩色 +opt.number = true -- 显示行号 +opt.relativenumber = true -- 相对行号 +opt.cursorline = true -- 高亮当前行 +opt.cursorcolumn = true -- 高亮当前列 +opt.signcolumn = "auto:1" -- 显示标记列 +opt.showmatch = true -- 高亮匹配的括号 +opt.showmode = false -- 不显示模式,由状态栏插件替代 +opt.laststatus = 3 -- 全局状态栏 +opt.cmdheight = 1 -- 命令行高度 +opt.scrolloff = 10 -- 光标上下保留的行数 +opt.sidescrolloff = 10 -- 光标左右保留的列数 +opt.wrap = false -- 不自动换行 +opt.linebreak = true -- 如果wrap开启,在单词边界处换行 +opt.list = true -- 显示不可见字符 +opt.listchars = { -- 设置不可见字符的显示方式 + tab = "» ", + trail = "·", + extends = "›", + precedes = "‹", + nbsp = "␣", + eol = "↴" +} +opt.fillchars:append({ -- 分隔符符号设置 + vert = "│", -- 窗口分隔符 + fold = "⠀", -- 折叠 + eob = " ", -- 缓冲区末尾的空行 + diff = "╱", -- 差异模式的删除行 +}) -g.mapleader = ' ' -- Make sure to set `mapleader` before lazy so your mappings are correct -g.maplocalleader = '\\' -- Same for `maplocalleader` +-- 编辑设置 +opt.tabstop = 4 -- Tab宽度 +opt.softtabstop = 4 -- 编辑时的Tab宽度 +opt.shiftwidth = 4 -- 缩进宽度 +opt.expandtab = true -- 使用空格替代Tab +opt.smartindent = true -- 智能缩进 +opt.autoindent = true -- 自动缩进 +opt.cindent = true -- C语言缩进规则 +opt.textwidth = 120 -- 文本宽度 +opt.formatoptions = "jcroqlnt" -- 格式化选项 +opt.foldenable = false -- 默认不折叠 +opt.foldmethod = "expr" -- 使用表达式进行折叠 +opt.foldexpr = "nvim_treesitter#foldexpr()" -- 使用treesitter进行折叠 -o.encoding = 'utf-8' -o.fileencoding = 'utf-8' -o.fencs = 'utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936' -o.hidden = true -o.wildmenu = true -o.hlsearch = true -o.incsearch = true -o.matchtime = 1 -o.showmatch = true -o.updatetime = 100 -o.ignorecase = true -o.smarttab = true -o.expandtab = true -o.laststatus = 2 -o.showcmd = true -o.ruler = true -o.history = 300 -o.backup = false -o.swapfile = false -o.foldenable = false -o.autoread = true -o.autowrite = true -o.mouse = 'a' +-- 搜索设置 +opt.ignorecase = true -- 搜索忽略大小写 +opt.smartcase = true -- 如果搜索包含大写字母,则区分大小写 +opt.hlsearch = true -- 高亮搜索结果 +opt.incsearch = true -- 增量搜索 -o.number = true -o.cursorline = true -o.relativenumber = true -o.cursorcolumn = true -o.signcolumn = 'auto:1' --- o.cmdheight = 0 -opt.list = true -opt.listchars:append('eol:↴') -opt.fillchars:append { diff = '╱' } +-- 性能设置 +opt.hidden = true -- 允许切换未保存的缓冲区 +opt.history = 500 -- 历史记录数 +opt.updatetime = 100 -- 更新时间(ms) +opt.timeout = true -- 启用超时 +opt.timeoutlen = 300 -- 键映射超时时间(ms) +opt.ttimeoutlen = 10 -- 键码超时时间(ms) +opt.synmaxcol = 240 -- 最大语法分析列数 -o.textwidth = 120 -o.smartindent = true -o.autoindent = true -o.cindent = true -o.shiftwidth = 4 -o.softtabstop = 4 -o.tabstop = 4 \ No newline at end of file +-- 文件设置 +opt.fileencoding = "utf-8" -- 文件编码 +opt.backup = false -- 不创建备份文件 +opt.swapfile = false -- 不创建交换文件 +opt.undofile = true -- 启用持久撤销 +opt.undodir = vim.fn.stdpath("data") .. "/undo" -- 撤销文件目录 + +-- 鼠标设置 +opt.mouse = "a" -- 启用鼠标 + +-- 分隔符设置 +opt.splitbelow = true -- 新的水平分割窗口在下面 +opt.splitright = true -- 新的垂直分割窗口在右边 + +-- 通用设置 +opt.clipboard = "unnamedplus" -- 使用系统剪贴板 +opt.completeopt = "menu,menuone,noselect" -- 补全选项 +opt.pumheight = 10 -- 弹出菜单高度 +opt.confirm = true -- 显示确认对话框 +opt.autoread = true -- 自动重新加载文件 + +-- 加载 .nvimrc, .exrc 等本地配置 +opt.exrc = true -- 启用 .exrc +opt.secure = true -- 限制本地配置中的命令 \ No newline at end of file diff --git a/nvim/lua/plugins/avante.lua b/nvim/lua/plugins/avante.lua new file mode 100644 index 0000000..aa406b6 --- /dev/null +++ b/nvim/lua/plugins/avante.lua @@ -0,0 +1,200 @@ +-- avante.lua - AI 编程助手,类似 Cursor 的体验 +-- 基于 OpenAI/Anthropic API 提供智能代码编辑 + +return { + { + "yetone/avante.nvim", + event = "VeryLazy", + version = false, -- 使用最新版本 + build = "make", -- 构建依赖 + dependencies = { + "nvim-treesitter/nvim-treesitter", + "stevearc/dressing.nvim", + "nvim-lua/plenary.nvim", + "MunifTanjim/nui.nvim", + -- 可选: 用于图片粘贴支持 + "HakonHarnes/img-clip.nvim", + }, + opts = { + -- 默认 AI 提供商 + provider = "openai", + + -- 提供商配置 (v0.46+ 版本结构) + providers = { + -- OpenAI 配置 + openai = { + endpoint = "https://api.openai.com/v1", + model = "gpt-4o", + timeout = 30000, + context_window = 128000, + extra_request_body = { + temperature = 0.75, + max_completion_tokens = 16384, + reasoning_effort = "medium", + }, + }, + + -- Anthropic Claude 配置(备选) + claude = { + endpoint = "https://api.anthropic.com", + model = "claude-3-5-sonnet-20241022", + timeout = 30000, + context_window = 200000, + extra_request_body = { + temperature = 0.75, + max_completion_tokens = 8192, + }, + }, + + -- Azure OpenAI 配置(企业用户) + azure = { + endpoint = "", -- 你的 Azure 端点,例如: https://.openai.azure.com + deployment = "", -- 部署名称 + api_version = "2024-12-01-preview", + timeout = 30000, + context_window = 128000, + extra_request_body = { + temperature = 0.75, + max_completion_tokens = 16384, + reasoning_effort = "medium", + }, + }, + + -- Copilot 配置(可选) + copilot = { + endpoint = "https://api.githubcopilot.com", + model = "gpt-4o-copilot", + timeout = 30000, + context_window = 128000, + extra_request_body = { + temperature = 0.75, + max_completion_tokens = 16384, + }, + }, + }, + + -- 系统提示词 - 定义 AI 助手的角色 + system_prompt = [[ +You are an expert coding assistant. Your task is to help users write, refactor, and understand code. + +Rules: +1. Always respond with code changes in the specified format +2. Explain your changes clearly +3. Consider code style and best practices +4. If unsure, ask clarifying questions +5. Be concise but thorough + +When suggesting code changes: +- Use the diff format if replacing existing code +- Ensure code is syntactically correct +- Follow the existing code style of the project +]], + + -- 浮动窗口样式 + windows = { + ---@type "right" | "left" | "top" | "bottom" + position = "right", + wrap = true, + width = 40, + sidebar_header = { + align = "center", + rounded = true, + }, + }, + + -- 高亮配置 + highlights = { + diff = { + current = "DiffText", + incoming = "DiffAdd", + }, + }, + + -- 差异视图配置 + diff = { + autojump = true, + list_opener = function() + -- 可以自定义差异列表打开方式 + vim.cmd("copen") + end, + }, + + -- 建议 Provider 配置(用于代码补全) + suggestion_provider = "copilot", -- 或 "default" + + -- 上下文窗口配置 + context_window = 6000, + + -- 行为配置 + behaviour = { + -- 是否自动应用建议 + auto_apply_suggestion_after_generation = false, + -- 是否支持图片粘贴 + support_paste_from_clipboard = false, + }, + + -- 映射配置(空表示使用默认映射) + mappings = { + -- 默认映射: + -- aa - 打开侧边栏 + -- ar - 重置对话 + -- af - 切换焦点 + -- ae - 编辑请求 + -- as - 切换侧边栏位置 + -- at - 停止生成 + }, + }, + keys = { + -- 打开 AI 侧边栏 + { + "aa", + function() + require("avante").toggle() + end, + desc = "AI 助手 (avante)", + mode = { "n", "v" }, + }, + -- 重置对话 + { + "ar", + function() + require("avante").reset() + end, + desc = "重置 AI 对话", + }, + -- 快速询问(选中代码) + { + "ai", + function() + require("avante").ask() + end, + desc = "AI 询问选中的代码", + mode = "v", + }, + -- 编辑代码 + { + "ae", + function() + require("avante").edit() + end, + desc = "AI 编辑代码", + mode = "v", + }, + }, + }, + -- 可选依赖: 图片粘贴支持 + { + "HakonHarnes/img-clip.nvim", + event = "VeryLazy", + opts = { + -- 默认配置即可 + default = { + embed_image_as_base64 = false, + prompt_for_file_name = false, + drag_and_drop = { + insert_mode = true, + }, + }, + }, + }, +} diff --git a/nvim/lua/plugins/coding.lua b/nvim/lua/plugins/coding.lua index 7e1c91e..54107f2 100644 --- a/nvim/lua/plugins/coding.lua +++ b/nvim/lua/plugins/coding.lua @@ -67,7 +67,7 @@ return { }, }, }, - + -- Python 服务器 pyright = { settings = { @@ -89,7 +89,7 @@ return { }, }, }, - + -- Go 服务器 gopls = { settings = { @@ -131,18 +131,6 @@ return { }, }, }, - - -- 自动设置功能 - setup = { - ruff_lsp = function() - require("lazyvim.util").lsp.on_attach(function(client, _) - -- 禁用 ruff 格式化功能,由 none-ls 处理 - if client.name == "ruff_lsp" then - client.server_capabilities.documentFormattingProvider = false - end - end) - end, - }, }, config = function(_, opts) -- 设置诊断标志 @@ -259,14 +247,21 @@ return { local server_opts = vim.tbl_deep_extend("force", { capabilities = vim.deepcopy(capabilities), }, opts.servers[server] or {}) - + -- 特殊设置钩子 - if opts.setup[server] then - if opts.setup[server](server, server_opts) then - return - end + if server == "ruff_lsp" then + -- 使用 LspAttach 自动命令来配置 ruff_lsp + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + -- 禁用 ruff 格式化功能,由 conform 处理 + if client and client.name == "ruff_lsp" then + client.server_capabilities.documentFormattingProvider = false + end + end, + }) end - + -- 启动服务器 require("lspconfig")[server].setup(server_opts) end, @@ -479,6 +474,7 @@ return { -- UI 相关 { "rcarriga/nvim-dap-ui", + dependencies = { "nvim-neotest/nvim-nio" }, keys = { { "du", function() require("dapui").toggle() end, desc = "Dap UI" }, }, diff --git a/nvim/lua/plugins/editor.lua b/nvim/lua/plugins/editor.lua index 3fe3519..7f98079 100644 --- a/nvim/lua/plugins/editor.lua +++ b/nvim/lua/plugins/editor.lua @@ -1,6 +1,26 @@ -- editor.lua - 编辑器增强插件配置 return { + -- LazyGit 集成 + { + "kdheepak/lazygit.nvim", + cmd = { + "LazyGit", + "LazyGitConfig", + "LazyGitCurrentFile", + "LazyGitFilter", + "LazyGitFilterCurrentFile", + }, + dependencies = { + "nvim-lua/plenary.nvim", + }, + keys = { + { "gg", "LazyGit", desc = "打开 LazyGit" }, + { "gf", "LazyGitCurrentFile", desc = "当前文件 Git 历史" }, + { "gc", "LazyGitConfig", desc = "LazyGit 配置" }, + }, + }, + -- 模糊搜索 { "nvim-telescope/telescope.nvim", @@ -95,6 +115,26 @@ return { end, }, + -- LazyGit 集成 + { + "kdheepak/lazygit.nvim", + cmd = { + "LazyGit", + "LazyGitConfig", + "LazyGitCurrentFile", + "LazyGitFilter", + "LazyGitFilterCurrentFile", + }, + dependencies = { + "nvim-lua/plenary.nvim", + }, + keys = { + { "gg", "LazyGit", desc = "打开 LazyGit" }, + { "gf", "LazyGitCurrentFile", desc = "当前文件 Git 历史" }, + { "gc", "LazyGitConfig", desc = "LazyGit 配置" }, + }, + }, + -- 高级语法高亮 { "nvim-treesitter/nvim-treesitter", diff --git a/nvim/lua/plugins/lint.lua b/nvim/lua/plugins/lint.lua new file mode 100644 index 0000000..fee0d86 --- /dev/null +++ b/nvim/lua/plugins/lint.lua @@ -0,0 +1,78 @@ +-- lint.lua - 代码检查配置 +-- 使用 nvim-lint 替代 null-ls 的诊断功能 +-- 与 conform.nvim 配合:conform 负责格式化,lint 负责诊断 + +return { + { + "mfussenegger/nvim-lint", + event = { "BufReadPre", "BufNewFile" }, + config = function() + local lint = require("lint") + + -- 按文件类型配置 linter + lint.linters_by_ft = { + -- Python: 使用 ruff 替代 flake8/pylint + python = { "ruff" }, + + -- Lua + lua = { "luacheck" }, + + -- Go + go = { "golangcilint" }, + + -- JavaScript/TypeScript + javascript = { "eslint" }, + typescript = { "eslint" }, + javascriptreact = { "eslint" }, + typescriptreact = { "eslint" }, + + -- 通用 + markdown = { "markdownlint" }, + yaml = { "yamllint" }, + dockerfile = { "hadolint" }, + sh = { "shellcheck" }, + } + + -- 设置自动触发 + local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true }) + + -- 保存后检查 + vim.api.nvim_create_autocmd({ "BufWritePost" }, { + group = lint_augroup, + callback = function() + lint.try_lint() + end, + }) + + -- 进入缓冲区时检查 + vim.api.nvim_create_autocmd({ "BufEnter" }, { + group = lint_augroup, + callback = function() + lint.try_lint() + end, + }) + + -- 插入模式离开后检查(可选,可能较频繁) + vim.api.nvim_create_autocmd({ "InsertLeave" }, { + group = lint_augroup, + callback = function() + lint.try_lint() + end, + }) + + -- 创建用户命令 + vim.api.nvim_create_user_command("Lint", function() + lint.try_lint() + end, { desc = "手动触发代码检查" }) + + vim.api.nvim_create_user_command("LintInfo", function() + local running_linters = lint.get_running() + if #running_linters == 0 then + vim.notify("没有正在运行的 linter", vim.log.levels.INFO) + else + vim.notify("运行中的 linter: " .. table.concat(running_linters, ", "), vim.log.levels.INFO) + end + end, { desc = "显示运行中的 linter" }) + end, + }, +} diff --git a/nvim/lua/plugins/lua.lua b/nvim/lua/plugins/lua.lua index e69de29..62caefd 100644 --- a/nvim/lua/plugins/lua.lua +++ b/nvim/lua/plugins/lua.lua @@ -0,0 +1,5 @@ +-- lua.lua - Lua 开发配置 + +return { + -- Lua 语言支持(已由 neodev 在 coding.lua 中配置) +} diff --git a/nvim/lua/plugins/null-ls.lua b/nvim/lua/plugins/null-ls.lua index 859aec0..8d8d39d 100644 --- a/nvim/lua/plugins/null-ls.lua +++ b/nvim/lua/plugins/null-ls.lua @@ -13,7 +13,6 @@ return { -- Python null_ls.builtins.formatting.black, null_ls.builtins.formatting.isort, - null_ls.builtins.diagnostics.ruff, }, } end, diff --git a/nvim/lua/plugins/python.lua b/nvim/lua/plugins/python.lua index e6047b5..4104b67 100644 --- a/nvim/lua/plugins/python.lua +++ b/nvim/lua/plugins/python.lua @@ -41,39 +41,30 @@ return { dependencies = { "nvim-neotest/neotest-python", }, - opts = { - adapters = { - ["neotest-python"] = { - -- 使用项目根目录中的 pytest.ini - runner = "pytest", - -- 可以使用 pytest 或 unittest - -- runner = function() - -- if vim.fn.filereadable("pytest.ini") == 1 then - -- return "pytest" - -- else - -- return "unittest" - -- end - -- end, - - -- 额外的 pytest 参数 - args = { - "--color=yes", - "-v", - }, - - -- Python 测试发现模式 - python = function() - -- 如果激活了虚拟环境,使用它 - if vim.env.VIRTUAL_ENV then - return vim.env.VIRTUAL_ENV .. "/bin/python" - end - - -- 否则使用系统的 Python - return "python" - end, + opts = function(_, opts) + -- 确保 adapters 是列表 + opts.adapters = opts.adapters or {} + -- 添加 neotest-python 适配器 + table.insert(opts.adapters, require("neotest-python")({ + -- 使用项目根目录中的 pytest.ini + runner = "pytest", + -- 额外的 pytest 参数 + args = { + "--color=yes", + "-v", }, - }, - }, + -- Python 测试发现模式 + python = function() + -- 如果激活了虚拟环境,使用它 + if vim.env.VIRTUAL_ENV then + return vim.env.VIRTUAL_ENV .. "/bin/python" + end + -- 否则使用系统的 Python + return "python" + end, + })) + return opts + end, keys = { { "pt", "lua require('neotest').run.run()", desc = "运行最近的测试" }, { "pT", "lua require('neotest').run.run(vim.fn.expand('%'))", desc = "运行文件中的测试" }, @@ -112,13 +103,27 @@ return { dependencies = { "mfussenegger/nvim-dap-python", }, - opts = function() - local path = require("mason-registry").get_package("debugpy"):get_install_path() - require("dap-python").setup(path .. "/venv/bin/python") - + config = function() + local ok, mason_registry = pcall(require, "mason-registry") + local debugpy_path = nil + if ok then + local ok2, debugpy_pkg = pcall(mason_registry.get_package, "debugpy") + if ok2 and debugpy_pkg then + local ok3, path = pcall(debugpy_pkg.get_install_path, debugpy_pkg) + if ok3 then + debugpy_path = path .. "/venv/bin/python" + end + end + end + -- 如果无法通过 mason 获取路径,使用默认路径 + if not debugpy_path then + debugpy_path = vim.fn.exepath("python3") or "python3" + end + require("dap-python").setup(debugpy_path) + -- 设置 pytest 调试 require("dap-python").test_runner = "pytest" - + -- 添加自定义配置 table.insert(require("dap").configurations.python, { type = "python", @@ -131,7 +136,7 @@ return { end, console = "integratedTerminal", }) - + -- 添加 FastAPI 配置 table.insert(require("dap").configurations.python, { type = "python", diff --git a/nvim/lua/plugins/snacks.lua b/nvim/lua/plugins/snacks.lua index fcfd409..78018e2 100644 --- a/nvim/lua/plugins/snacks.lua +++ b/nvim/lua/plugins/snacks.lua @@ -1 +1,68 @@ -return {"folke/snacks.nvim", opts={}} \ No newline at end of file +-- snacks.lua - folke's modern utility library +-- Provides: notifications, bigfile handling, quickfile, statuscolumn, word highlighting + +return { + { + "folke/snacks.nvim", + priority = 1000, + lazy = false, + opts = { + -- Bigfile optimization + bigfile = { + enabled = true, + notify = true, + line_length = 1000, + }, + + -- Notifications (replaces nvim-notify) + notifier = { + enabled = true, + timeout = 3000, + history = true, + render = "compact", + level = vim.log.levels.INFO, + }, + + -- Quick file navigation + quickfile = { + enabled = true, + exclude = { "gitcommit", "gitrebase" }, + }, + + -- Enhanced statuscolumn + statuscolumn = { + enabled = true, + left = { "mark", "sign" }, + right = { "fold", "git" }, + folds = { + open = true, + git_hl = false, + }, + }, + + -- Word highlighting and jumping + words = { + enabled = true, + debounce = 100, + notify_end = false, + jumplist = true, + mappings = { + ["]w"] = "next", + ["[w"] = "prev", + }, + }, + }, + keys = { + { "un", function() Snacks.notifier.hide() end, desc = "Dismiss All Notifications" }, + { "q", function() Snacks.quickfile() end, desc = "Quick File" }, + { "]w", function() Snacks.words.jump() end, desc = "Next Word Reference" }, + { "[w", function() Snacks.words.jump(-1) end, desc = "Prev Word Reference" }, + }, + init = function() + -- Override vim.notify + vim.notify = function(msg, level, opts) + Snacks.notifier.notify(msg, level, opts) + end + end, + }, +} diff --git a/nvim/lua/plugins/which-key.lua b/nvim/lua/plugins/which-key.lua index 40ce64f..e547ed8 100644 --- a/nvim/lua/plugins/which-key.lua +++ b/nvim/lua/plugins/which-key.lua @@ -1 +1,158 @@ -return {"folke/which-key.nvim", opts={}} \ No newline at end of file +return { + "folke/which-key.nvim", + event = "VeryLazy", + opts = { + -- 基础配置 + preset = "helix", -- 使用 helix 预设,更现代的样式 + + -- 延迟配置 + delay = 500, -- 显示 which-key 的延迟时间(毫秒) + + -- 过滤配置 + filter = function(mapping) + -- 只显示有描述的映射 + return mapping.desc and mapping.desc ~= "" + end, + + -- 触发配置 + triggers = { + { "", mode = "nxso" }, + }, + + -- 窗口配置 + win = { + no_overlap = true, + padding = { 1, 2 }, -- 上下, 左右 + title = true, + title_pos = "center", + zindex = 1000, + bo = {}, + wo = { + winblend = 10, + }, + }, + + -- 布局配置 + layout = { + width = { min = 20 }, -- 最小宽度 + spacing = 3, -- 列间距 + align = "left", -- 对齐方式 + }, + + -- 图标配置 + icons = { + breadcrumb = "»", -- 面包屑符号 + separator = "➜", -- 分隔符 + group = "+", -- 分组符号 + ellipsis = "…", + keys = { + Space = "", + Tab = "", + Return = "", + Escape = "", + Backspace = "", + Delete = "", + Insert = "", + Home = "", + End = "", + PageUp = "", + PageDown = "", + ScrollLock = "", + NumLock = "", + CapsLock = "", + Left = "", + Right = "", + Up = "", + Down = "", + F1 = "", + F2 = "", + F3 = "", + F4 = "", + F5 = "", + F6 = "", + F7 = "", + F8 = "", + F9 = "", + F10 = "", + F11 = "", + F12 = "", + Plug = "", + Action = "", + Alt = "%(?(.*)%)?", "%1" }, + { "^[cgls]%[?(.*)%]?$", "%1" }, + { "^ lua%.patterns%.(.+)$", "Pattern: %1" }, + { "^ lua%.snippets%.(.+)$", "Snippet: %1" }, + { "^ which%-key%.(.+)$", "WK: %1" }, + { "^.*%.(.+)$", "%1" }, + }, + }, + + -- 通知配置 + notify = true, + + -- 调试配置 + debug = false, + + -- 自动注册键组 + spec = {}, + }, + config = function(_, opts) + local wk = require("which-key") + wk.setup(opts) + + -- 注册键组 + wk.add({ + -- 文件操作 + { "f", group = "文件/查找", icon = { icon = "📁", color = "blue" } }, + + -- Git 操作 + { "g", group = "Git", icon = { icon = "🌿", color = "green" } }, + + -- LSP/Code 操作 + { "c", group = "代码/LSP", icon = { icon = "💻", color = "cyan" } }, + + -- 诊断 + { "x", group = "诊断", icon = { icon = "🚨", color = "red" } }, + + -- 搜索 + { "s", group = "搜索", icon = { icon = "🔍", color = "yellow" } }, + + -- 终端 + { "t", group = "终端", icon = { icon = "🖥️", color = "magenta" } }, + + -- 缓冲区 + { "b", group = "缓冲区", icon = { icon = "📋", color = "blue" } }, + + -- 通知 + { "u", group = "UI/通知", icon = { icon = "🎨", color = "purple" } }, + + -- AI 助手 + { "a", group = "AI 助手", icon = { icon = "🤖", color = "cyan" } }, + + -- Python + { "p", group = "Python", icon = { icon = "🐍", color = "green" } }, + + -- 会话 + { "q", group = "会话/退出", icon = { icon = "🚪", color = "red" } }, + + -- 窗口 + { "w", group = "窗口", icon = { icon = "🪟", color = "blue" } }, + }) + end, +} diff --git a/nvim/stylua.toml b/nvim/stylua.toml deleted file mode 100644 index 5d6c50d..0000000 --- a/nvim/stylua.toml +++ /dev/null @@ -1,3 +0,0 @@ -indent_type = "Spaces" -indent_width = 2 -column_width = 120 \ No newline at end of file