"F3文件浏览 F5运行 F10编译 F12行号 leader键为\ \s关闭ale语法检查 \d显示错误/警告详细信息 
"visual模式下选中文本\cs注释\cu取消
"中文支持
set encoding=utf-8
set fileencoding=utf-8
set fileencodings=utf-8,ucs-bom,chinese
"代码高亮
syntax on
"行号设置
set nu
noremap <silent> <F12> :call SetNU()<CR>
func! SetNU()
	if &number!=0
		exec "set nonu"
	else
		exec "set nu"
	endif
endfunc
"代码管理
call plug#begin('~/.vim/plugged')
"符号补全
Plug 'jiangmiao/auto-pairs'
"代码检查
Plug 'dense-analysis/ale'
"文件浏览
Plug 'preservim/NERDTree'
"运行信息输出
Plug 'skywind3000/asyncrun.vim'
"tags自动生成
Plug 'ludovicchabant/vim-gutentags'
"代码块注释
Plug 'preservim/nerdcommenter'
"中文文档
Plug 'yianwillis/vimcdoc'
"vim airline
Plug 'vim-airline/vim-airline'
"中文输入法
Plug 'ZSaberLv0/ZFVimIM'
Plug 'ZSaberLv0/ZFVimJob'
Plug 'ZSaberLv0/ZFVimIM_openapi'
"git相关命令
Plug 'tpope/vim-fugitive'
"coc C/C++代码补全
Plug 'neoclide/coc.nvim', {'branch': 'release'}
call plug#end()
"tags追加
set tags+=~/.cache/tags
" 设置tab补全
inoremap <silent><expr> <TAB>
    \ coc#pum#visible() ? coc#pum#confirm() :
    \ CheckBackspace() ? "\<Tab>" :
    \ coc#refresh()
inoremap <silent><expr> <ESC>
    \ coc#pum#visible() ? coc#pum#stop():"\<ESC>"
" function! CleverTab()
    " if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$'
         " return "\<Tab>"
    " else
         " return "\<C-N>"
    " endif
" endfunction
" inoremap <Tab> <C-R>=CleverTab()<CR>
" inoremap <silent><expr> <TAB>
      " \ coc#pum#visible() ? coc#pum#next(1) :
      " \ CheckBackspace() ? "\<Tab>" :
      " \ coc#refresh()
" inoremap <expr><S-TAB> coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"

" Make <CR> to accept selected completion item or notify coc.nvim to format
" <C-g>u breaks current undo, please make your own choice
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
function! CheckBackspace() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction
" NERDTree命令映射
map <F3> :NERDTreeMirror<CR>
map <F3> :NERDTreeToggle<CR>
"ale settings{{
"始终开启标志列
let g:ale_sign_column_always = 1
let g:ale_set_highlights = 0
"自定义error和warning图标
let g:ale_sign_error = '✗'
let g:ale_sign_warning = '⚡'
"在vim自带的状态栏中整合ale
let g:ale_statusline_format = ['✗ %d', '⚡ %d', '✔ OK']
"显示Linter名称,出错或警告等相关信息
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_echo_msg_format = '[%linter%] %s [%severity%]'
"普通模式下，sp前往上一个错误或警告，sn前往下一个错误或警告
nmap sp <Plug>(ale_previous_wrap)
nmap sn <Plug>(ale_next_wrap)
"<Leader>s触发/关闭语法检查
nmap <Leader>s :ALEToggle<CR>
"<Leader>d查看错误或警告的详细信息
nmap <Leader>d :ALEDetail<CR>
"打开文件时不进行检查
let g:ale_lint_on_enter = 0
"使用clang对c和c++进行语法检查，对python使用pylint进行语法检查
let g:ale_linters = {
\   'c++': ['clang'],
\   'c': ['clang'],
\   'python': ['pylint'],
\   'java': [''],
\}
"}}
" 自动打开高度为具体值的 quickfix 窗口
let g:asyncrun_open=15
" 运行前保存文件
let g:asyncrun_save=1
" 用<f10>编译
noremap <silent> <F10> :call CompileBuild()<CR>
func! CompileBuild()
    exec "w"
    if &filetype == 'c'
        exec ':AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 gcc -O3 -ggdb -Wall "$(VIM_FILEPATH)" -o "$(VIM_FILEDIR)/$(VIM_FILENOEXT)"'
    elseif &filetype == 'cpp'
        exec ':AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 g++ -O3 -ggdb -Wall "$(VIM_FILEPATH)" -o "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" -lpthread'
    elseif &filetype == 'go'
        exec ":AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 go build $(VIM_FILEDIR)/$(VIM_FILENOEXT)"
    elseif &filetype == 'java'
        exec ':AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 javac --module-path "/data/data/com.termux/files/usr/opt/javafx-sdk-20.0.2/lib/" --add-modules="javafx.controls" "$(VIM_FILEPATH)"'
    endif
endfunc

