How to quit Vi (and more tips for getting started with Vi)

If you opened vi or Vim because you heard it’s what all the cool kids use, chances are your first question is “Aaaaah! How the heck do I get out of this bizarre thing?!”

Don’t panic! Press the Escape key, to make sure you’re in Command Mode. Type “:q“, without the quotation marks, and press Enter.

If you get an error message saying “No write since last change”, type “:q!” and press Enter. You should now be back in your normal command line interface.

Phew! That’s a relief, huh? Now that you’re safely out of vi, here are some reasons why you should go back in and learn how to use it.

Reasons to use Vi (or Vim)

Vi (and usually Vim) is on practically every Unix-like system in existence

Vimlogo.svgVi is specified in the POSIX standard, which means that practically any flavor of Unix or Linux will include it. Sitting down at a coworker’s computer? Vi is waiting for you. Using SSH to go into a completely foreign system with literally nothing but the OS installed? Oh, hi vi, nice to see you again!

A brief note on the difference between vi and Vim: vi was written back in 1976. Vim is a “sequel” of sorts to vi that added features like syntax highlighting, scripting, advanced regular expressions, a help system, and more. I’m using Vim, but my understanding is the basic command structure is shared by both programs.

It’s fast to use

Or it will be, once you’ve used it enough. You rarely have to take your hands off the keyboard to complete almost any text editing task you can think of. In addition, vi’s interface is optimized such that the most commonplace tasks are on the home row, and extremely quick to perform. An experienced vi user can be extraordinarily productive.

It’s what all the cool kids use

Don’t underestimate the benefits of peer pressure! Vi and Vim have a huge community of users who swear by them, some of whom have been using it for decades. Through countless iterations of hardware and software, vi has stood the test of time as the preferred text editor of programmers and sysadmins everywhere. That’s got to count for something, right?

I could go into how powerful and customizable the vi editor is, but I’m just starting my own exploration of it, and frankly, the most important thing is that you can perform basic tasks, so the editor stops feeling like an alien torture device. Deeper understanding can wait until you’re comfortable. So let’s move onto:

Vi / Vim Basics

Opening vi

To open vi, open a terminal window, type “vi“, and press Enter. To open a file with vi, type the filename afterwards, as in “vi filename.txt“. If that file does not exist in the local directory, vi will begin creating a new file with that name.

Type “i” to enter Insert Mode

Vi is a modal editor, which means that the commands you can use depend on which mode you are in. When you open vi, it defaults to the Command Mode. For people who are used to standard text editors, Insert Mode will be far more familiar. Press the “i” key to enter Insert Mode, then begin typing normally. You’ll see your text entered onto the screen.

Undo and Redo (Vim only)

When you’re starting out, it’s natural to make mistakes. To undo, first make sure you’re in Command Mode (by pressing the Escape key). Then tap the “u” key. You should see your last change undone. You can keep pressing “u” to back up through vi’s change history. To redo, press “Ctrl + r” (“r” by itself is the Replace command).


h“, “j“, “k“, and “l” in Command Mode correspond to left, down, up, and right respectively. This will seem really weird at first, but using the keys right in the home row makes it very fast to navigate.

Note that you can use the regular arrow keys as well, but you should try your best to get used to the home row keys. Train that muscle memory: it’s worth it.

For faster navigation, use “Ctrl + u” and “Ctrl + d” to half-page up and down, respectively. There are many other ways to navigate a file as well, but these will serve you well enough for now.

Saving and Quitting

Once you’ve made some changes, type “:“. You’ll now notice your cursor is at the bottom of the terminal window. Press the “w” key so that the bottom of the window says “:w“. Press Enter, and you’ll get a message that your file was saved.

As mentioned above, you can now type “:q” to quit vi. If you tried to quit without saving, you’ll get an error. You can type “:wq” to save and quit at the same time, or “:q!” to quit without saving.


