我试图交织三组文本行.例如来自
a
a
a
b
b
b
c
c
c
Run Code Online (Sandbox Code Playgroud)
至
a
b
c
a
b
c
a
b
c
Run Code Online (Sandbox Code Playgroud)
有没有一种有效的方法呢?
在我的~/.vim文件深处的某处,我有一个:Interleave命令(附在下面).没有任何参数:Interleave只会正常交错.有两个参数,它将如何指定将多少组合在一起.例如,:Interleave 2 1从顶部开始排2行,然后从底部开始与1行交错.
现在来解决你的问题
:1,/c/-1Interleave
:Interleave 2 1
Run Code Online (Sandbox Code Playgroud)
1,/c/-1范围从第一行开始,结束第一行,与第一行匹配c.:1,/c/-1Interleave基本上交织了a's b' 和's'的组:Interleave 2 1 这个范围是整个文件.:Interleave 2 1将混合组a和bs 组交织在一起c.混合比为2比1.该:Interleave代码如下.
command! -bar -nargs=* -range=% Interleave :<line1>,<line2>call Interleave(<f-args>)
fun! Interleave(...) range
if a:0 == 0
let x = 1
let y = 1
elseif a:0 == 1
let x = a:1
let y = a:1
elseif a:0 == 2
let x = a:1
let y = a:2
elseif a:0 > 2
echohl WarningMsg
echo "Argument Error: can have at most 2 arguments"
echohl None
return
endif
let i = a:firstline + x - 1
let total = a:lastline - a:firstline + 1
let j = total / (x + y) * x + a:firstline
while j < a:lastline
let range = y > 1 ? j . ',' . (j+y) : j
silent exe range . 'move ' . i
let i += y + x
let j += y
endwhile
endfun
Run Code Online (Sandbox Code Playgroud)
这是一个“oneliner”(几乎),但是您必须为每个唯一的行重做它-1,在您的示例中重做2次。也许没有用,但我认为这是一个很好的练习,可以进一步了解 VIM 中的模式。只要整条线是唯一的(例如mno和mnp是两条唯一的线),它就可以处理所有类型的线。
首先确保这一点(并且没有映射到/任何内容或行中的其他任何内容):
:set nowrapscan
Run Code Online (Sandbox Code Playgroud)
然后映射例如这些(应该是递归的,而不是 nnoremap):
<C-R>并且<CR>应该按字面输入。
\v在模式中意味着“非常神奇”,@!消极的前瞻。\2使用第二个括号中的内容。
:nmap ,. "xy$/\v^<C-R>x$<CR>:/\v^(<C-R>x)@!(.*)$\n(\2)$/m-<CR>j,.
:nmap ,, gg,.
Run Code Online (Sandbox Code Playgroud)
然后执行,,任意次数,在您的示例中为 2 次。一为所有bs,一为所有cs。
编辑:映射的解释。我将使用问题中的示例,就好像它已经使用此映射运行过一次一样。
运行一圈后:
1. a
2. b
3. a
4. b
5. a
6. b
7. c
8. c
9. c
Run Code Online (Sandbox Code Playgroud)
然后光标位于最后a(第 5 行),当输入 时,,,它首先返回到第一行,然后运行映射 for ,.,该映射正在执行以下操作:
"xy$ # yanks current line (line 1) to reg. "x" ("a") "
/\v^<C-R>x$<CR> # finds next line matching reg. "x" ("a" at line 3)
:/\v^(<C-R>x)@!(.*)$\n(\2)$/m-<CR>
# finds next line that have a copy under it ("c" in line 7) and moves that line
# to current line (to line 3, if no "-" #after "m" it's pasted after current line)
# Parts in the pattern:
- ^(<C-R>x)@!(.*)$ # matches next line that don't start with what's in reg. "x"
- \n(\2)$ # ...and followed by newline and same line again ("c\nc")
- m-<CR> # inserts found line at current line (line 3)
j # down one line (to line 4, where second "a" now is)
,. # does all again (recursive), this time finding "c" in line 8
...
,. # gives error since there are no more repeated lines,
# and the "looping" breaks.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1051 次 |
| 最近记录: |