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). .vimrcconfiguration.
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
oldNamewithnewNameinteractively." - "Record and apply a macro that …"
- "Sample
.vimrcsnippet."
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:
- Operators:
ddelete,cchange,yyank (copy),>indent,gUuppercase. - Motions:
wnext word,bprevious word,eend of word,0line start,$line end,ggfile start,Gfile end,}next paragraph,f<char>find char on line. - Text objects:
iwinner word,awa word (with space),i"inside quotes,ipinner paragraph,aba 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:
iinsert before cursor;Iinsert at line start;aappend after;Aappend at line end;oopen new line below;Oabove.vcharacterwise visual;Vlinewise;Ctrl-vblockwise.: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:
dwdelete word,d$delete to end of line,d0delete to line start,dGdelete to file end,dggdelete to file start.ccchange line,cwchange word,ci(change inside parens,ca{change a block including braces.yyyank line,y2jyank current + next two lines,yi"yank inside quotes.5dddelete 5 lines,3yyyank 3 lines.
The grammar as a mini-algebra. Every Normal-mode edit is a word of this little language:
Semantics: apply the operator to exactly the text the motion travels over; the two counts multiply — 2d3w 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:
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)"0last yank"1…"9deleted 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:
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:
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¶
iao(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/gwhole-word replace.:%s/foo/bar/gcicase-insensitive confirm.
Yank / paste¶
yyline copy;5yy5 lines;pput after;Pput before.
Marks¶
mamark "a" at cursor;'ajump to line of mark;`ajump to exact column.
Folding¶
zfcreate fold;zatoggle;zRopen all;zMclose all.
Visual block¶
Ctrl-vblock; move to extend;Ithen text + Esc → insert into all lines;cchange 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.oopen new line below (Insert).Escreturn Normal.Jjoin the brokencout << ...lines into a single statement.:wsave,:qquit.
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
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 শুরু-শেষ (
qa…q), (২) মাঝের 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
@aor4@a.
Exercise 3, Task 4 — 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].
d3wdeletes the next three words.c$changes from cursor to end of line and enters insert.y2jyanks 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¶
:%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
- Save and quit? →
:wq. - Discard changes? →
:q!. - Copy a line? →
yy. - Delete 5 lines? →
5dd. - Undo? →
u.
Intermediate
- What does
ci"do? → Change inside quotes. - What does
>apdo? → Indent a paragraph. - Replace foo→bar only on lines 5–10? →
:5,10s/foo/bar/g. - Search backwards for "Re"? →
?Re. - Open Makefile in a vertical split? →
:vsp Makefile.
Hard
- Replace whole-word "Re" only? →
:%s/\<Re\>/Reynolds/g. - Repeat last
:scommand? →&(Normal mode). - Yank current C++ function body? → cursor in body,
ya{. - Append
;to every line? →:%s/$/;/. - Comment out lines 5–20 with
//? →:5,20s/^/\/\//(or:5,20s,^,//,).
Very Hard
- Run the same edit on 200 loaded buffers? →
:bufdo %s/foo/bar/ge | update. - Sort visually selected lines numerically? → select with
V, then:'<,'>!sort -n. - Reformat selected paragraph to 80 cols? → select,
gq, withset textwidth=80.
Deep Integration
- Batch-edit 50 SLURM scripts changing
--time=2:00:00to--time=4:00:00? →vim *.sbatchthen:argdo %s/--time=2:00:00/--time=4:00:00/ge | update. - Why is Vim more reliable on HPC than VS Code? → Works over SSH, no GUI, pre-installed, tiny memory.
Coding/Command
- Macro wrapping each line in
if(true) { … }. →qa I if(true) { <Esc>A }<Esc>jqthen@a/N@a. .vimrcmapping compiling with F5 — see 6.4.
Debugging
:s/foo/bar/gchanged only one line? → Need the range::%s/foo/bar/g.:wfails on a read-only file. →:w!or:w !sudo tee %.
Long Written
- (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.
(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.dat → G → o → type end → Esc → :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 bandwidth — iw is the "inner word" text object; cursor position within the word doesn't matter.
Q2. Why does d2w ≠ 2dw never differ, but 2dd ≠ d2d?
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: ddp — dd 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 = 13 → x = 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:
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-ছাঁটাই এক লাইনের কাজ।
15. MCQ Drill — Exam Section (34 questions)¶
Difficulty ramps from basic (1) to very hard (34). Questions marked (select all that apply) have more than one correct option.
1. Vim starts in which mode? A. Insert B. Normal C. Visual D. Command-line
Answer: B. Normal is home base; everything else is entered from it.
2. Enter Insert mode BEFORE the cursor: A. a B. i C. o D. A
Answer: B. i=insert here, a=after cursor, o=new line below, A=end of line.
3. Save and quit: A. :q B. :wq (or ZZ) C. :x!only D. Ctrl+S
Answer: B. :x and ZZ also write-and-quit; :q alone fails on unsaved changes.
4. Discard all changes and exit: A. :w! B. :q! C. :exit D. ZZ
Answer: B. The ! forces; ZZ would SAVE first — opposite intent.
5. Delete the current line: A. dw B. dd C. D D. x
Answer: B. dd=whole line, D=to end of line, dw=word, x=char.
6. Undo and redo: A. u / Ctrl-r B. Ctrl-z / Ctrl-y C. :undo only D. U / R
Answer: A. One u after a 200-line :%s undoes it ALL (undo is per command).
7. Copy (yank) a whole line, then paste below: A. yy p B. cc v C. Y P D. dd p
Answer: A. Y/yy yank; lowercase p pastes below, capital P above. (dd p MOVES the line.)
8. Which enter Visual modes? (select all that apply) A. v (character) B. V (line) C. Ctrl-v (block) D. :v
Answer: A, B, C. :v is an Ex command (v-global) — a different beast entirely.
9. Jump to line 42 / to the last line: A. 42j / L B. 42G / G C. :42j / $ D. g42 / ge
Answer: B. Also :42 for the former; gg = first line.
10. Search forward for "Re", then next/previous match: A. /Re then n / N B. ?Re then n / N C. fRe D. :find Re
Answer: A. ? searches backwards; * searches the word under cursor.
11. Vim's edit grammar is… A. [motion][operator][count] B. [count][operator][motion] C. random D. [operator] only
Answer: B. e.g. d2w, 3dd, c$ — 8 operators × 10 motions = 80 commands from 18 pieces.
12. ci" does…
A. copy inside quotes B. change the text inside the surrounding quotes C. cut whole line D. nothing
Answer: B. c=change + i"=inner-quotes text object; cursor may be anywhere within them.
13. The . (dot) command…
A. repeats the last search B. repeats the last CHANGE C. inserts a dot D. jumps back
Answer: B. The cheapest automation in Vim — position, then . per occurrence.
14. d2w and 2dw…
A. differ B. are identical by the grammar (counts multiply through) C. error D. delete different words
Answer: B. Both delete two words.
15. Swap two adjacent lines: A. xp B. ddp C. yyp D. Jk
Answer: B. dd cuts the line, p pastes it BELOW the next — swapped. (xp swaps two characters!)
16. :%s/foo/bar/gc — the flags mean…
A. global+confirm each B. group+copy C. case-insensitive D. count
Answer: A. % whole file, g=all per line, c=ask y/n each time.
17. :s/foo/bar/g changed only one line because…
A. bug B. no range — :s acts on the CURRENT line; % was missing C. g missing D. file read-only
Answer: B. Range first, then substitute: :%s, :5,10s, :'<,'>s.
18. Whole-word replace of Re only (not Reynolds):
A. :%s/Re/x/g B. :%s/\<Re\>/x/g C. :%s/"Re"/x/g D. impossible
Answer: B. Word boundaries \< \> — Vim regex flavour.
19. Record a macro into register a, then replay it 5 times: A. qa … q, then 5@a B. ma … 5`a C. :macro a 5 D. q5a
Answer: A. qa starts, q stops, @a plays, 5@a loops, @@ repeats the last.
20. Inspect what a macro recorded: A. :macros B. :reg a C. @a? D. impossible
Answer: B. Registers hold macros AS TEXT — debugging tool number one.
21. Apply macro a to every line containing <li>:
A. 100@a and hope B. :g/
Answer: B. :g executes a command on every matching line — no counting needed.
22. Registers: which statements are true? (select all that apply) A. "ayy yanks into register a B. "+ is the system clipboard C. "_ is the black hole D. "0 holds the last yank even after a delete
Answer: A, B, C, D. All four — and "_dd deletes WITHOUT clobbering your yank (multi-file exercise trick).
23. Why did the paste fail after dd in the multi-file exercise?
A. paste is broken across files B. dd overwrote the unnamed register that held the yank C. tabs block registers D. wrong mode
Answer: B. Solution: delete with "_dd or yank into a named register first ("ayy).
24. A buffer / window / tab is… A. file-in-memory / viewport / layout of windows B. clipboard / file / screen C. all the same D. process / thread / task
Answer: A. :e buffers, :sp/:vsp windows, :tabnew + gt/gT tabs.
25. Run the same substitution in ALL loaded buffers and save: A. :bufdo %s/foo/bar/ge | update B. repeat by hand C. :all s/foo/bar D. :windo w
Answer: A. e suppresses errors on buffers without matches; update writes only if changed. argdo is the arg-list twin.
26. Filter lines 5–25 through an external sort: A. :5,25!sort -n B. :sort! 5,25 C. !sort D. :r sort
Answer: A. The range is piped to the command; its stdout replaces the range — same mechanism as :%!column -t.
27. In :%s/\(Re\)\|\(Pr\)/X/g the backslashes exist because…
A. style B. Vim's default "magic" regex treats ( ) | as literals unless escaped C. POSIX requires it D. bug
Answer: B. Or prefix \v (very magic) to write (Re|Pr) ERE-style.
28. Insert a NEWLINE in a substitution replacement:
A. \n B. \r C. ^M literally impossible D. <CR>
Answer: B. Infamous asymmetry: in the PATTERN \n matches a newline; in the REPLACEMENT you must write \r.
29. Delete every line NOT containing ERROR: A. :g/ERROR/d B. :v/ERROR/d C. :%s/ERROR// D. dd repeatedly
Answer: B. :v (= :g!) acts on NON-matching lines; :g/ERROR/d would do the opposite.
30. In .vimrc, set expandtab is dangerous for…
A. C++ files B. Makefiles — recipes REQUIRE real tab characters C. Python D. logs
Answer: B. Guard with autocmd FileType make setlocal noexpandtab — otherwise "missing separator" (Ch 12).
31. The macro qa f=lDA42<Esc>q corrupts lines WITHOUT = because…
A. macros can't use f B. when f= fails the REMAINING keys still execute (D, A42) on the wrong text C. registers overflow D. 42 is special
Answer: B. Macro robustness rule: failed motions don't abort the rest — design macros to fail safely (start with searches/0) or filter lines with :g/=/normal! @a.
32. vim -p a b c opens…
A. three windows B. three tabs (navigate with gt / gT) C. a playlist D. read-only
Answer: B. -o/-O would open horizontal/vertical windows instead.
33. Repeat the last :s on the current line:
A. . B. & C. @: D. r
Answer: B. & repeats the substitute; @: repeats the last Ex command generally; . repeats the last CHANGE (which a :s is not).
34. Sort ONLY the visually selected block numerically by column 2: A. impossible B. select with V, then :'<,'>!sort -k2 -n C. :sort n2 D. gq
Answer: B. Visual range '<,'> + external filter — the two power features composed; exactly the exam's "align/convert with Vim" pattern.
End of Chapter 5.