Type “/” in Command Mode to open a search prompt at the bottom of the window. Then type whatever word you want to search for and press Enter. To go to the next search result, press the “n” key. To go to the previous result, press “Shift + N“.

Basic Vi Cheat Sheet

Quit without saving


Save and quit


Enter insert mode


Move left / down / up / right

h  j  k  l

Beginning of word / end of word

b  e

Move to the end of the line


Page up / page down

ctrl + u   ctrl + d

Leave insert mode


Search (must be in Command Mode)


Next Steps

You now know enough about vi to use it for simple tasks. Once you’re comfortable with the above, try typing “vimtutor” at the command line for a nice tour of some of Vim’s intermediate features.

Vi and Vim have a vast array of commands and customizable elements, far more than any blog post can hope to cover. Once I’m a little more familiar with Vim myself, I’ll post a follow-up article with some good tips.

In the meantime, here are some helpful resources on Vi:

Simple bash prompt customizations: shortened username, full filepath, current git branch

Today I learned… that your Mac terminal bash prompt can be customized and enhanced well beyond its basic boring default.

A full tour of bash customizations is outside the scope of this post, but I do want to share the simple customizations I use on my own bash prompt.

Screen Shot 2015-02-16 at 9.07.45 AM

My prompt displays my username, the current directory’s file path, and the git branch I’m currently in.

To make your bash prompt do this, open your .bashrc file.

$ open ~/.bashrc

