Skip to content

Chapter 5: Vim and Command-Line Editing

Source slides: L03_Vim_2025.pdf. Exercise: E03_Vim_2025.pdf (+ solutions). Test files: L03/L03/test-1.zip (the test/ directory used in the exercises).


1. Chapter Overview

On any HPC cluster you cannot use a GUI editor. The standard modal editor — installed everywhere, fast, scriptable — is Vim ("Vi IMproved"). Mastering Vim is non-negotiable for HPC. This chapter teaches:

  • Vim modes (Normal, Insert, Visual, Visual-Line, Visual-Block, Command-Line, Replace).
  • Movement (h/j/k/l, w/b/e, 0/^/$, gg/G, %, search /, marks).
  • Editing (i/a/o/I/A/O, x, dd, yy, p, dw, d$, c, r, J, u, Ctrl-r, .).
  • Search & replace (/pat, :s/old/new/, :%s/old/new/gc).
  • Registers (named, unnamed, system clipboard "+).
  • Macros (q[a-z] … q, replay @a, @@, 5@a).
  • Buffers, windows, tabs (:e, :bnext, :sp, :vsp, :tabnew, gt).
  • .vimrc configuration.

Why it matters in HPC/CFD: every config file (mesh, solver, sbatch script, Makefile, source code) is edited in Vim during cluster work. A user who knows macros and :%s can edit hundreds of cases in seconds.

What the examiner asks (very common):

  • "What are Vim's modes? How do you switch between them?"
  • "Write the keystrokes to delete 5 lines and paste at the end of file."
  • "Search & replace command for replacing all oldName with newName interactively."
  • "Record and apply a macro that …"
  • "Sample .vimrc snippet."

What you must master for top grade:

  • A clean mode diagram (Esc / i / v / : transitions).
  • The "verb + count + motion" grammar (d3w, c$, y2j, >aP).
  • Macro mechanics with named register.
  • Window/tab/buffer triad.
  • 5–10 lines of useful .vimrc.

2. Basics from Zero

A modal editor has different states. In Vim:

  • Normal mode (the default) → you type commands (move, copy, delete) — letters do actions, not text.
  • Insert mode → typing inserts characters (like a normal editor).
  • Visual mode → select text.
  • Command-line mode → type Ex commands like :w, :q, :s/old/new/g.

Switch by pressing Esc (back to Normal). The biggest beginner mistake is staying in Insert mode forever; everyday Vim is mostly Normal mode with brief Insert spurts.

বাংলায়: Vim-এর সবচেয়ে গুরুত্বপূর্ণ ধারণা হলো mode: Normal mode-এ প্রতিটা অক্ষর একেকটা কমান্ড (d মানে delete, w মানে পরের word-এ যাও), আর Insert mode-এ অক্ষরগুলো সত্যিকারের টেক্সট হয়ে ঢোকে। নতুনদের সবচেয়ে বড় ভুল সারাক্ষণ Insert mode-এ থাকা — দক্ষ ব্যবহারকারীরা বেশিরভাগ সময় Normal mode-এ থাকে, দরকারমতো কয়েক সেকেন্ডের জন্য Insert-এ ঢোকে। কোনো সন্দেহ হলেই Esc চাপো — পরীক্ষাতেও mode-এর প্রশ্ন প্রায় নিশ্চিত।

The real power: every command is a grammar:

[count] [operator] [motion / text-object]
  • Operators: d delete, c change, y yank (copy), > indent, gU uppercase.
  • Motions: w next word, b previous word, e end of word, 0 line start, $ line end, gg file start, G file end, } next paragraph, f<char> find char on line.
  • Text objects: iw inner word, aw a word (with space), i" inside quotes, ip inner paragraph, ab a block (with brackets).

Combine them: d2w deletes two words, ci" deletes inside "…" and enters Insert, ya{ yanks a { … } block including braces.

বাংলায়: Vim-এর কমান্ডগুলো আসলে একটা ছোট ভাষা: count + operator + motion — যেমন d2w মানে "delete করো, দুইটা word"। আলাদা আলাদা কমান্ড মুখস্থ করার দরকার নেই; operator আর motion আলাদাভাবে শিখলেই সব combination নিজে থেকে চলে আসে। পরীক্ষায় "keystroke লেখো" ধরনের প্রশ্নে এই grammar দিয়েই উত্তর সাজাবে — এতে examiner বোঝে তুমি যুক্তিটা জানো, মুখস্থ নয়।

Real-life analogy. Vim is like an industrial sewing machine: a steep dashboard, but once you learn it, you stitch faster than any GUI tailor. A normal text editor is a hand needle.

Real-life HPC example. You have 200 simulation cases each with a line Re = 1000. In Vim: :argdo %s/Re = 1000/Re = 5000/g | update. Done in one second.

What if you misunderstand? You hit random keys in Normal mode and accidentally delete lines (dd), change them (cc), or worse :q! and lose unsaved work.


3. Hard English Made Easy

