Today I Learned

A Hashrocket project

79 posts by doriankarter @dorian_escplan

Run Prettier on all #JavaScript files in a dir

If you are like me you must like formatters such as Prettier which probably prompted you to set your editor to auto format the file on save.

That's great for new projects but when working on an existing project, every file you touch will have a huge diff in git that can obscure the real changes made to the file.

To solve that you must run prettier on all your javascript files as an independent commit. You can do it with the following command:

find ./src/**/*.js | xargs prettier --write --print-width 80 --single-quote --trailing-comma es5

The flags after the prettier are all my personal preferences except for --write which tells prettier to write the file in place.

Note 1: Make sure you have all the files you are about to change committed to source control so that you can check them out if this did not go well.

Note 2: When committing this change it would be a good idea to use git add -p and go through the changes one by one (which is always a good idea...)

Note 3: To dry run and see which files will be changed run the find ./src/**/*.js by itself.

Fuzzy awesome copy to sys clipboard w/yank & fzf

Say you want to copy a pid of a process to system clipboard, you could run ps ax, maybe grep on the result, connect your trusty mouse and try to select the value and hit ⌘ + c.

Or you can use the amazing fuzzy finder FZF (brew install fzf) in combination with Yank (brew install yank).

ps ax | fzf | yank

Now simply start typing the name of the process. When you press return you will get the columns broken down into a selectable prompt - choose one and press return. It is now in your system clipboard.

Here's a demo:


This will work with any column spaced or even multiline response. Try running ps ax | yank.

Code splitting with Webpack 2 and Babel

Webpack 2 provides the ability to split your code into smaller files that are lazy loaded during runtime as they are needed.

When I first learned about this feature I thought it would be very intelligent in detecting which parts of the code are using a certain module and split all my modules into separate files automatically. That's not really the case.

If you want to have Webpack split your code and lazy load it you need to explicitly call import in your code. For example:

import Foo from './foo';

