Unit 9: vi editor

CSE105 — Creative Engineering Workshop 8 min read

vi (visual editor) is the standard full-screen text editor bundled with virtually every Unix and Linux system, written by Bill Joy in 1976 for the BSD distribution. It is a modal editor: the same keystroke means different things depending on the current mode, which is what makes it fast for experienced users and confusing for beginners. Its modern superset, vim (vi improved), is what most Linux systems actually launch when you type vi.

  • Modeless vs modal: vi is modal — keys either move/act (command mode) or type text (insert mode); an editor like nano is modeless.
  • The three modes:
    • Command mode: the default on startup; keystrokes are interpreted as commands (x deletes, dd cuts a line).
    • Insert mode: entered with i, a, o, etc.; keystrokes are inserted as literal text.
    • Ex / last-line mode: entered by typing : in command mode; used for save, quit, search-and-replace and settings.
  • Returning to command mode: press Esc; this is the universal "get me back" key and the pivot for every operation.
  • Case sensitivity: commands are case-sensitive — i and I, a and A, p and P all differ.
  • Count prefix: most commands accept a numeric repeat count, e.g. 5dd deletes five lines, 3w jumps three words.

II. Starting vi

Invoking the editor from the shell

The vi command opens a file into a screen buffer; edits happen in the buffer and reach disk only when saved.

  • Open or create a file: vi filename opens filename, or starts a fresh buffer bound to that name if it does not exist.
    • Example: vi notes.txt opens notes.txt in command mode with the cursor on line 1.
  • Open at a specific line: vi +n filename places the cursor on line n; vi + filename jumps to the last line.
  • Open at a search match: vi +/pattern filename opens with the cursor on the first line matching pattern.
  • Open multiple files: vi file1 file2 loads both; :n moves to the next file, :rewind back to the first.
  • Read-only view: vi -R filename (or the view command) opens the file protected against accidental writes.
  • Initial state: the screen shows the file contents with ~ marking lines beyond end-of-file; the editor sits in command mode, so typing text immediately would be interpreted as commands.

III. Navigation Commands

Moving the cursor within the buffer

Navigation is done in command mode; the home-row keys h j k l exist because early terminals lacked reliable arrow keys.

  • Character movement:
    • h: move left one character.
    • l: move right one character.
    • j: move down one line.
    • k: move up one line.
  • Word movement:
    • w: forward to the start of the next word; W ignores punctuation (whitespace-delimited).
    • b: back to the start of the previous word; B is its whitespace-delimited form.
    • e: forward to the end of the current/next word.
  • Line movement:
    • 0 (zero): jump to the first column of the line.
    • ^: jump to the first non-blank character.
    • $: jump to the end of the line.
  • Screen and file movement:
    • H: cursor to the top (Home) line of the screen; M to the middle; L to the last.
    • gg: go to the first line of the file; G: go to the last line.
    • nG: go to line n — e.g. 25G lands on line 25.
  • Targeted jumps: fx moves to the next occurrence of character x on the line; % jumps between a matching bracket pair (), {}, [].

IV. Scrolling Commands

Repositioning the visible window

Scrolling moves the viewport through a large file without necessarily changing the logical cursor target, and relies on Ctrl-key combinations.

  • Full-screen scroll:
    • Ctrl+f: scroll forward one full screen (page down).
    • Ctrl+b: scroll backward one full screen (page up).
  • Half-screen scroll:
    • Ctrl+d: scroll down half a screen.
    • Ctrl+u: scroll up half a screen.
  • Line scroll:
    • Ctrl+e: scroll the window down one line, cursor staying on its text.
    • Ctrl+y: scroll the window up one line.
  • Redraw with cursor placement (z family):
    • zz: redraw so the current line is centred on the screen.
    • zt: current line to the top of the screen.
    • zb: current line to the bottom of the screen.
  • Refresh: Ctrl+l redraws a screen garbled by stray output.

V. Insert and Edit Commands

Entering insert mode and altering text

These commands switch from command mode into insert mode; the difference between them is where text entry begins. Esc returns to command mode afterward.

  1. Insert-family (text begins at/around the cursor):
    • i: insert before the cursor.
    • I: insert at the first non-blank character of the line.
    • a: append after the cursor.
    • A: append at the end of the line.
  2. Open-family (text begins on a new line):
    • o: open a new line below the current one and insert.
    • O: open a new line above the current one and insert.
  • Replace commands:
    • r: replace a single character under the cursor without leaving command mode (rX writes X).
    • R: enter overtype mode, replacing characters as you type until Esc.
  • Change commands (delete-then-insert):
    • cw: change to end of word — deletes the word and enters insert mode.
    • cc: change the whole line; C changes from cursor to end of line.
  • Case and undo:
    • ~: toggle the case of the character under the cursor.
    • u: undo the last change; Ctrl+r redoes it; . repeats the last edit.

VI. Delete Commands

Removing text in command mode

Deletion in vi also cuts the removed text into an unnamed register, so every delete is implicitly a "cut" available for pasting.

  • Character deletion:
    • x: delete the character under the cursor.
    • X: delete the character before the cursor.
    • nx: delete n characters — 3x removes three characters rightward.
  • Word deletion:
    • dw: delete from the cursor to the start of the next word.
    • db: delete backward to the start of the previous word.
  • Line deletion:
    • dd: delete the entire current line; 3dd deletes three lines.
    • D: delete from the cursor to the end of the line (equivalent to d$).
  • Deletion to a position:
    • d0: delete from cursor back to the start of the line.
    • dG: delete from the current line to the end of the file.
    • dfx: delete up to and including the next x on the line.

VII. Copy-Paste Operations

Yanking and putting text via registers

Copying in vi is called yanking (y); the yanked text lands in the unnamed register and is inserted with put (p). Because deletes fill the same register, a deleted block can also be "pasted."

  • Yank (copy) commands:
    • yy (or Y): yank the current line.
    • yw: yank a word from the cursor.
    • nyy: yank n lines — 4yy copies four lines.
    • y$: yank from the cursor to the end of the line.
  • Put (paste) commands:
    • p: put the yanked/deleted text after the cursor (for a line yank, on the line below).
    • P: put it before the cursor (line above for a line yank).
  • Named registers: prefixing with "a–"z stores into a named register — "ayy yanks into register a, and "ap pastes from it, preserving text across other deletes.
  • Move-a-line idiom (worked example): to swap a line down one position, place the cursor on it and type:
    TEXT
      dd   " delete (cut) the current line into the register
      p    " put it back below the line that is now current

    The net effect exchanges the line with the one that followed it.

VIII. Save and Exit Operations

Writing the buffer and leaving the editor

Saving and quitting are ex-mode commands entered after :, confirmed with Enter; a handful of command-mode shortcuts also exist.

  • Write (save):
    • :w: write the buffer to the current file.
    • :w newname: write to a different file (Save As).
    • :w!: force a write even on a read-only file (when permissions allow).
  • Write and quit:
    • :wq: write then quit.
    • :x: write only if changed, then quit — avoids updating the timestamp needlessly.
    • ZZ: command-mode shortcut equivalent to :x (note the capitals).
  • Quit without saving:
    • :q: quit, permitted only when there are no unsaved changes.
    • :q!: quit forcibly, discarding all unsaved edits.
    • ZQ: command-mode shortcut equivalent to :q!.
  • Partial and multi-file writes:
    • :1,10w part.txt: write only lines 1–10 to part.txt.
    • :wa writes all modified buffers; :wqa writes all and quits.
  • Recovery: after an abnormal exit vi keeps a .swp file; vi -r filename recovers unsaved work from it.