Vim:如何自动编号段落以及如何参考这个编号?

ThG*_*ThG 8 vim

让我们说我有这个文本(段落用空行分隔 - 数字3和7,这里):

This is my first paragraph line 1
This is my first paragraph line 2

This is my second paragraph line 4
This is my second paragraph line 5
This is my second paragraph line 6

This is my third paragraph line 8
This is my third paragraph line 9
Run Code Online (Sandbox Code Playgroud)

问题1:如何自动编号这些段落(我成功了,但是使用了一个笨拙的宏),以获得这个结果:

1   This is my first paragraph line 1
    This is my first paragraph line 2

2   This is my second paragraph line 4
    This is my second paragraph line 5
    This is my second paragraph line 6

3   This is my third paragraph line 8
    This is my third paragraph line 9
Run Code Online (Sandbox Code Playgroud)

问题2:是否可以参考这些段落?例如,是否可以在前面的问题中将文本文件编入索引(由Prince Goulash和Herbert Sitz提供),但这次是使用段落编号而不是行号?

提前致谢

Pri*_*ash 2

问题一

\n

这是一个枚举段落的函数。:call EnumeratePara()只需在文件中的任意位置执行即可。该变量indent可以根据需要进行调整。如果有什么需要纠正或解释,请告诉我。

\n
function! EnumeratePara()\n    let indent = 5\n    let lnum = 1\n    let para = 1\n    let next_is_new_para = 1\n    while lnum <= line("$")\n        let this = getline(lnum)\n        if this =~ "^ *$"\n            let next_is_new_para=1\n        elseif next_is_new_para == 1 && this !~ "^ *$"\n            call cursor(lnum, 1)\n            sil exe "normal i" . para . repeat(" ", indent-len(para))\n            let para+=1\n            let next_is_new_para = 0\n        else\n            call cursor(lnum, 1)\n            sil exe "normal i" . repeat(" ", indent)\n        endif\n        let lnum += 1\n    endwhile\nendfunction\n
Run Code Online (Sandbox Code Playgroud)\n

问题二

\n

这不是一个非常优雅的方法,但它似乎有效。首先,这是一个将文件中的每一行映射到段落号的函数:

\n
function! MapLinesToParagraphs()\n    let lnum = 1\n    let para_lines = []\n    let next_is_new_para = 1\n    let current_para = 0\n    while lnum <= line("$")\n        let this = getline(lnum)\n        if this =~ "^ *$"\n            let next_is_new_para = 1\n        elseif next_is_new_para == 1\n            let current_para += 1\n            let next_is_new_para = 0\n        endif\n        call add(para_lines, current_para)\n        let lnum += 1\n    endwhile\n    return para_lines\nendfunction\n
Run Code Online (Sandbox Code Playgroud)\n

这样para_lines[i]就会给出 line\xc2\xa0 的段落i

\n

现在我们可以使用现有的IndexByWord()函数,并MapLinesToParagraph()在返回行号之前将行号转换为段落号:

\n
function! IndexByParagraph(wordlist)\n    let temp_dict = {}\n    let para_lines = MapLinesToParagraphs()\n    for word in a:wordlist\n        redir => result\n        sil! exe ':g/' . word . '/#'\n        redir END\n        let tmp_list = split(strtrans(result), "\\\\^\\@ *")\n        let res_list = []\n        call map(tmp_list, 'add(res_list, str2nr(matchstr(v:val, "^[0-9]*")))')\n        call map(res_list, 'para_lines[v:val]')\n        let temp_dict[word] = res_list\n    endfor\n    let result_list = []\n    for key in sort(keys(temp_dict))\n        call add(result_list, key . ' : ' . string(temp_dict[key])[1:-2])\n    endfor\n    return join(result_list, "\\n")\nendfunction\n
Run Code Online (Sandbox Code Playgroud)\n

我还没有非常彻底地测试这些函数,但它们似乎工作正常,至少在您的示例文本中是这样。让我知道你是怎么办的!

\n