Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That's a solid set and will take you far. I did eventually start peppering in a few pattern matching command things that don't require much regex.

* `:g` Global command, executes an Ex command on every line that matches via the pattern `:[range]g/pattern/cmd`

One common use I have for using `:g` is to delete all lines that match or do not match a pattern, like when I've removed an attribute from some data structure and I want to quickly fix all my mock objects to remove the attribute: `:g/pattern/d`

To delete patterns that do not match, useful for debugging: `:g!/pattern/d`

* `:norm` this thing motivated me to use more of the movement commands like `A`, `o`, `D`, `f`, `cw`, and `ci`. Used `:[range]norm cmd`, it acts like each key in the command is run on every line in range. I usually use it with a selection, for example to add a comma to the end of every line in range with `A`, or insert at the end of line: `:norm A,`

Or to delete everything after the first period in a range using `f` to move to character, `l` to move after that character, and `D` to delete everything after cursor: `:norm f.lD`

The best part about learning these two is that they can be used together. If you want to insert `fmt.Println(err)` after every line (using `o`), but only on the lines matching `err != nil`: `:g/err != nil/norm ofmt.Println(err)`

Or two write `time.Now(),` only on lines which have `"created_at":` and only after the colon: `:g/created_at/norm f:lDA time.now(),`

And if you've got hashes with string keys and string values i.e. `"key": "value"`, you can upper case the string values matching `"pattern"` with: `g/pattern/norm 3f"lvi"~` On lines it matches it finds the third double quote with `3f"` then moves a character over with `l`, visual selects inside the double quote with `vi"` and uppercases the selection with `~`.

One regex trick that I end up using with `:g` pattern matching is `^\s*`. When you put it before any pattern then the pattern matches only if it has some amount of whitespace preceding it, and that whitespace extends from the beginning of the line to the start of the pattern. It is good for targeting code indented with whitespace.

Final thought, when you're typing your commands in norm and you've entered insert mode, you can issue the escape command with <Ctrl-v><Esc> which when done right should look like `^[` but will not actually be those characters.

http://vim.wikia.com/wiki/Power_of_g



Very interesting.

>To delete patterns that do not match, useful for debugging: `:g!/pattern/d`

This is something I would normally use something like grep to achieve, nice to know it exists in vim as well.

>* `:norm` this thing motivated me to use more of the movement commands like `A`, `o`, `D`, `f`, `cw`, and `ci`. Used `:[range]norm cmd`, it acts like each key in the command is run on every line in range. I usually use it with a selection, for example to add a comma to the end of every line in range with `A`, or insert at the end of line: `:norm A,`

In this specific case, I would tend to (maybe in gvim) run a replace on `\n` -> `,\n` to achieve this. That's kind of what I'm looking for in terms of string replacement.

The rest is certainly interesting, but for my work flow I like to generally keep things as simple as possible (bad memory). I've never found myself thinking "I wish there were more movement commands" for example.


Thanks for this. Been using vim for 3-4 years and I've never seen the norm command.

This is next months habbit I guess!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: