2023-12-23 20:13:54 -07:00
|
|
|
# Quick help
|
|
|
|
```bash
|
|
|
|
for f in *.html; do nvim -Nes "$f" < ex_commands; done
|
|
|
|
for f in "$(rg -l homu)"; do nvim -Nes "$f" < ex_commands; done
|
|
|
|
|
|
|
|
for f in $(fd -tf -e html); do
|
|
|
|
nvim -Nes <<'EX'
|
|
|
|
g/^Stl/exe "norm! cStyle: new\<CR>\<esc>"
|
|
|
|
$ | a
|
|
|
|
# ex: ff=unix:
|
|
|
|
.
|
|
|
|
wq
|
|
|
|
EX
|
|
|
|
done
|
|
|
|
```
|
|
|
|
|
|
|
|
# Batch editing with ex
|
|
|
|
Ever needed to apply the same edit to several files? Well ex-mode is the only
|
|
|
|
generalized solution for this
|
|
|
|
|
|
|
|
Ex-mode is vim's equivalent of `ed` and `ex` is symlinked as `vim -e` on many
|
|
|
|
systems. Use the `-N` flag for a more familiar experience. Enter this mode while
|
|
|
|
in vim with `gQ`. Using the `ex` executable is slightly different from neovim's
|
|
|
|
implementation, notably neovim doesn't echo back with `nu` and `p`
|
|
|
|
|
|
|
|
```bash
|
|
|
|
ex file
|
|
|
|
vim -Nes file
|
|
|
|
```
|
|
|
|
|
|
|
|
Ex-mode uses vim's command-mode syntax, which is similar though different from
|
|
|
|
visual mode
|
|
|
|
|
|
|
|
```
|
|
|
|
:21 Goes to line 21. ^ and $ are for the first and last line
|
|
|
|
:10,20d Deletes lines 10 through 20, inclusive on both ends
|
|
|
|
:u[ndo] Undoes the last action
|
2023-12-23 20:13:55 -07:00
|
|
|
:mark a Makes a mark at a. From vim
|
|
|
|
:ka Also makes a mark at a. From ex
|
|
|
|
:'a Go to mark a
|
2023-12-23 20:13:54 -07:00
|
|
|
:g/re/p Globally exectute a command on lines with /re/
|
|
|
|
:v/re/p Inverse of :g. Executes on all lines without /re/
|
|
|
|
:3,6co$ Copy lines [3,6] to the end of the document
|
|
|
|
:3m6 Move line 3 to line 6
|
|
|
|
:z=3 Pretty print lines in [-2,+2]
|
2023-12-23 20:13:55 -07:00
|
|
|
:norm! @l Execute keystrokes, if all else fails
|
2023-12-23 20:13:54 -07:00
|
|
|
```
|
|
|
|
|
|
|
|
Several commands can be chained with `|`, similar to `;` in bash
|
|
|
|
|
|
|
|
```
|
|
|
|
:g/bash/exe "normal! cfish\<esc>" | undo | nu
|
|
|
|
```
|
|
|
|
|
|
|
|
Changes every line with "bash" to "fish", undoes that, then prints the line
|
|
|
|
|
|
|
|
:g/string/nu | g/num/nu
|
|
|
|
Does NOT print all the lines with `string` or `num`. This prints all the lines
|
|
|
|
with `string` then reprints them if they also have `num`. `:g` only uses a new
|
|
|
|
line to delimit its commands from the next set!
|
|
|
|
|
|
|
|
## Batch editing styles:
|
|
|
|
1. Here-string: For only one command, here-strings are a quick and easy choice
|
|
|
|
```bash
|
|
|
|
for f in $(find ~/); do nvim -Nes <<<"%s/re/p | wq"; done
|
|
|
|
```
|
|
|
|
|
|
|
|
2. Here-ansi-c-string: Allows including c-style escape sequences
|
|
|
|
```bash
|
|
|
|
for f in $(find ~/); do vim -Nes <<< $'%s/re/nu\nwq'; done
|
|
|
|
```
|
|
|
|
|
|
|
|
3. Here-documents: The best choice for quick batch edits
|
|
|
|
```bash
|
|
|
|
for file in $(fd -at type subs_); do
|
|
|
|
nvim -Nes $file <<'DOC'
|
|
|
|
g/^Stl/exe "norm! cStyle: new\<CR>\<esc>"
|
|
|
|
$ | a
|
|
|
|
# ex: ff=unix:
|
|
|
|
.
|
|
|
|
wq
|
|
|
|
DOC
|
|
|
|
done
|
|
|
|
```
|
|
|
|
|
|
|
|
```bash
|
|
|
|
for file in ~/.bash*; do vim -Nes $file <<EOF
|
|
|
|
a
|
|
|
|
# ex: set syntax=bash:ff=unix:
|
|
|
|
.
|
|
|
|
wq
|
|
|
|
EOF
|
|
|
|
done
|
|
|
|
```
|
|
|
|
|
|
|
|
4. Sourced documents: Better for recurring batch edits. Similar to `nvim -S`
|
|
|
|
```bash
|
|
|
|
fd -a subs_ -x ex < change_font
|
|
|
|
fd -a subs_ -x nvim -Nes < change_font
|
|
|
|
|
|
|
|
for f in *.html; do nvim -Nes "$f" < ex_commands; done
|
|
|
|
for f in "$(rg -l homu)"; do nvim -Nes "$f" < ex_commands; done
|
|
|
|
```
|
|
|
|
|
|
|
|
## Best practices
|
|
|
|
Use `-t file` in `fd`, otherwise `ex` may stop when it hits a directory
|
|
|
|
|
|
|
|
Unless you're really confident, always use files to store commands, then first
|
|
|
|
try them out on copies of files you'd like to edit. It's often hard to debug an
|
|
|
|
edit in advance and there's no undo
|
|
|
|
|
|
|
|
## Batch editing manually
|
|
|
|
This isn't really a batch edit... though it's worth mentioning
|
|
|
|
|
|
|
|
```bash
|
|
|
|
fd -t file . -X rg --files-with-matches 'ex:' | xargs -o vim
|
|
|
|
```
|