" ============================================================================
" EVi Configuration
" ============================================================================
" General
" ----------------------------------------------------------------------------
set nocompatible
set encoding=utf-8
set hidden
set history=1000
set clipboard=unnamedplus
set splitright
set splitbelow

" ----------------------------------------------------------------------------
" UI
" ----------------------------------------------------------------------------
set number
set relativenumber
set wildmenu
set showcmd
colorscheme jellybeans

" ----------------------------------------------------------------------------
" Transparent UI
" ----------------------------------------------------------------------------
augroup VimTransparent
  autocmd!
  autocmd ColorScheme * highlight Normal ctermbg=NONE guibg=NONE
        \ | highlight NonText ctermbg=NONE guibg=NONE
        \ | highlight LineNr ctermbg=NONE guibg=NONE
        \ | highlight SignColumn ctermbg=NONE guibg=NONE
        \ | highlight EndOfBuffer ctermbg=NONE guibg=NONE
augroup END

" ----------------------------------------------------------------------------
" Status Line
" ----------------------------------------------------------------------------
set laststatus=2
highlight EviStatus cterm=NONE ctermfg=White ctermbg=236
set statusline=%#EviStatus#%f\ %m%r\ %=%{&filetype}\ \ %l:%c\ %p%%

" ----------------------------------------------------------------------------
" Editing
" ----------------------------------------------------------------------------
set tabstop=4
set shiftwidth=4
set expandtab
set smartindent
set nowrap
set incsearch
set hlsearch
set ignorecase
set smartcase
set completeopt=menu,menuone,noselect

" ----------------------------------------------------------------------------
" File Types
" ----------------------------------------------------------------------------
syntax on
filetype plugin indent on

" ----------------------------------------------------------------------------
" fzf
" ----------------------------------------------------------------------------
if executable('rg')
    let $FZF_DEFAULT_COMMAND =
        \ 'rg --files --hidden --follow --glob "!.git/*"'
endif

nnoremap <C-p> :Files<CR>
nnoremap <C-o> :Buffers<CR>
nnoremap <C-s> :Rg<CR>
nnoremap <C-b> :Build<CR>

" ----------------------------------------------------------------------------
" Search
" ----------------------------------------------------------------------------
nnoremap <Esc><Esc> :nohlsearch<CR>
nnoremap n nzzzv
nnoremap N Nzzzv

" ----------------------------------------------------------------------------
" Window Navigation
" ----------------------------------------------------------------------------
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
nnoremap <C-x> <C-w>q

" ----------------------------------------------------------------------------
" LSP - OLS
" ----------------------------------------------------------------------------
packadd lsp
call LspOptionsSet(#{
    \   autoComplete: v:false,
    \   autoHighlight: v:false,
    \   autoHighlightDiags: v:true,
    \   autoPopulateDiags: v:true,
    \   semanticHighlight: v:false,
    \   showSignature: v:false,
    \   completionInPreview: v:false,
    \   condensedCompletionMenu: v:true,
    \ })

if executable('ols')
    call LspAddServer([#{
        \   name: 'ols',
        \   filetype: ['odin'],
        \   path: 'ols',
        \   args: ['--stdio'],
        \   features: #{
        \       diagnostic: v:false,
        \       completion: v:true,
        \       hover: v:true,
        \       signatureHelp: v:false,
        \       documentHighlight: v:true,
        \       semanticHighlight: v:true,
        \   },
        \ }])
endif

command! Action LspCodeAction
command! Rename LspRename

autocmd FileType odin setlocal omnifunc=LspOmniFunc
inoremap <C-@> <C-X><C-O>
nnoremap K :LspHover<CR>

" ----------------------------------------------------------------------------
" Go to Definition
" ----------------------------------------------------------------------------
function! GotoDefinitionSplit() abort
    vsplit
    LspGotoDefinition
endfunction

nnoremap gd :call GotoDefinitionSplit()<CR>

" ----------------------------------------------------------------------------
" Diagnostics
" ----------------------------------------------------------------------------
function! ToggleDiagnostics() abort
    for l:win in getwininfo()
        if get(l:win, 'quickfix', 0)
            execute l:win.winnr .. 'close'
            return
        endif
    endfor

    LspDiag show
endfunction

command! Diagnostics call ToggleDiagnostics()
nnoremap <C-i> :Diagnostics<CR>

" ----------------------------------------------------------------------------
" Netrw / File Tree
" ----------------------------------------------------------------------------
let g:netrw_banner = 0
let g:netrw_liststyle = 3
let g:netrw_browse_split = 0
let g:netrw_altv = 1
let g:netrw_winsize = 33
let g:netrw_keepdir = 0
nnoremap <C-e> :Lexplore<CR>

" ----------------------------------------------------------------------------
" Build System
" ----------------------------------------------------------------------------
function! Build(...) abort
    " Already in the build terminal → close it.
    if get(b:, 'build_terminal', 0) && &buftype ==# 'terminal'
        close
        echo ''
        return
    endif

    if !filereadable('build.sh')
        echohl WarningMsg
        echo 'No build.sh found in current directory.'
        echohl None
        return
    endif

    wall

    let l:command = './build.sh'

    if a:0 > 0
        let l:command .= ' ' .. join(a:000, ' ')
    endif

    botright vsplit
    execute 'vertical resize ' .. float2nr(&columns * 0.37)
    execute 'terminal ++curwin ' .. l:command

    let b:build_terminal = 1
    tnoremap <buffer> <CR> <Nop>
endfunction

command! -nargs=* Build call Build(<f-args>)
