【问题标题】:Creating a list or tuple out of one word-per-line in vim在 vim 中每行一个单词创建一个列表或元组
【发布时间】:2020-05-28 16:09:56
【问题描述】:

我经常遇到以下模式,我必须将一堆项目(通常在 excel 中)复制粘贴到 SQL 查询之类的东西中,通常最简单的方法是将数据复制粘贴到 vim然后在其上运行宏/命令以对其进行格式化。以下是输入数据的示例:

这对我来说涉及三个步骤:

  • 删除空行::g!/\S/d
  • 在其周围添加引号和, 分隔符::% s/\v(\S+)/"\1",
  • 将其放在一行中并添加一个换行符[...](...)ggVG(全选)、J(压缩全)、0i(CTRL-o$)

有没有一种方法可以将所有这些都放入一个函数或宏中,或者我可以采用上述输入并输入一些键盘快捷键的最佳方法是什么,例如 s 并以上述方式格式化所有内容?

虽然这看起来有点矫枉过正,但我​​可以在 TextMate 这样可以使用多光标的编辑器中轻松快速地完成这项工作(无需真正思考)。

【问题讨论】:

    标签: vim


    【解决方案1】:

    我最初的反应是从

    开始
    echo '['.join(map(filter(getline(1, '$'), '!empty(v:val)'), 'string(v:val)'),', ').']'
    

    可以变成什么

    %d
    call append(line('.')-1, '['.join(map(filter(getreg('"', 1, 1), '!empty(v:val)'), '"\"".v:val."\""'),', ').']')
    

    从而进入命令

    command! -range=% ToTuple 
    \ <line1>,<line2>d
    \|call append(<line1>-1, '['.join(map(filter(getreg('"', 1, 1), '!empty(v:val)'), '"\"".v:val."\""'),', ').']')
    

    注意

    echo string(filter(getreg('"', 1, 1), '!empty(v:val)')
    

    会简单得多,但是会使用单引号而不是双引号——这可能会对某些语言产生很大影响。

    【讨论】:

      【解决方案2】:

      那么问题是什么?把这些东西放到你的 vimrc 中就完成了。

      function s:do_stuff() abort
          %join
          s/\S\+/"&",/g
          s/^/(
          s/$/)
      endfunction
      
      nnoremap <silent><leader>s :call <SID>do_stuff()<CR>
      

      【讨论】:

      • 谢谢,是的,其中一件事是我不知道如何在 vim 中创建函数,所以您的问题有助于指出这个方向,谢谢。几个问题:(1)&lt;SID&gt; 是什么? (2)s:do_stuff()是什么,为什么不只是do_stuff(),最后,(3)%join是什么,这和%J一样吗?
      • @David542 (1) 和 (2) s: 表示“脚本本地”函数或变量。除非您指定脚本 ID(仅限函数),否则无法从外部访问它(包括映射),这是由 &lt;SID&gt; 完成的。顺便提一句。 do_stuff() 是非法的,因为全局函数必须以大写字母开头。 (3) %J 不是合法命令。 :join 记录在 :h :join
      • @David542 vimscript 由 ex 命令组成。 Join 是连接线的前命令。 Ex 命令倾向于按行工作,并采用指定它们操作位置的范围。 % 是整个文件的快捷范围。
      • @Matt 还有一个问题:为什么是"&amp;" 而不是"\1"
      • @David542 & 指的是整个匹配(Vi,Perl)。它更短,不是吗?
      【解决方案3】:

      我想到了另一种选择:

      :%s/\v(\w+)\n+/"\1",/g | norm $x | exec "norm! I(\<Esc>A)"
      

      作为命令行选项:

      vim -c ':%s/\v(\w+)\n+/"\1",/g | norm $x | s/.*/(&)/g' -c wq target.txt
      
      -c ........... vim command line (interactive shell)
      \v ........... very magic (simple regex system)
      \w+ .......... one or more words per line
      \n+ .......... one or more line breaks 
      () ........... regex group
      \1 ........... repeat the first regex group
      normal $x .... deletes the last character of the remaining single line
      

      一旦我在正则表达式组中仅使用单词\w+,则在替换中将忽略换行符。在最后一个替换中,我们不需要更多的%,因为此时我们只有一行。

      【讨论】:

        猜你喜欢
        • 2011-05-08
        • 1970-01-01
        • 2019-04-21
        • 2015-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多