如何格式化Vim quickfix条目?

如何格式化Vim quickfix条目?,vim,Vim,这是用于生成降价大纲的vim脚本: fun! TOC() call setloclist(0, []) let save_cursor = getpos(".") call cursor(1, 1) while search("^#", 'W') > 0 let msg = printf('%s:%d:%s', expand('%'), line('.'), substitute(getline('.'), '#', '»', 'g'))

这是用于生成降价大纲的vim脚本:

fun! TOC()
    call setloclist(0, [])
    let save_cursor = getpos(".")
    call cursor(1, 1)
    while search("^#", 'W') > 0
       let msg = printf('%s:%d:%s', expand('%'), line('.'), substitute(getline('.'), '#', '»', 'g'))
       laddexpr msg
    endwhile
    call setpos('.', save_cursor)
endfun

com! -bar TOC call TOC()

标记文件示例:


运行
:TOC
命令后,这是快速列表:

01-chapter1.markdown|5| »» 关于版本控制 »»
01-chapter1.markdown|11| »»» 本地版本控制系统 »»»
01-chapter1.markdown|22| »»» 集中化的版本控制系统 »»»
01-chapter1.markdown|33| »»» 分布式版本控制系统 »»»
01-chapter1.markdown|42| »» Git 简史 »»
01-chapter1.markdown|56| »» Git 基础 »»
01-chapter1.markdown|60| »»» 直接记录快照,而非差异比较 »»»
01-chapter1.markdown|74| »»» 近乎所有操作都是本地执行 »»»
01-chapter1.markdown|82| »»» 时刻保持数据完整性 »»»
01-chapter1.markdown|92| »»» 多数操作仅添加数据 »»»
01-chapter1.markdown|98| »»» 文件的三种状态 »»»
01-chapter1.markdown|121| »» 安装 Git »»
01-chapter1.markdown|125| »»» 从源代码安装 »»»
01-chapter1.markdown|152| »»» 在 Linux 上安装 »»»
01-chapter1.markdown|162| »»» 在 Mac 上安装 »»»
01-chapter1.markdown|177| »»» 在 Windows 上安装 »»»
01-chapter1.markdown|185| »» 初次运行 Git 前的配置 »»
01-chapter1.markdown|197| »»» 用户信息 »»»
01-chapter1.markdown|206| »»» 文本编辑器 »»»
01-chapter1.markdown|212| »»» 差异分析工具 »»»
01-chapter1.markdown|220| »»» 查看配置信息 »»»
01-chapter1.markdown|240| »» 获取帮助 »»
01-chapter1.markdown|254| »» 小结 »»

我想将快速修复条目格式化为:

|005| »» 关于版本控制 »»
|011| »»» 本地版本控制系统 »»»
|022| »»» 集中化的版本控制系统 »»»
|033| »»» 分布式版本控制系统 »»»
|042| »» Git 简史 »»
|056| »» Git 基础 »»
|060| »»» 直接记录快照,而非差异比较 »»»
|074| »»» 近乎所有操作都是本地执行 »»»
|082| »»» 时刻保持数据完整性 »»»
|092| »»» 多数操作仅添加数据 »»»
|098| »»» 文件的三种状态 »»»
|121| »» 安装 Git »»
|125| »»» 从源代码安装 »»»
|152| »»» 在 Linux 上安装 »»»
|162| »»» 在 Mac 上安装 »»»
|177| »»» 在 Windows 上安装 »»»
|185| »» 初次运行 Git 前的配置 »»
|197| »»» 用户信息 »»»
|206| »»» 文本编辑器 »»»
|212| »»» 差异分析工具 »»»
|220| »»» 查看配置信息 »»»
|240| »» 获取帮助 »»
|254| »» 小结 »»

我找不到任何办法来做这件事。如果你知道,请告诉我。谢谢

无法配置快速修复位置的设置方式 显示。只能通过以下方式指定如何解释它们:
errorformat
选项。但是,可以使用隐藏功能 在快速修复或位置列表窗口中隐藏文件名

以下命令支持隐藏和定义语法规则 匹配第一行之前行开头的任何文本
|
字符

:set conceallevel=2 concealcursor=nc
:syntax match qfFileName /^[^|]*/ transparent conceal
可以为每个快速修复或位置列表触发这些命令 使用自动命令打开窗口。但总的来说,这不是一个好主意, 因为在大多数情况下,显示文件名是一项有用的功能

对于问题中提出的情况,最好是 仅针对新收集的位置列表进行自定义。它需要 不过,先打开“位置列表”窗口

:lopen
:set conceallevel=2 concealcursor=nc
:syntax match qfFileName /^[^|]*/ transparent conceal

我最终通过使用
set modifiable
+替换实现了这一点,而不是隐藏一些东西:

function! b:Markdown_Toc()
    silent lvimgrep '^#' %
    vertical lopen
    let &winwidth=(&columns/2)
    set modifiable
    %s/\v^([^|]*\|){2,2} #//
    for i in range(1, line('$'))
        let l:line = getline(i)
        let l:header = matchstr(l:line, '^#*')
        let l:length = len(l:header)
        let l:line = substitute(l:line, '\v^#*[ ]*', '', '')
        let l:line = substitute(l:line, '\v[ ]*#*$', '', '')
        let l:line = repeat(' ', (2 * l:length)) . l:line
        call setline(i, l:line)
    endfor
    set nomodified
    set nomodifiable
endfunction
但您可能更喜欢:

Plugin 'plasticboy/vim-markdown'
这取决于你

截图:

试试这个:

