Timed Mouse-Free Navigation: Modes, Motions, Searches, and Jumps
Welcome back. You now have an isolated LazyVim profile and a small but important diagnostic habit: confirm which configuration is active, then use :verbose to discover where a behavior came from. That gives you a safe place to practice without turning Neovim into a large configuration project.
This begins the Mouse-Free Editing Through Deliberate Practice module. The aim is not to memorize a giant cheat sheet or to become fast immediately. It is to make a repeatable choice: first return to Normal mode, then choose a motion that targets a meaningful unit—line, word, character, or search result—rather than reaching for the mouse or holding an arrow key.
By the end of this session, you will complete a timed navigation route in a C#-shaped buffer using modes, core motions, character jumps, and search.
Modes are deliberate editor states
In a conventional IDE, typing, selecting, and navigating are usually variations of one state. In Neovim, they are distinct states with a clear purpose. Treat Normal mode as the control surface: it is where you navigate and issue commands without modifying text.
| State | Enter it | Use it for | Leave it |
|---|---|---|---|
| Normal | Esc | Navigation and commands | i, v, or : |
| Insert | i | Typing text before the cursor | Esc |
| Visual | v | Selecting a characterwise range with motions | Esc |
| Command-line | : | Commands such as :write or :set | Enter to run, Esc to cancel |
Two habits matter more than speed at this stage:
- Start a navigation action by pressing
Escif you are unsure of your current mode. In Normal mode, an extraEscis harmless. In Insert, Visual, or Command-line mode, it returns control to Normal mode. - Enter another mode only for a specific reason. Use
ibecause you intend to insert. Usevbecause you intend to select. Do not enter Insert mode merely to move the cursor.
In your LazyVim profile, the status line should make the active mode visible. Notice it during the drill. The goal is to stop experiencing modes as surprises.
Give Me 20 Minutes and I’ll Make You a Vim Motions Expert
Watch “Give Me 20 Minutes and I’ll Make You a Vim Motions Expert” by DevOps Toolbox for a compact visual demonstration of the navigation vocabulary used in this lesson.
Watch modes and home row for the Normal-mode mindset, h j k l, and the i/Esc transition. Then watch words and lines for word and line motions, followed by character finds for f, F, ;, and ,. Finish with search navigation, focusing on the distinction between n and N.
Think in targets, not keystrokes
h, j, k, and l are useful for short local corrections:
hmoves left;lmoves right.jmoves down;kmoves up.
Use them to adjust a position by a few characters or lines. They are not your default solution for reaching something that has a name, boundary, or recognizable shape.
A more productive internal question is:
What is the smallest meaningful target that contains the place I need?
For example:
- A nearby identifier is usually a word target.
- The start of an indented C# statement is a line-boundary target.
- A quote, slash, comma, or closing parenthesis on the same line is a character target.
- A method name or symbol elsewhere in the file is a search target.
The following core set covers a large fraction of day-to-day movement in C#, TypeScript, JSON, and configuration files.
| Target type | Motions | Where the cursor lands |
|---|---|---|
| Word | w, b, e | Next word start, previous word start, current/next word end |
| Line | 0, ^, $ | Absolute first column, first non-blank character, line end |
| File | gg, G, {count}G | File start, file end, specified line |
| Local character | f{x}, t{x} | On character x, or just before x |
| Local character backward | F{x}, T{x} | On character x, or just after x |
| Repeat a character jump | ;, , | Repeat last f/t-style jump, or reverse it |
| Search | /pattern, ?pattern | Next forward or backward matching text |
| Search repetition | n, N | Same direction as last search, or opposite direction |
| Count | {count}{motion} | Repeats the motion by that count |
For example, 7j is usually better than seven separate j presses, and 15G is a direct jump to line 15. Counts are estimates as well as exact instructions: if a target is roughly six lines away, 6j is often a useful first move, followed by a small adjustment.
Read MIT Missing Semester’s concise introduction to modal editing and navigation. It is useful as a stable reference for the motions you will practice, without adding a large plugin-specific vocabulary.
In Introductory Vim, read the mode descriptions from the three core modes. Then, in Basics under Movement, read the motion overview. Focus on which target each command chooses; do not try to learn operators such as d and c yet.
The precision pair: f and t
Character jumps deserve special attention because they are exceptionally effective in source code.
Suppose the cursor is somewhere earlier on this line:
var route = "/api/invoices/{invoiceId}?includeLines=true&includeNotes=false";
f?lands on?.t?lands just before?.F/searches backward and lands on the previous/.T/searches backward and lands just after the previous/.
After any of those, ; repeats the same kind of jump in the same direction, while , repeats it in the opposite direction. This is often faster and more reliable than a string search when the target is visible on the current line.
Use / when the target may be elsewhere in the file. Type /cancellationToken, press Enter, and Neovim moves to the next matching occurrence. Then:
ncontinues in the original search direction.Nmoves in the opposite direction.Escreturns fully to Normal mode. In your LazyVim profile, the mapping you added in the previous lesson also clears the active search highlight.
A backward search starts with ?, but the rule for n and N remains the same: n preserves the direction of the search you started, and N reverses it.
Prepare a controlled navigation buffer
Use your LazyVim profile in Windows Terminal. Open a scratch buffer:
:enew
To make the practice deliberately mouse-free, temporarily disable mouse input for this Neovim session:
:set mouse=
This does not alter your configuration file. When you want mouse support again, use:
:set mouse=a
Now enter Insert mode with i, paste or type the following sample using the keyboard, and press Esc when finished. You do not need to save this buffer.
using System.Net.Http;
using Microsoft.Extensions.Logging;
namespace Drill.Api;
public sealed class InvoiceClient
{
private readonly HttpClient _httpClient;
private readonly ILogger<InvoiceClient> _logger;
public async Task<Invoice?> FetchInvoiceAsync(
Guid invoiceId,
CancellationToken cancellationToken)
{
var route = "/api/invoices/{invoiceId}?includeLines=true&includeNotes=false";
_logger.LogInformation("Fetching invoice {InvoiceId}", invoiceId);
using var response = await _httpClient.GetAsync(
route,
cancellationToken);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<Invoice>(
cancellationToken);
}
}
Turn on absolute line numbers for this buffer so the target locations are unambiguous:
:setlocal number
Before timing anything, spend two minutes performing a quiet warm-up in Normal mode:
- Use
handlto move acrossSystem.Net.Http. - Use
jandkto move among the first few lines. - From the method declaration, use
w,e, andbto move aroundpublic,async, andTask. - On the
routeline, tryf/, then;, then,. - Finish with
gg, thenG, thenggagain.
If a command behaves unexpectedly, do not compensate with the mouse. Press Esc, reset with gg0, and run the motion more slowly.
Complete the timed mouse-free route
Set a four-minute timer outside the editor, place the cursor at the start of the file with Esc then gg0, and complete the route below without using the mouse, arrow keys, scroll wheel, or a picker.
The first attempt is a baseline, not a speed test. You may read the route while performing it. For attempts two and three, cover the command column and use only the targets.
| Stage | Required target and technique | Reference command sequence |
|---|---|---|
| 1 | Confirm intentional Insert and Visual mode transitions without changing the text | i, Esc, then v, e, Esc |
| 2 | Reach the indented _httpClient field with a vertical count; visit absolute start, first non-blank character, and line end | 7j, 0, ^, $ |
| 3 | Jump to the method declaration and move among public, async, and Task by word boundaries | 11G, ^, 2w, e, b |
| 4 | On the route line, find and repeat slash targets, reverse once, then use forward and backward character jumps | 15G, 0, f/, ;, ,, t?, F/, T/ |
| 5 | Search forward for cancellationToken, visit another result, return to the prior result, then clear highlighting | /cancellationToken, Enter, n, N, Esc |
| 6 | Search backward for the method name, then prove whole-file navigation | ?FetchInvoiceAsync, Enter, G, gg |
A run is complete when you finish at the top of the file after Stage 6 and the buffer is unchanged.
Record three pieces of information after each attempt:
| Attempt | Time | Mouse or arrow use? | Motion that caused hesitation |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 |
Use the results diagnostically:
- If Stage 1 feels awkward, your next practice should emphasize
Esc,i, andvtransitions. - If Stage 2 or 3 is slow, practice line and word targets before more
hjkl. - If Stage 4 is slow, practice on punctuation-heavy code. This is the kind of navigation common in route templates, generic types, function calls, and object literals.
- If Stage 5 feels slow, search is probably not yet your default for nonlocal targets. That is normal; repetition changes the default response.
Do not optimize this route by inventing mappings. The point is to develop portable Neovim behavior that works in a minimal profile, Kickstart, LazyVim, a remote shell, and any future Linux machine.
Use short, focused repetition between sessions
Interactive exercises are useful after you understand the commands, because they remove project context and let you repeat one motion family until it becomes automatic.
Practice Vim Motions - Interactive Exercises | VimGym
Use VimGym as a focused practice supplement after completing the local drill. Its value is immediate feedback and repeated exposure to exactly one motion family at a time.
Under What you will learn, inspect the exercise list from basic navigation through the combined workout. For this week, choose only Basic Navigation, Navigating Words, Find Character, and Search. Then read the practice rationale beginning the methodology section. Prefer several short attempts with one motion category over a long mixed session.
A practical routine for the next few days is ten minutes at a time:
- Run one VimGym motion category for roughly five minutes.
- Repeat the C# navigation route once without the reference commands.
- During normal work, impose one rule: before touching the mouse to move in the current file, try
/,f,t, a word motion, or a line motion first.
This keeps the training specific. The objective is not to ban the mouse permanently; it is to ensure that mouse use is a deliberate choice rather than the automatic response to navigation.
You have established the fundamental navigation loop:
- Return to Normal mode before navigating.
- Choose movement by target size: local adjustment, word, line boundary, exact character, or search result.
- Use
f/tfor visible punctuation and characters; use/or?for text elsewhere in the file. - Use
;,,,n, andNto exploit a navigation command you have already issued. - Measure improvement by fewer fallbacks and less hesitation, not only by elapsed time.
Next, you will turn these motions into edits by composing them with operators such as delete and change, then use undo and redo to recover confidently when an edit is not what you intended.
Can't find a good explanation? Sign up and we'll make it for you
Sign up