Hard Term Simple English বাংলা Example
Modal editor Editor with separate states মোডভিত্তিক এডিটর Vim
Normal mode Command mode কমান্ড মোড press Esc
Insert mode Typing mode টাইপিং মোড press i
Visual mode Selection mode নির্বাচন মোড press v
Command-line : mode কোলন কমান্ড :wq
Buffer Open file in memory মেমরিতে খোলা ফাইল :ls
Window A view of a buffer বাফার দেখার অংশ :sp
Tab Group of windows ট্যাব :tabnew
Yank Copy কপি yy
Put / Paste Paste পেস্ট p
Register Named clipboard slot ক্লিপবোর্ড স্লট "ay, "ap
Macro Recorded keystrokes রেকর্ডকৃত কীস্ট্রোক qa…q, @a
Motion Cursor movement command কার্সর মুভমেন্ট w b e 0 $
Text object A logical chunk (word, paragraph, brackets) টেক্সট ব্লক iw, i", i{
Operator Action verb অপারেটর d c y > gU
Count Repetition number সংখ্যা 5dd
Mark Bookmark বুকমার্ক ma, 'a
Quickfix list Search result list কুইকফিক্স তালিকা :vimgrep, :cnext
Vimrc Vim config file Vim কনফিগ ফাইল ~/.vimrc

4. Deep Theory Explanation

4.1 Modes (mode diagram)

                +-------------+
   Esc <------- |  NORMAL     | <-------- Esc
        +-----> |             | --------+
        |       +-------------+         |
        |          |   |   |            |
        |          i   v   :            |
        |          v   v   v            |
        |   INSERT VIS CMDLINE          |
        |          |   |   |            |
        +---- Esc ---+---+--- <Enter> --+

Switching:

  • i insert before cursor; I insert at line start; a append after; A append at line end; o open new line below; O above.
  • v characterwise visual; V linewise; Ctrl-v blockwise.
  • : command-line; / search forward; ? search backward.
  • Esc → back to Normal.

Mode state-machine (exam-ready version):

                            i  I  a  A  o  O
                ┌──────────────────────────────────────┐
                ▼                                      │
        ┌───────────────┐        Esc          ┌────────┴────────┐
        │    INSERT     │ ───────────────────►│                 │
        │  (type text)  │                     │     NORMAL      │
        └───────────────┘                     │  (start state,  │
                                              │   commands)     │
        ┌───────────────┐        Esc          │                 │
        │    VISUAL     │ ───────────────────►│                 │
        │ (select text) │◄─────────────────── │                 │
        └───────────────┘    v  V  Ctrl-v     └───┬───────▲─────┘
                                                  │ :  /  ?│
                                                  ▼        │ Esc or <Enter>
                                          ┌────────────────┴───┐
                                          │    COMMAND-LINE    │
                                          │ :w  :q!  :%s/a/b/g │
                                          └────────────────────┘

Every arrow into NORMAL is Esc (or <Enter> finishing a : command); every arrow out of NORMAL is a specific key. There is no direct Insert → Visual transition — you always pass through Normal.

বাংলায়: এই state diagram-টা পরীক্ষায় আঁকতে পারা বাধ্যতামূলক বলে ধরে নাও। কেন্দ্রে সবসময় Normal mode — সেখান থেকে i/a/o দিয়ে Insert-এ, v/V/Ctrl-v দিয়ে Visual-এ, আর colon দিয়ে Command-line-এ যাওয়া যায়; ফেরার রাস্তা সবসময় Esc। মনে রাখো: Insert থেকে সরাসরি Visual-এ যাওয়া যায় না, মাঝে Normal-এ আসতেই হয় — এই খুঁটিনাটিই ভালো নম্বর আর মাঝারি নম্বরের পার্থক্য।

4.2 Motions (movement)

Move Distance
h j k l left / down / up / right
w b e next/back/end of word
W B E WORD (whitespace-separated)
0 ^ $ line start / first non-blank / line end
gg G top / bottom
5G line 5
:42 line 42
f<c> t<c> jump to / before char on line
; , repeat / reverse f/t
% matching ()/{}/[]
* # next / previous occurrence of word under cursor
H M L top / mid / bottom of screen
Ctrl-d Ctrl-u half page down / up
Ctrl-f Ctrl-b full page forward / back
n N next / previous search match
m{a-z} '{a-z} mark / jump to mark

4.3 Editing operators

Verb Effect
d delete
c change (delete + insert)
y yank (copy)
> < indent / outdent
gU gu upper / lower case
~ toggle case
= auto-format
r replace one char
R replace mode (overtype)
s substitute char (delete + insert)
S substitute line
J join with next line
p P put after / before
u undo
Ctrl-r redo
. repeat last change

