2072 / PHP-Indenting-for-VIm

The official VIm indent script for PHP
http://www.2072productions.com/to/phpindent.txt
128 stars 29 forks source link

Vim hangs on GetLastRealCodeLNum #79

Open karangb opened 4 years ago

karangb commented 4 years ago

Here is the profile I captured, not sure if this helps:

FUNCTION  GetLastRealCodeLNum()
    Defined: ~/.vim/plugged/PHP-Indenting-for-VIm/indent/php.vim:593
Called 1 time
Total time:  72.036105
 Self time:  72.036105

count  total (s)   self (s)
                                "Inspired from the function SkipJavaBlanksAndComments by Toby Allsopp for indent/java.vim

    1              0.000002     let lnum = a:startline

                                " DEBUG call DebugPrintReturn('565: started GetLastRealCodeLNum ' . lnum . ' --- lastline: ' . getline(lnum) )
                                " Used to indent <script.*> html tag correctly
    1              0.000002     if b:GetLastRealCodeLNum_ADD && b:GetLastRealCodeLNum_ADD == lnum + 1
                                let lnum = b:GetLastRealCodeLNum_ADD
    1              0.000001     endif

1146747              0.905929     while lnum > 1
                                    " DEBUG call DebugPrintReturn('587: in while' )
1146747              1.803873   let lnum = prevnonblank(lnum)
1146747              1.772870   let lastline = getline(lnum)

                                " if we are inside an html <script> we must skip ?> tags to indent
                                " everything as php
1146747              1.245440   if b:InPHPcode_and_script && lastline =~ '?>\s*$'
                                    let lnum = lnum - 1
                                    " DEBUG call DebugPrintReturn('593' )
                                elseif lastline =~ '^\s*?>.*<?\%(php\)\=\s*$'
                                    let lnum = lnum - 1
                                    " DEBUG call DebugPrintReturn('596' )
                                elseif lastline =~ '^\s*\%(//\|#\|/\*.*\*/\s*$\)'
                                    " Deliberately treating #[ like a line comment so that subsequent
                                    " inserted lines will be correctly indented inside of blocks
                                    " (e.g. on class methods)
                                    let lnum = lnum - 1
                                    " DEBUG call DebugPrintReturn('592' )
                                elseif lastline =~ '\*/\s*$'
                                    " DEBUG call DebugPrintReturn('602' )
                                    " skip multiline comments
                                    call cursor(lnum, 1)
                                    if lastline !~ '^\*/'
                                    call search('\*/', 'W')
                                    " position the cursor on the first */
                                    endif
                                    let lnum = searchpair('/\*', '', '\*/', s:searchpairflags, 'Skippmatch2()')
                                    " find the most outside /*

                                    let lastline = getline(lnum)
                                    if lastline =~ '^\s*/\*'
                                    " if line contains nothing but comment
                                    " do the job again on the line before (a comment can hide another...)
                                    let lnum = lnum - 1
                                    else
                                    " DEBUG call DebugPrintReturn('613: break' )

                                    break
                                    endif

                                elseif lastline =~? '\%(//\s*\|?>.*\)\@<!<?\%(php\)\=\s*$\|^\s*<script\>'
                                    " DEBUG call DebugPrintReturn('625' )
                                    " skip non php code

                                    while lastline !~ '\(<?.*\)\@<!?>' && lnum > 1
                                    let lnum = lnum - 1
                                    let lastline = getline(lnum)
                                    endwhile
                                    if lastline =~ '^\s*?>'
                                    " if line contains nothing but end tag
                                    let lnum = lnum - 1
                                    else
                                    " DEBUG call DebugPrintReturn('630: break' )
                                    break
                                    " else there is something important before the ?>
                                    endif

                                    " Manage "here document" tags
                                elseif lastline =~? '^\a\w*;\=$' && lastline !~? s:notPhpHereDoc
                                    " DEBUG call DebugPrintReturn('644' )
                                    " match the end of a heredoc
                                    let tofind=substitute( lastline, '\(\a\w*\);\=', '<<<\\s*[''"]\\=\1[''"]\\=$', '')
                                    while getline(lnum) !~? tofind && lnum > 1
                                    let lnum = lnum - 1
                                    endwhile
                                elseif lastline =~ '^\s*[''"`][;,]'.s:endline || (lastline =~ '^[^''"`]*[''"`][;,]'.s:endline && IslinePHP(lnum, "") == "SpecStringEntrails")
                                    " DEBUG call DebugPrintReturn('651  '  . IslinePHP(lnum, "") . "  " . lastline)
                                    " match end of multiline strings horrors

                                    let tofind=substitute( lastline, '^.*\([''"`]\)[;,].*$', '^[^\1]\\+[\1]$\\|^[^\1]\\+[=([]\\s*[\1]', '')
                                    " DEBUG call DebugPrintReturn( 'mls end, to find:' . tofind . "   lnum" . lnum . '.. is this php? ' . IslinePHP(lnum, ""))
                                    let trylnum = lnum
                                    while getline(trylnum) !~? tofind && trylnum > 1
                                    let trylnum = trylnum - 1
                                    endwhile

                                    " DEBUG call DebugPrintReturn('trylnum ' . trylnum . ' --- lastline: ' . lastline )
                                    if trylnum == 1
                                    " we have failed... let things be.
                                    " DEBUG call DebugPrintReturn('656: break' )
                                    break
                                    else
                                    " we have found the start of this awful multiline horror
                                    if lastline =~ ';'.s:endline
                                        " the last line finished the declaration so we must find a
                                        " similar line
                                        while getline(trylnum) !~? s:terminated && getline(trylnum) !~? '{'.s:endline && trylnum > 1
                                        let trylnum = prevnonblank(trylnum - 1)
                                        endwhile

                                        " DEBUG call DebugPrintReturn('trylnum bis ' . trylnum)

                                        if trylnum == 1
                                        " we have failed... let things be.
                                        " DEBUG call DebugPrintReturn('671: break' )
                                        break
                                        end
                                    end
                                    let lnum = trylnum
                                    end
                                else
                                    " if none of these were true then we are done
                                    " DEBUG call DebugPrintReturn('679: break' )
                                    break
1146747              0.553956   endif
1146746              0.644220     endwhile

                                if lnum==1 && getline(lnum) !~ '<?'
                                let lnum=0
                                endif

                                " This is to handle correctly end of script tags; to return the real last php
                                " code line else a '?>' could be returned has last_line
                                if b:InPHPcode_and_script && 1 > b:InPHPcode
                                let b:InPHPcode_and_script = 0
                                endif

                                return lnum
2072 commented 4 years ago

Does this happen while typing or when indenting blocks of code?