DEV Community

Amin
Amin

Posted on

Surgical insertion — Neovim From Scratch

This episode is part of a serie called Neovim From Scratch where I show you the basics of how to use Neovim (and Vim) when editing text.

Previously, we saw that the i keybind was used to go from NORMAL to INSERT mode in Neovim.

Today, we will learn some more tricks to go into INSERT mode combining movements in order to grasp some few milliseconds while editing our texts.

This time, I'll make my Python lovers happy because we will be using Python as our example language. Many more to come!

So, let's start with this simple Python example code snippet.

def check_guess(guess: int, number: int):
    if guess == number:
        print("You found the number!")

    elif guess < number:
        print("The number is higher!")

    else:
        print("The number is lower!")

check_guess(5, 10)
Enter fullscreen mode Exit fullscreen mode

Let's say we are at the very beginning of this file, the very first character. If we wanted to insert a character at the end of this line, we could move our cursor using the l key that moves the cursor forward one character.

We could also move from words to words using w or W, or even better using the end of the word with e or E.

We could also find the character : using the f keybind.

All these approches are great, but you would need to then go into INSERT mode if you wanted to add something here using the i key. So this means many keys for this task.

What if I told you that you can achieve going to the end of the line and changing the mode to INSERT mode just by using one keybind?

That's right, you can use the A keybind in order to go to the end of the line and change the mode to INSERT mode right after, allowing you to quickly add characters without typing too many things.

As for every keybind, the casing is important here. But what about the a keybind?

It is used to go into INSERT mode and move the cursor just after the letter that is under the cursor.

For instance, if we move the cursor right there.

          Our cursor
              |
              |
              v
def check_guess(guess: int, number: int):
    if guess == number:
        print("You found the number!")

    elif guess < number:
        print("The number is higher!")

    else:
        print("The number is lower!")

check_guess(5, 10)
Enter fullscreen mode Exit fullscreen mode

And we wanted to insert a character after the cursor, we would have to move the cursor one character forward using the l keybind, and then pressing the i keybind in order to go into INSERT mode.

Instead, we can use the a keybind in order to do it in one keystroke.

      Insertion mode here
               |
               |
               |
def check_guess+(guess: int, number: int):
    if guess == number:
        print("You found the number!")

    elif guess < number:
        print("The number is higher!")

    else:
        print("The number is lower!")

check_guess(5, 10)
Enter fullscreen mode Exit fullscreen mode

Moving and inserting text is a powerful way of editing text since it allows you to combine many movements together in order to compose them and allow you to edit your text faster.

We can also move our cursor from anywhere to the beginning of the line and change the mode from NORMAL to INSERT mode quickly by using the I keybind.

          Our cursor
              |
              |
              v
def check_guess(guess: int, number: int):
    if guess == number:
        print("You found the number!")

    elif guess < number:
        print("The number is higher!")

    else:
        print("The number is lower!")

check_guess(5, 10)
Enter fullscreen mode Exit fullscreen mode

For instance, if we put our cursor here, we could use the I keybid in order to go to the first non-blank character and immediately change the mode from NORMAL to INSERT.

Insertion here
|
|
|
+def check_guess(guess: int, number: int):
    if guess == number:
        print("You found the number!")

    elif guess < number:
        print("The number is higher!")

    else:
        print("The number is lower!")

check_guess(5, 10)
Enter fullscreen mode Exit fullscreen mode

Often time, you'll find yourself needing to append some characters to a file because you missed something or you need to improve the code a bit. These keybind will help you do that faster than what you could using a non-modal text editor like VSCode!

With that, we could easily add new lines to this code by using those keybinds to go to the end of a line and insert a newline character for instance if we need to add a documentation for our function.

def check_guess(guess: int, number: int):
    """
    Check if the guess is correct
    """
    if guess == number:
        print("You found the number!")

    elif guess < number:
        print("The number is higher!")

    else:
        print("The number is lower!")

check_guess(5, 10)
Enter fullscreen mode Exit fullscreen mode

In order to do that, you would need to move your cursor in NORMAL mode to the first line, and anywhere from there you would press the A keybind in order to go into INSERT mode in the end of this line in order to add that missing documentation.

But that is too many keypress, and there is a better way of doing it.

If you find yourself needing to add a newline after the line under the cursor, anywhere in this line, you can use the o keybind (like open a new line) in order to add a new line after the current one and immediately go into insert mode.

           Our cursor
              |
              |
              v
def check_guess(guess: int, number: int):
Enter fullscreen mode Exit fullscreen mode

Once we press the o keybind, our cursor automatically moves after this line.

def check_guess(guess: int, number: int):
    +
    |
    |
Insertion cursor
Enter fullscreen mode Exit fullscreen mode

One interesting thing to note here is that Neovim is aware of this file type, and can even help you move the cursor on the correct indentation immediately after pressing the o letter.

Here, it makes sense because Python is an indented language, and you have to move one indentation away in order to help the interpreter understand that this is the body of our function.

You can even try with the if statement. Try adding a new line below and see that the indentation is smart when adding new lines!

For those of you that might have guessed, the uppercase version O does something similar. It adds a new line above the line under the cursor instead of below. This eliminate the need to go to the beginning of the line, and inserting a new line character manually.

Now, let's say that you wanted to change the letter e by the letters ur in check_guess (the name of our function).

From what we have learned, we could move the the letter e, use the keybind x, go into INSERT mode by pressing the keybind i and add those wanted letters.

And as you have guessed, there is a better way.

We can actually use the s keybind in order to remove a character, immediately go into INSERT mode after that operation and letting us add the characters we want.

    Our cursor
      |
      |
      v
def check_guess(guess: int, number: int):
Enter fullscreen mode Exit fullscreen mode

By pressing s here, we can immediately be starting to update this letter with something else.

def ch+ck_guess(guess: int, number: int):
      |
      |
   Insertion here
Enter fullscreen mode Exit fullscreen mode

And now we can add whatever we want and go back into NORMAL mode by pressing the escape key.

And as for the uppercase version of that keybind, it is a bit extreme, but very useful again to save some keystrokes since it will delete the entire content of the line under the cursor and go into INSERT mode right after. Pretty useful if you made a mistake on the whole line!

There is also another way of doing it, which is by pressing the c letter twice as in cc.

This is needed because the c letter takes a text object as its argument. Text objects are a powerful notion in Neovim, but we won't be covering them in this article, rather later so stay tuned!

And as for the uppercase version which is the C keybind, it is used to delete the entire content from the cursor until the end of the line and go into INSERT mode right after.

            Our cursor
               |
               |
               v
def check_guess(guess: int, number: int):
Enter fullscreen mode Exit fullscreen mode

Let's imagine we need to change the entire content of our parameters, a quick way of doing it would be to input the C keybind right at the location of the cursor as show above in order to get the following result.

            Insertion here
               |
               |
def check_guess+
Enter fullscreen mode Exit fullscreen mode

You can also do that using the D keybind. I know, there is a lot of keybind that do the same thing, but actually they are very different.

The d keybind for instance is rather used to delete lines. Easy to remember, d as in Delete. But this keybind takes an argument that is a motion, or a text object. So we'll get to know more about it in the next article.

That's it! Now you know how you can utilize the INSERT mode along with some new movements we just saw in this article in order to edit text faster.

In the next article, we will learn more about text objects, and different keybinds that utilizes these text objects in order to do even more powerful actions, so powerful that you'll wish you got to know Neovim earlier!

See you!

Top comments (0)