.vimrc config file

Part of my EPITA PIE starter kit: vim with clangd LSP, auto-pairs, snippets and format-on-save, reinstalled automatically at every PIE login.

Installation

curl -fsSL https://raw.githubusercontent.com/KazeTachinuu/epita-ing1-setup/master/setup.sh | sh

Configuration

Exam Config (memorize these 3 lines)

Exam machines have no AFS and no network, so nothing installs. Line 1 must come first: writing any ~/.vimrc silently disables the built-in defaults.vim, and line 1 turns it back on.

" EPITA exam vimrc - memorize these 3 lines, line 1 always first.
source $VIMRUNTIME/defaults.vim
set nu et sw=4 sts=4 cc=80
set hls ic scs cb=unnamedplus
" Line 1: restores vim's defaults (incsearch, scrolloff, mouse, filetype)
" Line 2: numbers, 4-space indent, 80-column marker
" Line 3: search highlight + smartcase, yank/paste = system clipboard
"
" Built-ins to use:
" K man page for word under cursor
" Ctrl-N complete identifiers (insert mode)
" :make :cn build, jump error to error
" :term shell in a split
" * highlight all uses of word under cursor
" Ctrl-W s/v split horizontal/vertical

Complete Config (PIE)

" ============================================================================
" EPITA PIE vimrc - vim-full 9.2, zero install, superset of vimrc.exam
" ============================================================================
" Layers: this file extends the 3-line exam core; muscle memory transfers.
" Every line changes verified behavior on the PIE image; defaults live in
" defaults.vim, the system vimrc, and ftplugins - not here.
" Any user vimrc suppresses defaults.vim (incsearch, scrolloff, mouse,
" ttimeout, filetype indent, last-cursor-position) - restore it first.
source $VIMRUNTIME/defaults.vim
" All autocmds live in one group, cleared on load: re-sourcing this file
" is idempotent (no duplicated handlers).
augroup pie | autocmd! | augroup END
" ---- interface -------------------------------------------------------------
set number " line numbers (gcc and gdb speak in them)
set mouse=a " mouse in every mode, any terminal
set wildmode=longest:full,full " complete longest, then cycle
set wildoptions=pum " popup completion menu for :commands
set laststatus=2 " always show the statusline
set signcolumn=yes " stable gutter (LSP diagnostics)
set scrolloff=8 " keep context around the cursor
set cursorline " highlight the current line
set breakindent " wrapped lines keep their indent
set splitright splitbelow " new splits open right/below
set hidden " switch buffers without saving first
set autoread " pick up external file changes
set ttimeoutlen=50 " snappy Esc
set clipboard=unnamedplus " y/p use the system clipboard
" the PIE runs no clipboard manager, so the X clipboard dies with vim
" (freedesktop SAVE_TARGETS, which vim never implemented): on exit, hand
" the last yank to xsel, which outlives vim and keeps it pasteable
autocmd pie VimLeave * if !empty($DISPLAY) && !empty(getreg('+'))
\ | silent! call system('xsel -ib', getreg('+')) | endif
" ---- colors ----------------------------------------------------------------
set termguicolors background=dark
silent! colorscheme habamax " also shipped: retrobox catppuccin sorbet
" ---- EPITA C style ---------------------------------------------------------
set colorcolumn=80 " the style's hard line limit
set expandtab tabstop=4 shiftwidth=4 softtabstop=4
set shiftround " >> snaps to multiples of 4
set autoindent
set list listchars=tab:>-,trail:- " expose tabs and trailing spaces
autocmd pie FileType c,cpp setlocal cinoptions=(0,:0 formatoptions+=j
" ---- search ----------------------------------------------------------------
set hlsearch ignorecase smartcase " highlight all; smart casing
nnoremap <silent> <Esc><Esc> :nohlsearch<CR>
" ---- files: undo yes, clutter no -------------------------------------------
set undofile undodir=~/.vim/undo// " undo history survives closing files
silent! call mkdir($HOME . '/.vim/undo', 'p')
set nowritebackup noswapfile " no *~ and .swp litter in repos
" ---- movement --------------------------------------------------------------
nnoremap <expr> j v:count ? 'j' : 'gj'
nnoremap <expr> k v:count ? 'k' : 'gk'
nnoremap <Down> gj
nnoremap <Up> gk
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk
" half-page jumps and search hits keep the cursor centered
nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz
nnoremap n nzzzv
nnoremap N Nzzzv
" join lines without moving the cursor
nnoremap J mzJ`z
" ---- leader ----------------------------------------------------------------
nnoremap <Space> <Nop>
let mapleader = " "
" ---- files and buffers -----------------------------------------------------
let g:netrw_banner = 0 " netrw: no banner,
let g:netrw_liststyle = 3 " tree view
nnoremap <C-n> :Lexplore<CR>
set path+=** " :find any file in the repo
" ---- C workflow: build, jump, format ---------------------------------------
set autowrite " save before :make
nnoremap <leader>m :make<CR>
nnoremap <leader>n :cnext<CR>
nnoremap <leader>p :cprev<CR>
nnoremap <leader>q :copen<CR>
nnoremap <leader>s :%s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>
" :Format runs the EPITA wrapper over the whole repo
if executable('clang-format-epita')
command! Format !clang-format-epita
endif
if executable('clang-format') " gq formats with the repo style
autocmd pie FileType c,cpp setlocal formatprg=clang-format\ --style=file\ --fallback-style=none
endif
" auto-format C files on save (vim-clang-format plugin, cloned by
" install.sh; inert without it). Only when a .clang-format governs the file.
let g:clang_format#auto_format = 1
let g:clang_format#detect_style_file = 1
let g:clang_format#enable_fallback_style = 0
" ---- built-in power (all exam-available) -----------------------------------
packadd! termdebug " :Termdebug ./a.out - GDB UI in vim
packadd! comment " gcc / gc toggles comments
packadd! matchit " % jumps on #if / #endif
runtime ftplugin/man.vim " :Man malloc (K also works bare)
" ---- LSP: clangd (preinstalled on the PIE) ---------------------------------
" install.sh clones yegappan/lsp into pack/kit/start once; inert without it.
" Snippet support (function-argument placeholders) lights up when vsnip is
" present; Tab jumps between placeholders.
autocmd pie User LspSetup call LspOptionsSet(extend(
\ {'semanticHighlight': v:true, 'showDiagWithVirtualText': v:true},
\ exists(':VsnipOpen') == 2 ? {'snippetSupport': v:true, 'vsnipSupport': v:true} : {}))
" Tab expands a snippet at the cursor (main, for, if... from
" friendly-snippets), else jumps to the next placeholder, else is a Tab.
autocmd pie VimEnter * if exists(':VsnipOpen') == 2
\ | imap <expr> <Tab> vsnip#expandable() ? '<Plug>(vsnip-expand)' : vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' : '<Tab>'
\ | smap <expr> <Tab> vsnip#expandable() ? '<Plug>(vsnip-expand)' : vsnip#jumpable(1) ? '<Plug>(vsnip-jump-next)' : '<Tab>'
\ | imap <expr> <S-Tab> vsnip#jumpable(-1) ? '<Plug>(vsnip-jump-prev)' : '<S-Tab>'
\ | smap <expr> <S-Tab> vsnip#jumpable(-1) ? '<Plug>(vsnip-jump-prev)' : '<S-Tab>'
\ | endif
autocmd pie User LspSetup call LspAddServer([{
\ 'name': 'clangd', 'filetype': ['c', 'cpp'],
\ 'path': 'clangd', 'args': ['--background-index', '--fallback-style=none'] }])
autocmd pie User LspAttached nnoremap <buffer> gd :LspGotoDefinition<CR>
autocmd pie User LspAttached nnoremap <buffer> gD :LspGotoDeclaration<CR>
autocmd pie User LspAttached nnoremap <buffer> gr :LspShowReferences<CR>
autocmd pie User LspAttached nnoremap <buffer> <leader>r :LspRename<CR>
autocmd pie User LspAttached nnoremap <buffer> <leader>a :LspCodeAction<CR>
autocmd pie User LspAttached nnoremap <buffer> <leader>h :LspSwitchSourceHeader<CR>
autocmd pie User LspAttached nnoremap <buffer> ]d :LspDiag next<CR>
autocmd pie User LspAttached nnoremap <buffer> [d :LspDiag prev<CR>
autocmd pie User LspAttached nnoremap <buffer> K :LspHover<CR>

Daily Fallback (dotfiles)

The same core, minus the PIE-only parts (AFS plugins, LSP, clipboard hack). Neovim is my daily driver; this is the vim that answers vi on my machines, linked by my dotfiles installer.

source $VIMRUNTIME/defaults.vim " first: any user vimrc disables defaults.vim
augroup dotfiles | autocmd! | augroup END " one autocmd group, cleared on re-source
" ---- interface -------------------------------------------------------------
set number " line numbers (gcc and gdb speak in them)
set mouse=a " mouse in every mode, any terminal
set wildmode=longest:full,full " complete longest, then cycle
set wildoptions=pum " popup completion menu for :commands
set laststatus=2 " always show the statusline
set scrolloff=8 " keep context around the cursor
set cursorline " highlight the current line
set breakindent " wrapped lines keep their indent
set splitright splitbelow " new splits open right/below
set hidden " switch buffers without saving first
set autoread " pick up external file changes
set ttimeoutlen=50 " snappy Esc
set clipboard=unnamedplus " y/p use the system clipboard
" ---- colors ----------------------------------------------------------------
set termguicolors background=dark
silent! colorscheme habamax
" ---- C style (EPITA) -------------------------------------------------------
set colorcolumn=80 " the style's hard line limit
set expandtab tabstop=4 shiftwidth=4 softtabstop=4
set shiftround " >> snaps to multiples of 4
set autoindent
set list listchars=tab:>-,trail:- " expose tabs and trailing spaces
autocmd dotfiles FileType c,cpp setlocal cinoptions=(0,:0 formatoptions+=j
" ---- search ----------------------------------------------------------------
set hlsearch ignorecase smartcase " highlight all; smart casing
nnoremap <silent> <Esc><Esc> :nohlsearch<CR>
" ---- files: undo yes, clutter no -------------------------------------------
set undofile undodir=~/.vim/undo// " undo history survives closing files
silent! call mkdir($HOME . '/.vim/undo', 'p')
set nowritebackup noswapfile " no *~ and .swp litter in repos
" ---- movement --------------------------------------------------------------
nnoremap <expr> j v:count ? 'j' : 'gj'
nnoremap <expr> k v:count ? 'k' : 'gk'
nnoremap <Down> gj
nnoremap <Up> gk
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk
" half-page jumps and search hits keep the cursor centered
nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz
nnoremap n nzzzv
nnoremap N Nzzzv
" join lines without moving the cursor
nnoremap J mzJ`z
" ---- leader ----------------------------------------------------------------
nnoremap <Space> <Nop>
let mapleader = " "
" ---- files and buffers -----------------------------------------------------
let g:netrw_banner = 0 " netrw: no banner,
let g:netrw_liststyle = 3 " tree view
nnoremap <C-n> :Lexplore<CR>
set path+=** " :find any file in the repo
" ---- C workflow: build, jump, format ---------------------------------------
set autowrite " save before :make
nnoremap <leader>m :make<CR>
nnoremap <leader>n :cnext<CR>
nnoremap <leader>p :cprev<CR>
nnoremap <leader>q :copen<CR>
nnoremap <leader>s :%s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>
if executable('clang-format') " gq formats with the repo style
autocmd dotfiles FileType c,cpp setlocal formatprg=clang-format\ --style=file\ --fallback-style=none
endif
" ---- built-in power ---------------------------------------------------------
packadd! termdebug " :Termdebug ./a.out - GDB UI in vim
packadd! comment " gcc / gc toggles comments
packadd! matchit " % jumps on #if / #endif
runtime ftplugin/man.vim " :Man malloc (K also works bare)