As a computer science student, I don't have the luxury of working on the same development machine day after day for years on end. At least once every few months, I'll need to set up a new development environment. This could be because I sit down at a different lab computer, I start working at a new internship, I'm given a virtual machine to complete an assignment, or I'm SSHing into a more powerful research workstation.

As a result, I require my setup for code development to be GUI-less and quick to setup, while of course maximizing productivity and ease-of-development. Enabling a painless setup process is exactly why all the code and configuration files I discuss here are available on Github. If you want to clone my setup, just run git clone & cd DotFiles & bash, and you're done! My operating system of choice is Ubuntu with a BASH shell, and my favorite tools are Git, Vim, and Tmux. Each tool is powerful, has a well-established community of users, stable, widely-available, and usable from the command line.


Deciding to move from Windows to Linux during my senior year of high school is probably the best decision I've ever made in regards to improving my CS knowledge and competency. Linux operating systems are basically designed for programmers, since they give you more control over the system and allow you to mess around with things which Windows wouldn't want you to touch. I originally chose Ubuntu because it was one of the most popular Linux OSs and was easy to set up (I'm looking at you here, Arch), and I've stuck with it because it's package selection is solid and as a whole is pretty stable.


Although it has weird syntax, plenty of gotcha's, and lots of unique quirks, BASH is great for automating stuff. The only customizations I've done to the standard shell can be found in a few lines in my ~/.bashrc. First, some visual customizations which change the default command prompt and listing colors:

# customize command prompt
RS="\[\033[0m\]"                                # reset
HC="\[\033[1m\]"                                # hicolor
FRED="\[\033[31m\]"                             # foreground red
FWHT="\[\033[37m\]"                             # foreground white
force_color_prompt=yes                          # color!
export PS1="$HC$FRED[$FWHT\w$FRED]$RS "   		# sets command prompt
export TERM=xterm-256color                      # allow color in "screen"

#customize ls colors
export LS_COLORS

Secondly, some more practical aliases for my commonly used commands which have lots of arguments:

alias gitlog='git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short'
alias gpp='g++ -g -std=c++11'                                                     
alias gss='gcc -S -masm=intel -fno-asynchronous-unwind-tables'


Get Git! A must-have for versioning control, it allows you to keep track of as many versions of your code as you want, work on the same code base as others simultaneously, and revert changes should you make any mistakes (I know you never do, but it's saved me many times!). Note that Git is distinct from Github; I use Git to version control any project of mine that exceeds 100 lines whether or not I'll be sharing that project with others. Even this website is a Git project!


Vim is notoriously difficult to get the hang of (leading to the most-viewed Stack Overflow question of all time), but once you're used to it, it's hard to go back to any other text editor. If you want to try Vim for the first time, I recommend first calling vimtutor from BASH, which provides an excellent tutorial. Vim is sometimes described as a programming language for text editing, and this video really opened my eyes to how Vim actions and commands are composable and repeatable. With a few well-placed Vim commands you can save yourself a lot of typing! It's also endlessly extensible and can support all the same features as a commercial IDE, but I've found a minimalist approach to work best for me. If I were developing using a large Java API all the time, I'd definitely want auto-complete, but currently I find it more distracting than useful.

Like everyone else, I've defined some custom key mappings which you don't care about. But, here are a few select Vim modifications which I think everyone might find useful:

set relativenumber
set number

function! NumberToggle()
    if (&relativenumber == 1 && &number == 1)
        set norelativenumber
        set nonumber
        set relativenumber
        set number
nnoremap  :call NumberToggle()

With this numbering scheme, the index of your current line is shown normally, but all other lines are numbered relatively. This helps for performing relative Vim actions and movements, since you can at a glance see how many lines to move without performing any mental math. The NumberToggle() function removes all line numbering when <CTL>+N is pressed, making it easy to copy-paste out of your Vim terminal without taking any garbage along for the ride.

set colorcolumn=81
highlight ColorColumn ctermbg=lightgrey guibg=lightgrey

If you need to remind yourself when you should consider using a line break, this snippet is for you! It will highlight the 81st column in a different color.

Lastly, here's a list of my favorite Vim plugins, which I manage with pathogen. I won't re-iterate what they do here, since you can find plenty of documentation online for each project:

# install pathogen
mkdir -p ~/.vim/autoload ~/.vim/bundle
curl -LSso ~/.vim/autoload/pathogen.vim

# install vim plugins
cd ~/.vim/bundle
    christoomey/vim-tmux-navigator  # vim-tmux nav
    tpope/vim-commentary            # easy commenting
    tpope/vim-surround              # editing shortcuts
    scrooloose/nerdtree             # tree fileviewer
    sirver/ultisnips                # expansion shortcuts
    airblade/vim-gitgutter          # show git changes
    tpope/vim-fugitive              # git integration
    itchyny/lightline.vim           # aesthetics
    tpope/vim-repeat                # plugin cmds now repeatable
    w0rp/ale                        # c syntax checker
for owner_repo in "${VIM_PLUGIN_REPOS[@]}"
    repo="$(cut -d "/" -f 2 <<< $owner_repo)"
    [ ! -d "$repo" ] && git clone "$owner_repo.git"