如何格式化vim quickfix条目?

时间:2012-06-26 00:00:50

标签: vim

这是生成Markdown大纲的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()

示例降价文件:https://github.com/progit/progit/raw/master/zh/01-introduction/01-chapter1.markdown


运行: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| »» 小结 »»

我找不到任何选择。如果你知道,请告诉我。谢谢!

3 个答案:

答案 0 :(得分:8)

无法配置quickfix位置的显示方式。它是 只能指定如何使用errorformat选项解释它们。 但是,可以使用隐藏功能隐藏quickfix中的文件名 位置列表窗口。

以下命令启用隐藏和定义与任何匹配的语法规则 第一个|字符前一行开头的文字。

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

可以为每个quickfix或位置列表窗口触发这些命令 使用自动命令。然而,从大多数情况来看,这并不是一个好主意 显示文件名的案例是一个有用的功能。所以,在提出的情况下 问题是,最好只针对新的定制 收集的位置列表。它需要先打开位置列表窗口, 虽然。

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

答案 1 :(得分:1)

我最终在plasticboy/vim-markdown this PR (with GIF animation)上使用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'

由你决定。 =)

截图:

enter image description here

答案 2 :(得分:0)

试试这个:

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 补丁中添加的:

  • 8.2.0933 'quickfixtextfunc' 无法获取位置列表的窗口 ID
  • 8.2.0959 使用 'quickfixtextfunc' 有点慢

:h quickfix-window-function


为了更好的性能,这里是 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()

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