Project 4: The Markdown Re-Sequencer

Reorder lists and reflow paragraphs using linewise operators and Ex commands.

Quick Reference

Attribute Value
Difficulty Beginner
Time Estimate 6-10 hours
Main Programming Language Markdown
Alternative Programming Languages Plain text
Coolness Level Level 1: Workflow Builder
Business Potential Level 2: Docs Speedup
Prerequisites Linewise motions, Basic Ex commands
Key Topics Ex Commands, Ranges, and Substitution, Operators and Change Types, Motions and Text Units

1. Learning Objectives

By completing this project, you will:

  1. Execute the core workflow for The Markdown Re-Sequencer without Visual mode.
  2. Apply motion-based edits to achieve a measurable output.
  3. Explain the reasoning behind each key command you used.
  4. Validate results against a deterministic outcome.

2. All Theory Needed (Per-Concept Breakdown)

Ex Commands, Ranges, and Substitution

Fundamentals Ex commands are Vim’s command-line language. They operate on ranges of lines and use patterns, which makes them ideal for batch edits. The most common Ex command is substitution (:s), but there are also global commands (:g), move (:m), copy (:t), and delete (:d). Ranges allow you to target specific lines, the whole file (:%), or a visual selection (:'<,'>). Mastering ranges and substitutions gives you the power to transform large files with a single command.

Ex commands are line-oriented by default, which makes them ideal for batch operations. They are composable: you can run a global command that executes another command, effectively creating a pipeline. This is why Ex is often the fastest path for large transformations.

Deep Dive The command-line mode in Vim is a separate language with its own grammar. You enter it with : for Ex commands, / for forward search, or ? for backward search. Ex commands apply to a range of lines. If no range is specified, the command applies to the current line. A range can be explicit (:1,10), symbolic (:% for whole file), or mark-based (:'<,'> for the last visual selection). Understanding ranges is essential, because it determines the scope of your command. A substitution on the wrong range can cause large unintended changes, so ranges are a safety feature as much as a power feature.

Substitution is the most commonly used Ex command. Its basic form is :s/old/new/, which replaces the first match on the line. Flags like g (global) and c (confirm) change behavior. The confirm flag is particularly important for safety; it allows you to review each match before replacing. Vim’s regex flavor includes special atoms and modes like \v (very magic) to reduce escaping. This allows complex transformations like swapping fields or normalizing log entries. However, complex regex can be brittle, so you should start with the simplest possible pattern and test on a small range before scaling.

Global commands (:g) are another powerful tool. :g/pattern/command runs a command on all lines matching the pattern. This is a second-order operation: you are not just moving to matches, you are performing an action on them. For example, :g/ERROR/d deletes all lines containing ERROR. Combined with :v (inverse global), you can filter files by inclusion or exclusion. These commands are fast and precise but can be dangerous; always test with :g/pattern/p to print the lines first.

Ex commands also interact with Normal mode. You can run Normal mode commands over a range with :normal, which allows you to apply motions and operators to multiple lines. This is useful when a single substitution is not enough. For example, you can use :g/pattern/normal to apply a Normal mode edit to all matching lines. This bridges the gap between linewise commands and structural edits. It also means your Normal mode grammar can scale to batch operations.

The command-line language is best understood as a batch editor. It is not just a fallback; it is a complementary interface. Visual mode can define a range, Ex commands operate on that range, and the results can be repeated with @: or &. This makes command-line operations repeatable in the same way as Normal mode edits. In practice, you should use Ex commands for large, line-oriented transformations, and Normal mode for structural edits within lines. Learning when to switch between them is the difference between a novice and an expert.

A safe workflow is to preview target lines with :g/pattern/p before running a destructive command. The inverse global :v is useful for deleting everything except matches, which is a common cleanup task. Ex commands can also be combined with marks and line numbers to build precise ranges. When you are unsure, use the confirm flag or narrow the range to a few lines, then expand once the pattern is proven.

How this fit on projects Projects 4, 5, and 10 use Ex commands for line operations and substitutions.

Definitions & key terms

  • Range: a set of lines (:1,10, :%, :'<,'>)
  • Substitute: :s/old/new/
  • Global: :g/pattern/command
  • Confirm flag: c prompts before each replacement

Mental model diagram

Range + Command + Pattern = batch editing

How it works

  1. Define a range.
  2. Choose a command (:s, :g, :m, :t).
  3. Provide a pattern or target.
  4. Execute and verify.

Minimal concrete example

:%s/foo/bar/gc
:1,10s/\v(\w+), (\w+)/\2 \1/
:g/ERROR/d

