DEV Community

M Bellucci
M Bellucci

Posted on

Vim practical example

The problem

In my job, I had to open in a browser a set of similar URLs.
A sample URL
https://db-provider.com/dashboard.html#database/the-db-name/<element-name>.<lang>.<locale>

In this concrete case, I had to access 6 elements and each one in 6 different languages.
36 different URLs.

Solution

Approach 1
Open the browser and type every URL
This would be reaaaaaaally boring.

Approach 2
Use Vim

Open vim
Write the sample URL
Then replicate this URL 5 times.

yy5p
Enter fullscreen mode Exit fullscreen mode

Now we have one line per element.
alt 1

Write every element name

:1s/<element-name>/element1/ # scoped to line 1 replace <element-name> with element1
:<up_arrow> # show previous executed command
:2s/<element-name>/element2/
Enter fullscreen mode Exit fullscreen mode

Repeat this 4 more times
alt 2

Replicate this block 5 times once per lang-locale

ggy6jG # go to top, yank 6 lines down, go to bottom
qq # start recording in register q
o<esc> # insert blank line
p # paste yanked block
G # go to bottom
q # stop recording
Enter fullscreen mode Exit fullscreen mode

At this point, we have recorded insert a new line and paste yanked block.
Let's repeat this 5 times.

5@q # execute register q 5 times
Enter fullscreen mode Exit fullscreen mode

alt 3

gg # Go to the top
Enter fullscreen mode Exit fullscreen mode

For each block replace first lang-locale with en.us
Create a macro for replacing one line and go to next line to replace.

qq # start recording
:.s/<lang>.<locale>/en.us/ # scoped to current line replace <lang>.<locale> with en.us
7jq # go 7 lines down and stop recording
5@q # repeat this macro 5 more times once per each block.
Enter fullscreen mode Exit fullscreen mode

At this point you should have something like this:
alt 4

Go to the second line and repeat the process with de.de

2gg # go to second line
Enter fullscreen mode Exit fullscreen mode

Repeate the process with pt.BR, es.MX, fr.fr and ja.jp

At this point, you should have something like
alt 5

Remove every empty line.

:g/^$/d # apply d command to lines matching /^$/
Enter fullscreen mode Exit fullscreen mode

We have built every possible URL.
Now we need to open them into default browser.

:%! xargs open # pass all lines as the argument to open command
Enter fullscreen mode Exit fullscreen mode

magic3

The default browser will open all those URLs in different tabs.
(open command is present on mac-os. For Linux you should have a similar)

I hope you've enjoyed.
All comments are welcome!

Top comments (11)

Collapse
 
vlasales profile image
Vlastimil Pospichal • Edited
Bash$ xargs open https://db-provider.com/dashboard.html#database/the-db-name/element{1,2,3,4,5,6}.{en.us,de.de,pt.BR,es.MX,fr.fr,ja.jp}
Collapse
 
delbetu profile image
M Bellucci • Edited

Oh, this is awesome
That would solve the problem faster!

Collapse
 
jerpint profile image
jerpint

Why not use a simple python script for this?

Seems like the second someone decides to add/remove a country or number of elements, you have to start all over again. Not saying this isn't cool, but seems overkill.

For example:


langs = ['en','de',...]
elems = [1,2,...]


for elem in elems:
    for lang in langs:
        print(base_url + '/element' + str(elem) + '/' + lang)
    print('')
Collapse
 
indrora profile image
Morgan Gangwere 🔹

A cleaner way:

import itertools

langs=('en','de','jp','fr')
nums=(1,2,3,4,5,6)

urls = map( lambda k: "http://provider.lol/some-path/{0}#lang/{1}".format(*k),
   itertools.product(nums,langs) )
Collapse
 
delbetu profile image
M Bellucci • Edited

The goal is practice new vim commands, the problem is not important in the context of this post.

Collapse
 
chrboe profile image
Christoph Böhmwalder

For the record, on most Linux distributions the tool to use is xdg-open

Collapse
 
moopet profile image
Ben Sinclair

In your example, you end up with the same five URLs repeated. E.g. line offset 40 is identical to line offset 33 in your last Vim screenshot. I'm not sure if this means you left off the final step?

Adding a blank line and then removing all the blank lines makes sense for understanding what you're doing (I do this sort of thing all the time) but for the purpose of this demo it's just extra work. I think you could improve the post by explaining that it's just done to make the screen of text easier to follow.

I know your post is demonstrating a bunch of different techniques, but you did ask for comments, so I'm going off on an efficiency jaunt.

The step of replicating the block could be reduced to simply adding a blank line at the end and then copy-pasting the whole thing, rather than using another macro recording:

Go<esc> # add a blank line at the end of the file
Ygg # copy from the end to the top
5P # paste the block (including its empty line) 5 times

You can also use 2G to go to the second line instead of 2gg if you want fewer keypresses but are ok with chords. Likewise Y5 instead of yy5.

Collapse
 
ronalterde profile image
Steffen Ronalter

Nice use case!

I‘m just wondering whether we could utilize C-a for increasing numbers from within insert mode.

By the way, is there a typo in the numbering?

Collapse
 
delbetu profile image
M Bellucci

Yes could be used for increasing numbers
And yes there is a typo on numbering, good catch!

Collapse
 
hoffmann profile image
Peter Hoffmann

Where is this function in sublime?

Collapse
 
delbetu profile image
M Bellucci

Lol I bet that sublime also has a fast way of doing this same job.

One thing that I noticed with vim is that you never stop learning so your editing skills are leveling up all the time, which makes you think different while programming, making it more enjoyable.