I am really not a fan of using vi or vim or emacs or whatever complicated built-in editor. If ever I'm on the server, I use nano because it's stupidly simple and gets the job done. Yes I realize there are a bazillion reasons as to why vi is better, but the amount of time needed to fully learn everything PLUS set up my working environment just the way I would want it isn't worth it to me. The value add does not justify the learning/time cost.

HOWEVER! As with all things, it's important to still be somewhat familiar with it. I have seriously been refusing to learn how to use vi, despite insistence from numerous colleagues. It wasn't until recently (now a few months ago, oh how quickly time flies) that I had learned a cool new trick. And I shall impart this knowledge to you, fellow reader, or to future me.

But first...

Let's go over some basics.

Super basic commands

Here's how to enter and exit out of vi/vim. vim is the "improved" version of vi, you know, version 2. wink

# to open a file with vi
vi file_name.text
# to exit out of a file without saving
:q
# to force quit w/o saving
:q!

# to exit out of a file && save
:wq

Note, you must add the : in there.

q is for quit, w is for write, so :wq is to write (save) and exit.

Let's move on now. Inserting text.

# to go into 'typing things into editor because its technically a text editor' mode
i  # (for insert)

# to exit out of insert mode
cntl-c
# or
<ESC>  # sometimes the ESC button works, sometimes it doesn't

Note: the ESC seems to work on Linux distros, such as Ubuntu, so when you're on the server then you can press Esc. On my Mac, that isn't the case and only cntl-c works.

And now let's delete a full line of text. Or a chunk of text.

# to delete the current line
dd                    # => cntl-k on nano

# to delete 20 lines (+1 extra on a mac)
20d (then press enter)
# Note: this deletes 20+1 lines from where the blinker/cursor is.

# to delete line 5 only
:5d

Jumping down to a particular line number. This is the equivalent to scrolling to line 10 and inserting your cursor there.

# jump down to line 10
:10

The fun stuff

Here's where the power of vi and vim lie. You can jump down to a certain line number, you can delete multiple lines, you can find and replace text within a file. All the things you can do in your standard editor like Atom or Sublime, you can now do in vi! Woo! /s

But really, I happen to enjoy using my mouse and highlighting/scrolling with it. Moving my hands from the keyboard doesn't make me a horrible programmer. Writing horrible code makes me a horrible programmer. It also doesn't really let me be less efficient either. Honestly, switching from keyboard to trackpad/mouse/pen allows your brain to switch gears and quietly pause and reflect on your coding decisions, such as "Did I really mean to write that line of code? Maybe I should delete it" vs going back and willy-nilly pull the trigger and delete 15 lines of code only to realize afterwards that it was probably a bad idea and you should have kept it because now you could have used it. It's a built in mechanism to prevent yourself from pulling the trigger too quickly. (Insert social commentary of how this should always be applied, mostly when actual weapons are involved...) However, in server-land, you don't get the built-in benefits of actually having a GUI, which means text editing must be done in a GUI-less environment.

I digress.

The main point of this entire post was really for this next reason. May I present to you.... Find and replace all! This has been the one main benefit to using vi. And if I am doing batch text changes, to a config file for example, this is the best way to do it.

# find all instances of phrase and replace it with something else
:%s/original_word/new_word

# for example...
# find all asdf and replace with 0000
:%s/asdf/0000

There is a caveat to the above. This will change all instances without confirmation, so if there is one you want to skip, this is not the command for you.

Let's look at the other options and iterations of the Find and Replace All command. First, let's confirm our individual find/replaces. Appending gc will do a global search with confirmation. You will have to type y or n for replace or skip. It will highlight the word it is looking to replace. I prefer this as it reminds me of git add -p and forcibly confirming each one.

# confirm each change before replacing
:%s/asdf/0000/gc

What happens if the word you want to replace is kind of funky? like http://localhost needs to be replaced with $APP_URL? Uh oh, you can't use / since the command also uses it as the delimiter. What do? Simple. Change the delimiter! I prefer the # for this, but it can be any symbol as long as if it's consistently used across the command.

# change delimiter and confirm before replacing
:%s#original_word#new_word#gc

Using the example (without bash code-style turned on)

:%s#http://localhost#$APP_URL#gc

It looks ugly but, wowza, this really works. If I had used nano to find text and then delete and replace it, that would have taken me ages. I could have also copied the text and pasted it into Atom to replace what I needed to replace, but both of these are costly. And my time is extremely expensive. In this case, the value add of this simple use case is incredibly high and far outweighs the knowledge cost.

So there you have it! Possibly the best thing about vi. I am sure I will encounter other fun handy things with vi, but for now, I'm pretty good with this list as is.

Don't forget to :wq your changes! grinning

Level up +5 (+10 if you've been avoiding vi as if it were the bubonic plague)


Questions? Comments? Hit me up at risaonrails !