https://dev.to/azrizhaziq/i-ve-been-using-vim-in-total-a-year-and-i-ll-stick-using-it-2e8k
-
It's stand for
change inside word
. -
You also can change w to any char like (,}.
-
Below are some other variation that you can use:
- diw delete inside word
- vi( visual inside bracket
- yiw yank inside word
- dis delete inside sentence.
- dip delete inside paragraph.
- ci3w change inside 3 words
Below I have a word inside bracket, and I would like to change it to my name:
# before Lorem ipsum dolor sit amet, (inven<cursor here>tore) adipisicing elit. # type: ciwazrizhaziq # after Lorem ipsum dolor sit amet, (azrizhaziq) adipisicing elit.
-
It's stand for
change around word
. -
Most of the points here is the same as point number 1.
-
For the variations of
around
, just change i to a:- daw delete around word
- va( visual around bracket
- Given below scenario you want to change around bracket to your name
# before Lorem ipsum dolor sit amet, (inven<cursor here>tore) adipisicing elit. # type: ca(azrizhaziq<esc> # after Lorem ipsum dolor sit amet, azrizhaziq adipisicing elit.
- Change this to implicit arrow function (remove return keyword and braces)
// before const average = (...numbers: number[]): number => { return /* <cursor here> */ numbers.reduce((acc, n) => acc + n, 0) / numbers.length } // type: Dva{p // Delete all right chars until the end, visual around {, and then paste // after const average = (...numbers: number[]): number => numbers.reduce((acc, n) => acc + n, 0) / numbers.length
-
t I'm not sure what it's stand for, f is find. Both used to find a char after cursor in current line.
-
The different is t will put cursor before the search char, while f will put at the char.
-
Now that you know small case
t & f
does, T and K does the opposite. Both will search before cursor in current line.- below example is not properly assign to
string[]
// typescript // before /* <cursor here> */ const names: string[] = ['azriz', 'haziq', 1985, 02, 30, true] // type f1dt]X // find 1, and put the cursor at it, find ] but put cursor before it, and delete a left char // after const names: string[] = ['azriz', 'haziq',]
- If you want to find the next occurrence of searched char in a line use ;
// below you want to change GBP $ to GBP £ // before /* <cursor here> */ const currencies: string[] = ['MYR RM', 'AUD $', 'CNY ¥', 'SGD $', 'GBP $', 'JPY ¥'] // type: f$;;r€ // find $, find next, find next, replace € // after const currencies: string[] = ['MYR RM', 'AUD $', 'CNY ¥', 'SGD $', 'GBP $', 'JPY ¥']
- below example is not properly assign to
- Instead of hit 5 keystrokes with below command its only 3 keystroke
- ZZ save and quit
- ZQ discard changes and quit
- Used to fold codes. If you have 1k LOC(line of code), this will be handy.
- You can focus on which chunk of code to focus.
- This command it's not in both video as I remember.
-
It join the whole line below current cursor and append to current cursor.
-
Kinda hard to put in words, let's see in action
// before /* <cursor here> */ var json = { name: 'azriz haziq', // see this line dob: '30 02 1985', hobbies: ['smash keyboard', 'press esc key'] } // type: J // after var json = { name: 'azriz haziq', dob: '30 02 1985', hobbies: ['smash keyboard', 'press esc key'] } // type: JJJ or 3J // after var json = { name: 'azriz haziq', dob: '30 02 1985', hobbies: ['smash keyboard', 'press esc key'] }
- I had a hard time at first how to differentiate certain key action. Some perform at before and sometime at after.
- So how I remember it usually, capital char will perform action before current cursor/char/line.
- O will add a new line before current line, while o will add new line after current line.
- I will move the cursor at beginning of current line, while i will change to insert mode and put the cursor before char.
- Same goes to P paste before a char, p paste after char.
- After you search a term, and then you can hit N to find previous, n and find after.
- But not all the case is like this, G, A, C, D perform differently.
-
Killer feature in vim.
-
Records all your keystrokes, and then you can replay the keystroke later.
-
AFAIK(as far as I know), you can't do this in any normal GUI editor like VS Code, Webstorm, notepad++, etc.
-
Macros only uses 2 keys which is q, and @.
-
The sequence to start macro is like this: qd...q.
- first q is to start recording, while the last q is stop recording.
- d save macro into 'd'. You can save this to any char.
...
stand for any command you want to record.- To run the macro that you just save in d, press it with @d.
-
Let's start with first example:
-
Below is CSP response header from
twitter.com
-
It's quite hard to read since it is a one line of string
-
So let chunk it up with macro.
# before <cursor here> connect-src 'self' blob: https://*.giphy.com https://*.pscp.tv https://*.video.pscp.tv https://*.twimg.com https://api.twitter.com https://api-stream.twitter.com https://ads-api.twitter.com https://aa.twitter.com https://caps.twitter.com https://media.riffsy.com https://pay.twitter.com https://sentry.io https://ton.twitter.com https://twitter.com https://upload.twitter.com https://www.google-analytics.com https://app.link https://api2.branch.io https://bnc.lt wss://*.pscp.tv https://vmap.snappytv.com https://vmapstage.snappytv.com https://vmaprel.snappytv.com https://vmap.grabyo.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net ; default-src 'self'; form-action 'self' https://twitter.com https://*.twitter.com; font-src 'self' https://*.twimg.com; frame-src 'self' https://twitter.com https://mobile.twitter.com https://pay.twitter.com https://cards-frame.twitter.com https://accounts.google.com/; img-src 'self' blob: data: https://*.cdn.twitter.com https://ton.twitter.com https://*.twimg.com https://analytics.twitter.com https://cm.g.doubleclick.net https://www.google-analytics.com https://www.periscope.tv https://www.pscp.tv https://media.riffsy.com https://*.giphy.com https://*.pscp.tv https://*.periscope.tv https://prod-periscope-profile.s3-us-west-2.amazonaws.com https://platform-lookaside.fbsbx.com https://scontent.xx.fbcdn.net https://scontent-sea1-1.xx.fbcdn.net https://*.googleusercontent.com; manifest-src 'self'; media-src 'self' blob: https://twitter.com https://*.twimg.com https://*.vine.co https://*.pscp.tv https://*.video.pscp.tv https://*.giphy.com https://media.riffsy.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net; object-src 'none'; script-src 'self' 'unsafe-inline' https://*.twimg.com https://www.google-analytics.com https://twitter.com https://app.link https://apis.google.com/js/platform.js https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js 'nonce-YmY0NTUzYjUtODYyYy00OGI0LTliZjctOTU4MDYxY2JkMjA2'; style-src 'self' 'unsafe-inline' https://*.twimg.com; worker-src 'self' blob:; report-uri https://twitter.com/i/csp_report?a=O5RXE===&ro=false # type below # qd # start record and save to d # f;a<enter><esc> # find ;, enter insert mode, enter and escape # q # stop recording # @d # run once the record command # @@ # run previous macros command # 5@d # run command 5 time connect-src 'self' blob: https://*.giphy.com https://*.pscp.tv https://*.video.pscp.tv https://*.twimg.com https://api.twitter.com https://api-stream.twitter.com https://ads-api.twitter.com https://aa.twitter.com https://caps.twitter.com https://media.riffsy.com https://pay.twitter.com https://sentry.io https://ton.twitter.com https://twitter.com https://upload.twitter.com https://www.google-analytics.com https://app.link https://api2.branch.io https://bnc.lt wss://*.pscp.tv https://vmap.snappytv.com https://vmapstage.snappytv.com https://vmaprel.snappytv.com https://vmap.grabyo.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net ; default-src 'self'; form-action 'self' https://twitter.com https://*.twitter.com; font-src 'self' https://*.twimg.com; frame-src 'self' https://twitter.com https://mobile.twitter.com https://pay.twitter.com https://cards-frame.twitter.com https://accounts.google.com/; img-src 'self' blob: data: https://*.cdn.twitter.com https://ton.twitter.com https://*.twimg.com https://analytics.twitter.com https://cm.g.doubleclick.net https://www.google-analytics.com https://www.periscope.tv https://www.pscp.tv https://media.riffsy.com https://*.giphy.com https://*.pscp.tv https://*.periscope.tv https://prod-periscope-profile.s3-us-west-2.amazonaws.com https://platform-lookaside.fbsbx.com https://scontent.xx.fbcdn.net https://scontent-sea1-1.xx.fbcdn.net https://*.googleusercontent.com; manifest-src 'self'; media-src 'self' blob: https://twitter.com https://*.twimg.com https://*.vine.co https://*.pscp.tv https://*.video.pscp.tv https://*.giphy.com https://media.riffsy.com https://dhdsnappytv-vh.akamaihd.net https://pdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://mdhdsnappytv-vh.akamaihd.net https://mpdhdsnappytv-vh.akamaihd.net https://mmdhdsnappytv-vh.akamaihd.net https://dwo3ckksxlb0v.cloudfront.net; object-src 'none'; script-src 'self' 'unsafe-inline' https://*.twimg.com https://www.google-analytics.com https://twitter.com https://app.link https://apis.google.com/js/platform.js https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js 'nonce-YmY0NTUzYjUtODYyYy00OGI0LTliZjctOTU4MDYxY2JkMjA2'; style-src 'self' 'unsafe-inline' https://*.twimg.com; worker-src 'self' blob:; report-uri https://twitter.com/i/csp_report?a=O5RXE===&ro=false
-
This example its pretty easy and can be done with normal IDE, just search everything
;
, move 1 right and then hit enter, it will have the same result as above.
-
-
Next, an example that is hard to achieve with normal editor.
-
So I have a pretty html here, and I want to change this to correct
<table>
markup. -
Based on the snippet below, you can see children of
<li>
does not have proper structure. Sometime, the children is in same lime with<li>
, and its also have multiline nested children.<!-- before --> <!-- <cursor-here> --> <ul> <li data-testId="1" class="abc"><span><svg /></span></li> <li data-testId="2" class="def"> <p><small>1 + 2 = 3</small><b>3</b></p> </li> <li data-testId="3" class="qwe"> <div> <button type="submit"> <span>Click me</span> </button> </div> </li> <li data-testId="4" class="zxc"><!-- this is empty --></li> <li data-testId="5" class="asd">🧑💻❤️🐈</li> </ul>
-
So what we are going to do is, change
<li>
to<tr>
, and<tr>
children will have${class}-${testId}
<!-- before --> <li data-testId="1" class="abc"><span><svg /></span></li> <!-- after --> <tr data-testId="1" class="abc">abc-1</tr>
-
I believe if we are going to do with normal editor it will take a lot of time. You will be spending hitting
CTRL
/CMD
/SHIFT
/Arrow-right
/Arrow-left
a lot. -
Bear with me as this is going to be very long steps.
<!-- type: <esc> is escape key, <enter> is enter key qq # start recording /data<enter> # search data dit # delete inside tag, I just knew this!! 0w # put cursor at starting line fd # find d dt> # delete up until before >, d also save into clipboard O # create new line above <tr <esc>pa></tr><esc> # please make after you type this line the result will be <tr data-testId="1" class="abc"></td> 0w # put cursor at starting line fcf"lywf>p # find c, find ", move 1 right, yank a word, find >, and paste 0w # put cursor at starting line f"lywt<a-<esc>p # find ", move 1 right, yank a word, find a put cursor before <, paste jdd # go down, delete whole line q # stop recording --> <!-- after running above commands --> <ul> <tr data-testId="1" class="abc">abc-1</tr> <!-- notice this line changed --> <li data-testId="2" class="def"> <p><small>1 + 2 = 3</small><b>3</b></p> </li> <li data-testId="3" class="qwe"> <div> <button type="submit"> <span>Click me</span> </button> </div> </li> <li data-testId="4" class="zxc"><!-- this is empty --></li> <li data-testId="5" class="asd">🧑💻❤️🐈</li> </ul>
<!-- since we save the macro to q, then we can type below --> <!-- type: @q --> <ul> <tr data-testId="1" class="abc">abc-1</tr> <!-- notice this line changed --> <tr data-testId="2" class="def">def-2</tr> <!-- notice this line changed --> <li data-testId="3" class="qwe"> <div> <button type="submit"> <span>Click me</span> </button> </div> </li> <li data-testId="4" class="zxc"><!-- this is empty --></li> <li data-testId="5" class="asd">🧑💻❤️🐈</li> </ul>
-
If you manage to reach here, Congratulation 🎉🎉.
-
Actually, we can shortcut few steps above with substitution
:%s/tr/li/g<enter>
, but I'll leave this for you to discover yourself.
-
-
This is a continuation from point 8.
-
please make sure your last command is @q
-
please note that this is no limited to macros only, you can literally use this . with any kind of command.
<!-- type: .... --> <ul> <tr data-testId="1" class="abc">abc-1</tr> <tr data-testId="2" class="def">def-2</tr> <tr data-testId="3" class="qwe">qwe-3</tr> <tr data-testId="4" class="zxc">zxc-4</tr> <tr data-testId="5" class="asd">asd-5</tr> </ul>
-
Lastly, as you can see it's not a correct html
<table>
markup. Hence, please feel free to change it by putting children of<tr>
to have<td>
, and change<ul>
to<table>
.
- last but not least, vim have its own massive docs. Just try to find any keyword that you want to know more.
:help del
:help v_it
search visual inside tag:
- Bonus tips
- In 1st and 2nd point, we learned
inside
andaround
. - There is another vim plugin which is to handle
surround
. - They have comprehensive examples on their readme, do check it out https://github.com/tpope/vim-surround.