Search code examples
vimnotepad++

how to script copy/paste within text file


how i can create macro/script that would put information i need for code in following syntax

switch n

case 1

    country=af
    coutry_word=Afghanistan
    country_flag=https://imgur.com/yRbLG3B
    country_code_number=+324
    
    break;

case 2
    ...

I'm doing this in notepad++, i was able to automate create everything except adding unique information for all these variables. (there are 240 of these case -s , so it means i would have to manually put 960 times into each of one of these variables)

But i already have in order information that needs to be putted into variables, and that (for easier scripting) is put right into same file as this code. I just need to add them correspondly (and list is sorted, so it just need to be put into variables in that sorted way)

Here's what i mean

    https://imgur.com/y9G1Nim
    https://imgur.com/xmU8rwh
    https://imgur.com/wfcLo9a
    https://imgur.com/wdRUl1Z
    https://imgur.com/vxnPnl3
    https://imgur.com/uNhaTYi
...

Afghanistan 
Åland Islands
Algeria 
Andorra
Antarctica
Argentina
Australia
...

TPE
AFG
ALB
ALG
ASA
AND
ANG
AIA
ROS
ATG
ARG
...

+123
+458
+554
+588
+585
+584
...

and they are within same file as this written code with macros in notepad++

i managed to get only this much (with NP++ macros)

switch n
    
    case 1
    
        country=
        coutry_word=
        country_flag=
        country_code_number=
        
        break;
    
    case 2
        ...

so only that remains is to put these ordered text into these variables. i tried with macro, but it doesn't continue to the end of file.

If NP++ can't, i'm also comfortable in Vim


