如何评论VIM宏

Lie*_*ers 4 vim macros editor

是否可以评论宏并重放它.

代替

  dddwj
Run Code Online (Sandbox Code Playgroud)

我想评论并执行以下片段

  dd # Delete line
  dw # Delete word
  j  # Move to next line
Run Code Online (Sandbox Code Playgroud)

一些背景

我们使用PICT生成测试用例输入(全对测试).由于这是一个迭代过程,因此生成代码的宏需要在后续运行之间进行调整.当一切都在一行上而没有注释时,很难修改宏.

PICT运行的输出可能是这样的:

1 cInstallationX Pu380
2 cInstallationY U400
Run Code Online (Sandbox Code Playgroud)

可以用宏转换成测试用例

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;
Run Code Online (Sandbox Code Playgroud)

DrA*_*rAl 11

我不知道用宏来做这个的好方法,但我可以看到一些可能有帮助的选项:

大量使用'正常'

这是最接近你的宏选项,但不是很好:让你保存的文件看起来像这样:

" Delete line
normal dd
" Delete word
normal dw
" Move to next line
normal j
Run Code Online (Sandbox Code Playgroud)

复杂的替代

这使用了正则表达式,但是这些正则表达式得到了很好的评论(这是基于你的实际例子).

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 . '!'
Run Code Online (Sandbox Code Playgroud)

把它贴在一个功能中

鉴于这变得相当复杂,我可能会这样做,因为它提供了更多的调整空间.在我看来,你想在白色空间上分割线并使用三个字段,所以像这样:

" A command to make it easier to call
" (e.g. :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
Run Code Online (Sandbox Code Playgroud)

在python中做它

这是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()
Run Code Online (Sandbox Code Playgroud)

要使用它,请将其另存为(例如)pict_convert.py并运行:

python pict_convert.py input_file.txt
Run Code Online (Sandbox Code Playgroud)

它会产生input_file.txt.output结果.