在括号 Vim 中切换多行或单行

Toggle multiline or single line in parenthesis Vim

编码时 Python 我经常发现自己想要将包含长列表的行或包含多个参数的函数分成多行。

在此之间:

# Example 1
foo(this_is_a_long_variable_1, this_is_a_long_variable_2, this_is_a_long_variable_3, this_is_a_long_variable_4)

# Example 2
def bar():
    return [this_is_a_long_variable_1, this_is_a_long_variable_2, this_is_a_long_variable_3, this_is_a_long_variable_4]

还有这个:

# Example 1
foo(
    this_is_a_long_variable_1,
    this_is_a_long_variable_2,
    this_is_a_long_variable_3,
    this_is_a_long_variable_4,
)

# Example 2
def bar():
    return [
        this_is_a_long_variable_1,
        this_is_a_long_variable_2,
        this_is_a_long_variable_3,
        this_is_a_long_variable_4,
    ]

最好的方法是什么?

据我所知,我想将一个特殊操作连接到 object-select 并且这些操作本身应该相对可以通过正则表达式替换为一些特殊处理,即在结束前添加一个额外的逗号阻止。

但我以前从未真正用 Vim 做过这么高级的事情,也不知道从哪里开始。

第一,低级件…

  1. 把括号里的内容改成这样:

    foo(
    )
    

    与:

    ci(<CR><Esc>
    

    将光标留在 )

  2. 将下列表达式的结果放在光标上一行:

    :put!=getreg('\"')->split(', *')->map('v:val . \",\"')<CR>
    

    表达式详细:

    • getreg('\"')获取默认寄存器的内容,这里原来是括号之间的内容,
    • split(', *') 将其拆分为单独的参数,
    • map('v:val . \",\"') 为每个项目附加一个 ,

    注意:上面的命令使用了新的“方法”符号。在旧的 Vims 中,它应该是这样的:

    :put!=map(split(getreg('\"'), ', *'), 'v:val . \",\"')
    
  3. 格式化我们刚刚放的内容:

    ='[
    

第二个,放在一起...

现在我们有了一个可行的解决方案,我们可能希望通过简单的视觉模式映射让它在手指上更容易一些,这是有道理的,因为它将保持简单和不可知:

xnoremap <key> c<CR><Esc><Cmd>put!=getreg('\"')->split(', *')->map('v:val . \",\"')<CR>='[

我们可以这样使用:

vi(<key>
vi[<key>
vip<key>

等等

注意:上面的映射使用了新的 <Cmd>“特殊文本”。在旧的 Vims 中,它应该是这样的:

xnoremap <key> c<CR><Esc>:<C-u>put!=map(split(getreg('\"'), ', *'), 'v:val . \",\"')<CR>='[

为了补充 romainl 的回答,我将给出反向命令,以便能够在单行和多行之间切换。

单行 -> 多行:

xnoremap <Key1> c<CR><Esc>:put!=map(split(getreg('\"'), ', *'), 'v:val . \",\"')<CR>='[

多行 -> 单行

xnoremap <Key2> :s/\%V\n\s*\(.*,\)$/ / <Bar> s/\%V\(.*\),\s\n// <CR>:noh<CR>

用法:

va(<Key2>

解释:

  • :s/match/replace/flags 是遵循正则表达式匹配的搜索和替换
  • \%V是只在选择中搜索
  • s/\%V\n\s*\(.*,\)$// 对于末尾带有逗号的行,将其移至前一行并删除多余的白色space
  • <Bar>这是一个管道
  • s/\%V\(.*\),\s\n// 删除多余的最后一个逗号,space 和换行符

但是请注意,两者都不能处理复杂的情况,例如包含其他列表的列表。