# VIM Mod

```sh
call plug#begin()

" ── File & Navigation ─────────────────────────────────────────────────────────
Plug 'preservim/nerdtree'
Plug 'ryanoasis/vim-devicons'
Plug '/opt/homebrew/opt/fzf'                     " Apple Silicon
" Plug '/usr/local/opt/fzf'                      " Intel Mac
Plug 'junegunn/fzf.vim'

" ── Syntax / Language ─────────────────────────────────────────────────────────
Plug 'pangloss/vim-javascript'
Plug 'leafgarland/typescript-vim'
Plug 'maxmellon/vim-jsx-pretty'
Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }
Plug 'heavenshell/vim-pydocstring', { 'do': 'make install' }

" ── LSP + Autocomplete ────────────────────────────────────────────────────────
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'                    " auto-installs LSP servers
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'

" ── Linting ───────────────────────────────────────────────────────────────────
Plug 'dense-analysis/ale'

" ── Git ───────────────────────────────────────────────────────────────────────
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter'

" ── Editing Utilities ─────────────────────────────────────────────────────────
Plug 'jiangmiao/auto-pairs'
Plug 'alvan/vim-closetag'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-commentary'
Plug 'junegunn/vim-easy-align'
Plug 'junegunn/goyo.vim'

" ── UI ────────────────────────────────────────────────────────────────────────
Plug 'itchyny/lightline.vim'
Plug 'Yggdroot/indentLine'
Plug 'embark-theme/vim', { 'as': 'embark' }

call plug#end()

" ── Mac ───────────────────────────────────────────────────────────────────────
set clipboard=unnamed
let g:python3_host_prog = '/opt/homebrew/bin/python3'   " Apple Silicon
" let g:python3_host_prog = '/usr/local/bin/python3'    " Intel Mac

" ── ALE ───────────────────────────────────────────────────────────────────────
let g:ale_sign_error            = '✗'
let g:ale_sign_warning          = '⚠'
let g:ale_echo_msg_format       = '[%linter%] %s [%severity%]'
let g:ale_fix_on_save           = 1
let g:ale_fixers = {
  \ '*':          ['remove_trailing_lines', 'trim_whitespace'],
  \ 'javascript': ['eslint'],
  \ 'typescript': ['eslint'],
  \ 'python':     ['black'],
  \ 'go':         ['gofmt'],
  \ }
let g:ale_linters = {
  \ 'javascript': ['eslint'],
  \ 'typescript': ['eslint'],
  \ 'python':     ['flake8'],
  \ 'go':         ['golint', 'go vet'],
  \ }

" ── vim-lsp ───────────────────────────────────────────────────────────────────
function! s:on_lsp_buffer_enabled() abort
  setlocal omnifunc=lsp#complete
  nmap <silent> gd <plug>(lsp-definition)
  nmap <silent> gr <plug>(lsp-references)
  nmap <silent> K  <plug>(lsp-hover)
  nmap <silent> <leader>rn <plug>(lsp-rename)
endfunction

augroup lsp_install
  au!
  autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
augroup END

" ── Asyncomplete ──────────────────────────────────────────────────────────────
inoremap <expr> <Tab>   pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <expr> <CR>    pumvisible() ? "\<C-y>" : "\<CR>"
set completeopt=menuone,noinsert,noselect

" ── Theme ─────────────────────────────────────────────────────────────────────
syntax on
set termguicolors
colorscheme embark

" ── Lightline ─────────────────────────────────────────────────────────────────
set noshowmode
let g:lightline = {
  \ 'colorscheme': 'embark',
  \ 'active': {
  \   'left':  [['mode','paste'],['gitbranch','readonly','filename','modified']],
  \   'right': [['lineinfo'],['percent'],['filetype']]
  \ },
  \ 'component_function': { 'gitbranch': 'FugitiveHead' },
  \ }

" ── IndentLine ────────────────────────────────────────────────────────────────
let g:indentLine_char                 = '│'
let g:indentLine_first_char           = '│'
let g:indentLine_showFirstIndentLevel = 1
let g:indentLine_setColors            = 0

" ── NERDTree ──────────────────────────────────────────────────────────────────
nnoremap <C-n> :NERDTreeToggle<CR>
let g:NERDTreeShowHidden = 1
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1
  \ && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif

" ── FZF ───────────────────────────────────────────────────────────────────────
nnoremap <C-p>      :Files<CR>
nnoremap <leader>b  :Buffers<CR>
nnoremap <leader>g  :Rg<CR>

" ── EasyAlign ─────────────────────────────────────────────────────────────────
xmap ga <Plug>(EasyAlign)
nmap ga <Plug>(EasyAlign)

" ── Editor ────────────────────────────────────────────────────────────────────
set number relativenumber
set cursorline
set showmatch
set smartindent autoindent
set tabstop=4 shiftwidth=4 expandtab
set laststatus=2
set updatetime=300
set signcolumn=yes
set hidden
set scrolloff=8                                  " keep 8 lines above/below cursor

filetype plugin indent on
let python_highlight_all = 1
```
