Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions after/ftplugin/qf.vim
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ let b:undo_ftplugin .= "| delcommand Filter"
\ . "| unlet! b:qf_isLoc"

" decide where to open the location/quickfix window
" :help g:qf_loclist_window_bottom
" :help g:qf_window_bottom
if (b:qf_isLoc == 1 && get(g:, 'qf_loclist_window_bottom', 1))
\ || (b:qf_isLoc == 0 && get(g:, 'qf_window_bottom', 1))
wincmd J
Expand Down
141 changes: 83 additions & 58 deletions autoload/qf.vim
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,6 @@
let s:save_cpo = &cpo
set cpo&vim

" open the current entry in th preview window
function qf#PreviewFileUnderCursor()
let cur_list = b:qf_isLoc == 1 ? getloclist('.') : getqflist()
let cur_line = getline(line('.'))
let cur_file = fnameescape(substitute(cur_line, '|.*$', '', ''))
if cur_line =~ '|\d\+'
let cur_pos = substitute(cur_line, '^\(.\{-}|\)\(\d\+\)\(.*\)', '\2', '')
execute "pedit +" . cur_pos . " " . cur_file
else
execute "pedit " . cur_file
endif
endfunction

" helper function
" returns 1 if the window with the given number is a quickfix window
" 0 if the window with the given number is not a quickfix window
Expand Down Expand Up @@ -73,13 +60,26 @@ function! qf#IsLocWindowOpen(nmbr) abort
return 0
endfunction

" returns location list of the current loclist if isLoc is set
" qf list otherwise
function! qf#GetList()
" returns current location list or quickfix list
function! qf#GetListItems(idx)
let what = { 'idx': a:->get('idx', 0), 'items': 1 }

if get(b:, 'qf_isLoc', 0)
return getloclist(0, what)["items"]
else
return getqflist(what)["items"]
endif
endfunction

" helper
" returns the number of items in a loc/qf list
function! qf#GetListSize()
let what = { 'size': 1 }

if get(b:, 'qf_isLoc', 0)
return getloclist(0)
return getloclist(0, what)["size"]
else
return getqflist()
return getqflist(what)["size"]
endif
endfunction

Expand Down Expand Up @@ -107,68 +107,93 @@ function! qf#SetList(newlist, ...)
endif
endfunction

function! qf#GetEntryPath(line) abort
" +- match from the first pipe to the end of line
" | declaring EOL explicitly is faster than implicitly
" | +- replace match with nothing
" | | +- no flags
return substitute(a:line, '|.*$', '', '')
endfunction

" open the quickfix window if there are valid errors
function! qf#OpenQuickfix()
function! qf#OpenQuickfixWindow()
if get(g:, 'qf_auto_open_quickfix', 1)
" get user-defined maximum height
let max_height = get(g:, 'qf_max_height', 10) < 1 ? 10 : get(g:, 'qf_max_height', 10)

let qf_list = getqflist()

