" use space as leader key
let mapleader = " "
set wildmenu
set wildmode=full
" 模拟 Bash 的快捷键
cnoremap <C-a> <Home> " 跳到命令开头
cnoremap <C-e> <End> " 跳到命令末尾
cnoremap <C-k> <C-\>e getcmdline()[:getcmdpos()-2]<CR> " 删除光标到行尾的内容
cnoremap <C-u> <C-\>e getcmdline()[:getcmdpos()-1]<CR> " 删除光标到行首的内容
let g:undo_dir = expand('~/.vim/undodir')
if !isdirectory(g:undo_dir)
silent! call mkdir(g:undo_dir, 'p')
endif
set undofile
execute 'set undodir=' . g:undo_dir
" fast completion absolute path"
cnoremap <expr> %% getcmdtype( ) == ':' ? expand('%:h').'/' : '%%'
" viminfo save mouse history
au BufReadPost * if line("'\"") > 0 | if line("'\"") <= line("$") | exe("norm '\"") | else | exe "norm $"| endif | endif
" set viminfo='1000,<50,s10,h " not useful
if executable('vimscript-language-server')
au User lsp_setup call lsp#register_server({
\ 'name': 'vimscript-language-server',
\ 'cmd': {server_info->['vimscript-language-server']},
\ 'whitelist': ['vim'],
\ })
endif
" for formatter
let g:python3_host_prog="$HOME/local/bin/python3"
"let g:formatterpath = ['~/local/opt/clang15/bin/clang-format', '~/local/bin/autopep8', '~/go/bin/shfmt']
let g:formatterpath = ['~/local/opt/llvm21/clang/bin/clang-format', '~/.local/bin/autopep8', '~/go/bin/shfmt']
" gf search path, such as c/cpp head file
set path=.,/usr/include,$HOME/local/include/**
" use plugin
set nocompatible
let g:polyglot_disabled = ['sensible']
filetype plugin indent on
call plug#begin('~/.vim/plugged')
Plug 'Valloric/YouCompleteMe'
Plug 'vim-autoformat/vim-autoformat'
"Plug 'vim-airline/vim-airline'
Plug 'preservim/nerdtree'
" Plug 'ludovicchabant/vim-gutentags'
Plug 'skywind3000/asyncrun.vim'
" Plug 'dense-analysis/ale'
Plug 'sheerun/vim-polyglot'
Plug 'joshdick/onedark.vim'
Plug 'preservim/tagbar'
"Plug 'prabirshrestha/vim-lsp'
"Plug 'mattn/vim-lsp-settings'
Plug 'llvm/llvm.vim'
call plug#end()
if executable('clangd')
augroup lsp_clangd
autocmd!
autocmd User lsp_setup call lsp#register_server({
\ 'name': 'clangd',
\ 'cmd': {server_info->['clangd']},
\ 'allowlist': ['c', 'cpp', 'objc', 'objcpp'],
\ })
augroup END
endif
"" YCM配置
" 全局YCM配置文件路径
let g:ycm_keep_logfiles = 1
let g:ycm_log_level = 'debug'
let g:ycm_global_ycm_extra_conf = '~/.vim/plugged/YouCompleteMe/.ycm_extra_conf.py'
let g:ycm_confirm_extra_conf = 0 " 不提示是否载入本地ycm_extra_conf文件
let g:ycm_min_num_of_chars_for_completion = 2 " 输入第2个字符就罗列匹配项
" Ctrl+J跳转至定义、声明或文件
nnoremap <c-j> :YcmCompleter GoToDefinitionElseDeclaration<CR>|
" 语法关键字、注释、字符串补全
let g:ycm_seed_identifiers_with_syntax = 1
let g:ycm_complete_in_comments = 1
let g:ycm_complete_in_strings = 1
" 从注释、字符串、tag文件中收集用于补全信息
let g:ycm_collect_identifiers_from_comments_and_strings = 1
let g:ycm_collect_identifiers_from_tags_files = 1
" 禁止快捷键触发补全
let g:ycm_key_invoke_completion = '<c-z>' " 主动补全(默认<c-space>)
noremap <c-z> <NOP>
" 输入2个字符就触发补全
let g:ycm_semantic_triggers = {
\ 'c,cpp,python,java,go,erlang,perl': ['re!\w{2}'],
\ 'cs,lua,javascript': ['re!\w{2}'],
\ }
let g:ycm_show_diagnostics_ui = 0 " 禁用YCM自带语法检查(使用ale)
" 防止YCM和Ultisnips的TAB键冲突,禁止YCM的TAB
"let g:ycm_key_list_select_completion = ['<C-n>', '<Down>']
"let g:ycm_key_list_previous_completion = ['<C-p>', '<Up>']
function! JumpToLogFileAndLine()
" Get the current line under the cursor
let l:line = getline('.')
"echo "Current line: " . l:line
" Define a regex pattern to match the log format: [timestamp][module][log_level][file_name:line_number]
let l:pattern = '\v\[(.{-})\]\[(.{-})\]\[(.{-})\]\[(.{-}):(\d+)\]'
"echo "Regex pattern: " . l:pattern
" Search for the pattern in the current line
if l:line =~ l:pattern
"echo "Pattern matched"
let l:matches = matchlist(l:line, l:pattern)
" Extract the file path and line number
let l:file = "src/" . l:matches[4]
let l:line_num = l:matches[5]
"echo "File: " . l:file
"echo "Line number: " . l:line_num
" Open the file and go to the specific line
execute 'edit ' . l:file
execute l:line_num
else
echo "No file and line number found on this line."
endif
endfunction
" Map a key to jump to the file and line number
nnoremap <leader>j :call JumpToLogFileAndLine()<CR>
colorscheme onedark
noremap <leader>f :Autoformat<CR>
" open vimrc config by ctrl,
nnoremap <silent> <C-,> :e ~/.vimrc<CR>
inoremap <silent> <C-,> <Esc>:e ~/.vimrc<CR>
"set fold by syntax
set foldmethod=syntax
set foldlevel=99
" for save file
inoremap <C-s> <Esc>:w<CR>a
nnoremap <C-s> :w<CR>
vnoremap <C-s> <Esc>:w<CR>gv
" make vim paste <==> physic machine
"autocmd TextYankPost * echo v:event
function! s:raw_echo(str)
if has('win32') && has('nvim')
call chansend(v:stderr, a:str)
else
if filewritable('/dev/fd/2')
call writefile([a:str], '/dev/fd/2', 'b')
else
exec("silent! !echo " . shellescape(a:str))
redraw!
endif
endif
endfunction
"function Copy()
" let c = join(v:event.regcontents,"\n")
" let c64 = system("base64 -w 0", c)
" let str1 = "\e]52;c;" . trim(c64) . "\x07"
" call s:raw_echo(str1)
"endfunction
function! Copy()
" 仅在 yank 操作时执行复制逻辑
if v:event.operator ==# 'y'
let c = join(v:event.regcontents, "\n")
let c64 = system("base64 -w 0", c)
let str1 = "\e]52;c;" . trim(c64) . "\x07"
call s:raw_echo(str1)
endif
endfunction
autocmd TextYankPost * call Copy()
""nnoremap <F5> :autocmd! TextYankPost *<CR>
""nnoremap <F6> :autocmd TextYankPost * call Copy()<CR>
" show space and line eof char
" set list listchars+=space:. listchars-=eol:$
"statusline
set laststatus=2
function! GitBranch()
return system("git rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n'")
endfunction
let branch=GitBranch()
function! ShortFileName()
let a=bufname("")
let filename = fnamemodify(a, ':t')
return filename
endfunction
map <Leader>r <ESC>:w <CR> :source $MYVIMRC<CR>
map <leader>t :TagbarToggle <CR>
set statusline=%1*%{branch}\ %{ShortFileName()}\ %m%r%h%w%2*%{tagbar#currenttag('%s','','f')}\ %=%3*\ %Y\ %4*%{\"\".(\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\ &bomb)?\"+\":\"\").\"\"}\ %5*%p%%\ %7*%LL%<'
"set statusline=
"set statusline+=%1*%{branch}\ %{ShortFileName()}\ %m%r%h%w\
"set statusline+=%2*%{tagbar#currenttag('%s','','f')}\ %=
"set statusline+=%3*\ %Y\
"set statusline+=%4*%{\"\".(\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\ &bomb)?\"+\":\"\").\"\"}\
"set statusline+=%5*[%p%%]\ \
"set statusline+=%7*%LL%<\
""" for ale config
"let g:ale_linters_explicit = 1
"let g:ale_completion_delay = 500
"let g:ale_echo_delay = 20
"let g:ale_lint_delay = 500
"let g:ale_echo_msg_format = '[%linter%] %code: %%s'
"let g:ale_lint_on_text_changed = 'normal'
"let g:ale_lint_on_insert_leave = 1
"let g:airline#extensions#ale#enabled = 1
"let g:ale_c_gcc_options = '-Wall -O2 -std=c99
" \ -I .
" \ -I /usr/include'
"let g:ale_cpp_gcc_options = '-Wall -O2 -std=c++17
" \ -I .
" \ -I /usr/include
" \ -I /opt/compiler/gcc-8.2/include/c++/8.2.0'
"let g:ale_linters = {
" \ 'c': ['gcc', 'cppcheck'],
" \ 'cpp': ['g++', 'cppcheck'],
" \ }
"let g:ale_c_cppcheck_options = ''
"let g:ale_cpp_cppcheck_options = '--check-level=exhaustive'
"
"" let g:ale_sign_error = "\ue009\ue009"
"hi! clear SpellBad
"hi! clear SpellCap
"hi! clear SpellRare
"hi! SpellBad gui=undercurl guisp=red
"hi! SpellCap gui=undercurl guisp=blue
"hi! SpellRare gui=undercurl guisp=magenta
""""""""""""""""end ale config
"nnoremap <leader>n :NERDTreeFocus<CR>
"nnoremap <C-n> :NERDTree<CR>
nnoremap <C-n> :NERDTreeToggle<CR>
"nnoremap <C-f> :NERDTreeFind<CR>
"for asyncRun
" open quickfix window auto,height
let g:asyncrun_open = 9
" bell when task done.
let g:asyncrun_bell = 1
" set open/close Quickfix window
nnoremap <leader>c :call asyncrun#quickfix_toggle(6)<cr>
" Map Alt-q to close the window
nnoremap <silent> <leader>q :q<CR>
"
"nnoremap <silent> <F8> :AsyncRun gcc -Wall "$(VIM_FILEPATH)" -o "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
"nnoremap <silent> <F5> :AsyncRun -raw -cwd=$(VIM_FILEDIR) "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
set termwinsize=20x120
" Define a function to set key mappings for shell files
function! SetShellKeymaps()
nnoremap <F8> :w<CR>:AsyncRun bash %:p <CR>
inoremap <F8> <ESC>:w<CR>:AsyncRun bash %:p<CR>
endfunction
" Set up an autocmd for the FileType event for shell files
autocmd FileType sh call SetShellKeymaps()
autocmd FileType bash call SetShellKeymaps()
" autocmd FileType zsh call SetShellKeymaps()
" Define a function to set key mappings for Python files
function! SetPythonKeymaps()
nnoremap <F8> :w<CR>:AsyncRun python3 %:p <CR>
inoremap <F8> <ESC>:w<CR>:AsyncRun python3 %:p<CR>
endfunction
" Set up an autocmd for the FileType event for Python files
autocmd FileType python call SetPythonKeymaps()
function! SetCKeymaps()
nnoremap <F7> :w<CR>:AsyncRun gcc -Wshadow -Wall -o %:p:r.out %:p <CR>
inoremap <F7> <ESC>:w<CR>:AsyncRun gcc -Wshadow -Wall -o %:p:r.out %:p <CR>
nnoremap <F8> :AsyncRun %:p:r.out <CR>
endfunction
autocmd FileType c call SetCKeymaps()
function! SetCXXKeymaps()
nnoremap <F7> :w<CR>:AsyncRun /opt/compiler/gcc-8.2/bin/g++ -Wshadow -Wall -std=c++2a -o %:p:r.out %:p <CR>
inoremap <F7> <ESC>:w<CR>:AsyncRun /opt/compiler/gcc-8.2/bin/g++ -Wshadow -Wall -std=c++2a -o %:p:r.out %:p <CR>
nnoremap <F8> :AsyncRun %:p:r.out <CR>
endfunction
autocmd FileType cpp call SetCXXKeymaps()
" for tags
set tags=./.tags;,.tags
let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project']
let g:gutentags_ctags_tagfile = '.tags'
let s:vim_tags = expand('~/.cache/tags')
let g:gutentags_cache_dir = s:vim_tags
let g:gutentags_ctags_extra_args = ['--fields=+niazS', '--extra=+q']
let g:gutentags_ctags_extra_args += ['--c++-kinds=+px']
let g:gutentags_ctags_extra_args += ['--c-kinds=+px']
if !isdirectory(s:vim_tags)
silent! call mkdir(s:vim_tags, 'p')
endif
" syntax highlight
syntax on
" show line number and relative number
set number
" set relativenumber
" indent when newline
set smartindent
" allow backspace delete char in different mode
set backspace=indent,eol,start
" mouse mode
set mouse=n
" focus window by Ctrl + hjkl
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-h> <C-w>h
nnoremap <C-l> <C-w>l
" use ag as grep program
if executable('ag')
set grepprg=ag\ --vimgrep\ $* " receive other parameter
set grepformat=%f:%l:%c:%m " file:line:column:message
endif
" just for best search
function! MySearch()
let grep_term = input("Search=> ")
if !empty(grep_term)
execute 'silent grep' grep_term | copen
else
echo "Empty search term"
endif
redraw!
endfunction
command! Search call MySearch()
nnoremap <leader>s :Search<CR>
" cancel backup and no generate swp file
set nobackup
set nowb
set noswapfile
" tab width =4
set tabstop=4
" indent = 4
set softtabstop=4
set shiftwidth=4
set expandtab
" use search highlight
set hlsearch
" increase search by result
set incsearch
" ignore but not always ignore
set ignorecase
set smartcase
" show n/N/*/# search index in status bar
set shortmess-=S
" set file encoding
set enc=utf-8
set fencs=utf-8,gbk,big5,cp936,gb18030,gb2312
set fenc=utf-8
"let &termencoding=&encoding
"set fileencodings=gbk,utf-8,gb18030,gb2312,big5
" jk -> <ESC>
inoremap jk <ESC>
" v as visual and select mode
"vnoremap jk <ESC>
" use emacs keymap in insert mode
inoremap <C-B> <LEFT>
inoremap <C-F> <RIGHT>
inoremap <C-A> <HOME>
inoremap <C-E> <END>
inoremap <C-D> <DEL>
inoremap <C-H> <BACKSPACE>
" cn to change multi place
nnoremap cn *``cgn
nnoremap cN *``cgN
" for multi line micro
imap <C-E> <ESC>A
xnoremap @ :<C-u>call ExecuteMacroOverVisualRange()<CR>
function! ExecuteMacroOverVisualRange()
echo "@".getcmdline()
execute ":'<,'>normal @".nr2char(getchar())
endfunction
" for brackets
inoremap ( ()<ESC>i
inoremap [ []<LEFT>
inoremap " ""<ESC>i
inoremap ' ''<ESC>i
inoremap { {}<ESC>i
inoremap {<CR> {<CR>}<ESC>O
function! ClosePair(char)
if getline('.')[col('.') - 1] == a:char
return "\<Right>"
else
return a:char
endif
endfunction
inoremap ) <c-r>=ClosePair(')')<CR>
inoremap } <c-r>=ClosePair('}')<CR>
inoremap ] <c-r>=ClosePair(']')<CR>
" add bracket on visual model
xnoremap ( <Esc>`<i(<Esc>`><RIGHT>a)<Esc>
xnoremap [ <Esc>`<i[<Esc>`><RIGHT>a]<Esc>
xnoremap { <Esc>`<i{<Esc>`><RIGHT>a}<Esc>
xnoremap " <Esc>`<i"<Esc>`><RIGHT>a"<Esc>
function! InsertFileHeader()
" 获取当前文件名
let filename = expand('%:t')
" 获取当前用户名
let author = $USER
" 获取邮箱地址(可以根据需要修改)
let email = author . '@baidu.com'
" 获取当前时间
let created_time = strftime('%a %m/%d %H:%M:%S %Y')
" 定义文件头模板
let header = "/*************************************************************************\n"
\ . " > File Name: " . filename . "\n"
\ . " > Author: " . author . "\n"
\ . " > Mail: " . email . "\n"
\ . " > Created Time: " . created_time . "\n"
\ . " ************************************************************************/\n\n"
" 定义代码模板
let template_code = "#include <bits/stdc++.h>\n"
\ . "using namespace std;\n\n"
\ . "void t1() {\n"
\ . " //\n"
\ . "}\n\n"
\ . "int main() {\n"
\ . " t1();\n"
\ . " return 0;\n"
\ . "}\n"
" 如果文件为空,则插入文件头和代码模板
if getline(1) == ''
call append(0, split(header . template_code, '\n'))
endif
" 找到包含注释 "// 指针放在这里" 的行号
let target_line = search("//", 'n') " 'n' 表示不移动光标
" 如果找到了目标行,则将光标移动到该行
if target_line > 0
call cursor(target_line, 1) " 移动光标到目标行的第一列
endif
endfunction
" 设置自动命令,在打开或创建文件时调用函数
autocmd BufNewFile,BufRead *.h,*.cc,*.cpp call InsertFileHeader()