class Bar {
  baz() {
    Foo.someMethod(); // this will not be split and lazy loaded

    import('./lazy_module').then(function(lazyModule) {
    }).catch(function(err) {
      console.log('Failed to load lazy module', err);

To have this work you need to install the Syntax Dynamic Import library

Then edit your .babelrc:

  "presets": [["es2015", { "modules": false }]],
  "plugins": ["syntax-dynamic-import"]

The modules: false part is really important. It basically instructs Babel to not try and parse the imports but let Webpack 2's native ability to parse imports to do the work. This was tricky.

There's more to that and it keeps changing so I recommend visiting this documentation

Git Garbage Collection - optimize local repository

As you work with git a lot of garbage gets accumulated in your .git folder such as file revisions and unreachable objects.

On large repositories and long running projects this negatively affects both operating performance and disk space utilization.

To clean up the garbage git provides a command:

git gc

This will not impact the remote repository and will only optimize the local copy so it is safe to run on any git repo you might have. (In fact this operation is already run for you automatically after some git commands that leave behind too many loose objects)

If you want a deeper cleaning (which you should every few hunderd changesets or so), run:

git gc --aggressive

This will take longer but will provide better results.

To learn more:

git help gc

Yarn global

Just like npm install -g, Yarn provides yarn global add. I found however that it did not work right out of the box to register executable binaries/CLIs.

To fix this add the following to your .zshrc/.bashrc:

# set yarn binaries on path
export PATH="$HOME/.config/yarn/global/node_modules/.bin:$PATH"

Now all binaries installed from yarn should be on your system PATH.

Save disk space with Yarn

Yarn is a fast, reliable and secure replacement for npm. Those are all important attributes in my book for a tool I use daily for development, but that's not all Yarn offers.

The node_modules directory is often a resource consuming hog both in space and number of files. It is full of junk such as test files, build scripts and example directories.

To clean some of those files Yarn offers the clean command. To run it:

yarn clean

Once run, the command will create a .yarnclean file with patterns of type of files to be deleted. By default yarn clean will delete the following:

# test directories

# asset directories

# examples

# code coverage directories

# build scripts

# configs

# misc

With this file in your project root directory Yarn will ensure to run a cleaning task after every install and report how much space it saved you.

Clean untracked files in Git

Given I am a developer
And I am working on a new branch in an existing project
And during one of my commits I introduced a few files/folders
And those files/folders are untracked (in .gitignore)
And those files/folders are automatically generated (e.g. node_modules/ webpack_bundle.js)
When I switch back to the main branch
Then I see those files
And I don't want to...

If you find yourself in the above situation, you may want to clean your untracked files. Git provides a command for that: git clean.

This command comes with a way to see which files/folders are going to be deleted (DRY RUN):

git clean -n

You may notice that the above command does not show any untracked directories. To add directories to that list use the -d switch:

git clean -dn

Alternatively you may choose to only remove files/dirs that are in .gitignore with the -X option:

git clean -X -dn

If you are ready to take action use the -f switch and remove the -n switch:

git clean -fd

Set persistent font in MacVim

Like many, I have MacVim installed through Homebrew Cask. When I first started using MacVim, I had to change the font to a powerline supported font so that my Airline looks spiffy.

To do that I went to Edit -> Font -> Show Fonts and selected a font.

Unfortunately this setting gets wiped out with each update of MacVim, and since it updates often, which is great, having to set the font over and over is not.

To have your font setting persisted in MacVim add this to your .gvimrc:

set guifont=Source\ Code\ Pro\ for\ Powerline:h24

You can set what ever font you like, just make sure to escape the spaces with a slash.

To get powerline (and Airline) patched fonts go here:

Map Caps Lock to Escape in macOS Sierra #seil

macOS Sierra was made available to the public yesterday and many of us early adopters rushed to install and test it out.

One of the things that broke and really affected my workflow was that Seil, the program I use to remap Caps Lock to ESC, no longer works. It's sister application Karabiner also stopped working.

Fortunately there's a solution available from the developer of Karabiner and Seil. It's a little more complicated than usual:

  1. Download and install Karabiner-Elements:

  2. Karabiner Elements will install a virtual keyboard driver, and you probably want to disable the default capslock behavior for the new virtual driver:

    disable capslock

  3. Use your favorite editor and edit the following file (create it if does not exist):

    vim ~/.karabiner.d/configuration/karabiner.json

    And add the following to it:

        "profiles": [
                "name": "Default profile",
                "selected": true,
                "simple_modifications": {
                    "caps_lock": "escape"

That's it. Just make sure you have Karabiner Elements running.

Remove both scrollbars from MacVim

If you use MacVim you may encounter the gray Mac OS scrollbar on the right side.

When you split the window you may encounter two scrollbars, one on each side.

I find that to ruin the look of MacVim, especially with a dark colorscheme (I use Dracula).


To remove only the left one use

set guioptions=r

This will tell vim to always show the right scrollbar only. To remove only the right one use

set guioptions=l

To remove all scrollbars, remove everything after the equal sign viml set guioptions=


Add this to your vimrc for a consistent experience.

Expecting change with RSpec #rails #testing #rspec

Usually when I try to test if a value has changed after a method has been called I will assert the initial value as one expectation followed by the action that changes it, and finally assert the value has changed.

For example this test will check if a user's bad login attempts are incremented when the user.record_bad_login! method is called:

describe '#record_bad_login!' do
  let(:user) { FactoryGirl.create(:user) }

  it 'increments the bad login attempts count' do
    expect(user.failed_login_attempts).to eq(0)
    expect(user.failed_login_attempts).to eq(1)

RSpec provides us with a more straight forward way to oneline this type of test while making it more declarative:

describe '#record_bad_login!' do
  let(:user) { FactoryGirl.create(:user) }

  it 'increments the bad login attempts count' do
    expect { user.record_bad_login! }.to change { user.failed_login_attempts }.from(0).to(1)

Read more here:

Toggle CursorLine, CursorColumn w/Vim Unimpaired

Vim Unimpaired plugin by Tim Pope ships with a shortcut for quickly toggling CursorLine and CursorColumn. This is particularly useful on large files with plenty of syntax highlighting.

Turning CursorLine/CursorColumn off can speed buffer navigation by reducing the blocks being re-rendered on the screen, making Vim snappy again.

To use this shortcut type cox from NORMAL mode and Vim will toggle CursorLine and CursorColumn on and off.

h/t Chris Erin

DEMO: demo

Postgres age function #postgresql

If you want to select records according to a specific interval, like Rails' ActiveSupport 1.year.ago PostgreSQL has you covered.

The age function returns an interval type and can be used in queries like so:

select * from sometbl where age(created_at) > '1 year';

By default the age function will use the current system time to calculate the age. If you want to calculate the age relative to a different time you can simply pass in another argument:

psql> select age(timestamp '2016-08-28', timestamp '1957-06-13');
 59 years 2 mons 15 days
(1 row)

You can also use the make_interval function to create intervals using numeric parameters:

psql> select make_interval(1,2,3,4,5);
 1 year 2 mons 25 days 05:00:00
 (1 row)

In a query it can be used like so:

select * from sometbl where age(created_at) > make_interval(1);

to select rows with created_at older than one year from now.

Read more about the age function and other cool date/time manipulations see the official documentation.

h/t Jack Christensen

Verify downloaded files from the web #security

If you download a file from the web on a public WiFi and want to run on your machine you might want to check if the file has not been tampered with by a man-in-the-middle-attack or if the file host has been breached.

The easiest way to do this is to check the publised md5 or sha-1 hash for that file (you can do that via your phone if you want to be extra secure). Not every package publishes that but if they do it will be on their website usually next to the download link.

To verify the file you will need to hash the file you downloaded using openssl. For example:

 $ openssl sha1 Kali-Linux-2016.1-vm-amd64.7z
 SHA1(Kali-Linux-2016.1-vm-amd64.7z)= 2b49bf1e77c11ecb5618249ca69a46f23a6f5d2d

Which matches the site's published sha-1 hash:


If you want to check md5, simply replace sha1 in the command with md5.

Treat null as if it is a known value #postgresql

When you query a table sometimes you want to check if a nullable field is not equal to a value. For example:

select * from sometable where afield != 'avalue';

However the query above will exclude rows where afield is null, so you would typically add that as an additional condition:

select * from sometable where afield is null or afield != 'avalue';

When you are doing it once it may be ok but as queries get bigger this makes the query messy and harder to read. Fortunately Postgres offers a more idiomatic way to check if a value does not equal something, including null values: is distinct from and is not distinct from.

select * from sometable where afield is distinct from 'avalue';

This query will return all the rows where afield is null or anything but avalue. Conversely:

select * from sometable where afield is NOT distinct from (select x from y limit 1);

will return all the values that are equal to the result of the subquery above and is useful when the result of the subquery could be null.

h/t Jack Christensen

Original docs:

Grep through compressed (gzipped) log files

The logrotate linux utility automatically compresses your ever-growing production log files.

If you encountered an error and wanted to search the history including all compressed logs, you may have considered unzipping all of them into a directory and run a grep in that directory.

Fortunately linux offers a more idiomatic way for grepping gzipped files: zgrep.

From the manual:

zgrep, zegrep, and zfgrep act like grep, egrep, and fgrep, respectively, but accept input files compressed with the compress(1) or gzip(1) compression utilities.

h/t Jack Christensen

See how long a process has been running on #linux

If you started a long-running process and want to know how long it has been on the run so to speak, you can use the -eo switch on ps to specify you want the elapsed time like so:

ps -eo pid,cmd,etime

This will yield something like:

112 [aws/0]                  2-10:27:00
114 [aws/1]                  2-10:27:00
115 [aws/2]                  2-10:27:00
123 [aws/3]                  2-10:27:00

Which means that process aws has been running for 2 days, 10 hours and 27 minutes.

You can of course pipe the result to grep:

ps -eo pid,cmd,etime | grep aws

Bundle in parallel using full CPU powa!!! #rails

Don't you wish there was a faster way to install your bundled gems for a project? Especially when cloning an existing Rails application from Github?

more powa

It turns out that since Bundler v1.5, Bundler supports Parallel Install.

To run bundler with parallel install use the --jobs option or -j for short.

Assuming your computer has 4 cores you can try

$ bundle install --jobs 4
$ # or
$ bundle install -j4

Finally if you want to set bundler to always use parallel install you can run this command:

bundle config --global jobs 4

The bundler team has seen speedups of 40-60%. That's amazing!

h/t Micah Cooper && bundler documentation

Capture IO.puts in ExUnit tests

Whenever writing a CLI you often have to communicate something to the user via IO.puts, and while some languages make it complicated to capture output in a test, Elixir makes it extremely straight-forward.

All we have to do is import the ExUnit.CaptureIO module into our test which exposes the capture_io method.



defmodule MyApp.CLI do
  def main(argv), do
    # parse args ...
    # return :help if the -h switch is supplied
    # pass to process
    |> parse_args
    |> process

  def process(:help) do
    IO.puts "usage: my_app <arg1> <arg2>"

IO capturing test:

defmodule CliTest do
  use ExUnit.Case

  import ExUnit.CaptureIO

  test "prints usage instructions when the help switch is supplied" do
    execute_main = fn ->

    assert capture_io(execute_main) =~ "usage:"

For more information read the ExUnit.CaptureIO documentation

Your own vim <leader> key in a pairing situation

Leader keys in Vim let you set up powerful and easy to access shortcuts for commands you use often.

For example I use <leader>vr to open my .vimrc in a split. That looks something like this:

nnoremap <leader>vr :vsp $MYVIMRC<cr>

I also use it to edit my vim bundles which are managed using the amazing vim-plug:

nnoremap <leader>vb :vsp ~/.vimrc.bundles<cr>

Finally, after making changes to both I need to source my vimrc:

nnoremap <leader>so :source $MYVIMRC<cr>

This allows for quick iteration on my vim configuration.

In a pair scenario though I cannot use my own configuration and more often than not the differences can be problematic for my muscle memory. For example at Hashrocket we use the \ key as leader.

In my personal vim setup I have <space> setup as the leader key. I find it to be more ergonomic and easier to access since I can slam it with either thumb.

Since there can only be one leader key you might need to add a leader alias. That can be done simply by adding this:

nmap <space> \

Remember not to use nnoremap if you wan this to work.

Use !! to quickly insert result of a bash command

Vim has the ability to read a result of a bash command into the current buffer. This can be done in many ways:

:read !echo "hello world"

To replace the content of the whole file with the result of a command use %!:

:%!cat file_to_copy_from.c

Similarly to replace the current line use . instead of %:


The command above will insert an ascii calendar into your buffer.

Last night I was testing to see what each of the keys in the number row do when used with the Shift key in Vim. One of the most interesting NORMAL mode mappings I found was the bangbang (!!). If pressed it opens the command line with .! and places your cursor right after that.

This allows for quickly bringing in data such as the date when you are working on a blog post.


Please tweet at me @dorian_escplan and @hashrockettil if you find other interesting uses for it.

Allow j and k to work on visual lines

Wrapped lines in Vim can be challenging at times. Try to move up or down in a perceived paragraph and instead of moving one line down/up you move to one of the ends of the paragraph.

To solve this you might be using gj and gk, but that slows your navigation considerably.

To allow vim to navigate between wrapped lines (visual lines) more naturally, as if they where hard lines, you can add the following mappings to your vimrc:

nnoremap k gk
nnoremap j gj

Now when you press j or k the cursor will move where you really intended for it to move. Normal j and k will still work as intended.

Script for bootstrapping a new project #bash #git

Creating a new project and publishing it usually involves many repeatitive steps. As developers we like to automate the tedious repetitive tasks to allow our creative juices to flow freely.

I wrote the following script for boostrapping a new project. Feel free to modify and add to your zshrc or bashrc:

function initprj() {
  # create the directory and cd into it unless the user uses '.'
  # to indicate current directory
  if [[ "$1" != "." ]]; then
    mkdir $1
    cd $1

  # setup git
  git init

  # setup remote repo on github and add it to git remote
  hub create

  # setup base files (add your own if you'd like)
  touch .gitignore

  # You must use tabs if you want to indent heredocs that use the <<- syntax
  cat <<-EOF > LICENSE
        Copyright (c) $(date +"%Y") Dorian Karter

        Permission is hereby granted, ...

To run the script simply type initprj my-project and watch the magic happen.

Note: you must have hub installed to create the remote repo.

React wrapper components with nested children

Say you want to create a component that acts as a wrapper such that you can pass it nested child components like so:

<WrapperComponent title="I am the wrapper">
  <ChildComponent body="Hello from child component" />

This can be achieved by using this.props.children as in this example:

class WrapperComponent extends Component {
  render() {
    return (
      <div className="wrapper">

class ChildComponent extends Component {
  render() {
    return (

class App extends Component {
  render() {
    return (
      <WrapperComponent title="I am the wrapper">
        <ChildComponent body="Hello from child component" />

Mounting App will produce the following markup:

<div class="wrapper">
  <h1>I am the wrapper</h1>
  <p>Hello from child component</p>

Emoji Variables in Swift #🚀

Swift allows developers to specify variable names in unicode, which is very helpful if you and the rest of the developers to ever touch your code speak a non-english language which uses unicode characters:

let 你好 = "你好世界"

It is also useful if you want to specify special constants such as

let π = 3.14159

most importantly though, it allows developers to use emojis for variable names:

let 🐶🐮 = "dogcow"
let #🚀 = "Hashrocket"

but don't take my word for it, read the official documentation which contains some of the above examples.

Note: the pound sign above (#) is unicode, that is why it is allowed as part of a variable name, whereas normal # sign is not.

P.S. to access emojis and other unicode symbols directly in the current edit field press ^⌘+<space> on Mac.

Write into a protected file without reopening Vim

If you ever worked on an SSH session on a remote machine and tried to edit a file that requires super user permissions you might be familiar with the following scenario:

  1. You open the file in vim (e.g. nginx.conf)
  2. You make a few changes, potentially many
  3. You are happy with the result and run the write command :w
  4. You get an error saying that the file is readonly or that you don't have permissions to write to it
  5. Now you are scrambling to copy all your changes and save them somewhere else
  6. Then you re-open the file with sudo vim ... paste your changes and save. Hopefully everything went smoothly and you did not lose your changes.

No more! Next time this happens try this:

:w !sudo tee %

I hope it saves you some frustration.

Execute a shell command on every commit in rebase

Git rebase allows you to execute a command on any commit in a rebase:

git rebase -i -exec "git reset-authors"

The result will look something like this:

pick xxxyyy Do stuff to things
exec git reset-authors
pick yyyzzz Do things to stuff
exec git reset-authors

It is very useful for resetting authors on multiple commits in case you forgot to set the current pair.

P.S. if you are curious about what git reset-authors does check out our .gitconfig in Hashrocket's dotfiles:

reset-authors = commit --amend --reset-author -CHEAD

Indent and de-indent line in INSERT MODE

While in insert mode it is possible to indent the current line while maintaining cursor position:

Ctrl+t - will indent the line in
Ctrl-d - will de-indent the line

Super useful.

Bypass aliases with the `command` command

If you are writing a bash script to be used by others and you call external dependencies you might encounter a situation where a user has defined an alias in place of the original command.

For example users of the hub command line utillity may have an alias

alias git='hub'

Or something more practically challenging:

alias grep='grep  --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn}'

If your command relies on the output of the original program without unexpected modifications you need a way to bypass the aliases and call the command directly.

To bypass aliases prefix the original program call it with the command command. For example:

command git --no-pager diff | command grep '[something]'

I like to think of it as the bash equivalent of Vim's noremap.

Repeatable operations on search matches with gn

When you find yourself having to operate on a certain string, you may first search for it:


To change it you will usually use a repeatable operation such as ciw followed by whatever you are changing it to.

Now to repeat that change you will first jump to the next search result using n then press the . operator to repeat the change. But if you know that you are going to do that there's an easier way:

Instead of ciw use cgn. Then just press the . and Vim will jump to the next match and change it for you.

According to Vim's help:

gn - Searches forward for the last used search pattern, like with n, and starts Visual mode to select the match.

for more info:

:h gn
:h gN (for searching backwards)

Note: this also works with * which searches for the word currently under the cursor.

Create a directory and cd into it with one command

I don't know about you but I tend to create directories from terminal often, and when I do, cding into them is the first thing I'll do after creating the directory.

This is what it usually looks like

mkdir -p foo/bar/baz
cd foo/bar/baz

This can get quite verbose. You may have also tried this pro tip:

mkdir -p foo/bar/baz
cd !$ # press <TAB> to expand !$ to the last argument of the previous command

But I think this can be even simpler and easier. Add the following to your .zshrc or .bashrc:

mkcd() {
  mkdir -p $1 && cd $1

Now source .zshrc/.bashrc and simply run:

mkcd foo/bar/baz


Word Count in Vim

Vim has a built in shortcut for counting words. To see the word count for the whole buffer type:


You will see something like:

Col 11 of 54; Line 12 of 24; Word 39 of 68; Byte 360 of 727

Meaning we are currently at word 39 and the whole buffer contains 68 words.

To see the word count for a selection, first select and type the same shortcut g<CTRL-g> the result should look something like this:

Selected 7 of 24 Lines; 23 of 68 Words; 234 of 727 Bytes

in this case I have selected 23 words.

Save harddrive space by using git shallow clones

Sometime you clone starter projects, libraries, or plugins to help you get started on a new project or POC.

Perhaps you are using git clone to get your project on a remote server.

When you clone a project what you also get is all the previous states of that repository at each commit. This can add up fast and take a good chunk of your hard drive space as well as take long to download and decompress.

To solve this you can clone a shallow copy of the repository by using the depth switch on the git clone command, and providing it with the value of 1.

git clone --depth 1

Use Vim counts for small arithematic calculations

In CSS land you often need to increment/decrement a pixel value. You can use <C-a> for incrementing and <C-x> for decrementing value but what if you want to move faster or increment by a specific number?

Counts for the rescue!

Every motion in vim can be preceded by a count, and as it turns out so does increment/decrement:

body {
  height: 1827px;

Say I want to increment the padding by 344. I can either:

  • replace the 1827 with 2171 after using my calculator.
  • Press <C-a> 344 times
  • Or alternatively 344<C-a>

You can also set a mapping to increment/decrement by 10.

Credit: Practical Vim by Drew Neil

Watch for database changes on #PostgreSQL

If you are trying to debug multi-threaded environments or a really fast job queue you might need to watch a table for changes.

In psql use the \watch command like so:

\watch 1 "select * from job_queue";

This will run the query every 1 second (you can change the second argument if you need it slower) and display the result as well as past results.

Add highlighted code from #Vim to #Apple #Keynote

Giving a talk with keynote? If you're like me and you love Vim and Apple Keynote you might struggle with getting your highlighted, indented code over to Keynote and making it look as good as it looks in Vim.

Fret no more - vim-copy-as-rtf is a plugin that will let you do that without installing any additional libraries on your mac.

Simply select the code snippet, type :CopyRTF and the highlighted code will be copied to your clipboard ready to be pasted into Keynote. That simple.

Get it here:

Types and type casting in #PostgreSQL

To see the type of column or any entity in PostgreSQL use pg_typeof. Here's an example:

select pg_typeof(array['thing']);


-- pg_typeof
-- ---------
-- text[]

To cast to another type use the :: operator:

select pg_typeof(array['thing']::varchar[]);


--      pg_typeof
-- -------------------
-- character varying[]

h/t Josh Branchaud

Quickly see the contents of a table in #PostgreSQL

Next time you want to see the contents of a table in Postgres' CLI don't type the whole:

select * from name_of_table;

Just use:

table name_of_table;

h/t Josh Branchaud

Persistent folds between Vim sessions

Folds are great. They help you when you have to deal with big files where compartmentalizing the logic might be of help.

The problem is that when you close Vim, your artfully folded code returns to its unfolded state.

The solution is quite simple - when you are ready to save your folds run the :mkview command. This will save your folds in the current buffer to your viewdir (:h viewdir) depending on your environment.

To load your folds use :loadview.

To automate this process add the following to your vimrc:

augroup AutoSaveFolds
  autocmd BufWinLeave * mkview
  autocmd BufWinEnter * silent loadview
augroup END

The folds will be local to your machine, but if you want you can configure mkview to save folds to a file in your project directory and share them with your team.

Switch direction of selection in Vim

Switch the free end of the cursor in Vim's VISUAL MODE.

Simply press o while selecting and the free end will go to the beginning of your selection.


Homebrew is eating up your harddrive

If you've been using Homebrew on your Mac (if you have a Mac you really should) you may not be aware that every time you upgrade your brew formulas using brew update && brew upgrade Homebrew is leaving behind a copy of the old versions.

With package updates becoming available daily you may end up with gigabytes of space being wasted away on old package versions.

To see how much space the old versions are using run brew cleanup -n. When I ran that command I got:

==> This operation would free approximately 9.2G of disk space.

Holy cannoli! zomg

If you feel like reclaiming that diskspace just run the command again without the -n: brew cleanup.

Enjoy space! 🚀

Find where anything is defined in Vim config

When your vim bundle and vimrc become a plugin soup you often need to debug where an autocmd, command, map or function are coming from.

The :verbose command can come in handy in this scenario. Here are some examples:

See where a mapping was set from:

:verbose map gY

See what happens when you enter a buffer:

:verbose autocmd BufEnter

See which file defined a command:

:verbose command Explore

Where is the abbreviation coming from:

:verbose abbrev bpry


Example output:

    Name        Args       Address   Complete  Definition
!   Explore     *    0c              dir           call netrw#Explore(<count>,0,0+<bang>0,<q-args>)
        Last set from /usr/local/Cellar/vim/7.4.1190/share/vim/vim74/plugin/netrwPlugin.vim

Happy hunting! 🔫

Browse and repeat Vim commands

If you typed a command in Vim's command line and want to repeat it you can open the command-line window and browse through past commands. There are two ways two do that:

  1. From Normal mode type q:
  2. From the command line after typing a colon press CTRL-f

In the command window you can browse up and down with HJKL and hit return to re-run the command.

Missed an alert message in vim?

If you ever missed an alert message in Vim, you know the ones that show up at the bottom in the command line, you can easily view a list of all past messages by running the :messages command.

You can also add your own using :echom, which adds a persistent message.

Try it now.

NOTE this will only show persistent messages (echom), and not momentary messages set using echo.

Highlight #markdown fenced code syntax in #Vim

Up until now I was editing all my blog posts in Atom for lack of markdown fenced code block highlighting in Vim. Atom supported it out of the box. As it turns out Vim can do that too, out of the box!

If you are running a recent version of Vim (mine at time of writing 7.4.9910) you can setup highlighting for fenced code blocks in markdown.

Open your .vimrc and add the following line:

let g:markdown_fenced_languages = ['html', 'vim', 'ruby', 'python', 'bash=sh']

You can customize it to your liking and add more languages.

Note: Not all languages are supported but you can try and see if they work. To see a list of languages you have installed on Mac (with Vim installed by Homebrew) run ls -l /usr/local/Cellar/vim/7.4.1190/share/vim/vim74/syntax


This is a game changer.

Breezy copy to system clipboard in Vim

When it's time to get text processed in Vim out of your editor and onto a shiny blog post many Vim Warriors reach for the awkward copy to system register keyboard chord.


Worse is trying to copy the whole file:


This feat of keyboard heroism has crushed many heroes and inflicted countless RSI wounds.

It's time to slay the dragon 🐲 by adding these to your .vimrc:

" copy to system clipboard
map gy "*y
" copy whole file to system clipboard
nmap gY gg"*yG

Pretty Print JSON/HTML in Vim

When working with external APIs often you will get a highly netsted json, like this one, all in one line, with no spaces:

{"batters":{"batter":[{"id":"1003","type":"Blueberry"},{"id":"1004","type":"Devil's Food"}]},"id":"0001","name":"Cake","ppu":0.55,"topping":[{"id":"5002","type":"Glazed"},{"id":"5007","type":"Powdered Sugar"}],"type":"donut"}

The horror. You are not a network cable! You deserve better!

Add the following to your .vimrc file:

command! PrettyPrintJSON %!python -m json.tool
command! PrettyPrintHTML !tidy -mi -html -wrap 0 %
command! PrettyPrintXML !tidy -mi -xml -wrap 0 %

Now you can paste the json into your Vim buffer and run the :PrettyPrintJSON command.

    "batters": {
        "batter": [
                "id": "1003",
                "type": "Blueberry"
                "id": "1004",
                "type": "Devil's Food"
    "id": "0001",
    "name": "Cake",
    "ppu": 0.55,
    "topping": [
            "id": "5002",
            "type": "Glazed"
            "id": "5007",
            "type": "Powdered Sugar"
    "type": "donut"


Same goes for HTML, just run :PrettyPrintHTML.

NOTE: For these to work you need to have python and tidy installed on your machine.

Some helpful #unix networking commands

If you are looking to make some connections in your local unix community you should keep in mind a few commands 😜:

Reverse DNS

dig -x

Will allow you to find the hostname for an IP address.

Find IPs and names of computers in your LAN

arp -a

Change Rails validation message completely

Rails always appends field name to validation messages, and when setting message: on a validation statement it gets appended to the humanized name of the field.

If you want to change the validation message completely use the locales file:

# config/locales/en.yml
        email: "E-mail address"
              blank: "is required"

This was particularly useful with the ValidatesTimeliness gem which does not support a lambda.

🎉Happy 500 post to TIL 🎉

Preserve params between omniauth req & callbacks

If you need to pass a param to omniauth callbacks so that you can maintain a certain state about the user signing in you can do the following:

In the url call to omniauth provider strategy add a querystring:

<a href="/users/auth/facebook?mobile=true">Sign In with Facebook</a>

Then to retrieve it on the callback url handler:


Swap panes and toggle pane layout in tmux

Use <leader>{ to swap panes in tmux.

Use <leader><spacebar> to toggle between different layouts.

Set custom user agent on #Capybara

Sometimes you want to emulate a request to your site from a device with a specific user-agent. This is particularly useful if you have a different behavior when users use those devices (e.g. wrapped mobile app using Cordova)

Setting the user agent can be accomplished by setting the header on the current session:

Capybara.current_session.driver.header('User-Agent', 'cordova')

Custom order #Postgres #SQL union queries

Consider the following data:

insert into users (email, first, last) values ('', 'New', 'User');
insert into users (email, first, last) values ('', 'Lemmy', 'Kilmister');
insert into users (email, first, last) values ('', 'Lemmy', 'Kilmister');

Assuming you want to match a user to the following data:

{ email: '', first: 'New', last: 'User' }

And you consider email a better indication of a match, and first and last name are a fallback. The following query will not yield the desired results despite the where conditions being ordered per the requirements:

select * from users where email = '' or (first = 'New' and last = 'User') limit 1;

This will result in:

1 | '' | 'New' | 'User'

To find by email first we will need to union two queries, rank the match then order by rank:

(select 1 as rank, id, email, first, last from users where email = '')
(select 2 as rank, id, email, first, last from users where first = 'New' and last = 'User')
order by rank
limit 1;

This will yield the correct result:

3 | '' | 'Lemmy' | 'Kilmister'

How to use the hidden #VNC client in #Mac #OSX

OS X has a built in VNC (Screen Sharing) server, but it is a little known feature that it also has a built in VNC client. No additional software is necessary.

To setup the server go to Preferences->Sharing and check the On checkbox next to Screen Sharing. Make sure to only allow access to Administrators or a specific user/user group.

Screen Sharing

You should see your computer name on the Screen Sharing configuration screen. To connect to your computer from another one using VNC open Finder and press ⌘+k. In the Server Address enter vnc:// followed by your computer name or IP address. Connect To Server

h/t Dillon Hafer

Check if a #ruby gem is installed from bash script

If you are adding customizations to your zshrc, such as adding auto completion for a certain gem, you want to make sure that the gem is installed before performing any action.

The gem list [gemname] -i command returns a boolean representing whether a gem is installed or not.

if `gem list lunchy -i`; then 
  echo "Lunchy gem is installed!"; 
  # do some configuration here

If you wish to be more granular you can check whether a specific version is installed by adding the --version [version] flag.

if `gem list lunchy -i --version 0.10.4`; then 
  echo "Lunchy v0.10.4 is installed!"; 
  # do some configuration here

Quickly edit and reload #tmux configuration

When you are playing around with your tmux config you often need to repeatedly open .tmux.conf file and then source it into the current tmux session.

To make things a little faster, add the following to your .tmux.conf:

bind-key r source-file ~/.tmux.conf \; display-message "~/.tmux.conf reloaded"
bind-key M split-window -h "vim ~/.tmux.conf"

Now you can quickly open the tmux config in tmux pane using <prefix> followed by shift + M, edit your configuration, and save when you done. To reload the tmux configuration use <prefix> followed by r.

** <prefix> is C-z for hashrocket's dotfile project (dotmatrix), if you are using tmux default configuration it would be C-b

Fix Tmux 2.1 mode-mouse error

If your tmux started displaying the following error message:

/Users/username/.tmux.conf:136: unknown option: mode-mouse
/Users/username/.tmux.conf:137: unknown option: mouse-select-pane
/Users/username/.tmux.conf:138: unknown option: mouse-resize-pane
/Users/username/.tmux.conf:139: unknown option: mouse-select-window

when you launch it, it is because the tmux 2.1 has a new syntax for turning mouse-mode on. All of the above are now combined into:

set -g mouse on

You'll also notice that after replacing the mouse mode setting with the new one in your config you still cannot scroll up/down with your mouse wheel. To fix that use the following configuration:

bind -n WheelUpPane   select-pane -t= \; copy-mode -e \; send-keys -M
bind -n WheelDownPane select-pane -t= \;                 send-keys -M

See the source and location for bash commands

The oh-my-zsh package comes with a lot of useful plugins. Often those plugins add bash functions to the global scope.

If you want to see where the function is defined you can use the type command.

For example the new_gh/exist_gh command which creates a remote repo for a folder

$ type exist_gh
exist_gh is a shell function from /Users/dkarter/.oh-my-zsh/plugins/github/github.plugin.zsh

To see the function source use the declare command:

$ declare -f new_gh
new_gh () {
        cd "$1"
        ghuser=$( git config github.user )
        git init
        print '.*'"\n"'*~' >> .gitignore
        git add ^.*
        git commit -m 'Initial commit.'
        git remote add origin${ghuser}/${repo}.git
        git push -u origin master

Change Vim cursor in different modes

Vim's NORMAL mode and VISUAL mode are complemented perfectly by the block cursor. When in INSERT mode however, you might want a little more precision. That's why changing the cursor to a slim pipe shape is beneficial (you know, like in any textbox on your OS). It is also a nice reminder that you are in VISUAL mode, without having to stare at the bottom of the screen.

While we are at it, you might also want REPLACE mode to have a cursor of it's own, for that an underscore style looks great.

To accomplish this customization add the following to your .vimrc

iTerm2 + Tmux on OS

let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\"
let &t_SR = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=2\x7\<Esc>\\"
let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\" 

iTerm2 on OS

let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_SR = "\<Esc>]50;CursorShape=2\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"

Vim startup time profiling

If you want to see why vim is taking so long, you can get a breakdown of how long each plugin took to load:

vim --startuptime startup.log

To make things a little easier, I created the following bash command, which will create the startup log, open it in vim and delete it when done.

vim --startuptime startup.log +qall && vim startup.log && rm startup.log

Graphing the data

You can use vim-plugins-profile shell script to get a better sense of which plugins are causing the biggest slowdown:

It will create a graph resembling the DevTools network tab: graph

and provide a summary similar to this one:

Generating vim startup profile...    
Parsing vim startup profile...     
Crunching data and generating profile plot ...    

Your plugins startup profile graph is saved     
as `profile.png` under current directory.    

Top 10 Plugins That Slows Down Vim Startup    
   1    105.13  "vim-colorschemes"    
   2    42.661  "vim-easytags"    
   3    31.173  "vim-vendetta"    
   4    22.02   "syntastic"    
   5    13.362  "vim-online-thesaurus"    
   6    7.888   "vim-easymotion"    
   7    6.931   "vim-airline"    
   8    6.608   "YankRing.vim"    
   9    5.266   "nerdcommenter"    
  10    5.017   "delimitMate"    

Profiling Vim

To find which plugins may be causing certain actions in vim run slowly try using the built in profiler:

:profile start profile.log
:profile func *
:profile file *

Then perform the slow action, when done run:

:profile pause

You can then open the profile.log file and look at the bottom to see summary, sorted by run time, of which functions took the most time, the function name may give away which plugin/core function is causing the issue. The top of the file will contain each line of code that was run in vim during the profiling session and how long it took.

Chrome DevTools navigation and editing tools

If you ever worked with editors such as Atom/Sublime Text you will appreciate the following: Chrome DevTools now sports fuzzy finders for your script/stylesheet files and for methods within them.

To get started open dev tools and hit Cmd+p start typing a filename or part of a filename: cmd-p

Then to jump to a specific method hit Cmd+Shift+P and start typing a method name: cmd-shift-p

If you are a big fan of multiple cursors, you'll be happy to learn that those are now available within chrome developer tools:

cmd-d [while the cursor is on a word hit Cmd+d to duplicate the cursor to the next match]

holding alt [holding alt and dragging down will allow you to edit a vertical line]

To search all files (scripts/html markup) hit Cmd+Option+f: cmd-alt-f

Change the source in dev tools and hit Cmd+s the updated code will be run the next time it is called. DevTools will indicate it has a modified version by changing the background color to bright orange: change in memory

Try all voices and languages available on OS X say

OS X's say command comes packed with different voices and languages, some of them very entertaining. You can use say to make your scripts more lively.

I wrote a shell script using the say -v? output with the help of vim macros to say the recommended test sentence for each voice sequentially:

Using awk to debug $PATH

If you ever tried printing your system PATH environment variable using echo $PATH you probably got something like this:


Not a pleasant read.

I thought that would be a good opportunity to practice my awk scripting skills and came up with this:

echo $PATH | awk '{ n = split($0, paths, ":"); for (i=0; ++i <= n;) print i, paths[i] }'

It prints a numerically indexed list of the paths and prints them in separate lines.

1 /usr/local/heroku/bin
2 /usr/local/bin
3 /Users/username/.rvm/gems/ruby-2.2.2/bin
4 /Users/username/.rvm/gems/ruby-2.2.2@global/bi
5 /Users/username/.rvm/rubies/ruby-2.2.2/bin
6 /usr/local/bin
7 /usr/bin
8 /bin
9 /usr/sbin
10 /sbin
11 /opt/X11/bin
12 .git/safe/../../bin
13 /Users/username/.bin
14 /usr/local/sbin
15 /Users/username/.rvm/gems/ruby-2.2.2/bin
16 /Users/username/.rvm/gems/ruby-2.2.2@global/b
17 /Users/username/.rvm/rubies/ruby-2.2.2/bin
18 /Users/username/.rvm/bin
19 /Users/username/.rvm/bin
20 /Users/username/Dropbox/Developer/gocode/bin

You can alias this command if you use it often:

alias print-path=`echo $PATH | awk '{ n = split($0, paths, ":"); for (i=0; ++i <= n;) print i, paths[i] }'`

You may want to check out another rocketeer's (Josh Branchaud) solution to this problem, written in Rust:

vim-surround is different for selected text

If you tried using vim-surround after selecting text in visual mode, just to get your text deselected and have nothing happen, it's because visual mode uses a different trigger for vim-surround:

In visual mode use S, followed by your surrounding character (e.g. S)).

This is different from the normal mode way of doing it ys[text-object] (e.g. ysap{)

I like thinking of this one as yes, surround! [my text object] and prefer it to selecting, but some cases require visually selecting.

Install a gem for all rubies in your system (RVM)

If you want a certain gem to be available in all your rubies (particularly common with gems which expose a CLI) use this command to install it for all ruby versions installed with RVM.

for x in $(rvm list strings); do rvm use $x@global && gem install hitch; done

(Replace hitch with your desired gem)

Kill process by name

While killing processes using their PID isn't hard, the process can be simplified further. You can kill a process by its name.

This is how you do it using PID:

ps aux | grep [process_name]
# copy the pid from the output
kill [PID] # paste pid

This is how it's done using the name of the process:

pkill [process_name]
# e.g. pkill rails

Spell check in vim

Don't let typos sneak into production, you can use a spell checker right from Vim. Here's how:

:set spell

To navigate between spelling mistakes use ]s and [s.

To correct spelling mistakes, go to the mistake and use z= to see suggestions.

P.S. if the spelling errors don't show up, make sure to check two things:

  1. That you are not a fantastic speller and a true scholar
  2. That the file type you are checking spell on is allowed (you can test it by setting your syntax to txt :set syntax=txt)

Find (and kill) all processes listening on a port

To search for processes that listen on a specific port use the lsof or List Open Files. The -n argument makes the command run faster by preventing it from doing a ip to hostname conversion. Use grep to show only lines containing the word LISTEN.

lsof -n | grep LISTEN

To filter for a specific port use the following:

lsof -n -i4TCP:[PORT] | grep LISTEN

To kill all processes listening on a specific port use:

lsof -n -i4TCP:[PORT] | grep LISTEN | awk '{ print $2 }' | xargs kill

The awk command returns only the second column (PID), and the xargs executes kill on each line returned.

Add colour to your man pages

Syntax highlighting makes a programmer's life more cheerful. Linux man pages shouldn't be an exception.

Add the following to your zshrc to highlight arguments and commands in man pages:

export LESS_TERMCAP_mb=$(printf '\e[01;31m') # enter blinking mode – red
export LESS_TERMCAP_md=$(printf '\e[01;35m') # enter double-bright mode – bold, magenta
export LESS_TERMCAP_me=$(printf '\e[0m') # turn off all appearance modes (mb, md, so, us)
export LESS_TERMCAP_se=$(printf '\e[0m') # leave standout mode
export LESS_TERMCAP_so=$(printf '\e[01;33m') # enter standout mode – yellow
export LESS_TERMCAP_ue=$(printf '\e[0m') # leave underline mode
export LESS_TERMCAP_us=$(printf '\e[04;36m') # enter underline mode – cyan


Browse ruby gem source inside of a vim tab

When you are working with gems you often need to jump to the gem's source. Vim has a really neat trick for that.

First make sure you have the vim-bundler plugin by Tim Pope installed: Then you can use the following command:

:Btabedit name_of_gem


Vim opens the gem's source starting with a netrw file list in a new tab for you.

Bonus: Vim will autocomplete the gem name for you based on your Gemfile.

Never leave the home row in bash

To edit a command in bash you often need to jump around in the line and revert to using the arrow keys. As a vim/emacs user this becomes a bit of a clumsy non-ergonomic movement, here are some shortcuts to help you keep your fingers on the home row. If you are an emacs user these are going to look familiar.

  • ctrl-p - previous command entered
  • ctrl-n - next command entered
  • ctrl-a - jump to BOL
  • ctrl-e - jump to EOL
  • alt-b - jump word forward
  • alt-f - jump word backwards
  • alt-b - jump character forward
  • alt-f - jump character backwards

If these shortcuts don't work try running set -o emacs

Alternatively you can turn on vi mode in your shell by calling set -o vi, which you can add to your .zshrc or add set editing-mode vi to your .inputrc. After setting this you can enter normal mode by hitting escape and use vi motions to edit/move.

Your shell just got upgraded. 💪💻

Use `watch` to monitor status commands in bash

If you need to monitor a status command such as monit status or service nginx status, instead of calling the command over and over use the watch command:

watch monit status

by default it will refresh the status every 2 seconds and highlight changes as they occur. You can modify the interval by using the -n switch:

watch -n 1 monit status

If your status command uses color you can turn it on by using the -c switch.

P.S. If you need to run this command on mac you will need to install the watch package using homebrew.

Use bash's Bang command to improve productivity

Bash has neat way to repeat last ran command. In your shell type !! this will put the last ran command in your prompt and allow you to edit and execute it. Use it to add sudo to any command:

$ apt-get install somepackage
Insufficient permissions
$ sudo !!
$ sudo apt-get install somepackage

If you want to go back to a specific command other than the last you have a few options:

You can execute a history command by its ID (to see all IDs run history, to clean history history -c)

$ history
1234 some really long command
1236 third command
$ !1234
$ some really long command
$!-2 # run two commands ago (not including bang commands)
$ history

You can run the last command containing a specific string:

$ foo bar
$ bar foo bazz
$ !foo # last command starting with foo
$ foo bar
$ !?bazz # last command containing the word bazz
$ bar foo bazz

Reuse last/first argument:

$ ls -la /development/reallylongnameidontwanttoretype
$ cd !$
$ cd -la /development/reallylongnameidontwanttoretype
$ $^ app
$ cd app

Confirm each find replace in Vim

If you are running a find replace on the whole file, you might want to use the c flag at the end of your replace command which will make vim confirm each replace.



h/t @joshbranchaud

Best practice for event binding in JavaScript

When binding an event to a DOM element you often need a way to update your event in runtime. This presents a challenge because setting the new event will not override the existing one but instead create an additional event. In that case you need to namespace (jQuery terminology) your event which will allow you to replace it.


$(window).on('scroll', function () { console.log('A') });

// Scroll output: 
// => A
// => A

$(window).on('scroll', function () { console.log('B') });

// Scroll output: 
// => A
// => B
// => A
// => B


$(window).off('scroll.myPlugin').on('scroll.myPlugin', function () { console.log('A') });
$(window).off('scroll.myPlugin').on('scroll.myPlugin', function () { console.log('B') });

// Scroll output: 
// => B
// => B

Vanilla JS - when using the addEventListener use named functions (instead of anonymous..). It may be a good idea to keep an array of your event handlers in your object tree.


var scrollHandler = function() { console.log('A') };
var scrollHandler2 = function() { console.log('B') };
window.addEventListener('scroll', scrollHandler);
window.removeEventListener('scroll', scrollHandler);
window.addEventListener('scroll', scrollHandler2);

// Scroll output: 
// => B
// => B

This is especially important when writing your own libraries to avoid collisions with user events.

ActiveRecord Dirty module

Rails provides a way to check if your model's attributes have changed since initially loading it from database. It also provides convenient methods for checking what the values were before the change using #{attribute_name}_was as in the example below.

# A newly instantiated object is unchanged:
person = Person.find_by_name('Uncle Bob')
person.changed?       # => false

# Change the name: = 'Bob'
person.changed?       # => true
person.name_changed?  # => true
person.name_was       # => 'Uncle Bob'
person.name_change    # => ['Uncle Bob', 'Bob'] = 'Bill'
person.name_change    # => ['Uncle Bob', 'Bill']

# Save the changes:
person.changed?       # => false
person.name_changed?  # => false

# Assigning the same value leaves the attribute unchanged: = 'Bill'
person.name_changed?  # => false
person.name_change    # => nil

# Which attributes have changed? = 'Bob'
person.changed        # => ['name']
person.changes        # => { 'name' => ['Bill', 'Bob'] }

Use console.table to display js collections

If you have a big JavaScript collection and you want to view it in a tabular fashion use console.table

  1. Open dev tools
  2. Type console.table(my_collection)

You get a sortable, indexed table containing your collection. Very neat.

RSpec multiple formats with different out buffers

On RSpec there is a way to use multiple formatters from the command line and pipe each into a different output buffer (file/stdout).

To do this use rspec -f p -f j --out result.json spec

-f is alias for --format which takes the arguments

[p]rogress (default - dots)
[d]ocumentation (group and example names)

--out will save the last formatter mentioned to a file.

The original formatter will print to $stdout so you end up having the normal display from RSpec and a JSON file which you can use to parse with your own script.