diff --git a/content/posts/vim-for-hackers.md b/content/posts/vim-for-hackers.md new file mode 100644 index 0000000..0e0d614 --- /dev/null +++ b/content/posts/vim-for-hackers.md @@ -0,0 +1,180 @@ +--- +title: "Vim for Hackers" +date: 2024-05-01T11:00:48+02:00 +description: "Advanced hacking skills with VIM to give you superpowers" +tags: +- tutorial +- til +- tips +--- + +{{< lead >}} +`vim` is a double edged sword. Use it properly and you'll see the benefits, +don't use it properly and it's just going to cause more pain and sorrow. +{{< /lead >}} + +# How to add text at the end of each line + +Use-case: assume you just copied a whole column of text and just want to +append a comma at the end + +```vim +:%s/$/,/ +``` + +```vim +:'<,'>s/$/,/ +``` + + +{{< alert "lightbulb" >}} +`'<,'>` assumes you selected text aka _visual select_ +{{< /alert >}} + +```vim +:'<,'>norm A, +``` + +# Remove lines that (do not) contain a specific word + +Use-case: you created a Kubernetes Secret via `kubectl create secret` and want +to remove all lines containing `creationTimestamp: null` + +```vim +:g /word/d +``` + +The reverse of this (meaning, remove lines that **don't contain** specific +word) would look like this + +```vim +:g!/word/d +``` + +# delete all blank lines + +```vim +:g/^$/d +``` + +# copy file contents to clipboard + +```vim +:%w !pbcopy +``` + +# replace text matching X with Y + +with confirmation + +```vim +:%s/replacethis/withthis/gc +``` + +without confirmation + +```vim +:%s/replacethis/withthis/g +``` + +# move existing window to existing tab + +As a window is just a viewport into a loaded buffer, you have to: + +1. Note the buffer number displayed in the current window. +2. `:close!` the window. +3. Switch to the existing target tab page. +4. `:sbuffer` the buffer number to re-open it. + +# save and restore multiple different sessions + +Use-case: assume you just upgraded vim or Terminal app and just want to +restart them + +```vim +:mksession ~/mysession.vim +``` + +source session to restore everything back + +```vim +:source ~/mysession.vim +``` + +open vim with the session + +```vim +$ vim -S ~/mysession.vim +``` + +# open filename under cursor like gf, but in a new tab + +- gf - Edit existing file under cursor in same window +- C-W f - Edit existing file under cursor in split window +- C-W C-F - Edit existing file under cursor in split window +- C-W gf - Edit existing file under cursor in new tabpage + +# make a new directory or file in `netrw`, vim's file explorer + +If you are in the file explorer mode, you can use: + +- `d` for creating a directory +- `%` for creating a new file + +You can get into the explorer mode with issuing a command `:Sexplore` or `:Vexplore` + +There is no need to call external commands with `!` + +# find and replace all instances of specific string in multiple files in vim + +The general workflow is: + +1. Search for your pattern across the project. +2. Operate on each match (safer, slower) or on each file with matches (riskier, faster). +3. Write your changes. + +The first step can be done with any command that populates the quickfix list: `:help :vimgrep`, `:help :grep`, something from a third-party plugin, etc. + +Taking `:grep` as an example: + +``` +:grep foo **/*.js + +``` + +will populate the quickfix list with an entry for every `foo` found in `*.js` files in the current directory and subcategories. You can see the list with `:cwindow`. + +The second step involves `:help :cdo` or `:help :cfdo`: + +``` +:cdo s/foo/bar/gc + +``` + +which will substitute every `foo` with `bar` on each line in the quickfix list and ask for confirmation. With `:cfdo` it would look like that: + +``` +:cfdo %s/foo/bar/gc + +``` + +If you are super confident, you can drop the `c` at the end. See `:help :s_flags`. + +The third step involves `:help :update`: + +``` +:cfdo update + +``` + +which will write every file in the quickfix list to disk if they have been changed. + +In short: + +``` +:gr foo **/*.js +:cdo s/foo/bar/gc +:cfdo up + +``` +