" 用<F5>运行
noremap <silent> <F5> :call CompileRun()<CR>
func! CompileRun()
    exec "w"
    if &filetype == 'c'
        exec ":AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 $(VIM_FILEDIR)/$(VIM_FILENOEXT)"
    elseif &filetype == 'cpp'
        exec ":AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 $(VIM_FILEDIR)/$(VIM_FILENOEXT)"
    elseif &filetype == 'python'
        exec ":AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 python3 $(VIM_FILEPATH)"
    elseif &filetype == 'html'
        exec ":AsyncRun -mode=term -pos=hide open $(VIM_FILEPATH)"
    elseif &filetype == 'go'
        exec ":AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 go run $(VIM_FILEPATH)"
    elseif &filetype == 'javascript'
        exec ":AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 node $(VIM_FILEPATH)"
    elseif &filetype == 'java'
        exec ':AsyncRun -mode=term -pos=bottom -rows=10 -focus=0 java  --module-path "/data/data/com.termux/files/usr/opt/javafx-sdk-20.0.2/lib/" --add-modules="javafx.controls" -cp $(VIM_FILEDIR) $(VIM_FILENOEXT)'
    endif
endfunc
"gutentags settings {{
" gutentags 搜索工程目录的标志，碰到这些文件/目录名就停止向上一级目录递归
let g:gutentags_project_root = ['.root', '.svn', '.git', '.hg', '.project','.sln']

" 所生成的数据文件的名称
let g:gutentags_ctags_tagfile = '.tags'

" 将自动生成的 tags 文件全部放入 ~/.cache/tags 目录中，避免污染工程目录
let s:vim_tags = expand('~/.cache/tags')
let g:gutentags_cache_dir = s:vim_tags

" 配置 ctags 的参数
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']

" 检测 ~/.cache/tags 不存在就新建
if !isdirectory(s:vim_tags)
   silent! call mkdir(s:vim_tags, 'p')
endif
"}}
"tags setting
" set tags=./.tags;,.tags
"NERDCommenter settings
" Add spaces after comment delimiters by default
let g:NERDSpaceDelims = 1
"add tab space
set ts=4
set softtabstop=4
set shiftwidth=4
set expandtab
set autoindent
"vim-airline settings
set laststatus=2  "永远显示状态栏
let g:airline#extensions#tabline#enabled = 1
"文件栏设置
noremap <silent><S-n> :tabnew<cr>
noremap <silent><S-d> :tabclose<cr>
noremap <silent><S-Tab> :bn!<CR>
"save file
nmap <C-s> :w<cr>
imap <C-s> <esc>:w<cr>
"undo settings
set undolevels=5000
nmap <silent><Leader>z :undo<cr>
imap <silent><Leader>z <esc>:call Insert_Undo()<cr>
func! Insert_Undo()
    let pos = getpos(".")
    undo
    startinsert
    let pos[2] +=1
    call setpos(".",pos)
endfunc
"设置中文/英文输入法数据库
let g:ZFVimIM_openapi_enable=1
let g:ZFVimIM_openapi_word_type='sentence'
function! s:ChineseDb()
    let db = ZFVimIM_dbInit({
                \   'name' : 'ChineseDb',
                \ })
    call ZFVimIM_cloudRegister({
                \   'mode' : 'local',
                \   'dbId' : db['dbId'],
                \   'repoPath' : '~/.vim/plugged/misc',
                \   'dbFile' : '/pinyin.txt',
                \   'dbCountFile' : '/pinyin_count.txt',
                \ })
endfunction
function! s:EnglishDb()
    let db = ZFVimIM_dbInit({
                \   'name' : 'EnglishDb',
                \ })
    call ZFVimIM_cloudRegister({
                \   'mode' : 'local',
                \   'dbId' : db['dbId'],
                \   'repoPath' : '~/.vim/plugged/misc',
                \   'dbFile' : '/english.txt',
                \   'dbCountFile' : '/english_count.txt',
                \ })
endfunction
autocmd User ZFVimIM_event_OnDbInit call s:EnglishDb()
autocmd User ZFVimIM_event_OnDbInit call s:ChineseDb()
"设置标点符号转换
let g:ZFVimIM_symbolMap = {
            \   ' ' : [''],
            \   '`' : ['·'],
            \   '!' : ['！'],
            \   '$' : ['￥'],
            \   '^' : ['……'],
            \   '-' : [''],
            \   '_' : ['——'],
            \   '(' : ['（'],
            \   ')' : ['）'],
            \   '[' : ['【'],
            \   ']' : ['】'],
            \   '<' : ['《'],
            \   '>' : ['》'],
            \   '\' : ['、'],
            \   '/' : ['、'],
            \   ';' : ['；'],
            \   ':' : ['：'],
            \   ',' : ['，'],
            \   '.' : ['。'],
            \   '?' : ['？'],
            \   "'" : ['‘', '’'],
            \   '"' : ['“', '”'],
            \   '0' : [''],
            \   '1' : [''],
            \   '2' : [''],
            \   '3' : [''],
            \   '4' : [''],
            \   '5' : [''],
            \   '6' : [''],
            \   '7' : [''],
            \   '8' : [''],
            \   '9' : [''],
            \ }
"自动补全相关设置
autocmd FileType python set omnifunc=pythoncomplete#Complete
autocmd FileType c set omnifunc=ccomplete#Complete
autocmd FileType cpp set omnifunc=omni#cpp#complete#Main
"使用\+q代替esc
imap <Leader>q <esc>
vmap <Leader>q <esc>