.bashrc is a shell script that bash runs when you open bash. This example modifies PS1 (the user prompt). To make yours look like mine, add this to the bottom of your .bashrc file (the # comments are optional).

Save the file, return to your terminal and type source ~/.bashrc to apply the changes.

$ source ~/.bashrc

More bash customizations

That’s just the tip of the iceberg, though, and chances are, there’s more you will want to do to your bash prompt.

Here are two articles I found helpful.

  1. This IBM Developer Works post on customizing bash includes a handy sequence guide and an explanation of how colors work in bash.
  2. Martin Fitzpatrick has a great guide to customizing terminal on Mac that I adapted for my own prompt customizations, plus helpful explanations of how this stuff works.
  3. What is the purpose of .bashrc and how does it work?

Git: How to automatically add the branch name to the end of every commit message

Today I learned… that git can be customized in a number of ways by using its hooks!

On my engineering team, it’s our convention to name feature branches after their corresponding JIRA issues. Likewise, we include the branch (issue) name in every commit message.

$ git commit -m "Fixed the thingy jira/story/ourproject-4555"

Including the branch name / issue name like this means the commit will show up in JIRA linked from the issue itself! Pretty cool. I’ve worked with JIRA a lot over the years, but I’ve never been on a team that actually integrates it with git like this, and the organizational benefits are worth the extra effort.

Alas, it is all too easy to forget to add the branch name at the end of a commit, and I got tired of amending my git messages (which is easy enough: git commit –amend will do it). I knew there had to be a way to automate this.

Adding a git hook

  1. Go into your project’s repo
  2. Open ./git/hooks directory (remember, .git is a hidden directory by default)
  3. Make a copy of .git/hooks/prepare-commit-msg.sample, paste it into the same folder, and remove the .sample extension. You should have a file named simply prepare-commit-msg with no extension.
  4. Paste this into the new file:
# Automatically adds branch name to the end of every commit message.

NAME=$(git branch | grep '*' | sed 's/* //')
echo $(cat "$1") "$NAME" > "$1"

The first line gets the git branch name and sets it to “NAME”.

The second line echoes the contents of your commit message (represented as $1), adds “NAME” to it, and replaces $1 with your message + NAME.

Just save the file and try it out in bash now! No need to reload bash or source anything.

Here’s the gist

# Automatically adds branch name to the end of every commit message. Handy for git/JIRA integrations.

# Make a copy of .git/hooks/prepare-commit-msg.sample in your repo and name the file prepare-commit-msg (remove "sample" extension)
# Paste the following into the file, save the file, and try it out in bash

NAME=$(git branch | grep '*' | sed 's/* //') 
echo $(cat "$1") "$NAME" > "$1"

More examples

There are many ways to approach this problem, and you can do a lot of sophisticated things with Git hooks. Here are some resources I found helpful in learning about git hooks and git in general:

Push to GitHub without entering username and password every time (Git Bash on Windows)

Today I learned… how to save my GitHub username and password so I don’t have to re-enter them every time I push something to GitHub from my Windows machine.

A bit of backstory:

I recently set up git on my Windows 7 machine using Git for Windows (mysisgit). That process went smoothly and I feel right at home in my little emulator, Git Bash, using all the same commands I already know and love from my Mac.

If you’re used to using git on a Mac and have to work on a Windows machine for whatever reason, I highly recommend mysisgit.

Credential check… every time!

Everything was going great until I pushed my changes. Every push triggered a new credentials check!

$ git push origin master
Username for '': xyz
Password for '':

I don’t want to enter my GitHub username and password every time I push something.


So I hit the Google and found this StackOverflow question, where some helpful folks say the problem results from connecting over HTTPS instead of SSH, but GitHub’s help documentation recommends connecting over HTTPS, not SSH.

I’m hesitant to disobey the word of GitHub, so instead of relying on SSH, I followed GitHub’s instructions to use a credentials helper.

Credentials Helper Setup

However… GitHub’s explanation of how to cache your password with the credentials helper aren’t very clear. They tell you to enter this line and then don’t tell you what to do next.

Here’s what I did – worked for me.

In your Git Bash window, enter this line:

$ git config --global credential.helper wincred

Now push a change to Github and enter your credentials – this is where your username and password information gets saved to the credential helper.

You won’t get any feedback telling you that, but you can confirm it worked by pushing another change. This time, you shouldn’t have to enter your credentials again.

But I have this problem on Linux!

Try this: Caching your GitHub password in Git

$ git config --global credential.helper cache

Quickly add lines to .gitignore using echo in the command line

Today I learned… that you don’t have to open .gitignore in your editor, add a line(s) to it, save it, and close it. You can do all that in one step from the command line using echo!

Here’s a preview:

$ echo '.DS_Store' >> .gitignore

How it works

Here’s a common scenario. You do git status on your working folder and discover git wants to add some file you don’t want added to your remote repository, like the pesky .DS_Store file.

Thanks, but no thanks, git. I don't want that .DS_Store file in my git repository.
Thanks, but no thanks, git. I don’t want that .DS_Store file in my git repository.

If your git project doesn’t already have a .gitignore file, create one in one step by typing this while in your project’s root directory:

$ touch .gitignore

From here, you could open that .gitignore file in an editor and add lines to it, save it and close it, but that’s rather cumbersome if all you need to add is one or a few lines.

Here’s a faster way, using “echo” to push some new data into the file.

$ echo '.DS_Store' >> .gitignore

The double >> is important. If you type just one >, you’ll overwrite the existing contents. Using >> appends your echo string to the end.

For a sanity check, open up .gitignore and you’ll see that .DS_Store has been added.

Once you’re more accustomed to using .gitignore you’ll probably come up with a “boilerplate” .gitignore to copy and paste into all your projects, but you’ll probably never reach a point where you aren’t occasionally surprised by an unwanted file showing up in your git status.


Automate Express server restarts with Nodemon

Today I learned… that you don’t have to navigate to Terminal, press CTRL + C to stop the server, and re-enter node server.js to start up the express server again in order to see your latest work in the browser.

There’s a better way: get Nodemon and automate this repetitive process!

Nodemon will watch the files in the directory you run it in and restart your server automatically when it detects a change.

To install Nodemon:

$ npm -g install nodemon

To get Nodemon running:

$ nodemon server.js

Leave that Terminal window open and let Nodemon work its magic.