我经常将文本行转换为数组。例如,这个:
Monday
Tuesday
Wednesday
变为:
[
'Monday',
'Tuesday',
'Wednesday',
]
我可以制作一张地图,更改其中一行(例如Monday
到'Monday',
),如下所示:
:nnoremap gsa ^i'<Esc>A,
我想要做的是让该命令采用移动或文本对象,以便我可以像gsaip
或gsip3j
那样执行它。
我该如何做到这一点?
答案 0 :(得分:3)
您可以'operatorfunc'
与g@
一起使用带有地图的地图
运动。帮助给出了完整的解释和示例
:map-operator
主题。基本上你设置你想要的功能
在您的地图中调用并使用g@
。 Vim将等待一个动作然后设置
标记'[
和']
并调用您的函数。
在你的功能中,你可以发挥创意,在这里我只是做了一个快速 如何将此原则应用于您所需的示例。
:nnoremap <silent> gsa :set opfunc=TransformToArray<cr>g@
function! TransformToArray(type)
if a:type == 'line'
let s=line("'[") " saving beginning mark
']s/\(\s*\).*\zs/\r\1]
exec s ",']-1s/\\s*\\zs.*/ '&',"
exec s 's/\(\s*\)\zs\ze /[\r\1'
elseif a:type == 'char'
" ...
endif
endfunction
答案 1 :(得分:1)
将其放入.vimrc
文件中:
vnoremap <silent> gsa :call Brackets()<CR>
function! Brackets()
execute "normal! I'"
if line(".") == a:lastline
execute "normal! A'\<cr>]"
execute a:firstline."s:^:[\r:"
else
execute "normal! A',"
endif
endfunction
选择所需的可视线条,例如vip
,然后按gsa
。
答案 2 :(得分:0)
准确地说,您似乎希望将映射应用于动画或文本对象所涵盖的每条线。
您可以通过可视模式建立此类范围:vip
或v2j
。然后,您可以使用:normal gsa
(键入;如果从可视模式进入命令行模式,Vim会自动插入所选范围(:'<,'>
),以将自定义映射应用于每个行(光标)根据{{1}})列在每一行的第一列。
答案 3 :(得分:0)
如果你真的想在最后一个项目之后添加一个逗号,我会这样做,以便保持寄存器不变。
function! s:to_list() range abort
let words = getline(a:firstline, a:lastline)
exe a:firstline.','.a:lastline.'d _' " remove the "_" to fill the unnamed register
let lines = ['['] + map(words, '" ".string(v:val).","') + [']']
call append(a:firstline-1, lines)
endfunction
command! -nargs=0 -range=% ToList <line1>,<line2>call s:to_list()
为了摆脱最后两行,我已编辑map()
结果的最后一项或使用join()
:
let lines = "[\n" . join(map(words, '" ".string(v:val)'), ",\n") . "\n]"
put!=lines