DEV Community
This article was originally published in HackerNoon
Over the years I've jumped back and forth between many code editors, IDEs and tools; but it seems that somehow I always end up coming right back to VIM, and not only for programming – guess which markdown editor I'm using to write this post.
I've have tried Atom, SublimeText, TextMate, Eclipse, Visual Studio, and most of the Jetbrains products, I'm constantly tweaking and looking for a better setup, however Vim always feels like home to me; and I'm to the point now where I rarely use IDEs – exception being messy and complex projects where IDEs can do a lot of heavily lifting (yes, Magento I'm talking about you.)
But other than that Vim is my default Ruby, Elixir, Python, PHP IDE and as well the main tool that I use for writing drafts and books.
What it look like
The Setup
So how does this magical tool work? Is all out of the box right? right? Well no, as with all the worthwhile things in life there is a bit of effort involved on getting the Vim setup just like I wanted it. Fortunately, is far from custom and is mostly the right combination of plugins.
You can find my current Vim configuration and dot files in its corresponding Github repository feel free to fork it and give a shot.
We are in particular interested in the vimrc file, let's break it down:
"""""""""""""""""""""""""""""""""""""
" Allan MacGregor Vimrc configuration
"""""""""""""""""""""""""""""""""""""
set nocompatible
syntax on
set nowrap
set encoding=utf8
"""" START Vundle Configuration
" Disable file type for vundle
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
" Utility
Plugin 'scrooloose/nerdtree'
Plugin 'majutsushi/tagbar'
Plugin 'ervandew/supertab'
Plugin 'BufOnly.vim'
Plugin 'wesQ3/vim-windowswap'
Plugin 'SirVer/ultisnips'
Plugin 'junegunn/fzf.vim'
Plugin 'junegunn/fzf'
Plugin 'godlygeek/tabular'
Plugin 'ctrlpvim/ctrlp.vim'
Plugin 'benmills/vimux'
Plugin 'jeetsukumaran/vim-buffergator'
Plugin 'gilsondev/searchtasks.vim'
Plugin 'Shougo/neocomplete.vim'
Plugin 'tpope/vim-dispatch'
" Generic Programming Support
Plugin 'jakedouglas/exuberant-ctags'
Plugin 'honza/vim-snippets'
Plugin 'Townk/vim-autoclose'
Plugin 'tomtom/tcomment_vim'
Plugin 'tobyS/vmustache'
Plugin 'janko-m/vim-test'
Plugin 'maksimr/vim-jsbeautify'
Plugin 'vim-syntastic/syntastic'
Plugin 'neomake/neomake'
" Markdown / Writting
Plugin 'reedes/vim-pencil'
Plugin 'tpope/vim-markdown'
Plugin 'jtratner/vim-flavored-markdown'
Plugin 'LanguageTool'
" Git Support
Plugin 'kablamo/vim-git-log'
Plugin 'gregsexton/gitv'
Plugin 'tpope/vim-fugitive'
"Plugin 'jaxbot/github-issues.vim'
" PHP Support
Plugin 'phpvim/phpcd.vim'
Plugin 'tobyS/pdv'
" Erlang Support
Plugin 'vim-erlang/vim-erlang-tags'
Plugin 'vim-erlang/vim-erlang-runtime'
Plugin 'vim-erlang/vim-erlang-omnicomplete'
Plugin 'vim-erlang/vim-erlang-compiler'
" Elixir Support
Plugin 'elixir-lang/vim-elixir'
Plugin 'avdgaag/vim-phoenix'
Plugin 'mmorearty/elixir-ctags'
Plugin 'mattreduce/vim-mix'
Plugin 'BjRo/vim-extest'
Plugin 'frost/vim-eh-docs'
Plugin 'slashmili/alchemist.vim'
Plugin 'tpope/vim-endwise'
Plugin 'jadercorrea/elixir_generator.vim'
" Elm Support
Plugin 'lambdatoast/elm.vim'
" Theme / Interface
Plugin 'AnsiEsc.vim'
Plugin 'ryanoasis/vim-devicons'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'sjl/badwolf'
Plugin 'tomasr/molokai'
Plugin 'morhetz/gruvbox'
Plugin 'zenorocha/dracula-theme', {'rtp': 'vim/'}
Plugin 'junegunn/limelight.vim'
Plugin 'mkarmona/colorsbox'
Plugin 'romainl/Apprentice'
Plugin 'Lokaltog/vim-distinguished'
Plugin 'chriskempson/base16-vim'
Plugin 'w0ng/vim-hybrid'
Plugin 'AlessandroYorba/Sierra'
Plugin 'daylerees/colour-schemes'
Plugin 'effkay/argonaut.vim'
Plugin 'ajh17/Spacegray.vim'
Plugin 'atelierbram/Base2Tone-vim'
Plugin 'colepeters/spacemacs-theme.vim'
" OSX stupid backspace fix
set backspace=indent,eol,start
call vundle#end() " required
filetype plugin indent on " required
"""" END Vundle Configuration
"""""""""""""""""""""""""""""""""""""
" Configuration Section
"""""""""""""""""""""""""""""""""""""
" Show linenumbers
set number
set ruler
" Set Proper Tabs
set tabstop=4
set shiftwidth=4
set smarttab
set expandtab
" Always display the status line
set laststatus=2
" Enable Elite mode, No ARRRROWWS!!!!
let g:elite_mode=1
" Enable highlighting of the current line
set cursorline
" Theme and Styling
set t_Co=256
set background=dark
if (has("termguicolors"))
set termguicolors
endif
let base16colorspace=256 " Access colors present in 256 colorspace
colorscheme spacegray
" colorscheme spacemacs-theme
let g:spacegray_underline_search = 1
let g:spacegray_italicize_comments = 1
" Vim-Airline Configuration
let g:airline#extensions#tabline#enabled = 1
let g:airline_powerline_fonts = 1
let g:airline_theme='hybrid'
let g:hybrid_custom_term_colors = 1
let g:hybrid_reduced_contrast = 1
" Syntastic Configuration
set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*
let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
" let g:syntastic_check_on_wq = 0
" let g:syntastic_enable_elixir_checker = 1
" let g:syntastic_elixir_checkers = ["elixir"]
" Neomake settings
autocmd! BufWritePost * Neomake
let g:neomake_elixir_enabled_makers = ['mix', 'credo', 'dogma']
" Vim-PDV Configuration
let g:pdv_template_dir = $HOME ."/.vim/bundle/pdv/templates_snip"
" Markdown Syntax Support
augroup markdown
au!
au BufNewFile,BufRead *.md,*.markdown setlocal filetype=ghmarkdown
augroup END
" Github Issues Configuration
let g:github_access_token = "e6fb845bd306a3ca7f086cef82732d1d5d9ac8e0"
" Vim-Alchemist Configuration
let g:alchemist#elixir_erlang_src = "/Users/amacgregor/Projects/Github/alchemist-source"
let g:alchemist_tag_disable = 1
" Vim-Supertab Configuration
let g:SuperTabDefaultCompletionType = "<C-X><C-O>"
" Settings for Writting
let g:pencil#wrapModeDefault = 'soft' " default is 'hard'
let g:languagetool_jar = '/opt/languagetool/languagetool-commandline.jar'
" Vim-pencil Configuration
augroup pencil
autocmd!
autocmd FileType markdown,mkd call pencil#init()
autocmd FileType text call pencil#init()
augroup END
" Vim-UtilSnips Configuration
" Trigger configuration. Do not use <tab> if you use https://github.com/Valloric/YouCompleteMe.
let g:UltiSnipsExpandTrigger="<tab>"
let g:UltiSnipsJumpForwardTrigger="<c-b>"
let g:UltiSnipsJumpBackwardTrigger="<c-z>"
let g:UltiSnipsEditSplit="vertical" " If you want :UltiSnipsEdit to split your window.
" Vim-Test Configuration
let test#strategy = "vimux"
" Neocomplete Settings
let g:acp_enableAtStartup = 0
let g:neocomplete#enable_at_startup = 1
let g:neocomplete#enable_smart_case = 1
let g:neocomplete#sources#syntax#min_keyword_length = 3
" Define dictionary.
let g:neocomplete#sources#dictionary#dictionaries = {
\ 'default' : '',
\ 'vimshell' : $HOME.'/.vimshell_hist',
\ 'scheme' : $HOME.'/.gosh_completions'
\ }
" Define keyword.
if !exists('g:neocomplete#keyword_patterns')
let g:neocomplete#keyword_patterns = {}
endif
let g:neocomplete#keyword_patterns['default'] = '\h\w*'
function! s:my_cr_function()
return (pumvisible() ? "\<C-y>" : "" ) . "\<CR>"
" For no inserting <CR> key.
"return pumvisible() ? "\<C-y>" : "\<CR>"
endfunction
" Close popup by <Space>.
"inoremap <expr><Space> pumvisible() ? "\<C-y>" : "\<Space>"
" AutoComplPop like behavior.
"let g:neocomplete#enable_auto_select = 1
" Enable omni completion.
autocmd FileType css setlocal omnifunc=csscomplete#CompleteCSS
autocmd FileType html,markdown setlocal omnifunc=htmlcomplete#CompleteTags
autocmd FileType javascript setlocal omnifunc=javascriptcomplete#CompleteJS
autocmd FileType python setlocal omnifunc=pythoncomplete#Complete
autocmd FileType xml setlocal omnifunc=xmlcomplete#CompleteTags
" Enable heavy omni completion.
if !exists('g:neocomplete#sources#omni#input_patterns')
let g:neocomplete#sources#omni#input_patterns = {}
endif
"let g:neocomplete#sources#omni#input_patterns.php = '[^. \t]->\h\w*\|\h\w*::'
"let g:neocomplete#sources#omni#input_patterns.c = '[^.[:digit:] *\t]\%(\.\|->\)'
"let g:neocomplete#sources#omni#input_patterns.cpp = '[^.[:digit:] *\t]\%(\.\|->\)\|\h\w*::'
" For perlomni.vim setting.
" https://github.com/c9s/perlomni.vim
let g:neocomplete#sources#omni#input_patterns.perl = '\h\w*->\h\w*\|\h\w*::'
" Elixir Tagbar Configuration
let g:tagbar_type_elixir = {
\ 'ctagstype' : 'elixir',
\ 'kinds' : [
\ 'f:functions',
\ 'functions:functions',
\ 'c:callbacks',
\ 'd:delegates',
\ 'e:exceptions',
\ 'i:implementations',
\ 'a:macros',
\ 'o:operators',
\ 'm:modules',
\ 'p:protocols',
\ 'r:records',
\ 't:tests'
\ ]
\ }
" Fzf Configuration
" This is the default extra key bindings
let g:fzf_action = {
\ 'ctrl-t': 'tab split',
\ 'ctrl-x': 'split',
\ 'ctrl-v': 'vsplit' }
" Default fzf layout
" - down / up / left / right
let g:fzf_layout = { 'down': '~40%' }
" In Neovim, you can set up fzf window using a Vim command
let g:fzf_layout = { 'window': 'enew' }
let g:fzf_layout = { 'window': '-tabnew' }
" Customize fzf colors to match your color scheme
let g:fzf_colors =
\ { 'fg': ['fg', 'Normal'],
\ 'bg': ['bg', 'Normal'],
\ 'hl': ['fg', 'Comment'],
\ 'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
\ 'bg+': ['bg', 'CursorLine', 'CursorColumn'],
\ 'hl+': ['fg', 'Statement'],
\ 'info': ['fg', 'PreProc'],
\ 'prompt': ['fg', 'Conditional'],
\ 'pointer': ['fg', 'Exception'],
\ 'marker': ['fg', 'Keyword'],
\ 'spinner': ['fg', 'Label'],
\ 'header': ['fg', 'Comment'] }
" Enable per-command history.
" CTRL-N and CTRL-P will be automatically bound to next-history and
" previous-history instead of down and up. If you don't like the change,
" explicitly bind the keys to down and up in your $FZF_DEFAULT_OPTS.
let g:fzf_history_dir = '~/.local/share/fzf-history'
"""""""""""""""""""""""""""""""""""""
" Mappings configurationn
"""""""""""""""""""""""""""""""""""""
map <C-n> :NERDTreeToggle<CR>
map <C-m> :TagbarToggle<CR>
" Omnicomplete Better Nav
inoremap <expr> <c-j> ("\<C-n>")
inoremap <expr> <c-k> ("\<C-p>")
" Neocomplete Plugin mappins
inoremap <expr><C-g> neocomplete#undo_completion()
inoremap <expr><C-l> neocomplete#complete_common_string()
" Recommended key-mappings.
" <CR>: close popup and save indent.
inoremap <silent> <CR> <C-r>=<SID>my_cr_function()<CR>
" <TAB>: completion.
inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
" <C-h>, <BS>: close popup and delete backword char.
inoremap <expr><C-h> neocomplete#smart_close_popup()."\<C-h>"
inoremap <expr><BS> neocomplete#smart_close_popup()."\<C-h>"
" Mapping selecting Mappings
nmap <leader><tab> <plug>(fzf-maps-n)
xmap <leader><tab> <plug>(fzf-maps-x)
omap <leader><tab> <plug>(fzf-maps-o)
" Shortcuts
nnoremap <Leader>o :Files<CR>
nnoremap <Leader>O :CtrlP<CR>
nnoremap <Leader>w :w<CR>
" Insert mode completion
imap <c-x><c-k> <plug>(fzf-complete-word)
imap <c-x><c-f> <plug>(fzf-complete-path)
imap <c-x><c-j> <plug>(fzf-complete-file-ag)
imap <c-x><c-l> <plug>(fzf-complete-line)
" Vim-Test Mappings
nmap <silent> <leader>t :TestNearest<CR>
nmap <silent> <leader>T :TestFile<CR>
nmap <silent> <leader>a :TestSuite<CR>
nmap <silent> <leader>l :TestLast<CR>
nmap <silent> <leader>g :TestVisit<CR>
" Vim-PDV Mappings
autocmd FileType php inoremap <C-p> <ESC>:call pdv#DocumentWithSnip()<CR>i
autocmd FileType php nnoremap <C-p> :call pdv#DocumentWithSnip()<CR>
autocmd FileType php setlocal omnifunc=phpcd#CompletePHP
" Disable arrow movement, resize splits instead.
if get(g:, 'elite_mode')
nnoremap <Up> :resize +2<CR>
nnoremap <Down> :resize -2<CR>
nnoremap <Left> :vertical resize +2<CR>
nnoremap <Right> :vertical resize -2<CR>
endif
map <silent> <LocalLeader>ws :highlight clear ExtraWhitespace<CR>
" Advanced customization using autoload functions
inoremap <expr> <c-x><c-k> fzf#vim#complete#word({'left': '15%'})
" Vim-Alchemist Mappings
autocmd FileType elixir nnoremap <buffer> <leader>h :call alchemist#exdoc()<CR>
autocmd FileType elixir nnoremap <buffer> <leader>d :call alchemist#exdef()<CR>
Each plugin in this setup is separated in the following categories:
Utility
This kind of a miscellaneous category and is comprised of plugins used to enhance or change the behaivour of core vim; the most useful important ones are:
- Nerdtree: It gives you easy access to the file system in the form of a directory tree on the left side of the screen, as well provides shortcuts for filesystem manipulation(create, delete, move files and directories)
- Tagbar: Quick tag browser for the current file, a must have if you are using any kind of ctags like exuberant-tags.
- FZF: Fuzzy finder, another handy utility for finding files and commands.
- Neocomplete: Vim Autocomplete on steroids.
Generic Programming Support
These plugins fall directly on the category of programming and are used my all or most of the programming languages that I currently have setup:
- Exuberant-Ctags: tags are named definitions of classes, functions, abstract types and so on; adding support to Vim gives you some of that 'magic' IDE code navigation functionality.
- Syntastic: THE syntax checking plugin for Vim, if you are familiar with the way that code inspections work on Jetbrains and similar IDEs, syntastic will make feel right at home.
- Vim-autoclose: Automatically closes a character that could/should have a matching closing counterpart, like () "" [] {} and so on.
Markdown/Writing
As I mentioned Vim is my go to editor for drafting new posts be it books, blogs or random angry letters. From this particular section only language tools deservers a special shot-out as it makes for a great Grammar checker directly from inside Vim.
Erlang/Elixir/PHP/Elm Support
When it comes down to the individual language support there isn't really much to highlight other than I've tried (and somewhat failed) to keep the plugins to a minimum and focus only on the essential language support.
So far elixir is winning the battle in terms of plugins as I've added additional functionality like the ability to run tests and generate content from inside Vim, I have yet to decide if I'm keeping all the plugins for it.
Git Support
Standard git support that I'm afraid I rarely use, I find myself going directly back to the shell and doing the git workflow outside of Vim, so I'm open to suggestions and to hear what everyone else is using in terms of setup.
Themes and Interfaces
Ok this is a big one but mostly because I keep forgetting to remove unused themes and colorschemes, let's highlight the important ones:
- Vimarline: Lean and mean status/tabline for Vim; it also looks cool as fuck.
- Vim-Devicons: Because not only atom gets all the fancy icons on the sidebar, highly recommended to if you are using nerdtree.
The remaining parts of the configuration file are either plugin configuration or personal key re-mappings that I use for quality of like; I've done my best to document and segment each section so it should be easy enough to understand what each setting is doing.
For anyone getting starting with Vim, I do want to bring special attention to the following:
" Disable arrow movement, resize splits instead.
if get(g:, 'elite_mode')
nnoremap <Up> :resize +2<CR>
nnoremap <Down> :resize -2<CR>
nnoremap <Left> :vertical resize +2<CR>
nnoremap <Right> :vertical resize -2<CR>
endif
As there is no quickest way to force one-self to use the home row for navigation.
Final Remarks
I hope that for some of you this post has been helpful for some, and I'm far from done with my current setup, in that sense this is very much a toy that I continue playing on a nearly daily basis; now that being said and in order to get back to the original premise of the post; it is indeed a very powerful toy, specially when combined with other tools like Tmux, here is a sneak peak of my Elixir 'IDE' powered by Vim and Tmux:
If you want to know more about my setup, or want to share yours please leave a comment below.
Ha, these kinds of comments always baffle me...
Your comment can be summarized as:
Your personal preference is wrong... You are not more productive with your favorite tools.
It's like telling someone "No, you shouldn't like chocolate", or "Your favorite movie is wrong".
the devs usually need to do DB queries, work with env tools, debug, see static analyzers warning, deploy dockers, run automatic tests, do merges, do huge refactoring that touches many files, find the "blame" on a bug, and so on (without writing or remember CLI commands or wasting time to setup the IDE).
I can do pretty much all of that in Vim with only a handful of plugins and little configuration. Also of note I've been in the biziness for roughly 7 years and have never had to deploy a container. 🤷🏼♂️ YMMV
B.G. ..... My subjective opinion: you are bore and hysterical. It is a fact. And all about what you find fault with the author of the article applies to your claims. All this is subjective, even your praised productivity.
I apologize for my english - google translate.
"Stay hungry ..stay foolish.". Steve Jobs.
I'm sorry but this statement is ludicrous. Productivity can indeed be measured, but the metrics you choose to measure are completely subjective.
That's somewhat besides the point, but coming from someone who seems downright angry that someone else presents subjective fact as the truth, your assertion is beyond hypocritical.
More importantly, it's absurd to argue that vim is inherently less productive than using any IDE. I keep hearing how vim users are preachy and judgmental, but I have never heard anything from a vim user as dogmatic, condescending, ignorant or absolutist as anything you've said in this thread.
Top comments (83)
dev.to where is the dislike button? :/
VIM is not an IDE, just an editor that helps you write faster
After you install 30 plugins and spend years of learning it you can come close to an IDE, but you lost a lot of time, for nothing.
The length of the post and the config file is working against you, is proof that is not easy to work with, and still not doing a proper job
If you would use an IDE in a proper manner (See Visual Studio or intelliJ) you will realize that your productivity is not about writing text (what Vim excels at), is at making your code work in the real world. Is more about development and less about being a type writer.
If you write books, articles or pseudocode Vim is the best tool I agree, but
..
the devs usually need to do DB queries, work with env tools, debug, see static analyzers warning, deploy dockers, run automatic tests, do merges, do huge refactoring that touches many files, find the "blame" on a bug, and so on (without writing or remember CLI commands or wasting time to setup the IDE).
Just saying, as a "director" you should appreciate productivity and do not make "feels like home" decisions for work projects. Do not confuse "what I like to do" with "what I have to do, as a professional".
By not using the proper tool, that gives you the fastest and most productivity you are wasting your employers money, so you are not being professional, you are just selfish.
Adrian,
VIM is a tool, every developer is entitled to its opinion and preference, VIM might not be the right fit for all stacks or all applications but I have successfully use it to work as you mention for writing, python development, elixir/erlang development.
IntelliJ is great and I use it for other kinds of development (ionic for example); I find the knee jerk reaction to the size of configuration file a bit risible, the configuration file as shared has support for several languages, stacks and some of my personal customizations.
Finally, I find that the ad hominem attack on the last part of your reply actually subtracts from what was actually some valid points on your argument.
I just wanted to raise awareness on "VIM priests" that spread their false gossips around, I probably sound more passive-aggressive then it should.
You just "forget" to mention that it is a personal preference, and state that "Vim is the perfect IDE" (for me?!), knowing in fact that is not even an IDE and not perfect. You "forget" to mention that you spent maybe years of being prolific, where in IDE's most of the things "just works".
VIM is great when you have many small scripts/projects, or you alter big projects with minimal invasion, edit big files, or you are a sys admin, or ...(insert here a lot of stuff you didn't mention), but ....
It is "a common trap" that I've seen are with web dev juniors, they usually:
This combined with the fact that people hate change, leads to bigger problems once the developer gets involved in bigger and more complex projects.
I just want to make things clear for the juniors and next generation of developers to make a big difference between "personal preferences" and "best tool for the job", and posts like this doesn't help at all.
Please keep in mind that everything you've said so far is anecdotal. Others, such as me, may have different experiences.
I tend to agree with BG. Tooling becomes vastly important when working with larger and more complex codebases. The kind of code analysis provided by actual IDEs simply cannot be replicated in Vim no matter how it's customized.
Vim is great, but Vim is ultimately just a powerful text editor. BG is correct in that the anti-IDE stance is alluring for junior devs, providing false machismo in the absence of experience and well-honed skills.
We really need to change the way we talk about Vim. Here are my suggestions:
Vim, conceptually, is mode-based text editing with consistent, highly optimized keybindings. The beautiful thing about vim-as-a-concept is that it's available in some form or fashion in nearly every IDE and text editor.
"vim-as-a-concept is that it's available in some form or fashion in nearly every IDE and text editor." ... and browser.
In my line of work, I've seen little to no benefit with static analysis. I am working on a highly dynamic codebase. Sure, if your language is static its great, but I really don't see this as being a reason for not using VIM. I've actually seen VIM autocompletion be more accurate than IDE's (for newer languages such as Rust).
I am very curious in what languages/line of work there are no benefits for static analysis, can you give some examples?
Javascript - we use dependency injection heavily.
wow ok, your team is great then! I was part of teams that didn't used but we ended up regretting.
I usually saw linters solving a lot of (very small) problems in large teams and projects, like (forces a coding standard, find small bugs like forgetting to type a var or forgetting a switch default, fewer git merges/conflicts) which leads to a better codebase in general (if you enforce the rules at commit/build).
As a sidenote linters are builtin in most IDEs so maybe you use them already, but only at a basic level.
We use eslint (for the older projects, a combination of jshint and jscs). The plugin I use for vim (ale) works with pretty much any kind of linter I've encountered.
This isn't the sort of static analysis I'd expect from and IDE though, this is what I'd expect from any kind of programmers editor (vscode, sublime, etc). What I meant by static analysis is the ability to goto definition, display documentation, refactor, etc. This is the sort of stuff which doesn't work consistently enough with our codebase to even bother trying.