Common misconceptions

  • :s only works on one line.” (Use ranges.)
  • “Regex must be escaped heavily.” (Use \v very magic.)
  • :g is a search.” (:g runs a command on matches.)

Check-your-understanding questions

  1. What does % mean in a range?
  2. How do you confirm each substitution?
  3. What does :g/pat/normal dd do?

Check-your-understanding answers

  1. The whole file.
  2. Add the c flag.
  3. Deletes lines matching pat.

Real-world applications

  • Transforming CSV, logs, and data dumps
  • Cleaning trailing whitespace
  • Bulk renaming identifiers

Where you’ll apply it Projects 4, 5, 10.

References

  • Vim :help cmdline.txt
  • Vim :help :substitute
  • Vim :help :global

Key insights Ex commands are Vim’s batch processor.

Summary Ranges and substitutions unlock fast, safe bulk editing.

Homework/Exercises to practice the concept

  1. Replace all TODO with DONE in a file.
  2. Swap “Last, First” to “First Last” with one command.

Solutions to the homework/exercises

  1. :%s/TODO/DONE/g.
  2. :%s/\v([^,]+), (.+)/\2 \1/.

Operators and Change Types

Fundamentals Operators are the verbs of Vim: delete, change, yank, indent, format, case-convert, filter. They determine what happens to a range of text defined by a motion or text object. Understanding operators reduces command memorization because you can express edits in a few primitives. For example, if you know d is delete and ap is a paragraph, then dap is obvious. The operator set is small but powerful, and it becomes more powerful when paired with motions and text objects.

Operators also determine the shape of the change: characterwise, linewise, or blockwise. The motion you choose controls that shape, which affects how text is stored in registers and how it pastes later.

Deep Dive Operators fall into categories. Destructive operators include delete (d) and change (c), which remove text (and in the case of c, also enter Insert mode). Copying operators include yank (y) and sometimes Y for linewise yank. Formatting operators include indent (> and <), reformat (gq), and filter (!). Case operations (gU, gu, g~) are transformations. Each operator interacts with motions to define a range. For example, gqap means “format a paragraph,” while >i{ means “indent inside braces.” Operators also define what gets placed in registers: delete and change write to registers, yank writes to register 0 and unnamed register, and some operators use specific registers. This is important because operators affect your clipboard history.

Change (c) is one of the most important operators because it includes both deletion and insertion, creating a single change for repeatability. This makes it ideal for dot command repetition. For example, cw changes the rest of a word and leaves you in Insert mode; this is faster and more repeatable than dw followed by i. Understanding this difference changes how you do refactors. Similarly, C is shorthand for c$, and D is shorthand for d$. These linewise shorthands are part of the operator vocabulary.

Indenting and formatting operators are critical in code and prose. Indenting with > and < is linewise by default when used with a count or a linewise motion. Formatting with gq respects textwidth and can be used to wrap comments or paragraphs. Filtering with ! sends a range through an external command. This is extremely powerful but can be dangerous if the command is destructive or unavailable. When using !, you should verify the command on a small range first.

Operators also have edge cases: some are linewise by default, some are characterwise, and some become linewise when doubled. The exact behavior depends on the motion used. If you use a linewise motion (like j with a count or }), you get a linewise operation. If you use a characterwise motion, you get a characterwise operation. This matters for registers and for how the change can be repeated. A good habit is to think about the shape of the operation: characterwise, linewise, or blockwise. Vim supports all three, and you should pick the one that aligns with your intent.

Operators also interact with the . repeat command. A clean operator-based change is usually easy to repeat; a complicated multi-step edit may not be. This is why many Vim users prioritize operator + motion patterns over Visual selection. The operator grammar leads to edits that are shorter and more repeatable. Once you can mentally separate “what to do” from “where to do it,” operators become a compact toolbox rather than a long list of shortcuts.

Beyond the core operators, g~ toggles case, = reindents using filetype rules, and ! filters a range through an external command. These operators are powerful but should be used with clear scope and a preview when possible. Because operator-based changes are a single change, they integrate cleanly with the dot command and undo history. This makes them safer than multi-step edits.

How this fit on projects Projects 2-6 rely on operators for deletion, change, formatting, and indentation.

Definitions & key terms

  • Delete (d): remove text
  • Change (c): delete and enter Insert mode
  • Yank (y): copy into a register
  • Indent (>/<): shift lines
  • Format (gq): reflow text
  • Filter (!): pipe range through external command

Mental model diagram

