My Current Vim Configuration

This is my current .vimrc file at work.

"Block Cursor
let &t_ti.="e[1 q"
let &t_SI.="e[5 q"
let &t_EI.="e[1 q"
let &t_te.="e[0 q"

"Syntax highlighting
syntax on
filetype on
au BufNewFile,BufRead *.jq set filetype=javascript "jquery files
au BufNewFile,BufRead *.html set filetype=javascript
au BufNewFile,BufRead *.htm set filetype=javascript

"Indentation
set cindent

"Text Display
set number
set bg=dark

"Search Settings
set hlsearch
set incsearch
set smartcase

"Mistype correction
command W w
command Wq wq

"Window Split Settings
set splitbelow
set splitright
set wmh=0 "Free up screen real estate from minimized windows

"Easier Split Navigation
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>

"Allow erasing with backspace in insert mode
set backspace=2

Better Vim Splits

I thought I knew everything there was to know about vim splits. Generally I’m the guy with so many different windows open that you can only see three lines at a time. But once again, I have learned a cool tweak for using vim. I won’t spoil all the details, so check out :

http://robots.thoughtbot.com/post/48275867281/vim-splits-move-faster-and-more-naturally

The code snippets (for your ~/.vimrc) are below:

Easier Split Mappings: (Ctrl-j instead of Ctrl-w j)

nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>

More Natural Split Opening:
This makes new splits open to the right or bottom of the window

set splitbelow
set splitright

 

 

The most useful thing in Bash

So I was reading hacker news when I stumbled across this gem:

https://coderwall.com/p/oqtj8w

Pretty cool right? I’m going to keep a copy here so I can find it in the future. Much thanks to Jude Robinson for posting this up!

Create ~/.inputrc and fill it with this:

"\e[A": history-search-backward
"\e[B": history-search-forward
set show-all-if-ambiguous on
set completion-ignore-case on

This allows you to search through your history using the up and down arrows … i.e. type “cd /” and press the up arrow and you’ll search through everything in your history that starts with “cd /”.

Taking the MD5 Hash of a directory’s entire contents

So my harddrive recently failed. Fortunately I had backups, which means I’ve been copying a lot of important files over to my new harddrive. Once concern that I’d always had was dealing with file corruption. I’d been meaning to get around creating a md5 database of my pictures and music files. Well I’ve taken the first step.

But how I can I easily tell if something important has changed? Some quick googling found this StackOverflow Post. Works great on GNU/Linux, unfortunately I’m using a Mac, which is BSD based system. So let’s fix it up!

Here’s my version, Uncomment out the proper line for your operating system.

md5dir:

#!/bin/bash

if [ $# != 1 ]; then
        echo "Calculates MD5 Hash of entire directory contents"
        echo "usage: md5dir "
        exit 1
fi

#Non-bsd (GNU linux) systems
#find $1 -type f -name *.py -exec md5sum {} + | awk '{print $1}' | sort | md5sum | awk '{print $1}'

#For BSD based systems
find "$1" -type f  -exec md5 -q {} +  | sort | md5 -q

After I wrote that, I wrote this little script to quickly compare the md5 hashes of two directories. You could always use a recursive diff, but I wanted to compare hashes. It uses the md5dir script I wrote above, and assumes that you have placed it somewhere in your path. (Put md5dir in /usr/local/bin)

comparedir:

#!/bin/bash

if [ $# != 2 ]; then
        echo "Compares MD5 hash of two directories"
        echo "usage: comparedir  "
        exit 1
fi

echo "Comparing $1 to $2"
x=$(md5dir "$1")
y=$(md5dir "$2")

if [ $x == $y ];
        then
                echo "Directories Are Matching!"
        else
                echo "Directories DO NOT MATCH!"
        fi

echo "$1: $x"
echo "$2: $y"

Automatically ls after cd (improved)

Here’s the new and improved version. This will properly handle a cd with no arguments.

alias cdd="builtin cd"
cd () {
        if [ "$*" = "" ]; then
                builtin cd ~
        else
                builtin cd "$*"
                        fi  
                        if [ $? -eq 0 ]; then
                                        ls --color=always
                                        fi  
}

Automatically ls after a cd

See: Improved Version

I’ve been meaning to get around to this for a while. I finally googled a solution.

Put this in your .bashrc:

alias cdd="builtin cd"
cd () {
  builtin cd "$*"
  if [ $? -eq 0 ]; then
    ls
  fi
}

Source

I’m only running the original fix right now, I had some issue with the “fixed” Tsubashi version in the source’s comments. I’ll have to take a look at it sometime.

Piping find into rm

The correct way to pipe the find command into rm is:
find . -name "*txt" -print0 | xargs -0 rm

The find command will output something like this:
./hello world/README.txt

xargs separates on spaces and lines, causing this problem:
rm: ./hello: No such file or directory
rm: world/README.txt: No such file or directory

Using the “-print0” for find outputs null-terminated strings. “xargs -0” sets null-characters as the separator. This sends the whole path. Your file is now deleted.

The Power of Aliases (Bash)

So I often type in a command like “go” or “hello” and get asked “How did you do that?” Simple! I use Aliases. Aliases are shortcuts that allow you to quickly set commands.

In this post I’ll teach you how to unlock this power for your own purposes.
Try it: 

alias showall='ls -al'

Now if you type in “showall” the command “ls -al” will be run
However this will only work in the current window until it is closed.

How to make permanent aliases:

  1. You need to add them to your .bashrc, this file is run every time you start up the shell. Type in “vim ~/.bashrc
  2. Go to the last line. Be careful not to delete anything already there.
  3. On each line you can add a different alias, a few examples are below
  4. Finally run “source ~/.bashrc” this loads the new configuration in your current shell (or start a new shell)

Useful Aliases:
I use the below aliases to help me quickly navigate and run commands. As well as login to my frequently used servers. You can cut and paste the below, just make sure to change [USERNAME] and [SERVER].

alias q="vim ~/.bashrc" #To quickly edit my current aliases
alias a="source ~/.bashrc" #To reload my aliases (after changes)
alias server="ssh [USERNAME]@[SERVER].com" #To quickly ssh into a server
alias fserver="sftp [USERNAME]@[SERVER].com" #For transferring files to a server

Bashing Tar

So I discovered today that I made the mistake of excluding hidden files while creating a website backup. The incorrect command that I naively used was:

tar -cf backup.tar *          (INCORRECT)

On the surface, it seems like a good command. However, the wildcard “*” does not include hidden files in bash. Alright, well that should be a simple enough fix right?

tar -cf backup.tar * .*       (INCORRECT)

With my quick and easy “fix”, I made the error of forgetting that “.*” includes “../“. Doh! But all is not lost. Let’s finesse the wildcard sequence:

tar -cf backup.tar * .[!.]*

Tada! Using the power of bash’s wildcard exclusion, we have prohibited all names that begin with “..“. We can now go about our business confident that our files are being backed up.

Now if you’ve been paying attention, you might be be wondering why I didn’t simply use the command:

tar -cf backup.tar .

The answer to that is simple, I really wanted to play with bash wildcards that day. So much so that I got stuck in the common error of fixing inefficient code.  Hopefully you’ll learn from my mistakes.
Bonus Command 
Using find and piping instead of wildcards. Does the same as above:

find /home/username/path -mindepth 1 | tar -cf backup.tar -T –