Solution

  • Here is how I would approach the problem, in Vim, on my Unix-like system:

    1. Clean up the data so that there is no leading or trailing whitespace:

      :%left
      :keeppattern [range]s/\s\+$//
      
    2. Select each block of data and write it into its own file, with the appropriate prefix:

      1. Place the cursor on the "country flags" block.
      2. Visually select the block with vip.
      3. Write the block to a file with :'<,'>!sed 's/^/country_flag=/' >> country_flag.txt.

      Repeat for the other blocks in their corresponding files:

      country_word.txt
      country.txt
      country_code_number.txt
      

      At this point, we should have the following:

      $ cat country.txt
      country=TPE
      country=AFG
      country=ALB
      country=ALG
      country=ASA
      country=AND
      
      $ cat country_code_number.txt
      country_code_number=+123
      country_code_number=+458
      country_code_number=+554
      country_code_number=+588
      country_code_number=+585
      country_code_number=+584
      
      $ cat country_flag.txt
      country_flag=https://imgur.com/y9G1Nim
      country_flag=https://imgur.com/xmU8rwh
      country_flag=https://imgur.com/wfcLo9a
      country_flag=https://imgur.com/wdRUl1Z
      country_flag=https://imgur.com/vxnPnl3
      country_flag=https://imgur.com/uNhaTYi
      
      $ cat country_word.txt
      country_word=Afghanistan
      country_word=Åland Islands
      country_word=Algeria
      country_word=Andorra
      country_word=Antarctica
      country_word=Argentina
      
    3. Interleave those files and insert the result in the buffer:

      :read !paste -d '\n' country*
      

      Which should give us the following:

      country=TPE
      country_code_number=+123
      country_flag=https://imgur.com/y9G1Nim
      country_word=Afghanistan
      country=AFG
      country_code_number=+458
      country_flag=https://imgur.com/xmU8rwh
      country_word=Åland Islands
      country=ALB
      country_code_number=+554
      country_flag=https://imgur.com/wfcLo9a
      country_word=Algeria
      country=ALG
      country_code_number=+588
      country_flag=https://imgur.com/wdRUl1Z
      country_word=Andorra
      country=ASA
      country_code_number=+585
      country_flag=https://imgur.com/vxnPnl3
      country_word=Antarctica
      country=AND
      country_code_number=+584
      country_flag=https://imgur.com/uNhaTYi
      country_word=Argentina
      
    4. All that is left is really to turn all that into case blocks.

      We could try to do it with a nifty one-liner but it is a lot easier and time-efficient to split the task into simpler subtasks.

      1. Add case n above each block as well as an empty line:

        :let i = 1 | g/country=/put!=['','case '.i] | let i += 1
        

        Which gives us the following:

        case 1
        country=TPE
        country_code_number=+123
        country_flag=https://imgur.com/y9G1Nim
        country_word=Afghanistan
        
        case 2
        country=AFG
        country_code_number=+458
        country_flag=https://imgur.com/xmU8rwh
        country_word=Åland Islands
        
        case 3
        country=ALB
        country_code_number=+554
        country_flag=https://imgur.com/wfcLo9a
        country_word=Algeria
        
        case 4
        country=ALG
        country_code_number=+588
        country_flag=https://imgur.com/wdRUl1Z
        country_word=Andorra
        
        case 5
        country=ASA
        country_code_number=+585
        country_flag=https://imgur.com/vxnPnl3
        country_word=Antarctica
        
        case 6
        country=AND
        country_code_number=+584
        country_flag=https://imgur.com/uNhaTYi
        country_word=Argentina
        
      2. Add the break statement at the end of each block:

        :g/country_word/put='break;'
        

        which gives us the following:

        case 1
        country=TPE
        country_code_number=+123
        country_flag=https://imgur.com/y9G1Nim
        country_word=Afghanistan
        break;
        
        case 2
        country=AFG
        country_code_number=+458
        country_flag=https://imgur.com/xmU8rwh
        country_word=Åland Islands
        break;
        
        case 3
        country=ALB
        country_code_number=+554
        country_flag=https://imgur.com/wfcLo9a
        country_word=Algeria
        break;
        
        case 4
        country=ALG
        country_code_number=+588
        country_flag=https://imgur.com/wdRUl1Z
        country_word=Andorra
        break;
        
        case 5
        country=ASA
        country_code_number=+585
        country_flag=https://imgur.com/vxnPnl3
        country_word=Antarctica
        break;
        
        case 6
        country=AND
        country_code_number=+584
        country_flag=https://imgur.com/uNhaTYi
        country_word=Argentina
        break;
        
      3. Last step, indent the country* lines:

        :g/^country/>
        

        Which should give us the following:

        case 1
          country=TPE
          country_code_number=+123
          country_flag=https://imgur.com/y9G1Nim
          country_word=Afghanistan
        break;
        
        case 2
          country=AFG
          country_code_number=+458
          country_flag=https://imgur.com/xmU8rwh
          country_word=Åland Islands
        break;
        
        case 3
          country=ALB
          country_code_number=+554
          country_flag=https://imgur.com/wfcLo9a
          country_word=Algeria
        break;
        
        case 4
          country=ALG
          country_code_number=+588
          country_flag=https://imgur.com/wdRUl1Z
          country_word=Andorra
        break;
        
        case 5
          country=ASA
          country_code_number=+585
          country_flag=https://imgur.com/vxnPnl3
          country_word=Antarctica
        break;
        
        case 6
          country=AND
          country_code_number=+584
          country_flag=https://imgur.com/uNhaTYi
          country_word=Argentina
        break;
        

    All the commands put together:

    :left
    :keepp [range]s/\s\+$
    vip
    :'<,'>!sed 's/^/country_flag=/' >> country_flag.txt
    (move cursor to next block)
    vip
    :<Up>
    <C-f>
    s/flag/word/g
    <CR>
    (move cursor to next block)
    vip
    :<Up>
    <C-f>
    s/_word//g
    <CR>
    (move cursor to next block)
    vip
    :<Up>
    <C-f>
    s/country/&_code_number/g
    <CR>
    :read !paste -d '\n' country*
    :let i = 1 | g/country=/put!=['','case '.i] | let i += 1
    :g/country_word/put='break;'
    :g/^country/>
    

    Now, my non-vimmer self from 2009 would probably have brushed this off as too weird or complicated but, for my vimmer self of early 2022, well… it all flows pretty naturally (except for the paste syntax that I always have to look up) so I guess it's all a matter of experience with one's tools. It took a lot longer for me to verify the result of my commands and write that answer than it took to formulate the answer in my head or than it would have taken to actually do it without having to write an answer at the same time. We are talking about a two-three minutes affair, tops.

    Reference:

    :help :left
    :help :keeppattern
    :help ip
    :help :range
    :help :!
    :help command-line-window
    :help :read
    :help :let
    :help :global
    :help :put
    :help :>
    $ man sed
    $ man paste