Combine with motions/text-objects:

  • dw delete word, d$ delete to end of line, d0 delete to line start, dG delete to file end, dgg delete to file start.
  • cc change line, cw change word, ci( change inside parens, ca{ change a block including braces.
  • yy yank line, y2j yank current + next two lines, yi" yank inside quotes.
  • 5dd delete 5 lines, 3yy yank 3 lines.

The grammar as a mini-algebra. Every Normal-mode edit is a word of this little language:

\[\text{cmd} ::= [\mathit{count}_1]\ \mathit{operator}\ [\mathit{count}_2]\ \mathit{motion}\]

Semantics: apply the operator to exactly the text the motion travels over; the two counts multiply2d3w deletes \(2 \times 3 = 6\) words, identical in effect to d6w and 6dw.

Role Symbols Meaning
Operator d delete
Operator c change (delete + Insert)
Operator y yank (copy)
Operator > indent
Operator = re-format / re-indent
Motion w to next word
Motion b back one word
Motion e to end of word
Motion $ to end of line
Motion 0 to start of line
Motion } to next paragraph
Motion G to last line

Composability rule. Knowing \(m\) operators and \(n\) motions gives you \(m \cdot n\) commands without memorising any of them individually:

\[|\text{commands}| = m \cdot n\]

Worked count: the lecture's core set is \(m = 8\) operators (d c y > < = gU gu) and \(n = 10\) motions (w b e $ 0 { } G gg and f<char>), hence \(8 \times 10 = 80\) distinct edit commands. Add a single-digit count and the space grows by another factor of 9 — this multiplicative structure is why Vim pays off.

Decomposition of d2w:

              d2w — one command, three parts
        ┌───────────┬───────────┬────────────────┐
        │     d     │     2     │       w        │
        │ operator  │   count   │     motion     │
        │ "delete"  │  "twice"  │ "to next word" │
        └─────┬─────┴─────┬─────┴───────┬────────┘
              │           │             │
              ▼           ▼             ▼
          action =    repeat the    region = cursor
          remove      motion 2×     to motion target
              └───────────┬─────────────┘
          delete from cursor across the next 2 words

   before:   the ▌quick brown fox
   after:    the ▌fox

বাংলায়: Grammar-টা গণিতের মতো ভাবো: operator হলো ফাংশন, motion হলো তার argument, আর count মানে কতবার। ৮টা operator আর ১০টা motion শিখলেই \(8 \times 10 = 80\)টা কমান্ড ফ্রি পেয়ে যাচ্ছ — এটাই Vim-এর composability, আর পরীক্ষায় "why is Vim efficient" প্রশ্নের মডেল উত্তর। আরও মনে রাখো, দুটো count গুণ হয়: 2d3w মানে ৬টা word delete।

4.4 Search and replace

/pattern        " forward search
?pattern        " backward
n / N           " next / previous match
*               " word under cursor

:s/old/new/         " replace first on line
:s/old/new/g        " all on line
:%s/old/new/g       " all in file
:%s/old/new/gc      " all in file with confirm
:5,20s/old/new/g    " lines 5..20
:'<,'>s/old/new/g   " visual selection
:argdo %s/o/n/ge | update     " all loaded files

% = whole file, g = global (all on line), c = confirm, i = ignore case, e = no error.

বাংলায়: :s কমান্ডের গঠন মনে রাখো: range + s + পুরনো + নতুন + flag। Range না দিলে শুধু বর্তমান লাইন, % দিলে পুরো ফাইল, 5,20 দিলে ৫ থেকে ২০ নম্বর লাইন। g flag ছাড়া প্রতি লাইনে শুধু প্রথম match বদলায় — এটা পরীক্ষার প্রিয় trap। আর c flag দিলে প্রতিটা বদলের আগে y/n জিজ্ঞেস করে, যেটা "interactively replace" বললে অবশ্যই লাগবে।

4.5 Registers

Named slots that hold text. 26 lowercase named registers ("a"z). Special:

  • "" unnamed (last yank/delete)
  • "0 last yank
  • "1"9 deleted text history
  • "+ system clipboard (Vim with +clipboard)
  • "* X selection
  • "_ black hole (discard)
  • "% current filename
  • ": last : command

Use: "ay yank to a, "ap put from a, "+yy copy line to system clipboard.

View all registers: :reg.

বাংলায়: Register মানে অনেকগুলো নামওয়ালা clipboard। সবচেয়ে দরকারি সূক্ষ্মতা: dd-ও unnamed register-এ লেখে, তাই আগে yank করা জিনিস delete করলেই হারিয়ে যায় — বাঁচার উপায় হয় named register ("ayy) নয়তো black hole ("_dd)। আর "0-তে সবসময় শেষ yank-টা থেকে যায়, delete যা-ই করো — paste নষ্ট হলে "0p দিয়ে উদ্ধার। সিস্টেম clipboard-এ নিতে "+y

4.6 Macros

A macro is just a recorded sequence of keystrokes saved in a register.

qa            " start recording into register a
... keystrokes ...
q             " stop recording
@a            " replay
@@            " replay last
5@a           " run 5 times

Macros are reusable Vim programs. Solution to Exercise 3 (Task 3) verbatim from the lecture:

qa /[<Enter> v /]<Enter> d 0 /><Enter> p 0 q

then @a to repeat on each subsequent line.

Macro as a stored function. Recording qa … q stores the keystroke sequence in register a; mathematically it defines a function \(f_a : \text{buffer} \to \text{buffer}\). @a evaluates \(f_a\) once; a count composes it with itself:

\[5@a \;=\; f_a^{\,5} \;=\; f_a \circ f_a \circ f_a \circ f_a \circ f_a\]

Worked example. If \(f_a\) = "wrap the current line in quotes, then move down one line", then 5@a transforms 5 consecutive lines — a loop without a loop construct. Replay aborts as soon as any step fails (e.g. a / search with no match, or j on the last line); that failure is the loop's built-in break condition, which is why you put the move to next line inside the recording.

Record / store / replay flow:

        RECORD                      STORE                  REPLAY
 ┌────────────────────┐      ┌─────────────────┐     ┌────────────────┐
 │ qa                 │      │  register "a"   │     │ @a    once     │
 │   ▼ your keys      │ ───► │  I"<Esc>A"<Esc>j│ ──► │ @@    repeat   │
 │ I"<Esc>A"<Esc>j    │      │  (inspect with  │     │ 5@a   5 times  │
 │ q                  │      │   :reg a)       │     └───────┬────────┘
 └────────────────────┘      └─────────────────┘             │
                            replay stops early if a motion or search fails

বাংলায়: Macro হলো register-এ জমানো keystroke-এর ফাংশন: qa দিয়ে রেকর্ড শুরু, q দিয়ে শেষ, @a দিয়ে একবার চালাও, 5@a মানে পরপর পাঁচবার। সবচেয়ে জরুরি কৌশল: রেকর্ডের শেষে j (পরের লাইনে নামা) ঢুকিয়ে দাও, তাহলে count দিলেই macro নিজে নিজে লাইন ধরে ধরে এগোবে। কোনো ধাপ fail করলে replay থেমে যায় — এটা bug নয়, এটাই নিরাপদ loop-break। পরীক্ষায় "macro লেখো" প্রশ্নে qa…q, @a, :reg a — এই তিনটা জিনিস দেখাতেই হবে।

4.7 Buffers, windows, tabs

  • Buffer = file loaded in memory.
  • Window = view onto a buffer.
  • Tab = group of windows.
:e file         " load file
:bnext / :bprev " switch buffers
:b 3            " buffer 3
:bd             " close buffer
:ls             " list buffers

:sp file        " horizontal split
:vsp file       " vertical split
Ctrl-w h/j/k/l  " move between windows
Ctrl-w =        " equalize sizes
Ctrl-w q / :q   " close window

:tabnew file    " new tab
gt / gT         " next / prev tab
:tabclose       " close tab
:tabs           " list tabs

বাংলায়: তিনটা স্তর গুলিয়ে ফেলো না: buffer হলো মেমরিতে খোলা ফাইল, window হলো সেই buffer দেখার একটা জানালা, আর tab হলো কয়েকটা window-র সাজানো layout। ১০টা buffer খোলা থাকতেই পারে কিন্তু window-তে দেখা যাচ্ছে মাত্র ২টা — :ls দিয়ে সব buffer-এর তালিকা দেখো। পরীক্ষায় "buffer vs window vs tab" তুলনাটা সরাসরি ৫ নম্বরের প্রশ্ন হিসেবে আসে।

4.8 .vimrc

The user config file at ~/.vimrc. Loaded at every Vim start. Example minimal config:

set nocompatible
syntax on
filetype plugin indent on
set number relativenumber
set tabstop=4 shiftwidth=4 expandtab
set hlsearch incsearch ignorecase smartcase
set autoindent smartindent
set wildmenu
set showcmd ruler
set clipboard=unnamedplus       " yank to system clipboard
set undofile undodir=~/.vim/undo
set background=dark
colorscheme desert

" mappings
let mapleader = ","
nnoremap <leader>w :w<CR>
nnoremap <leader>q :q<CR>
nnoremap <leader>h :nohlsearch<CR>
inoremap jk <Esc>

4.9 Diagram from L03 — the cheat-grid

Lecture has a 4×4 grid of motion vs operator (e.g. d/c/y rows × w/$/b/G columns). Recreate in the exam answer if asked to "summarise Vim's grammar".


5. Command / Syntax / Code Breakdown

vim file

  • Open file. If file doesn't exist, opens an empty buffer named so.

Mode-switch keys

  • i a o (Insert variants), Esc (back to Normal).

:w / :q / :wq / :x / ZZ / :q!

  • write / quit / write+quit / write+quit if changed / save+quit / discard.

:e file, :r file

  • edit (load) a file; read file into current buffer.

Search/Replace examples

  • :%s/\<oldname\>/newname/g whole-word replace.
  • :%s/foo/bar/gci case-insensitive confirm.

Yank / paste

  • yy line copy; 5yy 5 lines; p put after; P put before.

Marks

  • ma mark "a" at cursor; 'a jump to line of mark; `a jump to exact column.

Folding

  • zf create fold; za toggle; zR open all; zM close all.

Visual block

  • Ctrl-v block; move to extend; I then text + Esc → insert into all lines; c change column.

vimtutor

  • Run from terminal: vimtutor. A 30-minute hands-on tutorial. The exercise suggests doing it.

6. Mandatory Practical Examples

Example 6.1 — Edit a C++ file (mirrors Exercise 3, Task 1)

Purpose

Use Vim's basic commands to add an int ID declaration, two more couts, and join a broken line.

Input

File dir-1/myfile:

#include <iostream>
using namespace std;

int main() {
    string name;
    cout << "Enter your name: ";
    cin >> name;
    cout << "Hello, " << name
         << "! Welcome"<< endl;
    cout << "file:test/dir-1/myfile" << endl;
    return 0;
}

Code / Command (keystrokes in Vim)

Open: vim test/dir-1/myfile. Then in Normal mode:

/string name<Enter>     " jump to that line
o                       " open new line below in Insert
int ID;<Esc>            " add ID declaration
/cin >> name<Enter>     " jump there
o                       " open below
cout << "Enter your ID: ";<Esc>
o
cin >> ID;<Esc>
/Welcome<Enter>         " find broken Welcome line
J                       " join with previous
/return 0<Enter>
O                       " open above
cout << "ID = " << ID << "! Welcome" << endl;<Esc>
:w
:q

Expected Output

The buffer matches the right-hand side of the lecture's exercise.

Step-by-Step Explanation

  • /x<Enter> jump to text x.
  • o open new line below (Insert).
  • Esc return Normal.
  • J join the broken cout << ... lines into a single statement.
  • :w save, :q quit.

Real-Life HPC/CFD Meaning

Simulation source files are tweaked exactly like this — adding a parameter, fixing a printout, joining broken lines.

Written Exam Relevance

The examiner can paste a "before" and "after" code listing and ask which Vim keystrokes transform one into the other. Always answer with the Normal-mode grammar.

Example 6.2 — Multi-file copy via tabs (Task 2)

vim -p test/dir-1/myfile test/dir-2/myfile test/dir-3/myfile
" three tabs

" In tab 1
ggVGy                    " yank whole buffer
gt          " next tab
ggVG"_dP                 " replace whole buffer with paste
:%s/dir-1/dir-2/g
:w
gt
ggVG"_dP
:%s/dir-1/dir-3/g
:w
:qa

"_d deletes into the black-hole register so the yank survives.

বাংলায়: এখানে আসল কৌশল "_d — সাধারণ d মুছে-ফেলা লেখাকে unnamed register-এ ঢুকিয়ে তোমার yank নষ্ট করে দেয়; black-hole register "_ দিলে মুছে যাওয়াটা কোথাও জমা হয় না, ফলে p দিয়ে আগের yank-ই বসে। multi-file প্রশ্নে এই এক লাইনই পার্থক্য গড়ে।

Example 6.3 — Macro (Task 3)

Purpose. Move [date] from the end of an HTML <li> line to its start.

Input

<li><a href="https://www.google.com" target="_blank">Google</a>[29 Nov 2023]</li>
<li><a href="https://www.bing.com"   target="_blank">Bing</a>[01 Dec 2023]</li>
<li><a href="https://www.duckduckgo.com" target="_blank">DDG</a>[02 Dec 2023]</li>
<li><a href="https://www.startpage.com" target="_blank">SP</a>[03 Dec 2023]</li>
<li><a href="https://www.kagi.com"   target="_blank">Kagi</a>[04 Dec 2023]</li>

Code (Vim macro from the lecture solution)

qa              " start macro 'a'
/[<Enter>       " find first '['
v               " visual
/]<Enter>       " select to ']'
d               " delete (now in unnamed register)
0               " line start
/><Enter>       " find first '>' (i.e. after <li>)
p               " paste after '>'
0               " back to start
q               " end macro

Apply to the next 4 lines: position on each, @a (or 4@a).

Expected output

<li>[29 Nov 2023]<a href="https://www.google.com" target="_blank">Google</a></li>
...

Step-by-step. qa…q records into register a. The search/visual/delete sequence captures the bracketed date; jump to start, find >, paste, return to start. :reg a shows the recorded keys.

Real-Life HPC/CFD Meaning. Repetitive textual edits — reformatting hundreds of lines in a SLURM log or CFD case file — are bread-and-butter for HPC users. Macros do them in seconds.

Written Exam Relevance. Very common: "Write a Vim macro that …". Same pattern: qa … q, then @a.

বাংলায়: Macro-প্রশ্নের উত্তর সবসময় তিন ভাগে সাজাও: (১) recording শুরু-শেষ (qaq), (২) মাঝের keystroke-গুলো এক-একটা মন্তব্যসহ, (৩) প্রয়োগ (@a, 4@a বা :g/pat/normal! @a)। মাঝের ধাপগুলো position-independent রাখা চাই — তাই শুরুতে 0 আর search দিয়ে চলাচল।

Example 6.4 — Use .vimrc for HPC

Add to ~/.vimrc:

" HPC defaults
set tabstop=4 shiftwidth=4 expandtab
autocmd FileType make setlocal noexpandtab
nnoremap <F5> :w<CR>:!g++ -O2 -std=c++17 % -o %<<CR>:!./%<<CR>

F5 saves, compiles, and runs the current C++ file. (Note for Makefiles: real TABs required — hence noexpandtab.)


7. Real HPC/CFD Workflow

ssh hpc
tmux new -s edit
vim -p case01/in.dat case01/run.sh case02/in.dat
" Tab navigation: gt (next), gT (prev)
" Bulk edit: :argdo %s/Re=1000/Re=5000/ge | update
:qa

Plus: copy/paste between buffers via "+y / "+p (system clipboard) or named registers "ay / "ap.


8. Exercises and Solutions

Exercise 3, Task 1 — full keystroke walkthrough (see 6.1).

Marking scheme (8 marks): 1 each for: navigate to file — open with vim — switch to insert — add new lines — join broken line with J — save — quit — verify diff.

Exercise 3, Task 2 — multi-file editing (see 6.2).

Common mistake: using dd instead of "_dd so the yank register is overwritten and the paste fails.

Harder variation: open the three files in vertical splits (:vsp) and navigate with Ctrl-w l/h.

Exercise 3, Task 3 — macro (see 6.3).

Marking scheme (10 marks):

  • 1: enter recording with qa.
  • 2: search & visual select [ … ].
  • 1: delete to default register.
  • 2: jump to line start.
  • 1: jump to > after <li>.
  • 1: paste.
  • 1: end recording with q.
  • 1: replay with @a or 4@a.

Exercise 3, Task 4 — vimtutor

$ vimtutor

Spend 30 min — this single resource teaches all motions and operators.


9. Written Exam Focus

9.1 Short Answers

Q. Name Vim's main modes. A. Normal, Insert, Visual (char/line/block), Command-Line, Replace.

Q. Difference between dd and D. A. dd deletes the whole current line; D deletes from cursor to end of line.

Q. What does :%s/foo/bar/gc do? A. Replace every foo with bar in the entire file, asking for confirmation each time.

Q. What is a register in Vim? A. A named clipboard slot: 26 named registers plus specials — "+ (system clipboard), "0 (last yank), "_ (black hole).

Q. What is the role of .vimrc? A. A startup script of Ex-commands customising Vim — settings, key mappings, autocommands.

9.2 Medium Answers

Q. (8 marks) Explain Vim's "verb + count + motion" grammar with three examples.

A. Vim composes edits from small parts: [count][verb][motion or text-object].

  • d3w deletes the next three words.
  • c$ changes from cursor to end of line and enters insert.
  • y2j yanks the current line plus the next two.
  • ci" changes inside the quotes.

The grammar is combinatorial — knowing \(m\) verbs and \(n\) motions gives \(m \times n\) commands: e.g. 8 operators × 10 motions = 80 commands from 18 learned pieces.

Q. (5 marks) Difference between buffers, windows, and tabs?

A. A buffer is a file held in memory. A window is a viewport displaying a buffer. A tab is a layout of windows. Many buffers can be loaded with only some visible. Commands: :e (buffer), :sp/:vsp (window), :tabnew (tab).

9.3 Long Answer (12 marks)

Q. Describe the recording, viewing, and replay of a Vim macro with a real example.

A.

Introduction. Macros are reusable keystroke sequences stored in registers — ideal for repetitive edits in HPC log/config files.

Mechanism. q{a-z} starts recording into the register, perform the keys, q stops. Replay with @a, repeat with 5@a, last macro @@.

Example (move bracketed date — §6.3): qa /[<Enter> v /]<Enter> d 0 /><Enter> p 0 q.

Viewing. :reg a shows the recorded keys — the debugging tool for macros.

Repetition. @a per line, 5@a for the next 5, or :g/<li>/normal! @a for every matching line in the file.

Real HPC link. Bulk-edit CFD case dictionaries: add a ; to every line missing one, or rename a BC type project-wide. Hours saved.

Conclusion. Macros turn Vim into a tiny scripting environment with no extra tools.

9.4 Output / Behaviour Prediction

Initial:    Hello world
Press:      0 dw
Result:     world            " 'Hello ' deleted
Initial:    one two three
Press:      2dw
Result:     three            " 'one two ' deleted

:%s/cfd/CFD/gc → asks y/n/a/q at each match.

9.5 Comparison

Vim Nano
Modes Yes No
Learning curve Steep Tiny
Speed once learned Very high Modest
Default on cluster Usually Sometimes
Macros Yes No

Buffers / Windows / Tabs — see 9.2.

9.6 Templates

Edit-task template: "1) vim file. 2) Normal mode. 3) Navigate with motions. 4) operator+motion. 5) :w."

Macro template: "1) qa. 2) record. 3) q. 4) @a / 5@a. 5) :reg a to inspect."

9.7 Marking Scheme — "Vim modes" (5 marks)

  • 1: name Normal, Insert, Visual, Cmd-Line.
  • 1: Normal is the default.
  • 1: enter Insert with i/a/o.
  • 1: enter Visual with v/V/Ctrl-v.
  • 1: leave any mode with Esc.

10. Very Hard Questions

Beginner

  1. Save and quit? → :wq.
  2. Discard changes? → :q!.
  3. Copy a line? → yy.
  4. Delete 5 lines? → 5dd.
  5. Undo? → u.

Intermediate

  1. What does ci" do? → Change inside quotes.
  2. What does >ap do? → Indent a paragraph.
  3. Replace foo→bar only on lines 5–10? → :5,10s/foo/bar/g.
  4. Search backwards for "Re"? → ?Re.
  5. Open Makefile in a vertical split? → :vsp Makefile.

Hard

  1. Replace whole-word "Re" only? → :%s/\<Re\>/Reynolds/g.
  2. Repeat last :s command? → & (Normal mode).
  3. Yank current C++ function body? → cursor in body, ya{.
  4. Append ; to every line? → :%s/$/;/.
  5. Comment out lines 5–20 with //? → :5,20s/^/\/\// (or :5,20s,^,//,).

Very Hard

  1. Run the same edit on 200 loaded buffers? → :bufdo %s/foo/bar/ge | update.
  2. Sort visually selected lines numerically? → select with V, then :'<,'>!sort -n.
  3. Reformat selected paragraph to 80 cols? → select, gq, with set textwidth=80.

Deep Integration

  1. Batch-edit 50 SLURM scripts changing --time=2:00:00 to --time=4:00:00? → vim *.sbatch then :argdo %s/--time=2:00:00/--time=4:00:00/ge | update.
  2. Why is Vim more reliable on HPC than VS Code? → Works over SSH, no GUI, pre-installed, tiny memory.

Coding/Command

  1. Macro wrapping each line in if(true) { … }. → qa I if(true) { <Esc>A }<Esc>jq then @a/N@a.
  2. .vimrc mapping compiling with F5 — see 6.4.

Debugging

  1. :s/foo/bar/g changed only one line? → Need the range: :%s/foo/bar/g.
  2. :w fails on a read-only file. → :w! or :w !sudo tee %.

Long Written

  1. (250 words) Discuss why Vim's modal grammar saves time in HPC editing. (Base it on 9.2.)

11. Debugging and Mistake Analysis

Mistake Why wrong Correct Explanation
Typing while in Insert mode unintentionally mode confusion press Esc first watch the status bar
:s/foo/bar/g for whole file current line only :%s/foo/bar/g % = entire file
dd overwrote the yank delete fills unnamed register "_dd or "ayy first preserve clipboard
:wq! confusion ! forces choose deliberately :q! discards, :wq! forces write
PCRE habits in Vim regex Vim needs \( \\| \< \> escape or use \v "magic" mode
"Can't exit Vim" panic Esc then :q! beginner trap
:q fails (unsaved) forgot :w :wq or ZZ save then quit
Macro breaks on some lines position-dependent recording re-record using 0, searches inspect with :reg a

বাংলায়: Vim-ভুলের রাজা একটাই: এখন কোন mode-এ আছি, না জানা। অভ্যাস করো — কিছু গোলমাল লাগলেই আগে Esc, তারপর ভাবো। আর macro লেখার সময় প্রতিটা চলাচল absolute রাখো (0, search) — নাহলে এক লাইনে কাজ করা macro পরের লাইনে ভেঙে পড়বে।


12. Mini Project for Mastery

Goal: Convert a CSV column delimiter from , to | and align all columns.

:vsp data.csv
:%s/,/|/g
:%!column -t -s '|'
:w aligned.dat

(Uses :%!cmd to filter the whole buffer through an external command.)

Connection to exam: "use Vim to convert / align a file" — the :%! filter is the idiomatic answer, and it links Vim to the Ch 7 tools.


13. Final Chapter Cheat Sheet

Item Memorise
Modes Normal, Insert, Visual, Cmd-Line
Switch to Insert i a o I A O
Back to Normal Esc
Save & quit :wq (or ZZ)
Discard :q!
Move h j k l w b e 0 $ gg G %
Grammar [count][operator][motion] — m ops × n motions = m·n commands
Delete dw d$ dd 5dd diw da{
Yank yy y$ y2j yi"
Paste p P
Undo / Redo u / Ctrl-r
Search /pat, n, N, *
Replace :%s/old/new/gc
Whole-word \<word\>
Macro qa…q, @a, 5@a, :g/pat/normal! @a
Registers "a named, "+ system, "0 last yank, "_ blackhole
Buffers :e, :bnext, :b 3
Windows :sp, :vsp, Ctrl-w
Tabs :tabnew, gt, gT
.vimrc essentials set number, expandtab, hlsearch, incsearch
Filter :%!column -t (buffer through shell cmd)
Trap not pressing Esc before :wq
Top-grade phrase "Vim composes edits from count + verb + motion/text-object, allowing combinatorial productivity."

14. Mock Exam — Four Levels

Level 1 — Basic (definitions & syntax)

Q1. Exact keystrokes: open in.dat, jump to the last line, append the text end on a new line, save and quit.

Solution: vim in.datGo → type endEsc:wq.

Q2. What do x, dw, and dd delete respectively?

Solution: One character under the cursor; from cursor to start of next word; the whole line.

Q3. Keystroke to jump to line 42.

Solution: 42G (or :42).

Q4. Which command shows what is stored in register a?

Solution: :reg a.

Q5. How do you repeat the LAST change (not a macro)?

Solution: . (the dot command).

Level 2 — Intuitive (predict / explain why)

Q1. Cursor on the w of network_speed. Predict the result of ciw then typing bandwidth.

Solution: The whole word network_speed is replaced by bandwidthiw is the "inner word" text object; cursor position within the word doesn't matter.

Q2. Why does d2w2dw never differ, but 2ddd2d?

Solution: Counts multiply through operator+motion (d2w = 2dw by grammar). dd is a special line-wise doubling — 2dd deletes 2 lines, while d2d isn't standard grammar (the duplicated operator IS the motion).

Q3. You record qa dw j q on line 1 and run 3@a. What happens, line by line?

Solution: Each replay deletes the first word of the current line then moves down: lines 2, 3, 4 lose their first words (line 1 lost its word during recording). The j inside the macro is what makes blind repetition work.

Q4. :%s/\d\+/N/g on step 12 of 250 gives what?

Solution: step N of N\d\+ (Vim magic for one-or-more digits) matches both numbers; g replaces all on the line.

Q5. Why is u after a 200-line :%s a single undo, not 200?

Solution: Undo is grouped per command — one :s invocation = one change-set, however many replacements it made.

Level 3 — Hard (exam level)

Q1. (8 marks) Give the exact keystroke sequence to swap two adjacent lines, and explain why it works.

Solution: ddpdd cuts the current line into the unnamed register; p pastes it BELOW the new current line, completing the swap. (Swap upward: ddkP.) বাংলা ইঙ্গিত: p পেস্ট করে নিচে, P উপরে — ছোট অক্ষর/বড় অক্ষরের এই জোড়াটাই উত্তরটার মেরুদণ্ড।

Q2. (8 marks) Write ONE Ex command that, in lines 10–50 only, replaces whole-word dt with dt_local, with confirmation.

Solution: :10,50s/\<dt\>/dt_local/gc — range, word anchors, g (all per line), c (confirm). বাংলা ইঙ্গিত: চারটা টুকরা চারটা নম্বর: range + \< \> + g + c — একটা বাদ মানে এক নম্বর কম।

Q3. (10 marks) Record a macro that wraps the current line in double quotes and advances; then give the command applying it to ALL 100 lines of the file without counting them.

Solution: qa I"<Esc>A"<Esc>jq then :%normal! @a (applies to every line — no count needed; alternative 99@a requires knowing the count). বাংলা ইঙ্গিত: "সংখ্যা না গুনে সব লাইনে" শুনলেই :%normal! @a বা :g/^/normal! @a — এটাই পরীক্ষকের খোঁজা উত্তর।

Q4. (8 marks) Without leaving Vim, number-sort the data block from line 5 to line 25 by the 2nd column, and explain the mechanism.

Solution: :5,25!sort -k2 -n — the range is piped as stdin to the external command; sort's stdout replaces the range. Vim becomes a shell-filter frontend (same mechanism as :%!column -t). বাংলা ইঙ্গিত: ! মানে buffer-অংশ shell-কমান্ডের ভেতর দিয়ে যায় — Vim আর Ch 7 টুলের সেতু; mechanism-এর ব্যাখ্যাতেই অর্ধেক নম্বর।

Q5. (10 marks) A teammate's macro qb f=lDA42<Esc>q should set every assignment's value to 42 (x = 13x = 42). On some lines it destroys text. Diagnose all failure modes.

Solution: (1) Lines WITHOUT =: f= fails, but the remaining keys still run — D deletes from cursor and A42 appends 42 to a line that never had an assignment → corruption. (2) Lines with = but no space after: l lands on the value's first char — works by luck; with trailing spaces/comments after the value, D also kills the comment. Robust replacement: :%s/\(=\s*\).*/\142/ on assignment lines only (:g/=/s/...). বাংলা ইঙ্গিত: macro-র প্রাণঘাতী দুর্বলতা: search ব্যর্থ হলেও পরের কী-গুলো চলে; "কোন লাইনে ভাঙবে" প্রশ্নে সবসময় no-match কেসটা আগে দেখো।

Level 4 — Beyond the lecture (transfer + coding)

Q1. Combine Vim + bash (Ch 8): you have 80 case_*/run.sh files; inside Vim, load them all and append set -euo pipefail after the shebang of each. Give the full command sequence.

Solution:

vim case_*/run.sh
:argdo 1s/^#!.*$/&\rset -euo pipefail/ | update
argdo runs over the arg list; 1s targets line 1; & reuses the matched shebang; \r inserts a newline; update writes only changed files. বাংলা ইঙ্গিত: replacement-এ নতুন লাইন \r দিয়ে হয় (\n নয়!) — Vim-এর কুখ্যাত ব্যতিক্রম, পরীক্ষায় ফাঁদ হিসেবে প্রিয়।

Q2. Vim + Ch 6 regex: one substitute command converting every float in scientific notation (e.g. 1.5e-03) to SCI — write it with Vim's "very magic" mode and explain why \v helps.

Solution: :%s/\v\d+\.?\d*[eE][+-]?\d+/SCI/g — with \v (very magic) the pattern reads like ERE: no backslashes before + ? ( ). Without \v it would be \d\+\.\?\d*[eE][+-]\?\d\+ — error-prone. বাংলা ইঙ্গিত: জটিল regex Vim-এ লিখতে হলে আগে \v বসাও — ERE-মস্তিষ্ক দিয়ে ভাবা যায়, escape-জঙ্গল এড়ানো যায়।

Q3. During a cluster session your .vimrc is missing (fresh home dir). Set, for this session only, the four settings you'd want for editing a Makefile and a C++ file, and explain the Makefile-specific trap.

Solution: :set number hlsearch incsearch plus for C++: :set tabstop=4 shiftwidth=4 expandtab — but in the Makefile buffer: :setlocal noexpandtab because Make recipes REQUIRE real TAB characters; expandtab would silently convert them to spaces → "missing separator" (Ch 12 link). বাংলা ইঙ্গিত: expandtab সর্বত্র ভালো — শুধু Makefile-এ বিষ; setlocal দিয়ে buffer-প্রতি নিয়ম আলাদা করা যায়।

Q4. Power-move question: with one :g command, delete every line in a 10,000-line log that does NOT contain ERROR and explain the difference from :v.

Solution: :v/ERROR/d (equivalently :g!/ERROR/d) — :v runs the command on lines NOT matching. (:g/ERROR/d would do the opposite — delete the errors and keep the noise.) বাংলা ইঙ্গিত: :g = মেলে এমন লাইনে চালাও, :v = না-মেলা লাইনে — এই জোড়া মুখস্থ থাকলে log-ছাঁটাই এক লাইনের কাজ।


End of Chapter 5.