.vimrc Unlocked: Supercharge Vim with These Expert Configurations
A .vimrc file is a configuration file for Vim—a highly configurable text editor favored by developers and power users. This file is automatically loaded each time Vim starts, allowing you to customize editor behavior, define key mappings, set visual preferences, and load plugins. By editing your .vimrc, you tailor Vim to suit your coding style and workflow.
Table of Contents
- Introduction to .vimrc
- Tabbing and Indenting
- Plugin Management with Pathogen
- Display and Interface Settings
- Statusline Customizations
- File Navigation and netrw
- Key Mappings
- Custom Functions
- Conclusion
Introduction to .vimrc
The .vimrc file is Vim’s primary configuration file. It defines settings that control how Vim behaves—everything from indentation and syntax highlighting to plugin management and custom commands. When Vim starts, it reads the .vimrc file and applies these settings, allowing you to work in an environment optimized for your preferences. I’m going to be explaining a .vimrc file that I used to use but no longer maintain. Hopefully it can be of some use to someone! The whole .vimrc file will be available at the end.
Tabbing and Indenting
This section sets up how Vim handles indentation and tabbing:
-
Auto Indentation:
set autoindent set smarttab set smartindent
These commands ensure that new lines automatically inherit the indentation of the previous line, and that Vim intelligently applies indentation based on your programming language’s syntax.
-
Indentation Width:
set shiftwidth=4 set softtabstop=4 set tabstop=4
These settings define the width for auto-indenting, the number of spaces inserted when you press Tab, and the visual width of a tab character.
-
Spaces Instead of Tabs:
set expandtab
This command converts tab characters to spaces, ensuring consistent formatting across different environments.
-
Paste Mode Toggle:
set pastetoggle=<F2>
When pasting code, Vim’s auto-indentation can sometimes distort the original formatting. Toggling paste mode (with F2) temporarily disables auto-indenting, preserving the intended layout.
-
Leader Key and Debug Mapping:
let mapleader = "\\" inoremap <Leader>] import ipdb; ipdb.set_trace()
Here, the leader key is set to
\
, and in insert mode, typing\]
will insert a Python debugging breakpoint (import ipdb; ipdb.set_trace()
).
Plugin Management with Pathogen
Pathogen is a popular plugin manager for Vim. It simplifies the process of adding and managing Vim plugins:
execute pathogen#infect()
By executing pathogen#infect()
, Vim is instructed to load any plugins stored in the designated plugin directory (often ~/.vim/bundle
). This single line makes it easy to integrate a variety of plugins without cluttering your .vimrc.
Display and Interface Settings
This section is dedicated to the visual aspects and usability of Vim:
-
Color Scheme and Highlighting:
colorscheme koehler hi Search guibg=peru guifg=wheat
The color scheme
koehler
sets the overall look and feel, while thehi Search
command customizes the background and foreground colors of search matches. -
Cursor Positioning and Mode Display:
set scrolloff=9999 set showmode set number
scrolloff=9999
keeps the cursor centered in the window.showmode
displays the current mode (e.g., insert or visual), which is especially helpful for new users.set number
enables line numbering.
-
Syntax and Filetype Plugins:
syntax enable filetype plugin on
These commands turn on syntax highlighting and allow Vim to load filetype-specific plugins, enhancing code readability.
-
Enhanced Command-Line Completion:
set wildmenu
This setting provides a visual menu for command-line completion, making it easier to navigate through available commands.
Statusline Customizations
This section (currently commented out) includes a detailed custom statusline configuration:
-
Statusline Functions:
The file contains helper functions (e.g.,GitBranch()
andStatuslineGit()
) designed to display the current Git branch in the statusline. -
Statusline Layout:
The commented-out commands would construct a statusline that displays the file path, buffer number, current line/column information, and more. Although inactive, this section shows how to create a dynamic statusline that updates with your work context.
File Navigation and netrw
These settings improve file browsing and navigation within Vim:
-
Recursive File Search:
set path+=**
By appending
**
to thepath
option, Vim will search recursively through subfolders, making it easier to locate files. -
Wildmenu for File Completion:
set wildmenu
Reiterating the use of the wildmenu enhances tab completion for file names.
-
netrw Configuration:
let g:netrw_liststyle = 3
This setting customizes
netrw
(Vim’s built-in file explorer) to use a specific list style for displaying directory contents.
Key Mappings
Custom key mappings help streamline your workflow:
-
Quick Exit from Insert Mode:
inoremap kj <Esc>
Instead of reaching for the Escape key, typing
kj
in insert mode returns you to normal mode. -
Opening the .vimrc File:
nnoremap <C-c> :edit ~/.vimrc <CR>
This mapping makes it easy to open and edit your .vimrc by pressing Ctrl+C in normal mode.
-
Navigation Between Indented Code Blocks:
nnoremap <C-n> :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%>' . line('.') . 'l\S', 'e')<CR> nnoremap <C-p> :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%<' . line('.') . 'l\S', 'be')<CR>
These mappings allow you to jump to the next or previous line that has similar indentation—a useful feature when navigating code blocks in languages like Python.
-
Tab Navigation:
nnoremap tn :tabn<cr> nnoremap tp :tabp<cr>
Quickly switch between tabs using
tn
for next andtp
for previous. -
Repeating the Debug Mapping:
The mapping for inserting a debugging statement is repeated for emphasis:inoremap <Leader>] import ipdb; ipdb.set_trace()
-
Line Navigation Shortcuts:
nnoremap Y y$ map H ^ map L $
Y
is remapped to yank (copy) from the cursor to the end of the line.H
andL
are mapped to jump to the beginning and end of the line, respectively.
Custom Functions
The .vimrc also includes several custom functions that extend Vim’s capabilities:
-
CSV Column Highlighter:
function! CSVH(colnr) if a:colnr>1 let n = a:colnr - 1 execute 'match Keyword /^\([^,]*,\)\{'.n.'}\zs[^,]*/' execute 'normal! 0'.n.'f,' elseif a:colnr ==1 match Keyword /^[^,]*/ normal! 0 else match endif endfunction command! -nargs=1 Csv :call CSVH(<args>)
This function highlights a specific column in CSV files. By matching the pattern based on commas, it visually distinguishes the chosen column, which is especially useful when working with data files.
-
Test File Finder:
function! OTest() let filename = expand('%:t:r') execute 'find ' . filename . 'Test.py' endfunction command! OpenTest :call OTest()
Designed for a Python workflow, this function searches for a test file corresponding to the current script (e.g., if you’re editing
MyScript.py
, it looks forMyScriptTest.py
). -
CSV Row Viewer:
function! VRow() let first_line = getbufline(bufnr(bufname('%')), 1)[0] let first_line_split = split(first_line, ",") let len_first_list_split = len(first_line_split) let current_line = getbufline(bufnr(bufname('%')), line('.'))[0] let current_line_split = split(current_line, ",") let total_buffer='' let i = len_first_list_split - 1 while i >= 0 call append(line('.'), ' * ' . first_line_split[i] . "\t" . current_line_split[i] ) let i -= 1 endwhile endfunction command! ViewRow :call VRow()
This function takes a row from a CSV file and displays it vertically along with its header labels. It makes it easier to review data by aligning each header with its corresponding value.
-
Conditional Sourcing:
function! SourceIfExists(file) if filereadable(expand(a:file)) exe 'source' a:file endif endfunction call SourceIfExists("~/.vimrc.local")
This function checks if a file exists before sourcing it. By calling it with
~/.vimrc.local
, you can include additional, local settings without causing errors if the file isn’t present.
Conclusion
This .vimrc file is a robust example of how to customize Vim to match your workflow. It covers everything from basic indentation and display settings to advanced functions and key mappings. By understanding each section—from tabbing and indenting to plugin management and custom commands—you can tailor Vim into a powerful, personalized development environment. Whether you are debugging Python code, navigating CSV files, or simply editing text, each setting and function contributes to a smoother, more efficient editing experience.
Whole .vimrc
:
"""""""""""""""""""
" tabbing/indenting
set autoindent
set smarttab
set smartindent
set shiftwidth=4
set softtabstop=4
set tabstop=4
" tabs are just spaces instead of tab characters
set expandtab
" insert-paste mode avoids the extra indents that get added when pasting
" indented text - toggle by pressing F2 in insert mode
" https://stackoverflow.com/a/2514520
set pastetoggle=<F2>
let mapleader = "\\"
inoremap <Leader>] import ipdb; ipdb.set_trace()
""""""""""""""""""
" pathogen
execute pathogen#infect()
"""""""""""""""""""
" display/info
colorscheme koehler
" set search match color scheme
hi Search guibg=peru guifg=wheat
" make it so your cursor is always in the middle of the buffer (if possible)
set scrolloff=9999
" show if you are in insert/visual mode
set showmode
set number
" I forget why these are here
syntax enable
filetype plugin on
set wildmenu
"""""""""""""""""""
"" statusline
"" always show statusline
"set laststatus=2
"" statusline helper functions
"" both of these taken from https://shapeshed.com/vim-statuslines/
"function! GitBranch()
" return system("git rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n'")
"endfunction
"function! StatuslineGit()
" let l:branchname = GitBranch()
" return strlen(l:branchname) > 0?''.l:branchname.'':''
"endfunction
"" status line documentation: http://learnvimscriptthehardway.stevelosh.com/chapters/17.html
"set statusline=
"set statusline+=%#MatchParen# " Set highlight scheme
"set statusline+=(%{StatuslineGit()}) " Print git branch
"set statusline+=%#LineNr# " Set highlight scheme
"set statusline+=\ %.40F " Full path to the file (max width of 40 chars)
"set statusline+=%= " Switch to the right side
"set statusline+=Buf:%n " Buffer number
"set statusline+=\ Line: " Label
"set statusline+=%l " Current line
"set statusline+=/ " Separator
"set statusline+=%L " Total lines
"set statusline+=\ Col:%c " Current column
"""""""""""""""""""
" other stuff
" For finding files (taken from https://github.com/changemewtf/no_plugins/blob/master/no_plugins.vim)
" Search down into subfolders
" Provides tab completion for all file related tasks
set path+=**
" Display all matching files when we tab complete
set wildmenu
" netrw (vim's built-in filesystem - ':help netrw')
let g:netrw_liststyle = 3
""""""""""""""""""
" Mappings
" map kj to <Esc
inoremap kj <Esc>
" open vimrc
" can't use ctrl-c in normal mode anyway
nnoremap <C-c> :edit ~/.vimrc <CR>
" Both of below adapted from
" https://vim.fandom.com/wiki/Move_to_next/previous_line_with_same_indentation
" Find next char in current column (useful for jumping from if to else in python)
nnoremap <C-n> :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%>' . line('.') . 'l\S', 'e')<CR>
" Find previous in current column
nnoremap <C-p> :call search('^'. matchstr(getline('.'), '\(^\s*\)') .'\%<' . line('.') . 'l\S', 'be')<CR>
" convenient tab movement
nnoremap tn :tabn<cr>
nnoremap tp :tabp<cr>
inoremap <Leader>] import ipdb; ipdb.set_trace()
"""""""""""""""""""
" Functions
" highlight column in csv
" taken from https://vim.fandom.com/wiki/Working_with_CSV_files
function! CSVH(colnr)
if a:colnr>1
let n = a:colnr - 1
execute 'match Keyword /^\([^,]*,\)\{'.n.'}\zs[^,]*/'
execute 'normal! 0'.n.'f,'
elseif a:colnr ==1
match Keyword /^[^,]*/
normal! 0
else
match
endif
endfunction
command! -nargs=1 Csv :call CSVH(<args>)
" Say you have a file named MyScript.py, this ones a file named
" MyScriptTest.py
function! OTest()
" filename without extension
let filename = expand('%:t:r')
execute 'find ' . filename . 'Test.py'
endfunction
command! OpenTest :call OTest()
" View a csv row vertically
" - Matches up headers with values
" - Makes it easy to see what the row consists of
function! VRow()
let first_line = getbufline(bufnr(bufname('%')), 1)[0]
let first_line_split = split(first_line, ",")
let len_first_list_split = len(first_line_split)
let current_line = getbufline(bufnr(bufname('%')), line('.'))[0]
let current_line_split = split(current_line, ",")
let total_buffer=''
let i = len_first_list_split - 1
while i >= 0
call append(line('.'), ' * ' . first_line_split[i] . "\t" . current_line_split[i] )
let i -= 1
endwhile
endfunction
command! ViewRow :call VRow()
" The below function was taken from https://devel.tech/snippets/n/vIIMz8vZ/load-vim-source-files-only-if-they-exist/
" Function to source only if file exists {
function! SourceIfExists(file)
if filereadable(expand(a:file))
exe 'source' a:file
endif
endfunction
" }
call SourceIfExists("~/.vimrc.local")
nnoremap Y y$
map H ^
map L $
Also available at https://github.com/zcarciu/dotfiles/blob/master/.vimrc