preservim / tagbar

Vim plugin that displays tags in a window, ordered by scope
https://preservim.github.io/tagbar
Other
6.13k stars 488 forks source link

Is there a way to disable tagbar for very large files #636

Closed ericsunplus closed 4 years ago

ericsunplus commented 4 years ago

Hi there,

I am using tagbar for a long time and enjoy its' feature. However, recently I am profiling a problem that my vim runs very slow when loading a large header file, it turns out the root cause is tagbar makes a lot of iteration for this header file and spend quite a long time. The following is from my profiling result

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
    1  79.733105   0.000300  dist#ft#FTheader()
    4  79.654429   0.021717  <SNR>131_AutoUpdate()
    1  79.631572   4.059338  <SNR>131_ProcessFile()
69277  52.977399  10.519105  <SNR>131_ParseTagline()
69277  42.458294  10.486403  <SNR>131_ProcessTag()
  323  22.706893  22.026039  tagbar#sorting#sort()
69277  22.674011   2.594087  tagbar#prototypes#normaltag#new()
    1  21.794226   0.000258  <SNR>144_sortTags()
69383  18.492879  10.969571  tagbar#prototypes#basetag#new()
862470  17.951957             <SNR>149_compare_by_kind()
75180   8.094827   6.071874  <SNR>131_add_tag_recursive()
1248894   7.523308             <SNR>146_add_snr()
69383   1.849420   1.628480  <SNR>146_initFoldState()
277108   1.614862             <SNR>145_add_snr()
63871   0.819722             <SNR>144_addTag()
    1   0.798148   0.074979  <SNR>131_ExecuteCtagsOnFile()
    1   0.722627   0.034371  <SNR>131_ExecuteCtags()
69277   0.255400             <SNR>144_getTagsByName()
69388   0.220967             263()
69277   0.090358             <SNR>146_isSplitTag()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  323  22.706893  22.026039  tagbar#sorting#sort()
862470             17.951957  <SNR>149_compare_by_kind()
69383  18.492879  10.969571  tagbar#prototypes#basetag#new()
69277  52.977399  10.519105  <SNR>131_ParseTagline()
69277  42.458294  10.486403  <SNR>131_ProcessTag()
1248894              7.523308  <SNR>146_add_snr()
75180   8.094827   6.071874  <SNR>131_add_tag_recursive()
    1  79.631572   4.059338  <SNR>131_ProcessFile()
69277  22.674011   2.594087  tagbar#prototypes#normaltag#new()
69383   1.849420   1.628480  <SNR>146_initFoldState()
277108              1.614862  <SNR>145_add_snr()
63871              0.819722  <SNR>144_addTag()
69277              0.255400  <SNR>144_getTagsByName()
69388              0.220967  263()
69277              0.090358  <SNR>146_isSplitTag()
69703              0.078992  <SNR>146_getChildren()
    1   0.798148   0.074979  <SNR>131_ExecuteCtagsOnFile()
 5510              0.070964  <SNR>146_addChild()
    5              0.038166  <SNR>125_DisableOnLargeFile()
    1   0.722627   0.034371  <SNR>131_ExecuteCtags()

As can be seen, 131_ProcessFile takes approx. 80s because of the iterations inside.

So is there a way to disable tagbar for very large file (for example lines >= 10000)?

alerque commented 4 years ago

Off the top of my head I don't know how to do this, although I'm sure there is a way. I've wanted myself to avoid generated tags on super large files (which are often generated anyway). We should figure out how to do this cleanly and document it.

raven42 commented 4 years ago

Something like this could be added to the ProcessFile() routine.

function! s:ProcessFile(fname, ftype) abort
    let linecount = line('$')
    if linecount > g:tagbar_file_size_limit && !exists('b:tagbar_force_update')
        echo 'File too large (' . linecount . ' lines). not processing file'
        return
    endif
    ...
endfunction

"  tagbar#ForceUpdate() {{{2
function! tagbar#ForceUpdate() abort
    if !exists('b:tagbar_force_update')
        let b:tagbar_force_update = 1
        call s:AutoUpdate(fnamemodify(expand('%'), ':p'), 1)
        unlet b:tagbar_force_update
    endif
endfunction

This along with a global g:tagbar_file_size_limit could be used to simply not update the file, and then you could call tagbar#ForceUpdate() to manually update that specific file.

Note: Haven't actually coded this up... just thinking outloud

ericsunplus commented 4 years ago

@raven42 , thank you, the patch works fine, the only exception is the File too large (' . linecount . ' lines). not processing file repeat 3 times for a single file

raven42 commented 4 years ago

I've pushed an initial go for this. It seems to be stable enough, but I'd like to add an option to display in the tagbar window that the file was ignored or not processed. I'm not sure how best to do that though.

alerque commented 4 years ago

I agree displaying something as an indication of why a file was not processed is probably a really good idea. No I don't have any great ideas how to do this. Probably just stuffing an explanation into the Tagbar buffer will do the trick.