| | {{infobox |
| | | title = Editors |
| | | chapter = Linux Handbook, chapter 19 — vi, nano, and the text layer |
| | | core | Editing is the universal task — every config is text |
| | | editors | vi/vim · nano · ed · sed-as-editor · the rest |
| | | skills | vi fluency · nano survival · when to reach for which |
| | | next | Package management — installing software without building it |
| | }} |
| | |
| | **Every system task ends at an editor** — every config file, every script, every fstab, every authorized_keys. Two editors are *guaranteed*: **vi** (the POSIX-mandated one — present on every Unix ever) and **nano** (the kind one). This chapter teaches vi fluency as a survival skill and a fluency, nano as the friendly default, and when each is the right tool. |
| | |
| | ## vi — the one that's always there |
| | |
| | Vi's core trick: **modes** — `i` to insert, `Esc` back to normal, where every key is a command. The discipline feels alien for a day, then becomes how you think: |
| | |
| | ``` |
| | ESC — normal mode (the home base) |
| | i / a / o — insert before / after / new line |
| | :w — write · :q — quit · :wq — save+quit · :q! — force-quit |
| | :x — save+quit · ZZ — save+quit |
| | dd — delete line · yy — yank · p — paste · u — undo · Ctrl-R redo |
| | 0 / $ — line start/end · gg / G — file start/end |
| | /pattern — search · n — next · ? — search back |
| | :%s/old/new/g — sed inside the editor |
| | :wq — the command every tutorial drills |
| | ``` |
| | |
| | The verbs compose: `d` + motion = delete (`dw` word, `d$` to end, `d5d` five lines); `y` + motion = yank; `c` + motion = change. `5dd` deletes five lines; `ci"` changes inside quotes; `v` selects visually; `.` repeats the last command. The language is grammar — verb + motion — and fluency is learning to speak it. |
| | |
| | ## vim — vi's empire |
| | |
| | `vim` adds syntax highlighting, multiple files, splits, plugins — on most Linuxes `vi` *is* vim in compatible mode. `vimtutor` is the built-in tutorial — 20 minutes, genuinely sufficient. The survival set for config work: `i`/`Esc`, `:wq`, `dd`, `u`, `/`, `:set number`. Everything else is depth. |
| | |
| | ## nano — the kind one |
| | |
| | ``` |
| | nano file |
| | Ctrl-O — write out · Ctrl-X — exit · Ctrl-W — find |
| | Ctrl-K — cut line · Ctrl-U — uncut · Ctrl-G — help |
| | ``` |
| | |
| | The shortcuts are printed at the bottom — the editor that explains itself. For quick edits and for anyone not living in the terminal, nano is correct. `/etc/alternatives`/distro defaults set `EDITOR`/`VISUAL` — `export EDITOR=nano` makes it the system's default (which is what `visudo`, `crontab -e`, git commit messages invoke). |
| | |
| | ## vi — the complete grammar |
| | |
| | ```text |
| + | (POSIX vi covers the core; rows marked ‡ are vim-only — visual mode, text |
| + | objects, splits, redo — present on every Linux `vi`, absent on a true POSIX vi.) |
| + | |
| | MODES: |
| - | Esc — normal i/a/o/O — insert v/V/Ctrl-v — visual : — ex R — replace |
| - | Ctrl-o — one normal cmd from insert gv — reselect last visual |
| + | Esc — normal i/a/o/O — insert v/V/Ctrl-v — visual‡ : — ex R — replace |
| + | Ctrl-o — one normal cmd from insert‡ gv — reselect last visual‡ |
| | |
| | MOTIONS (verb+motion grammar): |
| | 0 $ ^ — line start/end/first-nonblank w b e — word fwd/back/end W B E — WORD |
| - | gg G — file start/end :n / nG — line n f F t T — char-target motions, ; , repeat them |
| - | { } — paragraph ( ) — sentence % — matching bracket * # — word under cursor |
| + | gg‡ G — file start/end :n / nG — line n f F t T — char-target motions, ; , repeat them |
| + | { } — paragraph ( ) — sentence % — matching bracket * # — word under cursor‡ |
| | |
| | VERBS + MOTIONS — the compositional language: |
| | d — delete y — yank c — change v — select > — indent < — dedent = — reformat |
| | dd yy cc — line forms d3w 3dw — delete 3 words d$ — to end df; — to the ; |
| - | ci" ca( ciw — inner/around quoted/paren/word cip — change paragraph |
| + | ci" ca( ciw — inner/around quoted/paren/word‡ cip — change paragraph‡ |
| | d/text — to the pattern yG — to end of file |
| | |
| | OPERATORS: |
| | x — char X — before s — substitute char S — line J — join lines |
| - | p P — paste after/before . — REPEAT last command — the superpower u U Ctrl-R — undo/line/redo |
| - | ~ — swap case gu gU — lower/upper r — replace char zz zt zb — recenter/top/bottom |
| + | p P — paste after/before . — REPEAT last command — the superpower u U Ctrl-R — undo/line/redo‡ |
| + | ~ — swap case gu gU — lower/upper‡ r — replace char zz zt zb — recenter/top/bottom‡ |
| | |
| | EX COMMANDS (:): |
| | :w :q :wq :x :q! ZZ ZQ — write/quit combos |
| | :e! — revert to disk |
| - | :set number / nonu — line numbers |
| - | :set paste / nopaste — the paste-mode fix for bracketed pastes |
| + | :set number / nonu — line numbers‡ |
| + | :set paste / nopaste — the paste-mode fix for bracketed pastes‡ |
| | :s/old/new/[gc] — sed inside — % = whole file, g = global, c = confirm |
| | :g/pat/d — delete every matching line — global+cmd |
| | :v/pat/d — delete every NON-matching |
| | :r file — read a file in |
| | :r! cmd — insert a command's output |
| | :! cmd — shell out |
| - | :w !sudo tee % — save-as-root — the classic fix |
| - | :split :vsplit :tabnew Ctrl-w— splits + tabs |
| - | :noh — clear search highlight |
| - | :history :buffers :ls — the state |
| + | :w !sudo tee % — save-as-root — the classic fix‡ |
| + | :split :vsplit :tabnew Ctrl-w— splits + tabs‡ |
| + | :noh — clear search highlight‡ |
| + | :history :buffers :ls — the state‡ |
| | :mark a, 'a — named marks |
| - | :registers — the yank registers |
| + | :registers — the yank registers‡ |
| | :x — like :wq but only writes if changed |
| | ``` |
| | |
| | ## vim — the additions worth it |
| | |
| | ```text |
| | vim file +20 # open at line 20 |
| | vim file +/pat # open at first match |
| | vim -R file # read-only |
| | vim -d a b # vimdiff — side-by-side diff |
| | vim file1 file2 # multiple — :n :prev :args |
| | vim -o/-O/-p a b # splits vs tabs |
| | vimtutor # the tutorial — run it |
| | |
| | :set nu rnu # absolute + relative numbers — the motion math |
| | :set list — show tabs/trailing |
| | :set hlsearch incsearch — search behavior |
| | :syntax on/off — highlighting |
| | :retab — tabs→spaces per ts |
| | gg=G — reindent the whole file |
| | q: q/ q? — the command/search history WINDOWS |
| | Ctrl-a Ctrl-x — inc/dec numbers under cursor |
| | ``` |
| | |
| | ## nano — the full set |
| | |
| | ```text |
| | Ctrl-O write · Ctrl-X exit · Ctrl-W find · Alt-W next · Ctrl-\ replace |
| | Ctrl-K cut · Ctrl-U uncut · Ctrl-Y prev-page · Ctrl-V next-page |
| | Alt-A mark · Alt-6 copy · Ctrl-_ go-to-line · Ctrl-C cursor pos |
| | Ctrl-T spell · Alt-U undo · Alt-E redo · Ctrl-G help |
| | nano -l -c file # line numbers + cursor pos |
| | ``` |
| | |
| | ## ed — the ancestor |
| | |
| | ```text |
| | ed file |
| | a — append i — insert c — change d — delete |
| | p — print n — numbered print ,p — print all 1,5p — lines |
| | /pat/ — search s/old/new/ — substitute w — write q — quit |
| | ``` |
| | |
| | `ed` is where `sed`'s `s///`, vi's `:` commands, and `grep`'s `g/re/p` all descend from — the original line editor. |
| | |
| | ## The others worth knowing |
| | |
| | - **ed** — the line editor — ancient, scriptable, the ancestor of `sed` and vi's `:` commands — `ed` survives in POSIX |
| | - **sed -i** — editing *without* an editor — `sed -i.bak 's/a/b/g'` is the scripted edit |
| | - **emacs** — the other giant — a lisp environment that edits text |
| | - **code/nvim/helix** — the moderns — VS Code, Neovim, Helix |
| | |
| | ## The config-file craft |
| | |
| | Real editing is config work — `/etc/fstab`, `sshd_config`, `.bashrc`: |
| | |
| | ```sh |
| | sudoedit /etc/fstab # edits as user, writes as root — safer than sudo vi |
| | vi /etc/ssh/sshd_config # the classic |
| | nano ~/.bashrc |
| | ``` |
| | |
| | The disciplines: **back up before editing** (`cp file file.bak`), **learn the file's syntax** (comments `#`, tabs vs spaces where it matters — `/etc/fstab` whitespace, `Makefile` tabs), **syntax-check after** (`sshd -t`, `visudo` checks sudoers automatically, `mount -a` tests fstab). A broken `/etc/fstab` boots to emergency mode; a broken sudoers locks out sudo — know the check command before saving. |
| | |
| | ## Where editors go wrong |
| | |
| | | Symptom | Cause | |
| | | --- | --- | |
| | | Typing produces commands, not text | vi in normal mode — `i` | |
| | | `:wq` didn't quit | Still in insert — `Esc` first | |
| | | `sudo vi file` leaves root-owned files | `sudoedit` or `sudo -e` is cleaner | |
| | | `git commit` opens an alien editor | `export EDITOR=nano` | |
| | | vi's colors unreadable | `:syntax off`, or TERM broken | |
| | | Saved but the change didn't take | The file needed a service restart / re-source | |
| | |
| | ## Exercises |
| | |
| | 1. `vimtutor` — once through, honestly. |
| | 2. Edit a scratch file: `dd` a line, `u` undo, `/search`, `:%s/x/y/g`. |
| | 3. `export EDITOR=nano; crontab -e` — see the default take effect. |
| | 4. `sed -i.bak 's/a/b/g'` a file — the no-editor edit. |
| | 5. Open `/etc/fstab` in vi — read-only practice, `:q!` out. |
| | |
| | ## See also |
| | |
| - | - [[Shell]] · [[Text processing]] · [[Core Utilities]] · [[Linux]] |
| + | - [[Shell]] · [[Text Processing]] · [[Core Utilities]] · [[Linux]] |
| | |
| | [[Category:Linux]] |
| | [[Category:Handbook]] |
| | [[Category:Editors]] |
| | [[Category:Linux Handbook]] |
| | |