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-ছাঁটাই এক লাইনের কাজ।
End of Chapter 5.