My development toolbox
A recent discussion on Twitter has prompted me to write about the toolset I'm using during development, covering both work-related and personal projects. I will not just provide names and links, but also explain how exactly I use every tool.
OS and Hardware
During the last 14 years, I've been nearly exclusively a GNU/Linux user, and my go-to distribution is Fedora, I also occasionally use RHEL, CentOS (Stream) and Debian (Stable). My desktop environment is MATE, a fork of Gnome 2, although I keep pondering switching to a lightweight tiling window manager.
I'm a long-term user of Lenovo Thinkpad laptop series, currently on X1 Gen 7 (which does have a few annoying glitches compared to Gen 8). Connected to my Thunderbolt dock station are one high(er)-end full HD monitor from Philips, an ergonomic keyboard (Perixx PERIBOARD-512), an ergonomic mouse (Perixx PERIMICE-508), a simple headset and a full HD web camera, both from Logitech.
For occasional music recordings I use a Focusrite 2i4 external audio interface. (I don't provide a link, because Focusrite decided to completely wipe all mentions of it from their web site once they discontinued the model.)
Editing: ViM
I am on team ViM for the last 7 years after a year of using Emacs and several more years with Sublime. I must admit I'm still learning how to get the most out of it. I typically use a two-pane layout, here is an example with this blog post (in progress) and a bit of MiniScript:
My vimrc is not the largest I've seen, but it does list a few plugins and some non-default settings and short-cuts.
Plugins
- syntastic
-
Automatically compiles source code or runs linters on it, and displays errors in a useful ways. I use it with Python (Flake8), Go and Rust (compilation and formatting). My settings currently are:
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_aggregate_errors = 1 let g:syntastic_python_checkers = ['flake8'] let g:syntastic_python_flake8_args = "--ignore=W503,E129,H238" let g:syntastic_rst_checkers = [] let g:syntastic_rust_checkers = ['rustc'] let g:syntastic_rust_rustc_exe = 'cargo check' let g:syntastic_rust_rustc_fname = '' let g:syntastic_rust_rustc_args = '--' highlight SyntasticErrorSign guifg=white guibg=red
- vim-visual-multi
-
Multiple cursors (and more) for ViM, Sublime users know what I'm talking about. I tend to use it more often than not even for operations that have native ViM counterparts, like replacing occurences of the same word. The only customizations I have are mappings to avoid using arrow keys (you don't use arrow keys with ViM/Emacs, do you?):
let g:VM_maps = {} let g:VM_maps["Select Cursor Down"] = '<C-j>' let g:VM_maps["Select Cursor Up"] = '<C-k>' let g:VM_maps["Select l"] = '<C-l>' let g:VM_maps["Select h"] = '<C-h>'
The first two commands create or remove an additional vertical cursor below or above the current cursor, the last two add text to the right or to the left to a cursor.
- YouCompleteMe
-
An advanced auto-completion engine supporting many programming languages. Offers fuzzy search, which I'm a big fan of. It did take some time to tune auto-completion pop-up to work exactly the way I want, the current configuration is:
set completeopt=preview,menuone,noselect,noinsert inoremap <expr> <CR> pumvisible() ? "\<C-y>\<CR>" : "\<CR>" let g:ycm_autoclose_preview_window_after_completion = 1
This prevents the completion from interfering with my input if I decide to ignore it (which I often do, especially when writing a text like this).
A downside of this plugin is that it requires compiling an external server, which crashes from time to time. It also does not work with ViM 7, so to support RHEL/CentOS I need to do
- python-mode, rust.vim and vim-go
-
No big surprises here, these plugins add additional support for Python, Rust and Go languages accordingly.
Go highlighting needs some tuning to my liking:
let g:go_highlight_fields = 1 let g:go_highlight_functions = 1 let g:go_highlight_function_calls = 1 let g:go_highlight_extra_types = 1 let g:go_highlight_operators = 1
Python configuration needs some tuning as well:
let g:pymode = 1 let g:pymode_indent = 1 let g:pymode_lint = 0 let g:pymode_breakpoint_bind = '<Leader>B' let g:pymode_rope = 1
(I'm enabling Rope integration and disabling features that conflict with other plugins and settings).
- fzf and fzf.vim
-
This is a true pearl of my toolbox! FZF is a fuzzy finder for… anything! If you just run it from the command line, it will start fuzzy search of files in the current directory. But together with ViM it opens amazing opportunities! Check out these short-cuts (the leader key is
\`
):" Search for files in the current git repository map <Leader>f :GFiles<CR> " Search for open buffers map <Leader>b :Buffers<CR> " Search for lines in the output of the_silver_searcher map <Leader>a :Ag<CR> " Search for lines in open buffers map <Leader>l :Lines<CR> " Search for lines in the current buffer map <Leader>s :BLines<CR>
All searches are fuzzy, which I am personally really fond of! It's also surprisingly fast.
- vim-commentary
-
Commands for file type dependent commenting and uncommenting of lines.
- ReplaceWithRegister
-
Command for replacing text with the content of a register.
- vim-wordmotion
-
This is a recent and controversial addition to my toolbox. Together with this bit of configuration:
it makes lower-case word motions stop at underscores and camel-case words, while the upper-case motions work more or less as normal motions in ViM.
- vim-swap
-
Commands for swapping arguments in a function call or a signature. Addresses the annoyingly common need of turning
into
(yes, I used this plugin right now to create these examples).
- Vundle
-
A plugin system for enabling the described plugins.
Settings
Some settings have not been covered above:
" Tabs and spaces (with an exception for YAML) set tabstop=8 set expandtab set softtabstop=4 set shiftwidth=4 autocmd BufEnter *.yml setlocal softtabstop=2 autocmd BufEnter *.yml setlocal shiftwidth=2 autocmd BufEnter *.yaml setlocal softtabstop=2 autocmd BufEnter *.yaml setlocal shiftwidth=2 " Enable line numbers set number " Configure text width (with an exception for Rust) set textwidth=79 set colorcolumn=80 autocmd BufEnter *.rs setlocal textwidth=100 autocmd BufEnter *.rs setlocal colorcolumn=101 " Highlight trailing whitespace with red autocmd BufEnter * highlight BadWhitespace ctermbg=red guibg=red autocmd BufEnter * match BadWhitespace /\s\+$/ " Jump to current search results set incsearch " Keep more context when scrolling set scrolloff=5 " Do not unload hidden buffers (prevents annoying requests to save changes " on switching buffers set hidden
Convenient short-cuts:
Shell
I spent most of my professional life in a shell. I'm using Fish, which is a
modern shell with usable defaults and nice built-in features. My fish config
includes an alias from vim
to vimx
(when present) and a custom prompt.
The tools I routinely use include:
ag
-
I've already mention
ag
aka the_silver_searcher when talking about ViM plugins, but I also actively use it as a replacement forgrep
. Its benefits include:Understanding
.gitignore
files.Extended regular expressions by default.
Recursive search by default.
Nice search highlighting.
bat
-
is an alternative to less with syntax highlighting, git integration, and other small improvements. The only thing that prevents me from aliasing
less
tobat
is that the former can deal with files containing occasional binary data (QEMU console dumps are one example). git
-
does not need an introduction! My gitconfig adds quite a few aliases, some of them inspired by SVN (remember it?):
[alias] ci = commit co = checkout dc = diff --cached ff = pull --ff-only st = status --short --branch top = log -1 --stat topp = log -1 --stat -p l = log --decorate ll = log --graph --all --decorate --oneline la = log --graph --all --decorate --stat lbr = branch --sort=-committerdate --verbose
git ll
is a much useful version ofgit log
, whilegit lbr
helps me navigating the surprisingly high number of branches in some repositories (like ironic).I also change a couple of defaults:
The latter references a custom gitignore:
*.swp .ropeproject/
tmux
-
The battle-tested
screen
alternative probably does not require an introduction as well. I have a habit of using it on all remote servers I access.
Ansible
I'm using Ansible as part of my involvement in the Bifrost project, but I'm also relying on it for configuring my development environment (as described above) on remote machines and testing VMs. My configuration playbook is capable of installing packages, checking out repositories and even configuring ViM! I cannot recommend this approach enough, it makes me feel at home no matter if I'm on my laptop or in one of the numerous VMs I create.