Operator chooses action; motion chooses target.

How it works

  1. Type an operator.
  2. Provide a motion or text object.
  3. Vim applies the operator to the computed range.
  4. The change is stored in registers and can be repeated.

Minimal concrete example

gUiw
>ap
gqip

Common misconceptions

  • “Change and delete are unrelated.” (c is d + Insert.)
  • “Indent only works in Visual mode.” (Operators work with motions.)
  • “Formatting requires plugins.” (gq is built in.)

Check-your-understanding questions

  1. What is the difference between d and c?
  2. What does gqap do?
  3. How do you lowercase inside quotes?

Check-your-understanding answers

  1. d deletes; c deletes and enters Insert.
  2. Formats (wraps) a paragraph.
  3. gui".

Real-world applications

  • Refactoring identifiers
  • Indenting code blocks
  • Formatting comments or prose

Where you’ll apply it Projects 2-6.

References

  • Vim :help operator
  • Vim :help change.txt
  • “Practical Vim” - Ch. 1-5

Key insights Operators are verbs; everything else is grammar.

Summary Learn operators and you can express any edit with a motion.

Homework/Exercises to practice the concept

  1. Uppercase three words with a single command.
  2. Re-indent a function with one operator.

Solutions to the homework/exercises

  1. gU3w uppercases three words.
  2. =ap or >ap depending on indent settings.

Motions and Text Units

Fundamentals Motions are the nouns of Vim. They define how Vim divides text into units: characters, words, WORDs, sentences, paragraphs, lines, and file boundaries. When you choose a motion, you are describing what kind of unit you care about. This is more powerful than counting characters because it scales across different file types and layouts. Motions are also composable with operators and counts, which means a single motion can drive navigation, deletion, selection, and formatting. Internalizing the difference between word and WORD, sentence and paragraph, line and screen line makes your movement precise.

Motions are also selections: any motion can be used after an operator to define the range. This means learning motions doubles as learning selection, so the same vocabulary controls navigation and editing.

Deep Dive Motions exist in multiple layers. At the smallest level are character motions (h, l, 0, $) and within-line motions like f, t, ;, and ,. These are surgical tools. Above that are word motions. Vim distinguishes between word (letters, digits, underscore, and configurable characters) and WORD (any non-blank sequence). This distinction matters because code often contains punctuation. For example, foo.bar is two words but one WORD. When you use w and W, you control whether punctuation is a separator or part of the token. This also interacts with the iskeyword option, which can redefine what Vim considers a word. Understanding this helps you tune behavior for different languages.

Next are sentence and paragraph motions () and }) which are not just text formatting concepts; they are semantic chunks. A paragraph is typically separated by a blank line or defined by a macro, which means it often aligns with logical blocks in prose, comments, or documentation. In code, paragraphs can correspond to logical sections or groups of statements. The motion keys for sentences and paragraphs let you move across these blocks without counting lines. Above that are screen-relative motions (H, M, L) and file-level motions (gg, G, %). Screen-relative motions help when the visible context matters more than the absolute line number; they are faster when you see the target but do not want to count lines. File-level motions are essential for jumping to file boundaries and structural markers.

Motions also include searches. /pattern and ?pattern are motion commands that move the cursor to the next or previous match. This is powerful because the search pattern can be as specific as you need, effectively creating a temporary motion for your current problem. You can combine search with operators to turn a search into a deletion or change, e.g., d/ or c?. This reduces the need for visual selection and opens the door to repeatable edits: search once, then repeat with n and .. Understanding that search is a motion is critical; it changes how you structure edits.

Another important layer is text-object-aware motions like % for matching pairs. % understands parentheses, brackets, and braces, which makes it ideal for code. This is a motion that depends on structure, not characters. Combined with operators, it becomes a structural editor. There are also jumps that create entries in the jump list, like searching, using G, or moving between files. These motions are navigation memory, not just movement. When you realize that motions define not just location but history, you will use them more carefully to create return points.

Motions have inclusive and exclusive behavior. For example, dw deletes up to the start of the next word, but de deletes through the end of the current word. This subtlety affects your results when combined with operators. The key is to pick the motion that matches your intent. When in doubt, choose the motion that aligns with your semantic unit rather than your visual estimate. Over time, your brain will pick the right motion automatically, which is where Vim speed appears.

Screen-line motions like gj and gk move by display lines when wrapping is enabled, which is useful in long prose. Similarly, ^ moves to the first non-blank character, which matters when indentation is significant. The more you align motions with structure (indent, punctuation, paragraphs), the less you need to count.

