我有一个具有以下基本格式的文件:
>> (N0) "string X0"
...
>> (N1) "string X1"
...
<< (N1+2) "string X1"
...
<< (N0+2) "string X0"
正如您所看到的,它是一个嵌套的构造。数字N0,N1,N *周围没有括号。这些可以像任何东西一样嵌套。字符串在引号内但它们没有编号,只是相同。嵌套字符串可以与外部字符串相同。
我打算制作一个宏来尝试缩进所有这些嵌套项目,以便更容易分析数据,但我不知道如何搜索N + 2.
如果我不能在vim中这样做,我只需编写一个perl脚本,但我想知道是否可以在vim中完成。
我在这里添加了一个更具体的输入和输出示例,虽然这个数据集不再重要,我更感兴趣的是找到如何找到下一个出现的找到的数字增加2:
>> 5 "foo" ... >> 2 "bar" ... << 4 "bar" ... << 7 "foo"
>> 5 "foo" ... >> 2 "bar" ... << 4 "bar" ... << 7 "foo"
所以基本上,我想找一个数字,比如5
,然后找到下一个5+2
,即7
。然后我就可以缩进它们之间的界限。
有什么想法吗?感谢。
答案 0 :(得分:2)
从您的示例中,我注意到您的>>
和<<
已配对。所以我假设在每一对中,
closing number = starting number +2
我只是没有检查号码。只需按<< and >>
计算缩进量,看看它是否符合您的需求。
首先获得此功能:
fun! GetIndent(line_num)
let lnum = a:line_num
if lnum == 0
return 0
endif
let sp = '^\s*>> \d'
let ep = '^\s*<< \d'
let l = getline(a:line_num)
if l =~ sp
while lnum > 0
let lnum = prevnonblank(lnum-1)
if getline(lnum) =~ sp
return indent(lnum)+&tabstop
break
endif
endwhile
endif
if l =~ ep
while lnum > 0
let lnum = prevnonblank(lnum-1)
if getline(lnum) =~ sp
return indent(lnum)
break
endif
if getline(lnum) =~ ep
return indent(lnum) -&tabstop
break
endif
endwhile
endif
return indent(a:line_num - 1)
endf
然后在文件的缓冲区中执行:
:setlocal indentexpr=GetIndent(v:lnum)
现在,您可以使用gg=G
格式化文字。例如:
这个
>> 1 "foo"
...
>> 2 "bar"
...
>> 3 "bar"
...
>> 4 "bar"
...
>> 5 "bar"
...
>> 6 "bar"
...
<< 6 "bar"
...
<< 5 "bar"
...
<< 4 "bar"
...
<< 3 "bar"
...
<< 2 "bar"
...
<< 1 "foo"
<{1>}之后将成为:
gg=G
正如我所说,我没有检查你的文字中的数字。我使用数字1-6作为开始和结束对只是为了以清晰的方式显示缩进。它可能是>> 1 "foo"
...
>> 2 "bar"
...
>> 3 "bar"
...
>> 4 "bar"
...
>> 5 "bar"
...
>> 6 "bar"
...
<< 6 "bar"
...
<< 5 "bar"
...
<< 4 "bar"
...
<< 3 "bar"
...
<< 2 "bar"
...
<< 1 "foo"
。如果我的功能不能满足您的要求,则需要检查数字+2。你可以从匹配的行中提取数字并进行检查。我的功能应该让你开始。
正则表达式不是进行数学计算的正确方法。基本上来说,正则表达式(单独)不能这样做。 - 肯特5月6日9:29