fu s:TOC() abort
    call setloclist(0, [])
    let curfile = expand('%:p')
    let save_cursor = getpos('.')
    call cursor(1, 1)
    while search('^#', 'W') > 0
       let msg = printf('%s:%d:%s',
           \ curfile,
           \ line('.'), getline('.')->substitute('#', '»', 'g')
           \ )
       laddexpr msg
    endwhile
    call setpos('.', save_cursor)
    call setloclist(0, [], 'r', {
        \ 'lines': getloclist(0)
        \     ->map('curfile .. "|" .. v:val.lnum .. " " .. v:val.col .. "|" .. v:val.text'),
        \ 'efm': '%f|%l %c|%m',
        \ 'quickfixtextfunc': function('s:quickfixtextfunc'),
        \ })
endfu

fu s:quickfixtextfunc(info) abort
    let ll = getloclist(a:info.winid, {'id': a:info.id, 'items': 0}).items
    let lnum_width = range(a:info.start_idx - 1, a:info.end_idx - 1)
        \ ->map({_, v -> ll[v].lnum})
        \ ->max()
        \ ->len()
    let formatted_lines = []
    for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
        let e = ll[idx]
        let fname = bufname(e.bufnr)->fnamemodify(':t')
        let line = printf('|%0*s| %s', lnum_width, e.lnum, e.text)
        call add(formatted_lines, line)
    endfor
    return formatted_lines
endfu

com -bar TOC call s:TOC()
它依赖于位置列表的
'quickfixtextfunc'
属性,该属性添加在以下两个Vim补丁中:

  • “quickfixtextfunc”未获取位置列表的窗口ID
  • 使用“quickfixtextfunc”有点慢


为了获得更好的性能,以下是Vim9中的相同代码:

vim9

def TOC()
    setloclist(0, [])
    var curfile: string = expand('%:p')
    var save_cursor: list<number> = getpos('.')
    cursor(1, 1)
    while search('^#', 'W') > 0
       msg = printf('%s:%d:%s',
           curfile,
           line('.'), getline('.')->substitute('#', '»', 'g')
           )
       laddexpr msg
    endwhile
    setpos('.', save_cursor)
    setloclist(0, [], 'r', {
        lines: getloclist(0)
            ->mapnew((_, v) => curfile .. '|' .. v.lnum .. ' ' .. v.col .. '|' .. v.text),
        efm: '%f|%l %c|%m',
        quickfixtextfunc: Quickfixtextfunc,
        })
enddef
var msg: string

def Quickfixtextfunc(info: dict<number>): list<string>
    var ll: list<any> = getloclist(info.winid, {id: info.id, items: 0}).items
    var lnum_width: number = range(info.start_idx - 1, info.end_idx - 1)
        ->map((_, v) => ll[v].lnum)
        ->max()
        ->len()
    var formatted_lines: list<string> = []
    for idx in range(info.start_idx - 1, info.end_idx - 1)
        var e: dict<any> = ll[idx]
        var fname: string = bufname(e.bufnr)->fnamemodify(':t')
        var line: string = printf('|%0*s| %s', lnum_width, e.lnum, e.text)
        add(formatted_lines, line)
    endfor
    return formatted_lines
enddef

com -bar TOC TOC()
vim9
def TOC()
setloclist(0,[])
var curfile:string=expand('%:p')
var save_cursor:list=getpos('.'))
光标(1,1)
而搜索('^#','W')>0
msg=printf(“%s:%d:%s”,
curfile,
行('.')、getline('.')->替换('#'、'»、'g')
)
laddexpr味精
循环结束
设置位置('.',保存光标)
setloclist(0,[],'r'{
行:getloclist(0)
->mapnew((_,v)=>curfile..'|'..v.lnum..'..v.col..v.text),
efm:“%f |%l%c |%m”,
quickfixtextfunc:quickfixtextfunc,
})
enddef
var-msg:string
def Quickfixtextfunc(信息:dict):列表
var ll:list=getloclist(info.winid,{id:info.id,items:0})
变量lnum\u width:number=范围(info.start\u idx-1,info.end\u idx-1)
->map((u,v)=>ll[v].lnum)
->最大值()
->len()
var格式化的_行:list=[]
适用于范围内的idx(info.start\u idx-1、info.end\u idx-1)
变量e:dict=ll[idx]
var fname:string=bufname(e.bufnr)->fnamemodify(“:t”)
变量行:string=printf('|%0*s |%s',lnum_宽度,e.lnum,e.text)
添加(格式化的行,行)
外循环
返回格式化的\u行
enddef
com-bar TOC TOC()

这需要最新的Vim版本。它适用于8.2.2451。

组名
非文本
表示指向同名突出显示组的链接。更好、更一致的名称可能是
qfFile
@Ingo:Maybe,但使用自定义高亮显示组名需要额外的命令。而且,这个自定义组实际上是一个虚拟组。由于
透明
隐藏
说明符,突出显示组没有使用,也没有要自定义的突出显示。你说得对,但我不明白你为什么需要另一个命令。因为这里没有使用突出显示组,所以您不需要定义它。@Ingo:事实上,您完全正确。我没有注意到,在这种情况下,没有必要先定义一个组。谢谢你的宝贵意见!是否可以使用此方法并保持高亮显示?例如,当我调用vimgrep和copen时,行号和列号高亮显示为黄色,但使用此方法删除文件名后,它们变为无色。我可以让它们保持黄色吗?顺便说一句,您的(非常好而且有用!)实现忽略了第一个标题。(在示例中,
#起步 #丢失。)您需要为第一个
搜索()包含“c”标志。
:。。。调用游标(1,1)let flags='cW',而搜索(“^#”,flags)>0 let flags='W'。。。