How this fit on projects Projects 1, 3, 4, 6, and 10 rely on word, sentence, paragraph, and search motions.

Definitions & key terms

  • word: letters/digits/underscore or defined by iskeyword
  • WORD: any non-blank sequence separated by whitespace
  • Sentence: ends with ., !, or ? followed by space or end-of-line
  • Paragraph: separated by blank lines or paragraph macros
  • Screen line: line as it appears on screen with wrapping

Mental model diagram

[chars] -> [word] -> [WORD] -> [sentence] -> [paragraph] -> [section]

Text unit hierarchy

How it works

  1. Decide which unit you want to move across.
  2. Choose the motion for that unit.
  3. Add a count if you want to scale the move.
  4. Combine with an operator if you want to act on it.

Minimal concrete example

w/W
b/B
e/E
{ }
gg/G

Common misconceptions

  • “WORD is just a bigger word.” (It treats punctuation as part of the WORD.)
  • w always stops at punctuation.” (Depends on iskeyword.)
  • “Paragraphs only mean blank lines.” (Macros can define boundaries.)

Check-your-understanding questions

  1. What is the difference between w and W on foo.bar?
  2. Why does cw behave like ce sometimes?
  3. How do you jump to the start of a file?

Check-your-understanding answers

  1. w stops at punctuation; W treats foo.bar as one WORD.
  2. cw is special-cased to change to end of word.
  3. gg.

Real-world applications

  • Navigating tokens vs full strings in code
  • Skipping across sentences in Markdown
  • Jumping between sections in long files

Where you’ll apply it Projects 1, 3, 4, 6, 10.

References

  • Vim :help word-motions
  • Vim :help sentence
  • Vim :help paragraph
  • “Learning the vi and Vim Editors” - Ch. 3

Key insights Picking the right unit is faster than counting characters.

Summary Motions are semantic. Learn word vs WORD, sentence vs paragraph, and line vs screen.

Homework/Exercises to practice the concept

  1. In a code file, practice w vs W on identifiers with punctuation.
  2. Move by paragraphs using { and } in a Markdown file.

Solutions to the homework/exercises

  1. Use w to stop at _ or ., use W to jump whole tokens.
  2. { moves backward, } moves forward.

3. Project Specification

3.1 What You Will Build

A reordered outline and reformatted paragraphs without copy/paste.

Included:

  • Unordered lists
  • Paragraphs
  • Headings

Excluded:

  • Markdown rendering tools

3.2 Functional Requirements

  1. Core workflow: Move list items using :m or dd/p
  2. Repeatability: Reflow a paragraph with gq
  3. Validation: Reorder a section using linewise operations

3.3 Non-Functional Requirements

  • Performance: Edits completed in under 2 minutes per section after practice.
  • Reliability: List structure remains intact.
  • Usability: Commands are documented with before/after snapshots.

3.4 Example Usage / Output

Use `:m` for line moves and `gqap` for paragraph formatting.

3.5 Data Formats / Schemas / Protocols

  • Markdown headings and bullet lists

3.6 Edge Cases

  • Mixed list types
  • Indented lists
  • Very long paragraphs

3.7 Real World Outcome

This is the deterministic output you can compare against directly.

3.7.1 How to Run (Copy/Paste)

  • vim release_notes.md

3.7.2 Golden Path Demo (Deterministic)

Reorder a list and reflow a paragraph with no manual wrapping.

3.7.3 If CLI: provide an exact terminal transcript

$ vim release_notes.md
# :2m1 then gqap
# Verify bullet order and wrapping

4. Solution Architecture

4.1 High-Level Design

Input file -> Vim workflow plan -> Verification checklist

4.2 Key Components

Component Responsibility Key Decisions
Input File Provides deterministic data Keep it stable and versioned
Vim Workflow Plan Documents motions and operators Prefer repeatable sequences
Verification Checklist Confirms correctness Use before/after snapshots

4.4 Data Structures (No Full Code)

  • Entry: a structured line or block with fields relevant to the task
  • Target: the specific token or structure you will move to or edit
  • Checklist: steps to verify the output

4.4 Algorithm Overview

Key Algorithm: Motion-First Editing Loop

  1. Identify the target structure (word, field, block, or line).
  2. Choose a motion or text object that selects it safely.
  3. Apply the operator or edit and verify the result.

Complexity Analysis:

  • Time: O(n) over lines edited
  • Space: O(1) additional space

5. Implementation Guide

5.1 Development Environment Setup

vim --version
vimtutor

5.2 Project Structure

