PHP-Indenting-for-VIm icon indicating copy to clipboard operation
PHP-Indenting-for-VIm copied to clipboard

Vim hangs on GetLastRealCodeLNum

Open karangb opened this issue 4 years ago • 1 comments

  • I am not sure how to reproduce it, but sometimes, vim hangs on GetLastRealCodeLNum
  • Version: 1.72

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

karangb avatar Sep 24 '20 18:09 karangb

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

2072 avatar Nov 02 '20 10:11 2072