How to comment on a VIM macro

Can I comment on a macro and play it back.

Example

instead

dddwj 

I would like to comment and execute the following snippet

  dd # Delete line dw # Delete word j # Move to next line 

Some background

We use PICT to generate All Pair testing inputs. Since this is an iterative process, the macro for generating the code needs to be tuned between subsequent runs. It is difficult to change the macro when everything is on the same line, without comment.

The result of PICT might look something like this:

 1 cInstallationX Pu380 2 cInstallationY U400 

which can be converted to test files with a macro

 procedure TWatchIntegrationTests.Test1; begin //***** Setup builder .withInstallation(cInstallationX) .withIsotope(Pu380) .Build; //***** Execute CreateAndCollectWatches; //***** Verify VerifyThat .toDo; end; procedure TWatchIntegrationTests.Test2; begin //***** Setup builder .withInstallation(cInstallationY) .withIsotope(U400) .Build; //***** Execute CreateAndCollectWatches; //***** Verify VerifyThat .toDo; end; 
+4
source share
2 answers

I don't know how to do this with macros, but there are a few options that I can see that can help:

Heavy use of "normal"

This is the closest option to your macro, but not very pleasant: make the saved file like this:

 " Delete line normal dd " Delete word normal dw " Move to next line normal j 

Difficult replacement

This uses regular expressions, but makes these regular expressions well-commented (this is based on your actual example).

 let pattern = '^' " Start of line let pattern .= '\(\d\+\)' " One or more digits (test number) let pattern .= '\s\+' " Space or tab as delimiter let pattern .= '\(\k\+\)' " Installation name let pattern .= '\s\+' " Space or tab as delimiter let pattern .= '\(\a\+\d\+\)' " One or more alphabetic characters, then one or more spaces (isotope) let pattern .= '\s*$' " Any spaces up to the end of the line let result = 'procedure TWatchIntegrationTests.Test\1;\r' let result .= 'begin\r' let result .= ' //***** Setup\r' let result .= ' builder\r' let result .= ' .withInstallation(\2)\r' let result .= ' .withIsotope(\3)\r' let result .= ' .Build;\r' let result .= '\r' let result .= ' //***** Execute\r' let result .= ' CreateAndCollectWatches;\r' let result .= '\r' let result .= ' //***** Verify\r' let result .= ' VerifyThat\r' let result .= ' .toDo;\r' let result .= 'end;\r' exe '%s!' . pattern . '!' . result . '!' 

Paste it into a function

Given that this is getting rather complicated, I will probably do it this way because it gives more options for customization. As I can see, you want to split the line into empty space and use three fields, something like this:

 " A command to make it easier to call " (eg :ConvertPICTData or :'<,'>ConvertPICTData) command! -range=% ConvertPICTData <line1>,<line2>call ConvertPICTData() " Function that does the work function! ConvertPICTData() range " List of lines producing the required template let template = [ \ 'procedure TWatchIntegrationTests.Test{TestNumber};', \ 'begin', \ ' //***** Setup', \ ' builder', \ ' .withInstallation({Installation})', \ ' .withIsotope({Isotope})', \ ' .Build;', \ '', \ ' //***** Execute', \ ' CreateAndCollectWatches;', \ '', \ ' //***** Verify', \ ' VerifyThat', \ ' .toDo;', \ 'end;', \ ''] " For each line in the provided range (default, the whole file) for linenr in range(a:firstline,a:lastline) " Copy the template for this entry let this_entry = template[:] " Get the line and split it on whitespace let line = getline(linenr) let parts = split(line, '\s\+') " Make a dictionary from the entries in the line. " The keys in the dictionary match the bits inside " the { and } in the template. let lookup = {'TestNumber': parts[0], \ 'Installation': parts[1], \ 'Isotope': parts[2]} " Iterate through this copy of the template and " substitute the {..} bits with the contents of " the dictionary for template_line in range(len(this_entry)) let this_entry[template_line] = \ substitute(this_entry[template_line], \ '{\(\k\+\)}', \ '\=lookup[submatch(1)]', 'g') endfor " Add the filled-in template to the end of the range call append(a:lastline, this_entry) endfor " Now remove the original lines exe a:firstline.','.a:lastline.'d' endfunction 

Do it in python

This is a task that is probably easier to do in python:

 import sys template = ''' procedure TWatchIntegrationTests.Test%(TestNumber)s; begin //***** Setup builder .withInstallation(%(Installation)s) .withIsotope(%(Isotope)s) .Build; //***** Execute CreateAndCollectWatches; //***** Verify VerifyThat .toDo; end; ''' input_file = sys.argv[1] output_file = input_file + '.output' keys = ['TestNumber', 'Installation', 'Isotope'] fhIn = open(input_file, 'r') fhOut = open(output_file, 'w') for line in fhIn: parts = line.split(' ') if len(parts) == len(keys): fhOut.write(template % dict(zip(keys, parts))) fhIn.close() fhOut.close() 

To use this, save it as (e.g.) pict_convert.py and run:

 python pict_convert.py input_file.txt 

As a result, it will produce input_file.txt.output .

+11
source

First of all, let me point out that @Al has posted some great solutions, and I suggest you use those, not what I'm going to post. Moreover, this does not work under any circumstances (for reasons that I do not understand).

Having said that, it seems that at least in this case you are doing what you want. It is assumed that <Space> in normal mode is not used to move the cursor. Displays it on :" where " is the comment character for cmline mode. This means that <Space> is the character that starts the comment in this case. A new line at the end stops the comment. # is here to make it clearer that we are dealing with comments. ( ^[ should be entered as one escape character).

 :nmap <Space> :" iHallo wereld^[ # Insert text (in dutch, better change that) Fe # Move backwards to e x # Delete ; # Move to next e ro # Change to o Fa # Move backwards to a re # Change to e A!^[ # Add exclamation mark 
+4
source

Source: https://habr.com/ru/post/1332328/


All Articles