" shorten paths if applicable
if get(g:, 'qf_shorten_path', 0) > 0
call setqflist(qf#ShortenPathsInList(qf_list))
endif

execute get(g:, "qf_auto_resize", 1) ? 'cclose|' . min([ max_height, len(qf_list) ]) . 'cwindow' : 'cclose|cwindow'
execute get(g:, "qf_auto_resize", 1) ? 'cclose|' . min([ max_height, qf#GetListSize() ]) . 'cwindow' : 'cclose|cwindow'
endif
endfunction

" open a location window if there are valid locations
function! qf#OpenLoclist()
function! qf#OpenLocationWindow()
if get(g:, 'qf_auto_open_loclist', 1)
" get user-defined maximum height
let max_height = get(g:, 'qf_max_height', 10) < 1 ? 10 : get(g:, 'qf_max_height', 10)

let loc_list = getloclist(0)
execute get(g:, "qf_auto_resize", 1) ? 'lclose|' . min([ max_height, qf#GetListSize() ]) . 'lwindow' : 'lclose|lwindow'
endif
endfunction

" shorten paths if applicable
if get(g:, 'qf_shorten_path', 0) > 0
call setloclist(0, qf#ShortenPathsInList(loc_list))
endif
function! qf#QuickfixTextFunc(options)
let items = a:options["quickfix"] == 1 ? getqflist() : getloclist(a:options["winid"])
return items->map({ key, val -> val->qf#FormatItem() })
endfunction

function! qf#FormatItem(item)
return [
\ a:item->qf#FormatFilename(),
\ a:item->qf#FormatLocation(),
\ a:item->qf#FormatText(),
\ ]->join('|')
endfunction

function! qf#FormatFilename(item)
let filename = a:item["bufnr"]->bufname()

execute get(g:, "qf_auto_resize", 1) ? 'lclose|' . min([ max_height, len(loc_list) ]) . 'lwindow' : 'lclose|lwindow'
if has('patch-8.2.1741')
return pathshorten(filename, g:->get("qf_shorten_path", 1))
else
return pathshorten(filename)
endif
endfunction

" shorten file paths in given qf/loc list
function! qf#ShortenPathsInList(list)
let index = 0
while index < len(a:list)
" item is a dict, sample: { lnum: 14, text: 'foo bar', bufnr: 3, ... }
let item = a:list[index]
function! qf#FormatLocation(item)
return [
\ a:item->get("lnum", 0)->qf#FormatLineNumber(),
\ a:item->get("col", 0)->qf#FormatColumn(),
\ a:item->get("type", '')->qf#FormatType(),
\ a:item->get("nr", 0)->qf#FormatErrorNumber(),
\ ]->join('')
endfunction

let filepath = bufname(item["bufnr"])
let trim_len = get(g:, "qf_shorten_path", 1)
function! qf#FormatText(item)
" return ' ' .. a:item->get("text", '')
return a:item["text"]
endfunction

" set the 'module' field to customise the visual filename in the qf/loc list (available since 8.0.1782)
if has('patch-8.2.1741')
let item["module"] = pathshorten(filepath, trim_len)
function! qf#FormatLineNumber(lnum)
return a:lnum != 0 ? a:lnum : '-'
endfunction

function! qf#FormatColumn(col)
return a:col > 0 ? ' col ' .. a:col : ''
endfunction

function! qf#FormatType(type)
let types = {
\ 'e': ' error',
\ 'i': ' info',
\ 'n': ' note',
\ 'w': ' warning'
\ }
return a:type != '' ? types[a:type] : ''
endfunction

function! qf#FormatErrorNumber(nr)
if a:nr > 0
if a:nr->string()->len() == 1
return ' ' .. a:nr
elseif a:nr->string()->len() == 2
return ' ' .. a:nr
else
let item["module"] = pathshorten(filepath)
return ' ' .. a:nr
endif

let index = index + 1
endwhile
return a:list
else
return ''
endif
endfunction

let &cpo = s:save_cpo
42 changes: 10 additions & 32 deletions autoload/qf/do.vim
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,18 @@
let s:save_cpo = &cpo
set cpo&vim

" do something with each entry
" a single function for :Doline and :Dofile both in a quickfix list and
" a location list
" falls back to :cdo, :cfdo, :ldo, :lfdo when possible
" Do something with each entry
" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
" Handles :Doline and :Dofile, in quickfix and location lists.
" Wrapper aound :cdo, :cfdo, :ldo, :lfdo.
function! qf#do#DoList(line, cmd)
if exists("b:qf_isLoc")
let prefix = b:qf_isLoc == 1 ? "l" : "c"
else
let prefix = "c"
endif
let prefix = b:->get("qf_isLoc", 1) ? "l" : "c"
let modifier = a:line == 1 ? "" : "f"

if v:version >= 705
\ || v:version == 704 && has("patch858")
if a:line == 1
let modifier = ""
else
let modifier = "f"
endif

try
execute prefix . modifier . "do " . a:cmd
catch /^Vim\%((\a\+)\)\=:E\%(553\|42\):/
endtry
else
try
silent execute prefix . "first"
while 1
execute a:cmd

silent execute a:line == 1 ? prefix . "next" : prefix . "nfile"
endwhile
catch /^Vim\%((\a\+)\)\=:E\%(553\|42\):/
endtry
endif
try
execute prefix . modifier . "do " . a:cmd
catch /^Vim\%((\a\+)\)\=:E\%(553\|42\):/
endtry
endfunction

let &cpo = s:save_cpo
66 changes: 40 additions & 26 deletions autoload/qf/filegroup.vim
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,54 @@
let s:save_cpo = &cpo
set cpo&vim

function! s:JumpToFirstItemOfFileChunk() abort
let l:chunk_file_path = qf#GetEntryPath(getline('.'))
function! qf#filegroup#NextFile() abort
if exists("b:qf_isLoc")
let items = qf#GetListItems(0)
let current_index = line('.') - 1
let current_bufnr = items[current_index]["bufnr"]
let limit = items->len()

while line('.') - 1 != 0
\ && l:chunk_file_path == qf#GetEntryPath(getline(line('.') - 1))
normal! k
endwhile
while current_index < limit && items[current_index]["bufnr"] == current_bufnr
let current_index += 1
endwhile

normal! zz
if current_index == limit
1
else
execute current_index + 1
endif
endif
endfunction

function! s:JumpFileChunk(down) abort
let l:start_file_path = qf#GetEntryPath(getline('.'))
let l:direction = a:down ? 'j' : 'k'
let l:end = a:down ? '$' : 1
function! qf#filegroup#PreviousFile() abort
if exists("b:qf_isLoc")
let items = qf#GetListItems(0)
let current_index = line('.') - 1
let current_bufnr = items[current_index]["bufnr"]
let limit = 0

while l:start_file_path
\ == qf#GetEntryPath(getline('.'))
\ && getline('.') != getline(l:end)
execute 'normal! ' . l:direction
endwhile
while current_index > limit && items[current_index]["bufnr"] == current_bufnr
let current_index -= 1
endwhile

call s:JumpToFirstItemOfFileChunk()
endfunction
if current_index == limit
normal! G
else
execute current_index + 1
endif

function! qf#filegroup#PreviousFile() abort
if exists("b:qf_isLoc")
call s:JumpFileChunk(0)
endif
endfunction
let current_index = line('.') - 1
let current_bufnr = items[current_index]["bufnr"]

function! qf#filegroup#NextFile() abort
if exists("b:qf_isLoc")
call s:JumpFileChunk(1)
while current_index > limit && items[current_index]["bufnr"] == current_bufnr
let current_index -= 1
endwhile

if current_index == limit
1
else
execute current_index + 2
endif
endif
endfunction

Expand Down
20 changes: 13 additions & 7 deletions autoload/qf/preview.vim
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@ set cpo&vim

" open the current entry in th preview window
function! qf#preview#PreviewFileUnderCursor()
let cur_list = qf#GetList()
let cur_line = getline(line('.'))
let cur_file = fnameescape(qf#GetEntryPath(cur_line))
let winview = winsaveview()

if cur_line =~ '|\d\+'
let cur_pos = substitute(cur_line, '^\(.\{-}|\)\(\d\+\)\(.*\)', '\2', '')
execute "pedit +" . cur_pos . " " . cur_file
let current_item = qf#GetListItems(line('.'))[0]
let current_file_name = current_item["bufnr"]->bufname()
let current_file_line = current_item->get('lnum', 0)
let current_file_column = current_item->get('col', 0)

if current_file_line && current_file_column
execute "pedit +" .. current_file_line .. " " .. current_file_name .. "|normal! " .. current_file_column .. "G"
elseif current_file_line && !current_file_column
execute "pedit +" .. current_file_line .. " " .. current_file_name
else
execute "pedit " . cur_file
execute "pedit " .. current_file_name
endif

call winrestview(winview)
endfunction

let &cpo = s:save_cpo
10 changes: 5 additions & 5 deletions autoload/qf/toggle.vim
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
let s:save_cpo = &cpo
set cpo&vim

" toggles the quickfix window
" Toggles the quickfix window.
function! qf#toggle#ToggleQfWindow(stay) abort
" save the view if the current window is not a quickfix window
if get(g:, 'qf_save_win_view', 1) && !qf#IsQfWindow(winnr())
Expand All @@ -38,7 +38,7 @@ function! qf#toggle#ToggleQfWindow(stay) abort
call winrestview(winview)
endif
else
execute get(g:, 'qf_auto_resize', 1) ? min([ max_height, len(getqflist()) ]) . 'cwindow' : max_height . 'cwindow'
execute get(g:, 'qf_auto_resize', 1) ? min([ max_height, qf#GetListSize() ]) . 'cwindow' : max_height . 'cwindow'
if qf#IsQfWindowOpen()
wincmd p
if !empty(winview)
Expand All @@ -51,8 +51,8 @@ function! qf#toggle#ToggleQfWindow(stay) abort
endif
endfunction

" toggles the location window associated with the current window
" or whatever location window has the focus
" Toggles the location window associated with the current window
" or whatever location window has the focus.
function! qf#toggle#ToggleLocWindow(stay) abort
" save the view if the current window is not a location window
if get(g:, 'qf_save_win_view', 1) && !qf#IsLocWindow(winnr())
Expand All @@ -70,7 +70,7 @@ function! qf#toggle#ToggleLocWindow(stay) abort
call winrestview(winview)
endif
else
execute get(g:, 'qf_auto_resize', 1) ? min([ max_height, len(getloclist(0)) ]) . 'lwindow' : max_height . 'lwindow'
execute get(g:, 'qf_auto_resize', 1) ? min([ max_height, qf#GetListSize() ]) . 'lwindow' : max_height . 'lwindow'
if qf#IsLocWindowOpen(0)
wincmd p
if !empty(winview)
Expand Down
Loading