├── .gitignore ├── images ├── screenshot.png └── screenshot_plugins.png ├── ultisnippets ├── xml.snippets ├── go.snippets └── php.snippets ├── LICENSE ├── README.md ├── vimrc.vim └── init.lua /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caixw/VimIDE/HEAD/images/screenshot.png -------------------------------------------------------------------------------- /images/screenshot_plugins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caixw/VimIDE/HEAD/images/screenshot_plugins.png -------------------------------------------------------------------------------- /ultisnippets/xml.snippets: -------------------------------------------------------------------------------- 1 | priority -50 2 | 3 | snippet xml "XML declaration" b 4 | 5 | 6 | endsnippet 7 | 8 | snippet t "Simple tag" b 9 | <${1:tag}> 10 | ${2:content} 11 | 12 | endsnippet 13 | 14 | snippet ti "Inline tag" b 15 | <${1:tag}>${2:content} 16 | endsnippet 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 caixw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | VimIDE 2 | ====== 3 | 4 | 自用的一个 vim 配置文件,适用于`Go`与`PHP`语言环境。 5 | 6 | 适用版本:macOS 下 vim9 或是对应版本的 macvim,其它系统未测试。 7 | 8 | ![screenshot](https://raw.github.com/caixw/VimIDE/master/images/screenshot.png) 9 | 10 | 11 | ### 快捷键 12 | 13 | 自定义的快捷键: 14 | 15 | 快捷键 | 对应操作 16 | ------------- | :--------- 17 | `` | 打开类/函数视图(tagbar) 18 | `` | 打开文件浏览窗口(NERDTree) 19 | 20 | 21 | ### 依赖的软件 22 | 23 | 24 | #### git、mercurial 25 | 26 | - vim-fugitive:依赖 git 才起作用; 27 | - vim-go:中的`:GoInstallBinaries`命令依赖`go get`,而`go get`依赖 git 和 mercurial; 28 | 29 | 30 | #### python 31 | 32 | UltiSnips 依赖 Python2 或是 Python3,若 vim 编译时是以 python/dyn 形式编译的, 33 | 则需要另外安装 python。windows 安装 Python3,一直提示各种错误,但是 python2.7 可以。 34 | 35 | 36 | #### ctags 37 | 38 | majutsushi/tagbar 插件依赖 ctags 来解析。可以从以下地址下载: 39 | [ctags](https://ctags.io/) 40 | 41 | 42 | #### powerline-fonts 43 | 44 | airline 需要使用到这些字体,用于美化状态栏。 45 | 46 | linux/macOS: 47 | 48 | ```shell 49 | cd ~ 50 | git clone github.com:powerline/fonts 51 | cd fonts 52 | ./install.sh 53 | ``` 54 | 55 | windows 下,则直接将[powerline-fonts](https://github.com/Lokaltog/powerline-fonts)下的字体依次安装下即可。 56 | 57 | 安装完之后,在配置文件(vimrc.vim)中的到以下变量,将其值设置为 1,才能起作用: 58 | 59 | ```vim 60 | let g:airline_powerline_fonts = 1 61 | ``` 62 | 63 | 64 | ### 安装 65 | 66 | 先安装好插件管理工具 plug,然后然将 vimrc.vim 复制到 ~/.vimrc 下。再执行 `:PlugInstall` 即可。 67 | 68 | ```url 69 | https://github.com/junegunn/vim-plug 70 | ``` 71 | 72 | 73 | ### 插件 74 | 75 | 插件具体功能可直接参考 vimrc.vim 中的说明,部分插件示意图: 76 | ![screenshot-plugins](https://raw.github.com/caixw/VimIDE/master/images/screenshot_plugins.png) 77 | 78 | 79 | ### 版权 80 | 81 | 本项目采用 [MIT](https://opensource.org/licenses/MIT) 开源授权许可证,完整的授权说明可在 [LICENSE](LICENSE) 文件中找到。 82 | -------------------------------------------------------------------------------- /ultisnippets/go.snippets: -------------------------------------------------------------------------------- 1 | # Snippets for Go 2 | 3 | priority -50 4 | 5 | # when to abbriviate and when not? 6 | # b doesn't work here, because it ignores whitespace 7 | # optional local name? 8 | snippet /^im/ "Import declaration" r 9 | import ( 10 | "${1:package}" 11 | ) 12 | endsnippet 13 | 14 | 15 | snippet fh "文件头" b 16 | // Copyright `!v strftime("%Y")` by caixw, All rights reserved. 17 | // Use of this source code is governed by a MIT 18 | // license that can be found in the LICENSE file. 19 | 20 | package ${1:main} 21 | endsnippet 22 | 23 | # Mostly converted from: https://github.com/AlanQuatermain/go-tmbundle 24 | snippet /^cons/ "Constants declaration" r 25 | const ( 26 | ${1:constant}${2/(.+)/ /}${2:type} = ${0:value} 27 | ) 28 | endsnippet 29 | 30 | snippet /^con/ "Constant declaration" r 31 | const ${1:name}${2/(.+)/ /}${2:type} = ${0:value} 32 | endsnippet 33 | 34 | snippet iota "Iota constant generator" b 35 | const ( 36 | ${1:constant}${2/(.+)/ /}${2:type} = iota 37 | ) 38 | endsnippet 39 | 40 | snippet st "Struct declaration" b 41 | type ${1:Struct} struct { 42 | ${0:${VISUAL}} 43 | } 44 | endsnippet 45 | 46 | snippet inf "Interface declaration" b 47 | type ${1:Interface} interface { 48 | ${0:${VISUAL}} 49 | } 50 | endsnippet 51 | 52 | # statements 53 | snippet f "For loop" b 54 | for ${1:condition}${1/(.+)/ /}{ 55 | ${0:${VISUAL}} 56 | } 57 | endsnippet 58 | 59 | snippet fi "Integer for loop" b 60 | for ${1:i} := 0; $1 < ${2:N}; $1++ { 61 | ${0:${VISUAL}} 62 | } 63 | endsnippet 64 | 65 | snippet fr "For range loop" b 66 | for ${1:k}, ${2:v} := range ${3:collection} { 67 | ${0:${VISUAL}} 68 | } 69 | endsnippet 70 | 71 | snippet if "If statement" b 72 | if ${1:condition}${1/(.+)/ /}{ 73 | ${0:${VISUAL}} 74 | } 75 | endsnippet 76 | 77 | snippet ierr "If err != nil" b 78 | if err ${1:!=} nil { 79 | return ${2:err} 80 | } 81 | endsnippet 82 | 83 | snippet sw "Switch statement" b 84 | switch ${1:expression}${1/(.+)/ /}{ 85 | case ${0} 86 | } 87 | endsnippet 88 | 89 | snippet sel "Select statement" b 90 | select { 91 | case${0} 92 | } 93 | endsnippet 94 | 95 | snippet case "Case clause" b 96 | case ${1:condition}: 97 | ${0:${VISUAL}} 98 | endsnippet 99 | 100 | snippet def "Default clause" b 101 | default: 102 | ${0:${VISUAL}} 103 | endsnippet 104 | 105 | snippet in "Interface{}" b 106 | interface{} 107 | endsnippet 108 | 109 | # functions 110 | snippet /^main/ "Main function" r 111 | func main() { 112 | ${0:${VISUAL}} 113 | } 114 | endsnippet 115 | 116 | snippet /^fuh/ "handler func" r 117 | func ${1:name}(w http.ResponseWriter, r* http.Request) { 118 | ${0:${VISUAL}} 119 | } 120 | endsnippet 121 | 122 | snippet /^fum/ "Method" r 123 | func (${1:receiver} ${2:type}) ${3:name}(${4:params})${5/(.+)/ /}${5:error} { 124 | ${0:${VISUAL}} 125 | } 126 | endsnippet 127 | 128 | snippet fun "Function" b 129 | func ${1:name}(${2:params})${3/(.+)/ /}${3:error} { 130 | ${0:${VISUAL}} 131 | } 132 | endsnippet 133 | 134 | snippet fut "testing function" b 135 | func Test${1:1}(t *testing.T) { 136 | a := assert.New(t) 137 | 138 | ${0:${VISUAL}} 139 | } 140 | endsnippet 141 | 142 | snippet fub "benchmark function" b 143 | func Benchmark${1:1}(b *testing.B) { 144 | for i := 0; i < b.N; i++ { 145 | ${2://TODO} 146 | } 147 | } 148 | endsnippet 149 | 150 | snippet fui "interface function" b 151 | ${1:funName}(${2:params})${3:error} 152 | endsnippet 153 | 154 | # types and variables 155 | snippet map "Map type" b 156 | map[${1:string}]${2:valtype} 157 | endsnippet 158 | 159 | snippet : "Variable declaration :=" b 160 | ${1:name} := ${0:value} 161 | endsnippet 162 | 163 | snippet var "Variable declaration" b 164 | var ${1:name}${2/(.+)/ /}${2:type}${3: = ${0:value}} 165 | endsnippet 166 | 167 | snippet vars "Variables declaration" b 168 | var ( 169 | ${1:name}${2/(.+)/ /}${2:type}${3: = ${0:value} } 170 | ) 171 | endsnippet 172 | 173 | snippet json "JSON field" 174 | \`json:"${1:displayName}"\` 175 | endsnippet 176 | 177 | # vim:ft=snippets: 178 | -------------------------------------------------------------------------------- /ultisnippets/php.snippets: -------------------------------------------------------------------------------- 1 | priority -50 2 | 3 | ## Snippets from SnipMate, taken from 4 | ## https://github.com/scrooloose/snipmate-snippets.git 5 | 6 | snippet fh "文件头" 7 | 11 | * @copyright ${2:caixw} 12 | * @package ${3:package} 13 | * @subpackage ${4:subpackage} 14 | */ 15 | endsnippet 16 | 17 | snippet ? "" 23 | 24 | endsnippet 25 | 26 | snippet ?f "" 27 | ${3:val}):?> 28 | ${0} 29 | 30 | endsnippet 31 | 32 | snippet ?i "" 33 | 34 | ${0} 35 | 36 | endsnippet 37 | 38 | snippet arr "array" 39 | $${1:arrayName} = array('${2}' => ${3});${4} 40 | endsnippet 41 | 42 | snippet def "define" 43 | define('${1}'${2});${3} 44 | endsnippet 45 | 46 | snippet do "do" 47 | do { 48 | ${2:// code... } 49 | } while (${1:/* condition */}); 50 | endsnippet 51 | 52 | snippet doci "doc_i" 53 | interface ${1:someClass} { 54 | ${4} 55 | } // END interface $1" 56 | endsnippet 57 | 58 | snippet else "else" 59 | else { 60 | ${1:// code...} 61 | } 62 | endsnippet 63 | 64 | snippet for "for" 65 | for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) { 66 | ${4:// code...} 67 | } 68 | endsnippet 69 | 70 | snippet foreachk "foreachk" 71 | foreach ($${1:variable} as $${2:key} => $${3:value}){ 72 | ${4:// code...} 73 | } 74 | endsnippet 75 | 76 | snippet get "get" 77 | $_GET['${1}']${2} 78 | endsnippet 79 | 80 | snippet if "if" 81 | if (${1:/* condition */}) { 82 | ${2:// code...} 83 | } 84 | endsnippet 85 | 86 | snippet elif "elseif" 87 | elseif (${1:/* condition */}) { 88 | ${2:// code...} 89 | } 90 | endsnippet 91 | 92 | snippet inc "inc" 93 | include '${1:file}';${2} 94 | endsnippet 95 | 96 | snippet log "log" 97 | error_log(var_export(${1}, true));${2} 98 | endsnippet 99 | 100 | snippet P "post" 101 | $_POST['${1}']${2} 102 | endsnippet 103 | 104 | snippet req1 "req1" 105 | require_once '${1:file}';${2} 106 | endsnippet 107 | 108 | snippet S "session" 109 | $_SESSION['${1}']${2} 110 | endsnippet 111 | 112 | snippet C "cookie" 113 | $_COOKIE['${1}']${2} 114 | endsnippet 115 | 116 | snippet t "t" 117 | $${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};${5} 118 | endsnippet 119 | 120 | snippet var "var" 121 | var_export(${1});${2} 122 | endsnippet 123 | 124 | snippet getter "PHP Class Getter" b 125 | /* 126 | * Getter for $1 127 | */ 128 | public function get${1/\w+\s*/\u$0/}() { 129 | return $this->$1;$2 130 | } 131 | $4 132 | endsnippet 133 | 134 | snippet setter "PHP Class Setter" b 135 | /* 136 | * Setter for $1 137 | */ 138 | public function set${1/\w+\s*/\u$0/}($$1) { 139 | $this->$1 = $$1;$3 140 | ${4:return $this;} 141 | } 142 | $0 143 | endsnippet 144 | 145 | snippet gs "PHP Class Getter Setter" b 146 | /* 147 | * Getter for $1 148 | */ 149 | public function get${1/\w+\s*/\u$0/}() { 150 | return $this->$1;$2 151 | } 152 | 153 | /* 154 | * Setter for $1 155 | */ 156 | public function set${1/\w+\s*/\u$0/}($$1) { 157 | $this->$1 = $$1;$3 158 | ${4:return $this;} 159 | } 160 | $0 161 | endsnippet 162 | 163 | snippet pub "Public function" b 164 | public function ${1:name}(${2:$param}) { 165 | ${VISUAL}${5:return null;} 166 | } 167 | $0 168 | endsnippet 169 | 170 | snippet pro "Protected function" b 171 | /** 172 | * ${3:undocumented function} 173 | * 174 | * @return ${4:void} 175 | */ 176 | protected function ${1:name}(${2:$param}) { 177 | ${VISUAL}${5:return null;} 178 | } 179 | $0 180 | endsnippet 181 | 182 | snippet pri "Private function" b 183 | private function ${1:name}(${2:$param}) { 184 | ${VISUAL}${5:return null;} 185 | } 186 | $0 187 | endsnippet 188 | 189 | snippet pubs "Public static function" b 190 | public static function ${1:name}(${2:$param}) { 191 | ${VISUAL}${5:return null;} 192 | } 193 | $0 194 | endsnippet 195 | 196 | snippet pros "Protected static function" b 197 | protected static function ${1:name}(${2:$param}) { 198 | ${VISUAL}${5:return null;} 199 | } 200 | $0 201 | endsnippet 202 | 203 | snippet pris "Private static function" b 204 | private static function ${1:name}(${2:$param}) { 205 | ${VISUAL}${5:return null;} 206 | } 207 | $0 208 | endsnippet 209 | 210 | snippet fun "Function snip" b 211 | function ${1:name}(${2:$param}) { 212 | ${VISUAL}${3:return null;} 213 | } 214 | $0 215 | endsnippet 216 | 217 | snippet fore "Foreach loop" 218 | foreach ($${1:variable} as $${3:value}) { 219 | ${VISUAL}${4} 220 | } 221 | $0 222 | endsnippet 223 | 224 | snippet new "New class instance" b 225 | $$1 = new $1($2); 226 | $0 227 | endsnippet 228 | 229 | snippet ife "if else" 230 | if (${1:/* condition */}) { 231 | ${2:// code...} 232 | } else { 233 | ${3:// code...} 234 | } 235 | $0 236 | endsnippet 237 | 238 | snippet cls "Class declaration template" b 239 | /** 240 | * $2 241 | */ 242 | $1class ${2:clsName} { 243 | public function ${4:__construct}(${5:$options}) { 244 | ${6:// code} 245 | } 246 | } 247 | $0 248 | endsnippet 249 | 250 | snippet construct "__construct()" b 251 | /** 252 | * @param $2mixed ${1/, /\n * \@param mixed /g} 253 | */ 254 | public function __construct(${1:$dependencies}) { 255 | ${1/\$(\w+)(, )*/\n $this->$1 = $$1;/g} 256 | } 257 | $0 258 | endsnippet 259 | 260 | snippet pc "Dumb debug helper in cli" 261 | var_export($1);$0 262 | endsnippet 263 | 264 | # :vim:ft=snippets: 265 | -------------------------------------------------------------------------------- /vimrc.vim: -------------------------------------------------------------------------------- 1 | vim9script 2 | 3 | # ============================================================================= 4 | # 自用的 vim 配置文件。适用以下版本: 5 | # macvim >= 9.0 6 | # 7 | # Author: caixw 8 | # Version: 0.6.20230908 9 | # Licence: MIT 10 | # ============================================================================= 11 | 12 | set nocompatible # 设置不兼容 VI 模式,在增强模式下运行。 13 | set nobackup # 覆盖文件时不备份 14 | 15 | 16 | # set noswapfile # 不启用交换文件 17 | set fileformats=unix,dos # 保存文件格式 18 | set fileencodings=ucs-bom,utf-8,cp936,gb2312,gb18030,gbk # 读文件时,使用的编码。前 2 个顺序不能错 19 | set fileencoding=utf-8 # 保存时,使用的编码 20 | set encoding=utf-8 # 程序使用的编码 21 | set termencoding=utf-8 # 终端上使用的编码 22 | set history=500 # 记录历史行数 23 | set autochdir # 自动切换目录 24 | # set noignorecase # 默认不区分大小写 25 | 26 | 27 | 28 | $LANG = 'zh_CN.UTF-8' 29 | set langmenu=zh_CN.utf-8 # 菜单语言,必须要在 set encoding 之后,界面加载之前 30 | set mousehide # 自动隐藏鼠标 31 | set mousemodel=popup # 右键点击时,弹出菜单 32 | set guioptions-=m # 不显示菜单栏 33 | set guioptions-=T # 不显示工具栏 34 | set guioptions+=r # r 代表 right,就是在右侧显示滚动条 35 | set guioptions-=b # b 代表 bottom,就是不在下面加入滚动条 36 | set lines=60 # 高度 37 | set columns=220 # 宽度 38 | set scrolloff=3 # 设定光标离窗口上下边界 3 行时窗口自动滚动 39 | set cursorline # 高亮显示当前行 40 | set cursorcolumn #$ 高亮显示当前列 41 | set nu # 显示行号 42 | set hlsearch # 搜索时高亮关键字 43 | # set incsearch # 搜索时逐字高亮 44 | set wildmenu # 命令行按 tab 补全时,显示一个候选菜单 45 | set showmatch # 高亮显示匹配的符号,大括号什么的 46 | set ruler # 右下角显示光标状态的行 47 | set showmode # 左下角显示当前的模式 48 | set showcmd # 显示当前输入的命令 49 | 50 | # 弹出框样式,比如自动补全的下拉框。 51 | highlight Pmenu guibg=darkgrey guifg=black 52 | highlight PmenuSel guibg=lightgrey guifg=black 53 | 54 | # 设置 browse 命令打开的目录,current 当前,buffer 当前 buffer 相同,last 上次的目录 55 | set browsedir=last 56 | 57 | set foldenable # 可折叠 foldenable/nofoldenable 58 | 59 | # manual 手动折叠 60 | # indent 使用缩进表示折叠 61 | # expr 使用表达式定义折叠 62 | # syntax 使用语法定义折叠 63 | # diff 对没有更改的内容进行折叠 64 | # marker 使用标记款待折叠,默认标记为{{{和}}} 65 | set foldmethod=syntax 66 | setlocal foldlevel=1 67 | set foldlevelstart=99 # 默认不折叠 68 | 69 | # 按空格折叠代码 70 | nnoremap @=((foldclosed(line('.')) < 0) ? 'zc' : 'zo') 71 | 72 | 73 | set autoindent 74 | set smartindent 75 | set cindent 76 | # set expandtab # 使用空格代替 tab. 77 | set backspace=indent,eol,start 78 | set tabstop=4 79 | set softtabstop=4 80 | set shiftwidth=4 81 | # 显示一些不显示的空白字符 82 | # 通过 set list 和 set nolist 控制是否显示或是用 set list! 切换显示 83 | set listchars=tab:>-,eol:$,trail:- 84 | 85 | 86 | 87 | if has("gui_running") 88 | if has("gui_gtk2") 89 | set guifont=Monofur\ Nerd\ Font\ Mono:h15 90 | # 比英文字体大一点,这样汉字的间距就不会太大了 91 | # set guifontwide=Droid\ Sans\ 13 92 | elseif has("gui_kde") 93 | # set guifont=Courier\ New/11/-1/5/50/0/0/0/1/0 94 | elseif has("x11") 95 | # set guifont=-*-courier-medium-r-normal-*-*-180-*-*-m-*-* 96 | elseif has("gui_macvim") 97 | set guifont=Monofur\ Nerd\ Font\ Mono:h15 98 | # set guifontwide=PingFang:h15 99 | elseif has("gui_kde") 100 | # todo 101 | elseif has("gui_win32") 102 | set guifont=Monofur\ Nerd\ Font\ Mono:h15 103 | # set guifontwide=Microsoft\ YaHei\ UI:h12 104 | else 105 | # set guifont=YaHei\ Consolas\ Hybrid:h10 106 | endif 107 | endif 108 | 109 | # ============================================================================== 110 | # ========================== 开始加载插件 111 | # ============================================================================== 112 | 113 | filetype off 114 | 115 | call plug#begin('~/.vim/plugged') 116 | 117 | # lsp 服务以及自动完成功能 118 | Plug 'prabirshrestha/async.vim' 119 | Plug 'prabirshrestha/vim-lsp' 120 | Plug 'mattn/vim-lsp-settings' 121 | Plug 'prabirshrestha/asyncomplete.vim' 122 | Plug 'prabirshrestha/asyncomplete-lsp.vim' 123 | Plug 'ryanolsonx/vim-lsp-typescript' 124 | 125 | 126 | # 侧边树状文件夹浏览 127 | Plug 'scrooloose/nerdtree' 128 | 129 | # 侧边栏显示相关函数定义等,可能依赖 https://ctags.io/ 130 | Plug 'majutsushi/tagbar' 131 | 132 | # 代码片段,需要 Python 支持 133 | Plug 'SirVer/ultisnips' 134 | Plug 'thomasfaingnaert/vim-lsp-snippets' 135 | Plug 'thomasfaingnaert/vim-lsp-ultisnips' 136 | 137 | # 多光标支持 138 | Plug 'terryma/vim-multiple-cursors' 139 | 140 | # 缩进高亮,显示一条竖线 141 | Plug 'Yggdroot/indentLine' 142 | 143 | # 快速注释 144 | Plug 'scrooloose/nerdcommenter' 145 | 146 | # 显示 git 的更改内容 147 | Plug 'airblade/vim-gitgutter' 148 | 149 | # 对 EditorConfig 的支持 150 | Plug 'editorconfig/editorconfig-vim' 151 | 152 | # airline 状态栏美化。 153 | Plug 'vim-airline/vim-airline' 154 | Plug 'vim-airline/vim-airline-themes' 155 | 156 | # 一些好用的主题 157 | Plug 'tomasr/molokai' 158 | Plug 'Haron-Prime/evening_vim' 159 | Plug 'vim-scripts/desertEx' 160 | Plug 'lifepillar/vim-solarized8' 161 | 162 | # 启动页面 163 | Plug 'mhinz/vim-startify' 164 | 165 | # 中文文档 166 | Plug 'asins/vimcdoc' 167 | 168 | call plug#end() 169 | 170 | filetype plugin indent on 171 | 172 | syntax enable 173 | syntax on 174 | 175 | # ============================================================================== 176 | # ======================== 开始插件配置 177 | # ============================================================================== 178 | 179 | # LSP 的快捷键设置 180 | 181 | def On_lsp_buffer_enabled() 182 | setlocal omnifunc=lsp#complete 183 | setlocal signcolumn=yes 184 | if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif 185 | 186 | nmap gd (lsp-definition) 187 | nmap (lsp-hover) 188 | nmap (lsp-next-diagnostic) 189 | enddef 190 | 191 | augroup lsp_install 192 | au! 193 | # call On_lsp_buffer_enabled only for languages that has the server registered. 194 | autocmd User lsp_buffer_enabled call On_lsp_buffer_enabled() 195 | augroup END 196 | 197 | g:lsp_format_sync_timeout = 1000 198 | autocmd! BufWritePre *.go call execute('LspDocumentFormatSync') | call execute('LspCodeActionSync source.organizeImports') 199 | 200 | 201 | # NERDTree 202 | g:NERDTreeHighlightCursorline = 1 203 | g:NERDTreeIgnore = ['.\.obj$', '.\.o$', '.\.so$', '.\.exe$', '.\.git$', '.\.swp$'] 204 | g:NERDTreeWinSize = 35 205 | g:NERDTreeChDirMode = 2 206 | g:NERDChristmasTree = 1 207 | map :NERDTreeToggle 208 | 209 | # 在 NERDTree 窗口中禁用 BD 命令。 210 | autocmd FileType nerdtree cnoreabbrev bd 211 | 212 | # 当关闭得只剩下 NERDTree 一个窗口时,自动关闭 vim 213 | def CloseIfOnlyNerdTreeLeft() 214 | if exists("t:NERDTreeBufName") 215 | if bufwinnr(t:NERDTreeBufName) != -1 216 | if winnr("$") == 1 217 | q 218 | endif 219 | endif 220 | endif 221 | enddef 222 | autocmd WinEnter * call CloseIfOnlyNerdTreeLeft() 223 | 224 | 225 | # tagbar 226 | nmap :TagbarToggle 227 | g:tagbar_width = 40 228 | g:tagbar_type_go = { 229 | \ 'ctagstype': 'go', 230 | \ 'kinds': [ 231 | \ 'p:包', 232 | \ 'i:引用包:1', 233 | \ 'c:常量', 234 | \ 'v:变量', 235 | \ 't:类型', 236 | \ 'n:接口', 237 | \ 'w:字段', 238 | \ 'e:嵌入对象', 239 | \ 'm:方法', 240 | \ 'r:构建函数', 241 | \ 'f:函数' 242 | \ ], 243 | \ 'sro': '.', 244 | \ 'kind2scope': { 245 | \ 't': 'ctype', 246 | \ 'n': 'ntype' 247 | \ }, 248 | \ 'scope2kind': { 249 | \ 'ctype': 't', 250 | \ 'ntype': 'n' 251 | \ }, 252 | \ 'ctagsargs': '-sort -silent' 253 | \ } 254 | 255 | 256 | g:asyncomplete_auto_popup = 1 257 | 258 | 259 | # UltiSnips 260 | g:UltiSnipsExpandTrigger = "" 261 | g:UltiSnipsJumpForwardTrigger = "" 262 | g:UltiSnipsJumpBackwardTrigger = "" 263 | g:UltiSnipsSnippetDirectories = ["ultisnippets"] 264 | 265 | 266 | # editorConfig 267 | g:EditorConfig_exclude_patterns = ['fugitive://.*', 'scp://.*'] 268 | 269 | 270 | # ariline 271 | # 使用 powerline 的箭头,需要安装 powerline 字体,在未安装 powerline 字体的情况下, 272 | # 可以将此值设置为 0,这将使用之后的这些默认的符号替换。 273 | g:airline_powerline_fonts = 1 274 | 275 | g:airline_mode_map = { 276 | \ '__': '-', 277 | \ 'n': '标准', 278 | \ 'i': '插入', 279 | \ 'R': '替换', 280 | \ 'c': '命令行', 281 | \ 'v': '可视', 282 | \ 'V': '可视', 283 | \ '': '可视', 284 | \ 's': '选择', 285 | \ 'S': '选择', 286 | \ '': '选择', 287 | \ } 288 | 289 | set laststatus=2 290 | 291 | # airline-tabline 扩展设计,若需要更专业的 buffer 列表显示插件, 292 | # 可以使用 techlivezheng/vim-plugin-minibufexpl 插件! 293 | g:airline#extensions#tabline#enabled = 1 294 | g:airline#extensions#tabline#buffer_nr_show = 1 295 | g:airline#extensions#tabline#fnamemod = ':p:t' # 只显示文件名,不显示路径内容。 296 | 297 | 298 | # 启动画面 299 | g:startify_custom_header = [ 300 | \ ' __ ___ _ _______ _________ ', 301 | \ ' \ \ / (_) | | | |____ \ | |_______|', 302 | \ ' \ \ / / _ _ __ ___ | | | | | \ | |_______ ', 303 | \ ' \ \/ / | | `_ ` _ \ | | | | | | | |_______|', 304 | \ ' \ / | | | | | | | | | | |____| | | |_______ ', 305 | \ ' \/ |_|_| |_| |_| |_| |_|_____/ |_|_______|', 306 | \ '', 307 | \ ' https://github.com/caixw/VimIDE', 308 | \ '', 309 | \ ] 310 | g:startify_custom_footer = [ 311 | \ '', 312 | \ '', 313 | \ ' 适用于 Go 语言开发,由 caixw 整理发布!', 314 | \ ] 315 | 316 | 317 | # 中文在斜体显示时,会比较怪异,统一去掉 318 | g:solarized_italics = 0 319 | 320 | 321 | # 帮助语言为中文 322 | set helplang=cn 323 | 324 | colors solarized8 325 | set background=dark 326 | 327 | # 自动开启语法高亮 328 | syn on 329 | 330 | 331 | # 去除 linux 下菜单(包含右键菜单)乱码,放最后。 332 | source $VIMRUNTIME/delmenu.vim 333 | source $VIMRUNTIME/menu.vim 334 | 335 | -------------------------------------------------------------------------------- /init.lua: -------------------------------------------------------------------------------- 1 | --------------------------------------------------- 2 | -- NeoVIM 配置 3 | -- 4 | -- Author: caixw 5 | -- Version: 0.8.0.20250401 6 | -- Licence: MIT 7 | -- 8 | -- NOTE: macOS 终端下部分快捷键可能会不可用。 9 | --------------------------------------------------- 10 | 11 | vim.g.encoding = "utf-8" 12 | vim.o.syntax = "enable" 13 | vim.o.autochdir = true -- 自动切换目录 14 | vim.o.fileformats = unix 15 | vim.o.laststatus = 3 -- 全局状态栏 16 | 17 | vim.o.showmatch = true 18 | vim.o.showmode = true -- 左下角显示当前的模式 19 | vim.o.showcmd = true -- 显示当前输入的命令 20 | vim.o.mousemodel = popup -- 右键点击时,弹出菜单 21 | vim.o.mouse = 'a' 22 | vim.o.clipboard = 'unnamedplus' -- use system clipboard 23 | 24 | -- vim.o.relativenumber = true -- 显示相对行号 25 | vim.o.number = true -- 显示行号 26 | vim.o.cursorline = true -- 高亮所在行 27 | vim.o.wrap = true -- 自动换行 28 | vim.o.ruler = true -- 显示光标位置 29 | 30 | -- 搜索 31 | vim.o.incsearch = true -- 边输入边搜索 32 | vim.o.hlsearch = true -- 开启搜索匹配高亮 33 | vim.o.smartcase = true -- 搜索时自行判断是否需要忽略大小写 34 | 35 | -- tab 相关设置 36 | vim.o.tabstop = 4 37 | vim.o.softtabstop = 4 38 | vim.o.expandtab = false 39 | vim.bo.expandtab = false 40 | vim.o.shiftwidth = 4 41 | vim.bo.shiftwidth = 4 42 | vim.o.autoindent = true 43 | vim.bo.autoindent = true 44 | vim.o.smartindent = true 45 | 46 | -- 使用 jk 移动光标时,上下方保留8行 47 | vim.o.scrolloff = 8 48 | vim.o.sidescrolloff = 8 49 | 50 | vim.o.history = 1000 51 | vim.o.undofile = true 52 | 53 | vim.o.list = true 54 | vim.o.listchars = "tab:» ,lead:·,trail:·,extends:…" 55 | 56 | -- gui 限定 57 | vim.o.guifont = "Monofur Nerd Font Mono:h15" 58 | 59 | -- 代码折叠,可以有以下值: 60 | -- manual 61 | -- indent 62 | -- marker 63 | -- expr 64 | -- syntax 65 | -- diff 66 | vim.opt.foldmethod = "indent" 67 | vim.opt.foldlevel = 99 68 | 69 | 70 | ---------------- 开始插件设置 71 | 72 | local bufferline 73 | 74 | local floatBorder = 'single' -- 浮动窗口的边框 75 | 76 | -- 加载 lazy 插件管理 77 | local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" 78 | if not vim.loop.fs_stat(lazypath) then 79 | vim.fn.system({ 80 | "git", 81 | "clone", 82 | "--filter=blob:none", 83 | "https://github.com/folke/lazy.nvim.git", 84 | "--branch=stable", 85 | lazypath, 86 | }) 87 | end 88 | vim.opt.rtp:prepend(lazypath) 89 | 90 | require("lazy").setup({ 91 | { 92 | -- LSP 93 | -- https://github.com/neovim/nvim-lspconfig 94 | "neovim/nvim-lspconfig", 95 | config = function() 96 | require("lspconfig").gopls.setup({ 97 | on_attach = function(client, buffer) 98 | -- 几种需要边框的 99 | require('lspconfig.ui.windows').default_options.border = floatBorder 100 | vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, {border = floatBorder}) 101 | vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with(vim.lsp.handlers.signature_help, {border = floatBorder}) 102 | vim.diagnostic.config({float = {border = floatBorder}}) 103 | 104 | -- 在插入模式可以按 触发补全 105 | -- vim.api.nvim_buf_set_option(buffer, "omnifunc", "v:lua.vim.lsp.omnifunc") 106 | 107 | local opts = { noremap=true, silent=true } 108 | vim.api.nvim_buf_set_keymap(buffer, "n", "", "lua vim.lsp.buf.hover()", opts) 109 | vim.api.nvim_buf_set_keymap(buffer, "n", "", "lua vim.lsp.buf.code_action()", opts) 110 | vim.api.nvim_buf_set_keymap(buffer, "n", "gD", "lua vim.lsp.buf.declaration()", opts) 111 | vim.api.nvim_buf_set_keymap(buffer, "n", "gd", "lua vim.lsp.buf.definition()", opts) 112 | vim.api.nvim_buf_set_keymap(buffer, 'n', '', 'lua vim.diagnostic.goto_next()', opts) 113 | 114 | -- imports 115 | vim.api.nvim_create_autocmd("BufWritePre", { 116 | pattern = "*.go", 117 | callback = function() 118 | local params = vim.lsp.util.make_range_params() 119 | params.context = {only = {"source.organizeImports"}} 120 | -- 可以有第四个参数,默认为 1000 ms,如果有多次写入可以添加此值, 121 | -- 比如:vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 2000) 122 | local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params) 123 | for cid, res in pairs(result or {}) do 124 | for _, r in pairs(res.result or {}) do 125 | if r.edit then 126 | local enc = (vim.lsp.get_client_by_id(cid) or {}).offset_encoding or "utf-8" 127 | vim.lsp.util.apply_workspace_edit(r.edit, enc) 128 | end 129 | end 130 | end 131 | vim.lsp.buf.format({async = false}) 132 | end -- end callback 133 | }) 134 | end, -- end on_attach 135 | 136 | settings = { 137 | gopls = { 138 | gofumpt = true, 139 | staticcheck = true, 140 | analyses = { 141 | unusedparams = true 142 | } 143 | } 144 | }, 145 | }) 146 | 147 | require('lspconfig').ts_ls.setup({ 148 | on_attach = function(client, buffer) 149 | -- 几种需要边框的 150 | require('lspconfig.ui.windows').default_options.border = floatBorder 151 | vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, {border = floatBorder}) 152 | vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with(vim.lsp.handlers.signature_help, {border = floatBorder}) 153 | vim.diagnostic.config({float = {border = floatBorder}}) 154 | 155 | -- 在插入模式可以按 触发补全 156 | -- vim.api.nvim_buf_set_option(buffer, "omnifunc", "v:lua.vim.lsp.omnifunc") 157 | 158 | local opts = { noremap=true, silent=true } 159 | vim.api.nvim_buf_set_keymap(buffer, "n", "", "lua vim.lsp.buf.hover()", opts) 160 | vim.api.nvim_buf_set_keymap(buffer, "n", "", "lua vim.lsp.buf.code_action()", opts) 161 | vim.api.nvim_buf_set_keymap(buffer, "n", "gD", "lua vim.lsp.buf.declaration()", opts) 162 | vim.api.nvim_buf_set_keymap(buffer, "n", "gd", "lua vim.lsp.buf.definition()", opts) 163 | vim.api.nvim_buf_set_keymap(buffer, 'n', '', 'lua vim.diagnostic.goto_next()', opts) 164 | end, 165 | }) 166 | end -- end config 167 | }, 168 | { 169 | -- 智能感知 170 | -- https://github.com/hrsh7th/nvim-cmp 171 | "hrsh7th/nvim-cmp", 172 | event = "InsertEnter", 173 | dependencies = { 174 | "hrsh7th/cmp-nvim-lsp", 175 | "hrsh7th/cmp-buffer", 176 | "hrsh7th/cmp-path", 177 | "hrsh7th/cmp-cmdline", 178 | "hrsh7th/cmp-vsnip", 179 | }, 180 | config = function() 181 | vim.opt.completeopt = { "menu", "menuone", "noselect" } 182 | local cmp = require("cmp") 183 | 184 | cmp.setup({ 185 | snippet = { 186 | expand = function(args) 187 | vim.fn["vsnip#anonymous"](args.body) 188 | end, 189 | }, 190 | 191 | mapping = cmp.mapping.preset.insert({ 192 | [''] = cmp.mapping.select_next_item(), 193 | [''] = cmp.mapping.select_prev_item(), 194 | [''] = cmp.mapping.complete(), 195 | [''] = cmp.mapping.abort(), 196 | [''] = cmp.mapping.confirm({ select = true }), 197 | }), 198 | 199 | window = { 200 | documentation = cmp.config.window.bordered() 201 | }, 202 | 203 | sources = cmp.config.sources({ 204 | { name = 'nvim_lsp' }, 205 | { name = 'nvim_path' }, 206 | { name = 'vsnip' }, 207 | }) 208 | }) -- end setup 209 | 210 | local capabilities = require('cmp_nvim_lsp').default_capabilities() 211 | require('lspconfig')['go'].setup { 212 | capabilities = capabilities 213 | } 214 | end 215 | }, 216 | { 217 | -- buffer 栏 218 | -- https://github.com/akinsho/bufferline.nvim 219 | 'akinsho/bufferline.nvim', version = "*", 220 | dependencies = 'nvim-tree/nvim-web-devicons', 221 | config = function() 222 | bufferline = require("bufferline") 223 | bufferline.setup({ 224 | options = { 225 | offsets = {{ 226 | filetype = "NvimTree", 227 | text = "文件夹", 228 | separator = true, 229 | text_align = "left", 230 | }}, 231 | diagnostics = "nvim_lsp", 232 | numbers = "ordinal", 233 | } 234 | }) 235 | end 236 | }, 237 | { 238 | -- 文件浏览 239 | -- https://github.com/nvim-tree/nvim-tree.lua 240 | "nvim-tree/nvim-tree.lua", 241 | dependencies = "nvim-tree/nvim-web-devicons", 242 | config = function() 243 | require("nvim-tree").setup({ 244 | actions = { 245 | change_dir = { 246 | enable = true, 247 | global = true 248 | }, 249 | open_file = { 250 | resize_window = true 251 | } 252 | }, 253 | renderer = { 254 | indent_markers = { 255 | enable = true 256 | } 257 | }, 258 | view = { 259 | width = 40 260 | } 261 | }) 262 | end 263 | }, 264 | { 265 | -- 状态栏 266 | -- https://github.com/nvim-lualine/lualine.nvim 267 | "nvim-lualine/lualine.nvim", 268 | dependencies = "nvim-tree/nvim-web-devicons", 269 | config = function() 270 | local modes = { -- 几种模式对应的中文 271 | NORMAL = "标准", 272 | VISUAL = "可视", 273 | INSERT = "插入", 274 | SELECT = "选择", 275 | COMMAND = "命令行", 276 | REPLACE = "替换", 277 | } 278 | 279 | local mode_name = function(mode) -- 根据模式返回中文名称 280 | if modes[mode] ~= nil then 281 | return modes[mode] 282 | end 283 | return mode 284 | end 285 | 286 | require("lualine").setup({ 287 | sections = { 288 | lualine_a = {{'mode',fmt = mode_name }}, 289 | }, 290 | }) 291 | end 292 | }, 293 | { 294 | --https://github.com/sindrets/diffview.nvim 295 | "sindrets/diffview.nvim", 296 | config = function() 297 | require("diffview").setup() 298 | end 299 | }, 300 | { 301 | -- 文档结构 302 | -- https://github.com/simrat39/symbols-outline.nvim 303 | "simrat39/symbols-outline.nvim", 304 | config = function() 305 | require("symbols-outline").setup({ 306 | width = 20 307 | }) 308 | end 309 | }, 310 | { 311 | -- git 状态 312 | -- https://github.com/lewis6991/gitsigns.nvim 313 | "lewis6991/gitsigns.nvim", 314 | config = function() 315 | require("gitsigns").setup() 316 | end 317 | }, 318 | { 319 | -- https://github.com/goolord/alpha-nvim 320 | "goolord/alpha-nvim", 321 | dependencies = "nvim-tree/nvim-web-devicons", 322 | config = function() 323 | require("alpha").setup(require("alpha.themes.startify").config) 324 | end 325 | }, 326 | { 327 | -- https://github.com/nvim-telescope/telescope.nvim 328 | "nvim-telescope/telescope.nvim", branch = "0.1.x", 329 | dependencies = { "nvim-lua/plenary.nvim" }, 330 | }, 331 | { 332 | -- https://github.com/dstein64/nvim-scrollview 333 | "dstein64/nvim-scrollview", 334 | config = function() 335 | require("scrollview").setup() 336 | end 337 | }, 338 | { 339 | -- https://github.com/folke/todo-comments.nvim 340 | "folke/todo-comments.nvim", 341 | dependencies = { "nvim-lua/plenary.nvim" } 342 | }, 343 | 344 | -- 以下开始为主题内容 345 | 346 | { 347 | -- colors 348 | -- https://github.com/marko-cerovac/material.nvim 349 | "marko-cerovac/material.nvim", 350 | }, 351 | }, { 352 | ui = { 353 | border = floatBorder 354 | } 355 | }) 356 | 357 | -- 样式 358 | vim.o.background = "dark" 359 | vim.o.termguicolors = true 360 | vim.opt.termguicolors = true 361 | vim.g.material_style = "Oceanic" 362 | vim.cmd.colorscheme "material" 363 | vim.keymap.set("n","","za",{noremap = true, silent = true}) -- 折叠从 za 改为 space 364 | 365 | vim.keymap.set("n", "", "NvimTreeToggle") 366 | vim.keymap.set("n", "", "SymbolsOutline") 367 | 368 | -- 以下的 绑定了 macOS 的 command 键,每个 gui 客户端的定义可能不一样。 369 | -- neovide,neovim-qt 可用,其它的未试。 370 | 371 | -- 允许 cmd+c,cmd+v 372 | vim.g.neovide_input_use_logo = 1 373 | vim.keymap.set('', '', '+p', { noremap = true, silent = true}) 374 | vim.keymap.set('!', '', '+', { noremap = true, silent = true}) 375 | vim.keymap.set('t', '', '+', { noremap = true, silent = true}) 376 | vim.keymap.set('v', '', '+', { noremap = true, silent = true}) 377 | 378 | -- 按 cmd+number 切换 379 | for i = 1, 9 do 380 | vim.keymap.set('n', '', function() bufferline.go_to_buffer(i, true) end) 381 | end 382 | 383 | -- cmd+p 打开文件搜索 384 | vim.keymap.set("n", "", ":Telescope find_files", { noremap = true, silent = true}) 385 | vim.keymap.set("n", "", ":Telescope lsp_document_symbols", { noremap = true, silent = true}) 386 | 387 | -- cmd+w / cmd+s 388 | vim.keymap.set("n", "", ":bd", { noremap = true, silent = true}) 389 | vim.keymap.set("n", "", ":w", { noremap = true, silent = true}) 390 | 391 | vim.keymap.set("n", "", ":lua vim.lsp.buf.rename()", { noremap = true, silent = true}) 392 | 393 | 394 | -- neovide 限定 395 | if vim.g.neovide then 396 | vim.g.neovide_scroll_animation_length = 0 397 | vim.g.neovide_cursor_animation_length = 0 398 | end 399 | --------------------------------------------------------------------------------