project-root/
|-- input/
|   `-- sample.txt
|-- notes/
|   `-- keystrokes.md
`-- outputs/
    `-- expected.txt

5.3 The Core Question You’re Answering

“Reorder lists and reflow paragraphs using linewise operators and Ex commands.”

5.4 Concepts You Must Understand First

Stop and research these before editing:

  • Linewise motions
  • Basic Ex commands

5.5 Questions to Guide Your Design

  1. Which motion or text object targets the structure directly?
  2. Can the change be repeated with dot or a macro?
  3. How will you verify correctness after the change?

5.6 Thinking Exercise

Before editing, sketch the steps needed to complete the task on paper.

5.7 The Interview Questions They’ll Ask

  1. “Which motion did you choose and why?”
  2. “How did you ensure the edit was repeatable?”
  3. “What is the risk of using Visual mode here?”
  4. “How did you validate the output?”

5.8 Hints in Layers

Hint 1: Start with a stable cursor position Use 0, ^, or a search to align before editing.

Hint 2: Choose the smallest safe unit If a word is enough, use a word object; if not, use a larger object.

Hint 3: Make it repeatable Design the first change so . works on the next target.

Hint 4: Validate Check before/after snapshots after each batch of edits.

5.9 Books That Will Help

Topic Book Chapter
Core workflow “Practical Vim” Ch. 1-4
Motions “Practical Vim” Ch. 8
Editing language “Learning the vi and Vim Editors” Ch. 3

5.10 Implementation Phases

Phase 1: Foundation (6-10 hours)

Goals:

  • Load the input file and identify targets
  • Verify core motions and search behavior

Tasks:

  1. Create a short checklist of target patterns
  2. Practice on 3-5 lines

Checkpoint: You can complete the smallest edit without mistakes.

Phase 2: Core Functionality (6-10 hours)

Goals:

  • Execute the main workflow end-to-end
  • Keep edits repeatable

Tasks:

  1. Apply the main edit sequence to the full file
  2. Record keystrokes or a macro if needed

Checkpoint: Output matches the golden path demo.

Phase 3: Polish & Edge Cases (6-10 hours)

Goals:

  • Handle edge cases
  • Document the workflow

Tasks:

  1. Test edge cases from section 3.6
  2. Write a short summary of decisions

Checkpoint: Edge cases are handled or documented.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
Targeting strategy Search vs find vs motion Choose the most stable Stability beats speed early on
Repeatability Dot vs macro Use dot first Lower complexity
Verification Visual check vs checklist Use a checklist Prevents silent errors

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Manual Checks Validate edits Before/after snapshots
Repeatability Tests Ensure dot/macro works Run on 3+ targets
Edge Case Tests Handle boundary conditions Missing fields or empty lines

6.2 Critical Test Cases

  1. Nominal case: Apply the workflow to a standard line.
  2. Duplicate target: Handle two targets on the same line.
  3. Irregular line: Verify behavior when a field is missing.

6.3 Test Data

Use the provided sample input file and create 3 additional lines with variations.

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

Pitfall Symptom Solution
Over-using Visual mode Changes are hard to repeat Use operator + motion
Wrong motion choice Target missed Use a larger text object
No validation step Silent errors Use a checklist

7.2 Debugging Strategies

  • Replay slowly: Step through the workflow one command at a time.
  • Use undo: Roll back and re-apply with a clearer motion.

7.3 Performance Traps

Overusing j/k on large files instead of search can make the workflow slow.


8. Extensions & Challenges

8.1 Beginner Extensions

  • Repeat the workflow on a smaller file
  • Document the exact keystroke sequence

8.2 Intermediate Extensions

  • Apply the workflow to a real project file
  • Reduce keystroke count by 20%

8.3 Advanced Extensions

  • Build a macro to automate the workflow
  • Create a custom mapping to speed up a frequent step

9. Real-World Connections

9.1 Industry Applications

  • Remote server editing: Vim is common on production systems
  • Incident response: quick log edits without GUI tools
  • Vim: core editor reference
  • Neovim: modernized modal editor
  • Universal Ctags: tag generation tool

9.3 Interview Relevance

  • Motion grammar questions
  • Repeatability and macro questions
  • Command-line editing scenarios

10. Resources

10.1 Essential Reading

  • “Practical Vim” by Drew Neil - focus on motion and change workflows
  • “Learning the vi and Vim Editors” - foundational navigation

10.2 Video Resources

  • “Vim as a Language” talk (searchable title)
  • “Practical Vim” author talks (searchable title)