Skip to content

Instantly share code, notes, and snippets.

@jpseibt
Last active August 5, 2026 22:50
Show Gist options
  • Select an option

  • Save jpseibt/0f4104feebbd9311a78e06f60c586c70 to your computer and use it in GitHub Desktop.

Select an option

Save jpseibt/0f4104feebbd9311a78e06f60c586c70 to your computer and use it in GitHub Desktop.
"Handmade" Development Environment in Vim (no plugins)
" Colorscheme name: naz
highlight clear
if exists('syntax_on')
syntax reset
endif
let g:colors_name = 'naz'
" ===========================================
" Color Palette Reference (loose)
" ===========================================
" Background: #101622 | Foreground: #c3ccdc
" Comments: #7c8f8f | Functions: #0094ea
" Strings: #37b166 | Types: #c77212
" Statements: #db9e60 | Constants: #90ee90
" PreProc: #ff5874 | Identifiers: #7fdbca
" ===========================================
"------------------------------
" Core UI Elements
"
hi Normal guibg=#101622 guifg=#c3ccdc
hi Terminal guibg=#101622 guifg=#c3ccdc
hi LineNr guibg=NONE guifg=#4b6479
hi LineNrAbove guibg=NONE guifg=#4b6479
hi LineNrBelow guibg=NONE guifg=#4b6479
hi CursorLine guibg=#11324d guifg=NONE gui=NONE cterm=NONE
hi CursorLineNr guibg=#11324d guifg=#0094ea gui=NONE cterm=NONE
hi VertSplit guibg=NONE guifg=#252c3f gui=NONE cterm=NONE
hi Visual guibg=#1d3b53 guifg=NONE
hi Search guibg=#38507a guifg=#d6deeb gui=NONE cterm=NONE
hi IncSearch guibg=#ffcb8b guifg=#171a22 gui=NONE cterm=NONE
hi NormalFloat guibg=#316394 guifg=#d6deeb
hi FloatBorder guibg=#09243a guifg=#c3ccdc
hi Pmenu guibg=#09243a guifg=#c3ccdc
hi PmenuSel guibg=#316394 guifg=#d6deeb
hi StatusLine guibg=#11324d guifg=#0094ea gui=bold cterm=bold
hi StatusLineNC guibg=#252c3f guifg=#a1aab8 gui=NONE cterm=NONE
hi StatusLineTerm guibg=#588c58 guifg=#90ee90 gui=bold cterm=bold
hi StatusLineTermNC guibg=#366656 guifg=#a1aab8 gui=NONE cterm=NONE
hi MatchParen guibg=#002700 guifg=#00ff00 gui=underline cterm=underline
hi ColorColumn guibg=#2c3043 guifg=NONE
hi Directory guibg=NONE guifg=#8888ff
hi EndOfBuffer guibg=NONE guifg=#444466
hi NonText guibg=NONE guifg=#444466
hi Folded guibg=#336666 guifg=#000000
hi FoldColumn guibg=#336666 guifg=#000000 gui=bold cterm=bold
hi SignColumn guibg=NONE guifg=#ffffff gui=bold cterm=bold
hi ModeMsg guibg=NONE guifg=#90ee90
hi MsgArea guibg=NONE guifg=NONE
hi MsgSeparator guibg=#11324d guifg=#0094ea gui=bold cterm=bold
hi MoreMsg guibg=NONE guifg=#40ffbb
hi WildMenu guibg=#dddddd guifg=#0094ea
"------------------------------
" Standard Syntax (C)
"
hi Comment guifg=#7c8f8f
hi Constant guifg=#90ee90 " Numbers
hi String guifg=#37b166 " String literals
hi Character guifg=#ae81ff " Char literals
hi Identifier guifg=#7fdbca " Variables
hi Function guifg=#0094ea " Function names
hi Statement guifg=#db9e60 gui=NONE " if, else, for, while
hi PreProc guifg=#ff5874 " #include, #define, #ifdef
hi Type guifg=#c77212 gui=NONE " int, void, struct, size_t
hi StorageClass guifg=#db9e60 " static, const
hi Operator guifg=#ff5874 " sizeof, +, -, *
hi Special guifg=#ff5874 " \n, \t inside strings
"------------------------------
" C/C++ Specific Overrides
"
hi cTypedef guifg=#db9e60
hi cppAccess guifg=#db9e60
hi cppCast guifg=#7fdbca
hi cppExceptions guifg=#a1cd5e
hi cppModifier guifg=#db9e60
hi cppOperator guifg=#a1cd5e
hi cppStatement guifg=#7fdbca
hi cppStructure guifg=#db9e60
"------------------------------
" QuickFix / Diagnostic
"
hi ErrorMsg guibg=NONE guifg=#ff514e gui=bold cterm=bold
hi WarningMsg guibg=NONE guifg=#ffc64b gui=bold cterm=bold
hi OkMsg guibg=NONE guifg=#90ee90 gui=bold cterm=bold
hi StderrMsg guibg=NONE guifg=#ff514e gui=bold cterm=bold
hi StdoutMsg guibg=NONE guifg=NONE
hi QuickFixLine guibg=#11324d guifg=NONE
hi qfFileName guifg=#c77212
hi Todo guibg=NONE guifg=#dd0000 gui=bold,underline cterm=bold,underline
"------------------------------
" Diff
"
hi DiffAdd guibg=#009966 guifg=#000000
hi DiffChange guibg=#88a899 guifg=#222222
hi DiffDelete guibg=#884444 guifg=#dd6666 gui=bold cterm=bold
hi DiffText guibg=#006666 guifg=#ffffff
hi DiffTextAdd guibg=#007766 guifg=#000000
"------------------------------
" Netrw
"
hi netrwDir guifg=#0094ea gui=bold cterm=bold " Directories
hi netrwClassify guifg=#ff5874 " Trailing symbols like / or *
hi netrwExe guifg=#90ee90 " Executable files
hi netrwSymLink guifg=#7fdbca " Symlinks
hi netrwTreeBar guifg=#4b6479 " Tree formatting characters (|)
hi netrwPlain guifg=#c3ccdc " Regular files (Foreground)
"------------------------------
" Tabs
"
hi TabLine guibg=#11324d guifg=#0094ea gui=NONE cterm=NONE " Inactive tabs
hi TabLineSel guibg=#366656 guifg=#90ee90 gui=bold cterm=bold " The currently active tab
hi TabLineFill guibg=#252c3f guifg=#8c9f9f gui=NONE cterm=NONE " The empty space behind tabs
hi TabLineInfo guibg=#252c3f guifg=#8c9f9f gui=italic cterm=italic
" TabLineInfo needed to apply style without affecting the other tab highlights
"------------------------------
" Terminal Colors (ANSI Palette)
"
" Neovim
let g:terminal_color_0 = '#000000' " Black
let g:terminal_color_1 = '#e06c75' " Red
let g:terminal_color_2 = '#98c379' " Green
let g:terminal_color_3 = '#c77212' " Yellow
let g:terminal_color_4 = '#0094ea' " Blue
let g:terminal_color_5 = '#c678dd' " Magenta
let g:terminal_color_6 = '#56b6c2' " Cyan
let g:terminal_color_7 = '#c3ccdc' " White
let g:terminal_color_8 = '#222222' " Bright Black
let g:terminal_color_9 = '#ff5874' " Bright Red
let g:terminal_color_10 = '#90ee90' " Bright Green
let g:terminal_color_11 = '#ffcb8b' " Bright Yellow
let g:terminal_color_12 = '#51afef' " Bright Blue
let g:terminal_color_13 = '#d670d6' " Bright Magenta
let g:terminal_color_14 = '#46ddff' " Bright Cyan
let g:terminal_color_15 = '#eeeeee' " Bright White
" Vim
if !has('nvim')
let g:terminal_ansi_colors = [
\ '#000000', '#e06c75', '#98c379', '#c77212',
\ '#0094ea', '#c678dd', '#56b6c2', '#c3ccdc',
\ '#222222', '#ff5874', '#90ee90', '#ffcb8b',
\ '#51afef', '#d670d6', '#46ddff', '#eeeeee'
\ ]
endif
@echo off
:: Usage:
:: v [--vim] [--edit | --term] [-e | -t | -d] [files...]
::
:: Description:
:: Generate terminal-to-host / remote Vim or Nvim command calls
::
:: Options:
:: --vim Use Vim instead of Neovim (must be the first argument)
:: -e Edit file in the current window (default)
:: -t Edit file in a new tab
:: -d Open two files in a new tab and `windo diffthis`
:: --edit Open the `v` script for editing (at %userprofile%\vimfiles\v\v.bat)
:: --term Open current directory (netrw) and launch germinal on a new tab
::
:: Examples:
:: v . Open current directory ($ nvim --server %NVIM% --remote .)
:: v --vim -t main.c Open `main.c` in a new tab ($ vim --servername SERVER --remote-tab main.c)
:: v -d file_a file_b Diff `file_a` (lhs) and `file_b` (rhs)
:: ($ nvim --server %NVIM% --remote-tab file_a
:: $ nvim --server %NVIM% --remote-send "<C-\><C-n> :execute 'vert split ' . fnameescape('file_b') | windo diffthis<CR>")
::
:: Note: if there's no Vim or Neovim server, launch new Vim/Neovide instance
set "V_PRG=nvim"
set "V_SERVER_OP=--server"
set "V_REMOTE_OP=--remote"
set "V_SERVER=%NVIM%"
set "V_ARGS="
set "V_DIFF=0"
set "V_TERM=0"
set "V_FILE_A="
set "V_FILE_B="
:: ==================================================
:: Argument parsing
:: ==================================================
:: Check for the `--vim` (only on %1) flag to set V_PRG to Vim or NeoVim
if "%~1" == "--vim" (
set "V_PRG=vim"
set "V_SERVER_OP=--servername"
set "V_SERVER="
for /f "tokens=*" %%i in ('vim --serverlist') do (
set "V_SERVER=%%i"
goto for_out
)
:for_out
shift
)
:: Set var based on the flag `-e = --remote`, `-t` = remote-tab)
if "%~1" == "-e" (
shift
) else if "%~1" == "-t" (
set "V_REMOTE_OP=--remote-tab"
shift
) else if "%~1" == "-d" (
set "V_DIFF=1"
set "V_FILE_A="%~f2""
set "V_FILE_B=%~f3"
goto end
)
if %V_DIFF% == 0 (
if "%~1" == "" (
set "V_ARGS=."
goto end
) else if "%~1" == "--edit" (
set "V_ARGS="%userprofile%\vimfiles\v\v.bat""
goto end
) else if "%~1" == "--term" (
set "V_ARGS=."
set "V_TERM=1"
goto end
)
)
::echo [DEBUG] V_FILE_A: %V_FILE_A%
::echo [DEBUG] V_FILE_B: %V_FILE_B%
:: Build variable with every arg from the new %1 onwards
:loop
if "%~1" == "" goto end
:: Expand file paths (chek for `-` or `+` for flags)
:: Syntax for getting chars from arguments: %variable:~start_index,length%
set "curr_arg=%~1"
::echo [DEBUG] curr_arg: %curr_arg%
set "prefix=%curr_arg:~0,1%"
::echo [DEBUG] prefix: [%prefix%]
if not "%prefix%" == "-" (
if not "%prefix%" == "+" (
set "curr_arg="%~f1""
)
)
if "%V_ARGS%" == "" (
set "V_ARGS=%curr_arg%"
) else (
set "V_ARGS=%V_ARGS% %curr_arg%"
)
shift
goto loop
:end
:: ==================================================
:: Running commands
:: ==================================================
:: If V_PRG is nvim and there's no Neovide instance, define a server pipe name
:: and launch Neovide, passing --listen to nvim (sleep to wait for Neovide to open)
if "%V_SERVER%" == "" (
if "%V_PRG%" == "nvim" (
set "NVIM=\\.\pipe\neovide_v_server"
set "V_SERVER=\\.\pipe\neovide_v_server"
start neovide -- --listen \\.\pipe\neovide_v_server
) else (
set "V_SERVER=VIM_v_server"
start vim --servername VIM_v_server
)
timeout /t 1 /nobreak >nul
)
:: Launch the V_PRG with server (NeoVim server path is stored in %NVIM% or custom pipe)
if "%V_DIFF%" == "1" (
%V_PRG% %V_SERVER_OP% %V_SERVER% --remote-send "<C-\><C-n> :execute 'tabnew ' . fnameescape('%V_FILE_A%')<CR>"
%V_PRG% %V_SERVER_OP% %V_SERVER% --remote-send "<C-\><C-n> :execute 'vert split ' . fnameescape('%V_FILE_B%') | windo diffthis<CR>"
) else (
%V_PRG% %V_SERVER_OP% %V_SERVER% %V_REMOTE_OP% %V_ARGS%
if %V_TERM% == 1 (
timeout /t 1 /nobreak >nul
%V_PRG% %V_SERVER_OP% %V_SERVER% --remote-send "<C-\><C-n> :Termhere<CR>"
)
)
#!/bin/bash
# Usage:
# v [--vim] [--edit | --term] [-e | -t | -d] [files...]
#
# Description:
# Generate terminal-to-host / remote Vim or Nvim command calls
#
# Options:
# --vim Use Vim instead of Neovim (must be the first argument)
# -e Edit file in the current window (default)
# -t Edit file in a new tab
# -d Open two files in a new tab and `windo diffthis`
# --edit Open the `v` script for editing (at $HOME/.config/vim/v/v)
# --term Open current directory (netrw) and launch germinal on a new tab
#
# Examples:
# v . Open current directory ($ nvim --server $NVIM --remote .)
# v --vim -t main.c Open `main.c` in a new tab ($ vim --servername SERVER --remote-tab main.c)
# v -d file_a file_b Diff `file_a` (lhs) and `file_b` (rhs)
# ($ nvim --server $NVIM --remote-tab file_a
# $ nvim --server $NVIM --remote-send "<C-\><C-n> :execute 'vert split ' . fnameescape('file_b') | windo diffthis<CR>")
#
# Note: if there's no Vim or Neovim server, launch new Vim/Neovide instance
V_PRG="nvim"
V_SERVER_OP="--server"
V_REMOTE_OP="--remote"
V_SERVER="$NVIM"
V_ARGS=()
V_DIFF=0
V_TERM=0
V_FILE_A=""
V_FILE_B=""
# ==================================================
# Argument parsing
# ==================================================
# Check for the `--vim` (only on $1) flag to set V_PRG to Vim or NeoVim
if [[ "$1" == "--vim" ]]; then
V_PRG="vim"
V_SERVER_OP="--servername"
V_SERVER=$(vim --serverlist | head -n 1)
shift
fi
# Set var based on the flag `-e = --remote`, `-t` = remote-tab)
if [ "$1" == "-e" ]; then
shift
elif [ "$1" == "-t" ]; then
V_REMOTE_OP="--remote-tab"
shift
elif [ "$1" == "-d" ]; then
V_DIFF=1
V_FILE_A=$(realpath "$2")
V_FILE_B=$(realpath "$3")
shift 3
fi
if [ "$V_DIFF" -eq 0 ]; then
# If there are no arguments left or `--term`, default to open Netrw on dir
if [ -z "$1" ]; then
V_ARGS=(".")
elif [ "$1" == "--term" ]; then
V_ARGS=(".")
V_TERM=1
elif [ "$1" == "--edit" ]; then
V_ARGS=("$HOME/.config/vim/v/v")
else
# Loop through remaining args
while [ $# -gt 0 ]; do
curr_arg="$1"
prefix="${curr_arg:0:1}"
if [ "$prefix" != "-" ] && [ "$prefix" != "+" ]; then
curr_arg=$(realpath "$curr_arg")
fi
V_ARGS+=("$curr_arg")
shift
done
fi
fi
# ==================================================
# Running commands
# ==================================================
# If V_PRG is nvim and there's no Neovide instance, define a server socket and
# launch Neovide, passing --listen to nvim (sleep to wait for Neovide to open)
if [ -z "$V_SERVER" ]; then
if [ "$V_PRG" == "nvim" ]; then
export NVIM="/tmp/neovide_v_server"
V_SERVER="/tmp/neovide_v_server"
neovide -- --listen "$NVIM" &
else
V_SERVER="VIM_v_server"
"$TERMINAL" --execute vim --servername "$V_SERVER" &
fi
sleep 1
fi
if [ "$V_DIFF" -eq 1 ]; then
"$V_PRG" "$V_SERVER_OP" "$V_SERVER" --remote-send "<C-\><C-n> :execute 'tabnew ' . fnameescape('$V_FILE_A')<CR>"
"$V_PRG" "$V_SERVER_OP" "$V_SERVER" --remote-send "<C-\><C-n> :execute 'vert split ' . fnameescape('$V_FILE_B') | windo diffthis<CR>"
else
# [@] expand the elements of the array with spaces between them
"$V_PRG" "$V_SERVER_OP" "$V_SERVER" "$V_REMOTE_OP" "${V_ARGS[@]}"
if [ "$V_TERM" -eq 1 ]; then
sleep 1
"$V_PRG" "$V_SERVER_OP" "$V_SERVER" --remote-send "<C-\><C-n> :Terminal<CR>"
fi
fi
" Zero dependencies vimrc - naz
" Built-in packages used: netrw, termdebug
let s:is_win = has('win32') || has('win64')
syntax enable
set nocompatible
set termguicolors
colorscheme naz
set hidden " :q will act like :hide
set confirm " Ask to save changes or not if closing last window
set nobackup " Don't keep a backup file after overwriting a file
set nowritebackup " Don't make a backup before overwriting a file
set number " Show line numbers
set relativenumber " Show relative line numbers
set scrolloff=0 " !Keep lines of context around the cursor
set backspace=indent,eol,start
set showcmd
set showcmdloc=last " Show commands on the last line
set wildoptions=pum " Show wildmenu as a pop-up
set formatoptions-=c fo-=r fo-=o fo-=t " Disable comment leader insertion and automatic line breaks
"============================================================
" Searching
"============================================================
set incsearch " Incremental search
set hlsearch " Highlight search results
set ignorecase " Ignore case when searching
set smartcase " Respect case if the query contains uppercase letters
set showmatch " Highlight matching parenthesis.
set tags+=tags;
command! Ctags silent execute '!ctags -R --c-kinds=+p .' | redraw!
"============================================================
" Indentation
"============================================================
set expandtab " Use spaces instead of tabs
set tabstop=2 " Number of spaces a <Tab> counts for
set shiftwidth=2 " Number of spaces to use for auto-indentation
set softtabstop=2 " Number of spaces <Tab> inserts in edit mode
set autoindent " Copy indent from current line when starting a new one
set cindent " Use C-style indentation
set smartindent
" Make trailing whitespace chars visible
set list
set listchars=tab:▸\ ,trail:·
"============================================================
" Terminal
"============================================================
tnoremap <Esc> <C-\><C-n>
"------------------------------
" Global terminal buffer
"
let s:germinal_name = "(GERMINAL)"
let s:germinal_bufnr = bufnr(s:germinal_name)
" The mode arg is used to change the way to invoke the germinal (should only be one instance/buffer).
" A function call will have different behaviors based on the fact that: -> `X. (applies to modes) ...`
" A. (modes [0-4]) The germinal buf is `UNLISTED` (does not exist, buffer not created)
" B. (modes [0-4]) The germinal buf is `IN_VIEW` (open on any window in the active tab);
" C. (mode 3) The germinal buf is `IN_A_TAB` (open on any tab).
"
" `a:mode`s:
" 0:
" A.`UNLISTED`-> create and open a germinal buf on the active window;
" B.`IN_VIEW` -> jump the cursor to the germinal buf.
" 1:
" A.`UNLISTED`-> do a horizontal split on the active window, and create and open a germinal buf;
" B.`IN_VIEW` -> hide/close the germinal buf window, do a horizontal split on the active window,
" and open a germinal buf;
" 2:
" A.`UNLISTED`-> same as mode 1, but doing a vertical split
" B.`IN_VIEW` -> same as mode 1, but doing a vertical split
" 3:
" A.`UNLISTED`-> create a new tab, and create and open a germinal buf;
" B.`IN_VIEW` -> hide/close the germinal buf window, and (C)... ;
" C.`IN_A_TAB`-> activate the first tab that has a germinal buf open, else create a new tab, and
" open the germinal buf;
" 4:
" A.`UNLISTED`-> do a full-width top split (Quake-like), and create and open a germinal buf;
" B.`IN_VIEW` -> hide/close the germinal buf window.
function! GlobalTerminal(mode, count)
let s:germinal_bufnr = bufnr(s:germinal_name)
let l:split_count = (a:count > 0) ? a:count : ''
if s:germinal_bufnr == -1
echomsg '[GlobalTerminal] New terminal buffer assigned to ' . s:germinal_name
if a:mode == 1
execute 'horizontal ' . l:split_count . 'split'
elseif a:mode == 2
execute 'vertical ' . l:split_count . 'split'
elseif a:mode == 3
execute 'tabnew'
elseif a:mode == 4
execute 'topleft ' . l:split_count . 'split'
endif
execute has('nvim') ? 'terminal' : 'terminal ++curwin'
execute 'file ' . s:germinal_name
sleep 500m
else
echomsg '[GlobalTerminal] Using ' . s:germinal_name
" Check if the buf is visible and will split
let l:winnr = bufwinnr(s:germinal_bufnr)
if l:winnr != -1
" Is in view
if a:mode == 0
execute l:winnr . 'wincmd w'
return
else
execute l:winnr . 'hide'
if a:mode == 4
" Quake terminal toggle
return
endif
endif
endif
if a:mode == 3
" Loop through the tabs checking if there's one germinal buf open
let l:first_tabpagenr_with_germinal = -1
for i in range(tabpagenr('$'))
if index(tabpagebuflist(i + 1), s:germinal_bufnr) != -1
let l:first_tabpagenr_with_germinal = i + 1
break
endif
endfor
if l:first_tabpagenr_with_germinal > 0
execute 'tabnext ' . l:first_tabpagenr_with_germinal
execute bufwinnr(s:germinal_bufnr) . 'wincmd w'
return
else
execute '$tabnew'
endif
else
if a:mode == 1
execute 'horizontal ' . l:split_count . 'split'
elseif a:mode == 2
execute 'vertical ' . l:split_count . 'split'
elseif a:mode == 4
execute 'topleft ' . l:split_count . 'split'
endif
endif
execute 'buf ' . s:germinal_bufnr
endif
endfunction
command! Germ call GlobalTerminal(0, 0)
command! -count Serm call GlobalTerminal(1, <count>)
command! -count Verm call GlobalTerminal(2, <count>)
command! Term call GlobalTerminal(3, 0)
command! Germinal call GlobalTerminal(0, 0)
command! -count Serminal call GlobalTerminal(1, <count>)
command! -count Verminal call GlobalTerminal(2, <count>)
command! Terminal call GlobalTerminal(3, 0)
function! GerminalHere(mode, count)
let l:head_dir = (&filetype == 'netrw') ? b:netrw_curdir : expand('%:p:h')
call GlobalTerminal(a:mode, a:count)
call feedkeys("i\<C-c> cd " . ShellEscape(l:head_dir) . "\<CR>\<Esc>", 't')
endfunction
command! Germhere call GerminalHere(0, 0)
command! -count Sermhere call GerminalHere(1, <count>)
command! -count Vermhere call GerminalHere(2, <count>)
command! Termhere call GerminalHere(3, 0)
command! Herm call GerminalHere(3, 0)
command! -count=12 Quake call GlobalTerminal(4, <count>)
command! -count=12 Quakehere call GerminalHere(4, <count>)
nnoremap <C-`> :Quake<CR>
tnoremap <C-`> <C-\><C-n>:hide<CR>
" Fallback for Vim/gVim
nnoremap <F12> :Quake<CR>
tnoremap <F12> <C-\><C-n>:hide<CR>
"============================================================
" Quickfix and Location Lists
"============================================================
"------------------------------
" Quickfix List - only for :make
" (for other commands like :vimgrep, use location list counterpart)
"
" Prepend regex to parse (%f, %l, %t, %m) compiler/linker output correctly for QFListCount()
if !exists('s:prepend_regex_errorformat')
let s:prepend_regex_errorformat = 1
set errorformat& " Reset errorformat to default
" Raw/Generic messages (wrong args or options passed to compiler)
set errorformat^=%t%*[^:]:\ %m
" Clang/LLD (`lld-link: error: cannot open output file ...` or `clang: error: linker command failed ...`)
set errorformat^=%o:\ %t%*[^:]:\ %m
" Clang/GCC Compiler
set errorformat^=%f:%l:%c:\ %t%*[^:]:\ %m
" MSVC Linker (`file.obj : error LNK2019: ...`)
set errorformat^=%f\ :\ %t%*[^:]:\ %m
" MSVC Linker Fatal (`file.obj : fatal error LNK2019: ...` or `c1xx: fatal error C1083: ...`)
set errorformat^=%f\ :\ fatal\ %t%*[^:]:\ %m
set errorformat^=%f:\ fatal\ %t%*[^:]:\ %m
" MSVC Compiler (`file.cpp(#line): error C2065: ...` or `file.cpp(#line) : warning C4700: ...`)
set errorformat^=%f(%l):\ %t%*[^:]:\ %m
set errorformat^=%f(%l)\ :\ %t%*[^:]:\ %m
endif
if !exists('s:qf_entries')
let s:qf_entries = 0
let s:qf_errors = 0
let s:qf_warnings = 0
endif
function! s:QFListCount()
let l:qf_list = getqflist()
let l:entries = 0
let l:errors = 0
let l:warnings = 0
for l:item in l:qf_list
if l:item.valid
let l:entries += 1
if l:item.type ==? 'E'
let l:errors += 1
elseif l:item.type ==? 'W'
let l:warnings += 1
endif
endif
endfor
let s:qf_entries = l:entries
let s:qf_errors = l:errors
let s:qf_warnings = l:warnings
if s:qf_entries > 0
echomsg printf("[s:QFListCount] Entries: %d | Errors: %d | Warnings: %d", s:qf_entries, s:qf_errors, s:qf_warnings)
else
echomsg '[s:QFListCount] Quickfix list is empty'
endif
endfunction
function! s:LocListCount()
let l:loc_list = getloclist(0)
let l:entries = 0
for l:item in l:loc_list
if l:item.valid
let l:entries += 1
endif
endfor
let w:loc_list_entries = l:entries
if w:loc_list_entries > 0
echomsg printf("[s:LocListCount] Matches: %d", w:loc_list_entries)
else
echomsg '[s:LocListCount] Location list is empty'
endif
endfunction
function! QFTabline()
return (s:qf_entries > 0) ? printf("E:%d|W:%d", s:qf_errors, s:qf_warnings) : 'E:_|W:_'
endfunction
augroup QFUpdate
autocmd!
autocmd QuickFixCmdPost [^l]* call s:QFListCount()
autocmd QuickFixCmdPost l* call s:LocListCount()
augroup END
command! Ccount call s:QFListCount()
command! Lcount call s:LocListCount()
command! Cclear cexpr [] | cw
command! Lclear lexpr [] | lw
"============================================================
" Compiling & Debugging
"============================================================
"------------------------------
" Defaults & Compiler
"
if s:is_win
let s:c_compiler = 'clang'
let s:cpp_compiler = 'clang++'
else
let s:c_compiler = 'gcc'
let s:cpp_compiler = 'g++'
endif
" Base and warning flags
let s:common_flags = '-Wall -Wextra -Wpedantic'
let s:c_flags = s:common_flags . ' -std=c99'
let s:cpp_flags = s:common_flags . ' -std=c++03'
" Output program path pattern
let s:dft_out_file = '%:p:h' . '/build/' . '%:t:r' . (s:is_win ? '.exe' : '')
"------------------------------
" Commands for makeprg
"
if !exists('s:makeprg_cmd_name')
let &makeprg = ''
let s:makeprg_cmd_name = ''
let s:makeprg_out_file = ''
endif
command! Makeclear let &makeprg = '' | let s:makeprg_cmd_name = '' | let s:makeprg_out_file = '' | redrawtabline
function! s:SetMakeprg(name, cmd, output)
let s:makeprg_cmd_name = a:name
let &makeprg = a:cmd
let s:makeprg_out_file = a:output
redrawtabline
echo '==> ' . s:makeprg_cmd_name . ' [' . &makeprg . '] set as &makeprg <=='
echo "Output file:\n\t" | echohl WarningMsg | echo s:makeprg_out_file | echohl None
endfunction
" C debug build (default for .c)
command! Makec call s:SetMakeprg('Makec', printf('%s -g -O0 %s "%%:p" -o "%s"', s:c_compiler, s:c_flags, s:dft_out_file), s:dft_out_file)
" C final build
command! MakecRelease call s:SetMakeprg('MakecRelease', printf('%s -O3 %s "%%:p" -o "%s"', s:c_compiler, s:c_flags, s:dft_out_file), s:dft_out_file)
" C++ debug build (default for .cpp)
command! Makecpp call s:SetMakeprg('Makecpp', printf('%s -g -O0 %s "%%:p" -o "%s"', s:cpp_compiler, s:cpp_flags, s:dft_out_file), s:dft_out_file)
" C++ final build
command! MakecppRelease call s:SetMakeprg('MakecppRelease', printf('%s -O3 %s "%%:p" -o "%s"', s:cpp_compiler, s:cpp_flags, s:dft_out_file), s:dft_out_file)
" C fsyntax-only
command! Makecfsyntax call s:SetMakeprg('Makefsyntax', printf('%s -fsyntax-only %s "%%:p"', s:c_compiler, s:c_flags), '')
" C++ fsyntax-only
command! Makecppfsyntax call s:SetMakeprg('Makecppfsyntax', printf('%s -fsyntax-only %s "%%:p"', s:cpp_compiler, s:cpp_flags), '')
" MSVC debug build (need vcvars env)
command! Makecl call s:SetMakeprg('Makecl', 'cd "' . fnamemodify(s:dft_out_file, ':h') . '" && cl /FC /Zi /Od /W4 "%:p"', s:dft_out_file)
" MSVC final build (need vcvars env)
command! MakeclRelease call s:SetMakeprg('MakeclRelease', 'cd "' . fnamemodify(s:dft_out_file, ':h') . '" && cl /FC /O2 /W4 "%:p"', s:dft_out_file)
" Custom makeprg
function! s:PromptCustomMakeprg()
let l:name = input('Name: ', 'Makecustom')
if !empty(l:name)
let l:cmd = input('Command: ', expand('%:p:h') . '/build.bat')
if !empty(l:cmd)
echo "\n"
let l:output = input('Output: ', expandcmd(s:dft_out_file))
echo "\n"
call s:SetMakeprg(l:name, l:cmd, l:output)
return
endif
endif
echomsg 'Setting custom makeprg aborted'
endfunction
command! Makecustom call s:PromptCustomMakeprg()
" Copy makeprg to clipboard
command! Cpmakeprg let @+ = &makeprg | echo '==> ' . s:makeprg_cmd_name . ' [' . @+ . '] copied to the clipboard <=='
" Copy expanded makeprg to clipboard
command! Cpmake let @+ = expandcmd(&makeprg) | echo '==> ' . s:makeprg_cmd_name . ' (expanded) [' . @+ . '] copied to the clipboard <=='
"------------------------------
" Build & Debugging
"
if !exists('s:last_build_out_file')
let s:last_build_out_file = ''
let s:curr_debuggee = ''
endif
command! Buildclear let s:last_build_out_file = '' | let s:curr_debuggee = ''
function! s:IsRaddbgRunning()
" Regex to remove the CSV header of the `tasklist` output
return s:is_win && !empty(substitute(system('tasklist /FO CSV /FI "IMAGENAME eq raddbg.exe"'), '^.[^\n]*\n', '', ''))
endfunction
" Send commands to primary RAD Debugger instance
function! s:SendRaddbgCommand(command)
let l:expd_command = expandcmd(a:command)
call system('raddbg.exe --ipc ' . l:expd_command)
echohl WarningMsg | echo '> raddbg.exe --ipc ' . l:expd_command | echohl None
endfunction
" Create build directory based on s:makeprg_out_file
function! s:CheckBuildDir()
if empty(s:makeprg_out_file) | return | endif
let l:build_dir = fnamemodify(expandcmd(s:makeprg_out_file), ':p:h')
if !isdirectory(l:build_dir)
call mkdir(l:build_dir, "p")
echohl Directory | echomsg 'Build directory ["' . l:build_dir . '"] created.' | echohl None
endif
endfunction
function! s:BuildAndCheck()
let s:last_build_out_file = ''
if empty(&makeprg) | echo 'makeprg is empty...' | return | endif
call s:CheckBuildDir()
execute 'w'
echo 'Build command: ' . expandcmd(&makeprg)
execute 'silent make!'
let l:target_out = expandcmd(s:makeprg_out_file)
" If build fails and raddbg is running, send a Kill command to the current debuggee and retry
if (s:qf_errors > 0 || v:shell_error != 0) && s:is_win
if !empty(l:target_out) && s:IsRaddbgRunning() && s:curr_debuggee == l:target_out
echohl ErrorMsg | echo '- Build failed (possible executable lock): sending Kill command to raddbg and retrying -' | echohl None
call s:SendRaddbgCommand(printf("kill \"%s\"", s:curr_debuggee))
sleep 500m
execute 'silent make!'
endif
endif
" NOTE: `redraw!` seems to be needed on my current linux terminal emulator
if !s:is_win
execute 'redraw!'
endif
if s:qf_errors > 0 || v:shell_error != 0
execute 'copen'
echohl ErrorMsg | echo '==> Build Failed <==' | echohl None
else
let s:last_build_out_file = l:target_out
if s:qf_entries > 0
echohl WarningMsg | echo '==> Build Successful (s:qf_entries:' . s:qf_entries . ') <==' | echohl None
else
echohl OkMsg | echo '==> Build Successful <==' | echohl None
execute 'cclose'
endif
endif
endfunction
" a:mode = 0 -> Raddbg
" a:mode = 1 -> termdebug
" a:run_to_line format is: /path/to/source/file.c:64 (stop at line 64 of file.c)
function! s:BuildAndDebug(mode, run_to_line)
call s:BuildAndCheck()
if empty(s:last_build_out_file)
if empty(s:makeprg_out_file)
echohl WarningMsg | echo "Debuggee: No output file defined for current makeprg" | echohl None
else
echohl ErrorMsg | echo "Debuggee: Last build failed, aborting debugger launch" | echohl None
endif
return
endif
let l:new_target = s:curr_debuggee != s:last_build_out_file
let s:curr_debuggee = s:last_build_out_file
echomsg 'Debuggee: ' . s:curr_debuggee
if a:mode == 0 && s:is_win
" RAD Debugger
if !s:IsRaddbgRunning()
call system('start raddbg.exe')
echohl OkMsg | echo '- RAD Debugger Launched -' | echohl None
let l:new_target = 1
sleep 500m
endif
if l:new_target
call s:SendRaddbgCommand(printf("add_target \"%s\"", s:curr_debuggee))
endif
if !empty(a:run_to_line)
call s:SendRaddbgCommand(printf("run_to_line \"%s\"", a:run_to_line))
else
call s:SendRaddbgCommand('step_over')
endif
elseif a:mode == 1 || !s:is_win
" termdebug
let l:expd_run_to_line = expandcmd(a:run_to_line) " need to expand before running termdebug
if !exists(':Termdebug') | packadd termdebug | endif
execute 'Termdebug ' . s:curr_debuggee
if !empty(a:run_to_line)
call TermDebugSendCommand('tbreak "' . l:expd_run_to_line . '"')
call TermDebugSendCommand('run')
else
call TermDebugSendCommand('start')
endif
" Open disassembly window, local and argument variables window, then jump to the gdb window
execute 'Var'
execute 'Asm'
execute 'Gdb'
"[LEGACY] Launch GDB in a new terminal
"let l:gdb_args = '-tui -ex "layout split" -ex "set print pretty" -ex "set logging file gdb_out.log" -ex "set logging enable on"'
"call system(printf("xfce4-terminal --execute gdb %s \"%s\" &", l:gdb_args, s:curr_debuggee))
"echohl OkMsg | echo '- GDB Launched -' | echohl None
"execute 'redraw!'
endif
endfunction
command! Build call s:BuildAndCheck()
nnoremap <F5> :Build<CR>
"------------------------------
" RAD Debugger commands and maps
"
command! Raddbg call s:BuildAndDebug(0, '')
command! -nargs=1 Radtoline call s:BuildAndDebug(0, '%:p:' . <args>)
command! -nargs=+ Radcmd call s:SendRaddbgCommand(<q-args>)
command! -nargs=+ Radwatch call s:SendRaddbgCommand('toggle_watch_expr "' . <q-args> . '"')
command! -nargs=+ Radmem call s:SendRaddbgCommand('go_to_memory "' . <q-args> . '"')
command! Radbreak call s:SendRaddbgCommand('toggle_breakpoint "%:p:' . line('.') . '"')
command! Radwatchthis call s:SendRaddbgCommand('toggle_watch_expr "<cword>"')
command! Radmemthis call s:SendRaddbgCommand('go_to_memory "<cword>"')
nnoremap <F10> :Raddbg<CR>
nnoremap <C-F10> :Radtoline line('.')<CR>
nnoremap <F9> :Radbreak<CR>
nnoremap <A-w> :Radwatchthis<CR>
nnoremap <A-g> :Radmemthis<CR>
"------------------------------
" termdebug commands and maps
"
command! Tdbg call s:BuildAndDebug(1, '')
command! -nargs=1 Tdbgtoline call s:BuildAndDebug(1, '%:p:' . <args>)
command! -nargs=+ Tdbgcmd call TermDebugSendCommand(<q-args>)
nnoremap <S-F10> :Tdbg<CR>
nnoremap <S-C-F10> :Tdbgtoline line('.')<CR>
function! TermdebugEnableMappings()
nnoremap <F11> :Step<CR>
nnoremap <F10> :Over<CR>
nnoremap <F9> :Break<CR>
nnoremap <F5> :Continue<CR>
echohl WarningMsg | echo '- termdebug mappings enabled -' | echohl None
endfunction
function! TermdebugDisableMappings()
silent! nunmap <F11>
nnoremap <F10> :Raddbg<CR>
nnoremap <F9> :Radbreak<CR>
nnoremap <F5> :Build<CR>
echohl WarningMsg | echo '- termdebug mappings disabled -' | echohl None
endfunction
augroup Termdebug
autocmd!
autocmd User TermdebugStartPost call TermdebugEnableMappings()
autocmd User TermdebugStopPost call TermdebugDisableMappings()
augroup END
"============================================================
" Misc & Netrw
"============================================================
function! ShellEscape(str)
if s:is_win
return '"' . tr(a:str, '/', '\') . '"'
else
return shellescape(a:str)
endif
endfunction
let g:netrw_keepdir = 0
"------------------------------
" Marked files list
"
if !exists('s:nazrw_global_mark_list')
let s:nazrw_global_mark_list = []
endif
function! s:NazrwFetchGlobalMarkList()
let s:nazrw_global_mark_list = netrw#Expose("netrwmarkfilelist")
if type(s:nazrw_global_mark_list) == type("") || empty(s:nazrw_global_mark_list)
let s:nazrw_global_mark_list = []
endif
redrawstatus
endfunction
function! s:NazrwClearGlobalMarkList()
call netrw#Call('NetrwUnMarkFile', 0)
let s:nazrw_global_mark_list = []
redrawstatus
endfunction
function! s:NazrwShowMarkList(last)
call s:NazrwFetchGlobalMarkList()
if empty(s:nazrw_global_mark_list)
echohl Directory | echo '==> Mark list is empty <==' | echohl None
return
else
" copy the mark list with relative paths
let l:rel_mark_list = map(copy(s:nazrw_global_mark_list), "fnamemodify(v:val, ':.')")
let l:len_mark_list = len(l:rel_mark_list)
if a:last
echohl Directory | echo '* ' . l:rel_mark_list[l:len_mark_list - 1] . ' ('. (l:len_mark_list - 1) . ' more...)' | echohl None
else
echohl Directory | echo '[' . len(l:rel_mark_list) . '] marks:' | echohl None
echo '* ' . join(l:rel_mark_list, "\n* ")
endif
endif
endfunction
"------------------------------
" Copy / Move
"
" NOTE (OS file system behavior):
" - Windows: copying/moving a folder into an existing folder will cause a MERGE
" - Linux: copying/moving a folder into an existing folder will cause a NEST (`dest/src_tail`)
function! s:GetCopyMoveCmd(is_move, is_dir)
if a:is_move
if s:is_win
return 'move /Y'
else
return 'mv -f'
endif
else
if s:is_win
return (a:is_dir) ? 'xcopy /E /I /Q /H /Y' : 'copy /Y'
else
return 'cp -rf'
endif
endif
endfunction
" Copy all files from the global mark list and copy/move them to the current dir (b:netrw_curdir)
function! s:NazrwCopyMove(is_move)
call s:NazrwFetchGlobalMarkList()
if empty(s:nazrw_global_mark_list)
echohl Directory | echo '==> Mark list is empty <==' | echohl None
return
endif
" Choices: [1]'Yes', [2]'No', [3]'All' (:help confirm() -> [0] is for <Esc>, CTRL-C)
let l:choice = 2
for l:curr_file in s:nazrw_global_mark_list
" Use regex to remove trailing slashes ('/' or '\'), so `:t` also return directories (for '~/dir//', tail is 'dir')
let l:src_path = fnamemodify(l:curr_file, ':p')
let l:src_path = substitute(l:src_path, '[/\\]\+$', '', '')
let l:dest_path = b:netrw_curdir . '/' . fnamemodify(l:src_path, ':t')
let l:src_is_dir = isdirectory(l:src_path)
let l:dest_is_dir = isdirectory(l:dest_path)
let l:cmd = s:GetCopyMoveCmd(a:is_move, l:src_is_dir)
"(NEST check) Collisions for copying/moving directories on Linux happen in `dest/src_tail`
let l:final_dest_path = l:dest_path
if !s:is_win && l:src_is_dir && l:dest_is_dir
let l:final_dest_path = l:dest_path . '/' . fnamemodify(l:src_path, ':t')
endif
" Check for overwrite and escape ([0] <Esc>)
if (filereadable(l:final_dest_path) || isdirectory(l:final_dest_path)) && l:choice != 3
let l:choice = confirm("Confirm overwrite of file [" . l:final_dest_path . ']?', "&yes\n&no\n&all")
if l:choice == 0
echomsg '[s:NazrwCopyMove()] Aborted.'
break
elseif l:choice == 2
continue
endif
endif
let l:src_path = ShellEscape(l:src_path)
let l:dest_path = ShellEscape(l:dest_path)
echomsg '[s:NazrwCopyMove()]$ ' . l:cmd . ' ' . l:src_path . ' ' . l:dest_path
call system(l:cmd . ' ' . l:src_path . ' ' . l:dest_path)
endfor
call s:NazrwClearGlobalMarkList()
execute "normal \<C-l>"
endfunction
"------------------------------
" Archiving
"
if !exists('s:tarprg')
let s:tarprg = (s:is_win) ? 'tar' : 'bsdtar'
let s:valid_archive_exts = ['zip', 'gz', 'tar', 'tgz', '7z', 'xz', 'bz2', 'tbz2']
let s:default_archive_ext = (s:is_win) ? 'zip' : 'tar.gz'
endif
" Put all files from the global mark list into one archive, prompting for the archive file path
function! s:NazrwArchive()
call s:NazrwFetchGlobalMarkList()
if empty(s:nazrw_global_mark_list)
echohl Directory | echo '==> Mark list is empty <==' | echohl None
return
endif
" Prompt for the archive file path. If no extension is given, a default one is assigned (input() doesn't add a '\n')
let l:archive_path = input('Archive marked files to: ', b:netrw_curdir . '/nazrw_archive.' . s:default_archive_ext, 'file')
echo "\n"
if empty(l:archive_path)
" input() returns an empty string for <Esc>
echomsg '[s:NazrwArchive()] Aborted.'
return
elseif empty(fnamemodify(l:archive_path, ':e'))
" No archive extension provided, set default archiving method
let l:archive_path .= '.' . s:default_archive_ext
endif
" Check if archive head directory exists
let l:archive_head = fnamemodify(l:archive_path, ':h')
if !isdirectory(l:archive_head)
call mkdir(l:archive_head, 'p')
endif
if s:is_win
"==============================
" Windows
" -> bsdtar version does not support the `-s` flag
" -> big batch jobs can exceed the CMD 8,191 character limit
"==============================
let l:cmd = s:tarprg . ' -acf ' . ShellEscape(l:archive_path)
" Loop through the files in the mark list and append ` -C file_head file_tail` to the tar command
for l:curr_file in s:nazrw_global_mark_list
" Use regex to remove trailing slashes ('/' or '\'), so `:t` also returns directories (for '~/dir//', tail is 'dir')
let l:curr_file = substitute(l:curr_file, '[/\\]\+$', '', '')
let l:cmd .= ' -C ' . ShellEscape(fnamemodify(l:curr_file, ':h')) . ' ' . ShellEscape(fnamemodify(l:curr_file, ':t'))
endfor
echomsg '[s:NazrwArchive()]$ ' . l:cmd
call system(l:cmd)
else
"==============================
" Linux
" -> use `-s` regex with `--files-from` option to handle any number of files
"==============================
" Loop through the files in the mark list to generate an array of normalized absolute paths
let l:temp_paths_list = []
for l:curr_file in s:nazrw_global_mark_list
" Normalize slashes and use regex to remove trailing slashes (for '~/dir//', tail is 'dir')
let l:curr_file = tr(l:curr_file, '\', '/')
let l:curr_file = substitute(l:curr_file, '[/\\]\+$', '', '')
call add(l:temp_paths_list, l:curr_file)
endfor
" Write normalized absolute paths to a temp file for the --files-from option
let l:temp_file = tempname()
call writefile(l:temp_paths_list, l:temp_file)
" -s flag regex ensures archive member names include only the file tail (strip everything before the last '/'),
" equivalent to `-C file_head file_tail` for every file path in the temp file
let l:cmd = printf('%s -acf %s -s "|.*/||" --files-from %s', s:tarprg, ShellEscape(l:archive_path), ShellEscape(l:temp_file))
echomsg '[s:NazrwArchive()]$ ' . l:cmd
call system(l:cmd)
call delete(l:temp_file)
endif
call s:NazrwClearGlobalMarkList()
execute "normal \<C-l>"
endfunction
" Extract all files from the global mark list to a directory, prompting for the directory path
function! s:NazrwExtract()
call s:NazrwFetchGlobalMarkList()
if empty(s:nazrw_global_mark_list)
echohl Directory | echo '==> Mark list is empty <==' | echohl None
return
endif
" Prompt for extraction destination directory
let l:extract_dir = input('Extract marked files to: ', b:netrw_curdir . '/nazrw_extracted_' . strftime('%Y%m%d_%H%M%S'), 'dir')
echo "\n"
if empty(l:extract_dir)
echomsg '[s:NazrwExtract()] Aborted.'
return
endif
" Check if destination directory exists
if !isdirectory(l:extract_dir)
call mkdir(l:extract_dir, 'p')
endif
for l:curr_file in s:nazrw_global_mark_list
let l:src_path = fnamemodify(l:curr_file, ':p')
let l:src_path = substitute(l:src_path, '[/\\]\+$', '', '')
let l:extension = tolower(fnamemodify(l:src_path, ':e'))
" Check if extension of current file is a valid archive ext
if index(s:valid_archive_exts, l:extension) == -1
echomsg '[s:NazrwExtract()] Skipping non-archive file: ' . fnamemodify(l:src_path, ':t')
continue
endif
let l:dest_path = l:extract_dir . '/' . fnamemodify(l:src_path, ':t:r')
" Strip .tar extension if it exists (e.g., tar.gz)
if l:dest_path =~? '\.tar$'
let l:dest_path = fnamemodify(l:dest_path, ':r')
endif
if !isdirectory(l:dest_path)
call mkdir(l:dest_path, 'p')
endif
let l:cmd = s:tarprg . ' -xf ' . ShellEscape(l:src_path) . ' -C ' . ShellEscape(l:dest_path)
echomsg '[s:NazrwExtract()]$ ' . l:cmd
call system(l:cmd)
endfor
call s:NazrwClearGlobalMarkList()
execute "normal \<C-l>"
endfunction
"------------------------------
" Commands
"
" NOTE (see `:help command-bar`): Needs `-bar` to pipe custom commands like `:Markclear | Marklast`
command! -bar Nazrwcp call s:NazrwCopyMove(0)
command! -bar Nazrwmv call s:NazrwCopyMove(1)
command! -bar Nazrwzip call s:NazrwArchive()
command! -bar Nazrwunzip call s:NazrwExtract()
command! -bar Smarklist call s:NazrwShowMarkList(0)
command! -bar Smarklast call s:NazrwShowMarkList(1)
command! -bar Markclear call s:NazrwClearGlobalMarkList()
augroup NazNetrw
autocmd!
" [Y]-> Copy file/dir path under the cursor on Netrw
autocmd Filetype netrw nnoremap <buffer> Y :let @+ = ShellEscape(b:netrw_curdir . '/' . expand('<cfile>')) <bar> echo '==> [' . @+ . '] copied to the clipboard <=='<CR>
autocmd Filetype netrw nnoremap <buffer> ~ :e ~/<CR>
autocmd Filetype netrw nnoremap <buffer> mp :Nazrwcp<CR>
autocmd Filetype netrw nnoremap <buffer> mv :Nazrwmv<CR>
autocmd Filetype netrw nnoremap <buffer> mz :Nazrwzip<CR>
autocmd Filetype netrw nnoremap <buffer> mZ :Nazrwunzip<CR>
autocmd Filetype netrw nnoremap <buffer> mu :Markclear <bar> Smarklast<CR>
autocmd Filetype netrw nnoremap <buffer> ml :Smarklist<CR>
autocmd Filetype netrw nnoremap <buffer> mL :Smarklast<CR>
autocmd Filetype netrw nmap <buffer> ; mf:Smarklast<CR>j
autocmd Filetype netrw nmap <buffer> , mf:Smarklast<CR>k
augroup END
command! Cpath :let @+ = ShellEscape((&filetype == 'netrw') ? b:netrw_curdir : expand('%:p')) | echo '==> [' . @+ . '] copied to the clipboard <=='
let mapleader = "\<Backspace>"
nnoremap <leader>cop :copen<CR>
nnoremap <leader>ccl :cclose<CR>
nnoremap <leader>src :source $MYVIMRC <bar> redraw! <bar> redrawtabline <bar> redrawstatus <CR> :echo "==> sourced vimrc <=="<CR>
nnoremap <leader>erc :tab drop $MYVIMRC<CR>
" Make arrow keys behave like Vim in Neovim's wildmenu
if has('nvim')
cnoremap <expr> <down> wildmenumode() ? '<right>' : '<down>'
cnoremap <expr> <up> wildmenumode() ? '<left>' : '<up>'
cnoremap <expr> <right> wildmenumode() ? '<down>' : '<right>'
endif
"============================================================
" Tabline & Statusline
"============================================================
set showtabline=2 " Always show tabline
set laststatus=2 " Always show statusline
let s:superscripts = ['', '¹', '²', '³', '', '', '', '', '', '']
nnoremap <C-S-PageDown> :tabmove +1<CR>
nnoremap <C-S-PageUp> :tabmove -1<CR>
"------------------------------
" Tabline
"
" :help setting-tabline
function! NazTabline()
let l:tabline_str = ''
" Loop through each tab page
for l:i in range(tabpagenr('$'))
let l:tabnr = l:i + 1
" Set the highlighting
if l:tabnr == tabpagenr()
let l:tabline_str .= '%#TabLineSel#'
else
let l:tabline_str .= '%#TabLine#'
endif
" Set the tab page number ('T' enables mouse support)
let l:tabline_str .= '%' . (l:tabnr) . 'T'
" Generate tab label: " ³[2] main.c "
" Convert window count to superscript (`³` part)
let l:win_count = tabpagewinnr(l:tabnr, '$')
let l:win_count_sup = l:win_count < 10 ? s:superscripts[l:win_count] : '^' . l:win_count
" Get active buffer name in curr tab (buflist is 0-indexed, winnr is 1-indexed)
let l:buflist = tabpagebuflist(l:tabnr)
let l:winnr = tabpagewinnr(l:tabnr)
let l:bufnr = l:buflist[l:winnr - 1]
let l:bufname = bufname(l:bufnr)
let l:buf_filetype = getbufvar(l:bufnr, '&filetype')
" Set filename (`main.c` part)
if l:buf_filetype == 'netrw'
let l:filename = '(NETRW) ' . fnamemodify(getbufvar(l:bufnr, 'netrw_curdir'), ':t') . '/'
elseif l:buf_filetype == 'qf'
" Check if window is a Location List (see :help getwininfo)
if getwininfo(win_getid(l:winnr, l:tabnr))[0].loclist
let l:loc_list_entries = gettabwinvar(l:tabnr, l:winnr, "loc_list_entries", 0)
let l:filename = '(Loc) M:' . (l:loc_list_entries > 0 ? l:loc_list_entries : '_')
else
let l:filename = '(QF) %{QFTabline()}'
endif
else
let l:filename = fnamemodify(l:bufname, ':t')
if l:filename == ''
let l:filename = '-No Name-'
endif
endif
" Append a '*' if the buffer has unsaved changes
if getbufvar(l:bufnr, '&modified')
let l:filename .= '*'
endif
let l:tabline_str .= ' ' . l:win_count_sup . '[' . (l:tabnr) . '] ' . l:filename . ' '
endfor
" Add the label to close the current tab page
if tabpagenr('$') > 1
let l:tabline_str .= '%#TabLine#%999X|x|'
endif
" Fill the remaining blank space with TabLineFill highlighting
let l:tabline_str .= '%#TabLineFill#%T'
let l:tabline_str .= '%#TabLineInfo#%T'
let l:tabline_str .= empty(s:makeprg_cmd_name) ? '' : '%=[%{QFTabline()}] ' . s:makeprg_cmd_name
"let l:tabline_str .= " | %{strftime('%H:%M')}"
return l:tabline_str
endfunction
set tabline=%!NazTabline()
"------------------------------
" Statusline
"
function! NazStatusline()
let l:statusline_str = '[%n]%<' " buffer number
let l:bufnr = winbufnr(g:statusline_winid)
let l:buf_filetype = getbufvar(l:bufnr, '&filetype')
if l:buf_filetype == 'netrw'
" current directory relative $HOME and number of marks
let l:statusline_str .= ' %#Directory#' . fnamemodify(getbufvar(l:bufnr, 'netrw_curdir'), ':~') . '%*'
let l:len_mark_list = len(s:nazrw_global_mark_list)
if l:len_mark_list > 0
let l:statusline_str .= ' %#WarningMsg#[M:' . l:len_mark_list . ']%*'
endif
else
" full file path and flags
let l:statusline_str .= ' %F %m%r%h%w'
endif
let l:loc_list_entries = getwinvar(g:statusline_winid, 'loc_list_entries', 0)
if l:loc_list_entries > 0
let l:statusline_str .= ' %#MoreMsg#[Loc:' . l:loc_list_entries . ']%*'
endif
let l:winwidth = winwidth(g:statusline_winid)
if winwidth > 72
let l:statusline_str .= ' %=ch(%b) | %l:%c-%L ↓%p%%'
elseif winwidth > 62
let l:statusline_str .= ' %=%l:%c ↓%p%%'
else
let l:statusline_str .= ' %=↓%p%%'
endif
return l:statusline_str
endfunction
set statusline=%!NazStatusline()
"============================================================
" Cursor & Background
"============================================================
if has('gui_running') || exists('g:neovide')
if has('nvim')
set guicursor=n-v-c:block-Cursor,i-ci-ve-t:ver25-iCursor,r-cr:hor20-iCursor,o:hor50-oCursor
else
set guicursor=n-v-c:block-Cursor,i-ci-ve:ver25-iCursor,r-cr:hor20-iCursor,o:hor50-oCursor
endif
highlight Cursor gui=NONE guifg=Red guibg=#00ff00
highlight iCursor gui=NONE guifg=Black guibg=#ff0000
highlight oCursor gui=NONE guifg=Black guibg=#00ffff
else
let &t_SI = "\e[5 q" " Blinking bar for Insert mode
let &t_SR = "\e[3 q" " Blinking underline for Replace mode
let &t_EI = "\e[1 q" " Blinking block for Normal mode
endif
autocmd InsertEnter * set cursorline
autocmd InsertLeave * set nocursorline
let s:bg_colors = ['#101622', '#000d1a', '#00080f', '#171d2a']
let s:bg_index = 0
function! s:CycleBackground(prev)
if a:prev
let s:bg_index = (s:bg_index - 1 + len(s:bg_colors)) % len(s:bg_colors)
else
let s:bg_index = (s:bg_index + 1) % len(s:bg_colors)
endif
let l:next_color = s:bg_colors[s:bg_index]
execute 'highlight Normal guibg=' . l:next_color
endfunction
command! CycleBGNext call s:CycleBackground(0)
command! CycleBGPrev call s:CycleBackground(1)
nnoremap <leader>bgn :CycleBGNext<CR>
nnoremap <leader>bgN :CycleBGPrev<CR>
"============================================================
" Neovide & GVim
"============================================================
if has('gui_running') || exists('g:neovide')
let &guifont = 'Cousine' . ((s:is_win || has('nvim')) ? ':h12' : ' 12')
if has('nvim')
"------------------------------
" Neovide
"
" Initial scale
if !exists('g:neovide_scale_factor')
let g:neovide_scale_factor = 1.0
endif
let g:neovide_scroll_animation_length = 0.2
command! Scalen :let g:neovide_scale_factor += 0.1
command! ScaleN :let g:neovide_scale_factor -= 0.1
command! Scale :let g:neovide_scale_factor = 1.0
nnoremap <A-Enter> :let g:neovide_fullscreen = (g:neovide_fullscreen) ? v:false : v:true<CR>
else
"------------------------------
" GVim
"
set guioptions+=c " Use console dialogs for simple choices
"set guioptions+=s " Enable fullscreen mode
set guioptions-=m " Remove menu bar
set guioptions-=T " Remove toolbar
set guioptions-=e " Remove gui tag pages
set guioptions-=r " Remove right-hand scrollbar
set guioptions-=L " Remove left-hand scrollbar
function! s:GVimFontScale(amount)
" Grab the trailing digits and add a:amount
let l:font_size = matchstr(&guifont, '\d\+$')
if l:font_size == ''
echomsg '[GVimFontScale] Something went wrong. guifont should be "Font Name N" (N is the size).'
echo &guifont
return
endif
let l:new_size = str2nr(l:font_size) + a:amount
" Swaps the old size for the new size
let &guifont = substitute(&guifont, '\d\+$', l:new_size, '')
endfunction
command! -count=1 Scalen call s:GVimFontScale(<count>)
command! -count=1 ScaleN call s:GVimFontScale(-<count>)
command! Scale let &guifont = 'Cousine' . (s:is_win ? ':h12' : ' 12')
nnoremap <C-_> :ScaleN<CR>
nnoremap <expr> <A-Enter> &guioptions =~# 's' ? ":set guioptions-=s<CR>" : ":set guioptions+=s<CR>"
endif
nnoremap <C-=> :Scalen<CR>
nnoremap <C--> :ScaleN<CR>
nnoremap <C-0> :Scale<CR>
nnoremap <C-ScrollWheelUp> :Scalen<CR>
nnoremap <C-ScrollWheelDown> :ScaleN<CR>
endif
"------------------------------
" Contents of init.lua
"
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
" Linux path: `~/.config/nvim/init.lua`
" Windows path: `%localappdata%\nvim\init.lua`
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"-- Vim paths to Neovim
"local vimrc_path = ""
"local vimfiles_dir = ""
"
"if vim.fn.has('win32') == 1 or vim.fn.has('win64') == 1 then
" vimrc_path = vim.fn.expand('~/vimfiles/vimrc')
" vimfiles_dir = vim.fn.expand('~/vimfiles')
"else
" vimrc_path = vim.fn.expand('~/.config/vim/vimrc')
" vimfiles_dir = vim.fn.expand('~/.config/vim')
"end
"
"vim.opt.runtimepath:prepend(vimfiles_dir)
"vim.opt.runtimepath:append(vimfiles_dir .. '/after')
"vim.opt.packpath = vim.opt.runtimepath:get()
"
"-- Source my vimrc
"vim.cmd('source ' .. vimrc_path)
"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment