Ver Fonte

Squashed 'src/ted2go/' changes from ae66ba141..f6f785a72

f6f785a72 Merge branch 'dev'
89d79d526 Fixex completion list size for small theme scale.
6a9953dc9 Disabled autocompletion inside of commented blocks.
226cc2721 Improved keywords capitalizer.
e5b0c2649 Cleanups in process reader.
052f0d732 Cleanups.
9ba996d41 Fixed app crashes (it was error in process reader).
59ef941f5 (wip)
31a4cf3ce Some doc parsing changes.
197a7e386 (wip) parsing doc.
40d3b91a8 no message

git-subtree-dir: src/ted2go
git-subtree-split: f6f785a7290fcf41519f0fb0c1ffbf54a2637d9d
Mark Sibly há 8 anos atrás
pai
commit
b120f075dd

+ 13 - 16
MainWindow.monkey2

@@ -414,12 +414,6 @@ Class MainWindowInstance Extends Window
 		_menuBar.AddMenu( _windowMenu )
 		_menuBar.AddMenu( _windowMenu )
 		_menuBar.AddMenu( _helpMenu )
 		_menuBar.AddMenu( _helpMenu )
 		
 		
-		
-		'_browsersTabView.AddTab( "Project",_projectView,True )
-		'_browsersTabView.AddTab( "Source",_docBrowser,False )
-		'_browsersTabView.AddTab( "Debug",_debugView,False )
-		'_browsersTabView.AddTab( "Help",_helpTree,False )
-		
 		_buildErrorsList=New ListViewExt
 		_buildErrorsList=New ListViewExt
 		_buildErrorsList.Visible=False
 		_buildErrorsList.Visible=False
 		_buildErrorsList.OnItemChoosen+=Lambda()
 		_buildErrorsList.OnItemChoosen+=Lambda()
@@ -1462,18 +1456,21 @@ Class MainWindowInstance Extends Window
 			_mx2cc=_mx2ccDir+StripDir( _mx2cc )
 			_mx2cc=_mx2ccDir+StripDir( _mx2cc )
 		Endif
 		Endif
 		
 		
-		
-		_docsManager.LoadState( jobj )
-		_buildActions.LoadState( jobj )
-		_projectView.LoadState( jobj )
+		App.Idle+=Lambda() 'delay execution
+			
+			_docsManager.LoadState( jobj )
+			_buildActions.LoadState( jobj )
+			_projectView.LoadState( jobj )
 		 
 		 
-		If Not _projectView.OpenProjects _projectView.OpenProject( CurrentDir() )
-		
-		UpdateRecentFilesMenu()
-		UpdateRecentProjectsMenu()
-		UpdateCloseProjectMenu()
+			If Not _projectView.OpenProjects _projectView.OpenProject( CurrentDir() )
+			
+			UpdateRecentFilesMenu()
+			UpdateRecentProjectsMenu()
+			UpdateCloseProjectMenu()
 
 
-		DeleteTmps()
+			DeleteTmps()
+			
+		End
 	End
 	End
 	
 	
 	
 	

+ 18 - 32
ProcessReader.monkey2

@@ -39,34 +39,20 @@ Class ProcessReader
 	
 	
 	#rem monkeydoc Obtain a reader instance.
 	#rem monkeydoc Obtain a reader instance.
 	#end
 	#end
-	Function Obtain:ProcessReader( tag:String )
-	
-		Local r:=New ProcessReader
-'		If _recycled.Empty
-'			r=New ProcessReader
-'		Else
-'			r=_recycled[0]
-'			_recycled.Remove( r )
-'			r.Finished=Null
-'			r.PortionRead=Null
-'			r.Error=Null
-'			r._running=False
-'		Endif
-		r.Tag=tag
-		_items.Add( r )
-		Return r
+	Method New( tag:String="" )
+	
+		Tag=tag
+		_items.Add( Self )
 	End
 	End
 	
 	
-	#rem monkeydoc Recycle a reader instance. So we can get it again using Obtain.
-	#end
-	Function Recycle( r:ProcessReader )
+	Function StopAll()
 	
 	
-		_items.Remove( r )
-		'r.Stop()
-		'_recycled.Add( r )
+		For Local r:=Eachin _items
+			r.Stop()
+		Next
 	End
 	End
 	
 	
-	#rem monkeydoc Stops all obtained readers if them are running and not recycled.
+	#rem monkeydoc
 	#end
 	#end
 	Function WaitingForStopAll( wait:Future<Bool> )
 	Function WaitingForStopAll( wait:Future<Bool> )
 		
 		
@@ -121,13 +107,13 @@ Class ProcessReader
 		If Not _procOpen
 		If Not _procOpen
 '			If _stdoutWaiting
 '			If _stdoutWaiting
 '				_stdoutWaiting.Set( False )
 '				_stdoutWaiting.Set( False )
-'				_stdoutWaiting=Null
 '			Endif
 '			Endif
 			Return
 			Return
 		Endif
 		Endif
 		
 		
 		_process.Terminate()
 		_process.Terminate()
-		_running=False
+		
+		OnStop()
 	End
 	End
 	
 	
 	#rem monkeydoc Is reading currently in progress.
 	#rem monkeydoc Is reading currently in progress.
@@ -137,10 +123,6 @@ Class ProcessReader
 		Return _running
 		Return _running
 	End
 	End
 	
 	
-	Protected
-	
-	Method New()
-	End
 	
 	
 	Private
 	Private
 	
 	
@@ -150,7 +132,6 @@ Class ProcessReader
 	Field _stdoutWaiting:Future<Bool>
 	Field _stdoutWaiting:Future<Bool>
 	Field _stdoutOpen:Bool,_procOpen:Bool
 	Field _stdoutOpen:Bool,_procOpen:Bool
 	Global _items:=New Stack<ProcessReader>
 	Global _items:=New Stack<ProcessReader>
-	Global _recycled:=New Stack<ProcessReader>
 	Global _stopSize:Int,_stopCounter:Int
 	Global _stopSize:Int,_stopCounter:Int
 	
 	
 	Method RunInternal:String( cmd:String )
 	Method RunInternal:String( cmd:String )
@@ -209,7 +190,7 @@ Class ProcessReader
 	
 	
 		If Not _running Or _procOpen Or _stdoutOpen Return
 		If Not _running Or _procOpen Or _stdoutOpen Return
 	
 	
-		_running=False
+		OnStop()
 		
 		
 		Local code:=_process.ExitCode
 		Local code:=_process.ExitCode
 		
 		
@@ -218,8 +199,13 @@ Class ProcessReader
 		
 		
 		If _stdoutWaiting
 		If _stdoutWaiting
 			_stdoutWaiting.Set( True )
 			_stdoutWaiting.Set( True )
-			_stdoutWaiting=Null
 		Endif
 		Endif
 	End
 	End
 	
 	
+	Method OnStop()
+		
+		_running=False
+		_items.Remove( Self )
+	End
+	
 End
 End

+ 2 - 1
Ted2.monkey2

@@ -110,6 +110,7 @@
 #Import "view/ViewExtensions"
 #Import "view/ViewExtensions"
 #Import "view/DockingViewExt"
 #Import "view/DockingViewExt"
 
 
+#Import "Tuple"
 #Import "Plugin"
 #Import "Plugin"
 #Import "ThemeImages"
 #Import "ThemeImages"
 #Import "Prefs"
 #Import "Prefs"
@@ -129,7 +130,7 @@ Using tinyxml2..
 
 
 Const MONKEY2_DOMAIN:="http://monkeycoder.co.nz"
 Const MONKEY2_DOMAIN:="http://monkeycoder.co.nz"
 
 
-Global AppTitle:="Ted2Go v2.6"
+Global AppTitle:="Ted2Go v2.7"
 
 
 
 
 Function Main()
 Function Main()

+ 99 - 0
Tuple.monkey2

@@ -0,0 +1,99 @@
+
+Namespace ted2go
+
+
+Class Tuple Abstract
+
+End
+
+'---------------------------
+' Tuple 2
+'---------------------------
+
+Class Tuple2<T1,T2> Extends Tuple Final
+	
+	Method New( item1:T1,item2:T2 )
+		
+		_i1=item1
+		_i2=item2
+	End
+	
+	Property Item1:T1()
+		Return _i1
+	End
+	
+	Property Item2:T2()
+		Return _i2
+	End
+	
+	Private
+	
+	Field _i1:T1,_i2:T2
+End
+
+
+'---------------------------
+' Tuple 3
+'---------------------------
+
+Class Tuple3<T1,T2,T3> Extends Tuple Final
+	
+	Method New( item1:T1,item2:T2,item3:T3 )
+		
+		_i1=item1
+		_i2=item2
+		_i3=item3
+	End
+	
+	Property Item1:T1()
+		Return _i1
+	End
+	
+	Property Item2:T2()
+		Return _i2
+	End
+	
+	Property Item3:T3()
+		Return _i3
+	End
+	
+	Private
+	
+	Field _i1:T1,_i2:T2,_i3:T3
+End
+
+
+'---------------------------
+' Tuple 4
+'---------------------------
+
+Class Tuple4<T1,T2,T3,T4> Extends Tuple Final
+	
+	Method New( item1:T1,item2:T2,item3:T3,item4:T4 )
+		
+		_i1=item1
+		_i2=item2
+		_i3=item3
+		_i4=item4
+	End
+	
+	Property Item1:T1()
+		Return _i1
+	End
+	
+	Property Item2:T2()
+		Return _i2
+	End
+	
+	Property Item3:T3()
+		Return _i3
+	End
+	
+	Property Item4:T4()
+		Return _i4
+	End
+	
+	Private
+	
+	Field _i1:T1,_i2:T2,_i3:T3,_i4:T4
+End

+ 96 - 57
document/CodeDocument.monkey2

@@ -120,6 +120,11 @@ Class CodeDocumentView Extends Ted2CodeTextView
 
 
 	Protected
 	Protected
 	
 	
+	Method OnThemeChanged() Override
+		
+		_doc.HideAutocomplete()
+	End
+	
 	Method OnRenderContent( canvas:Canvas ) Override
 	Method OnRenderContent( canvas:Canvas ) Override
 	
 	
 		Local color:=canvas.Color
 		Local color:=canvas.Color
@@ -194,6 +199,8 @@ Class CodeDocumentView Extends Ted2CodeTextView
 				End
 				End
 			Endif
 			Endif
 			
 			
+			CheckFormat( event,key )
+			
 			Select key
 			Select key
 			
 			
 				Case Key.Space
 				Case Key.Space
@@ -293,8 +300,6 @@ Class CodeDocumentView Extends Ted2CodeTextView
 			
 			
 				Case Key.Enter,Key.KeypadEnter 'auto indent
 				Case Key.Enter,Key.KeypadEnter 'auto indent
 			
 			
-					If _typing Then DoFormat( False )
-			
 					Local line:=CursorLine
 					Local line:=CursorLine
 					Local text:=Document.GetLine( line )
 					Local text:=Document.GetLine( line )
 					Local indent:=GetIndent( text )
 					Local indent:=GetIndent( text )
@@ -471,11 +476,6 @@ Class CodeDocumentView Extends Ted2CodeTextView
 					Return
 					Return
 			
 			
 			
 			
-				Case Key.Up,Key.Down
-			
-					DoFormat( True )
-			
-			
 				Case Key.V
 				Case Key.V
 			
 			
 					If CanPaste And ctrl
 					If CanPaste And ctrl
@@ -505,6 +505,8 @@ Class CodeDocumentView Extends Ted2CodeTextView
 			
 			
 		Case EventType.KeyChar
 		Case EventType.KeyChar
 			
 			
+			CheckFormat( event,event.Key )
+			
 			If event.Key = Key.Space And ctrl
 			If event.Key = Key.Space And ctrl
 				If _doc.CanShowAutocomplete()
 				If _doc.CanShowAutocomplete()
 					Local ident:=IdentBeforeCursor()
 					Local ident:=IdentBeforeCursor()
@@ -1065,7 +1067,9 @@ Class CodeDocument Extends Ted2Document
 	End
 	End
 	
 	
 	Method GotoDeclaration()
 	Method GotoDeclaration()
-	
+		
+		If Not _parsingEnabled Return
+		
 		Local ident:=_codeView.FullIdentAtCursor
 		Local ident:=_codeView.FullIdentAtCursor
 		Local line:=TextDocument.FindLine( _codeView.Cursor )
 		Local line:=TextDocument.FindLine( _codeView.Cursor )
 		Local item:=_parser.ItemAtScope( ident,Path,line )
 		Local item:=_parser.ItemAtScope( ident,Path,line )
@@ -1101,6 +1105,11 @@ Class CodeDocument Extends Ted2Document
 		If Not Prefs.AcEnabled Return False
 		If Not Prefs.AcEnabled Return False
 		
 		
 		Local line:=TextDocument.FindLine( _codeView.Cursor )
 		Local line:=TextDocument.FindLine( _codeView.Cursor )
+		
+		' is inside of comment?
+		Local state:=TextDocument.LineState( line )
+		If state & 255 <> 255 Return False
+		
 		Local text:=TextDocument.GetLine( line )
 		Local text:=TextDocument.GetLine( line )
 		Local posInLine:=_codeView.Cursor-TextDocument.StartOfLine( line )
 		Local posInLine:=_codeView.Cursor-TextDocument.StartOfLine( line )
 		
 		
@@ -1114,40 +1123,38 @@ Class CodeDocument Extends Ted2Document
 		If ident = "" Then ident=_codeView.IdentBeforeCursor()
 		If ident = "" Then ident=_codeView.IdentBeforeCursor()
 		
 		
 		'show
 		'show
-		Local line:=TextDocument.FindLine( _codeView.Cursor )
+		Local lineNum:=TextDocument.FindLine( _codeView.Cursor )
+		Local lineStr:=TextDocument.GetLine( lineNum )
+		Local posInLine:=_codeView.Cursor-TextDocument.StartOfLine( lineNum )
 		
 		
 		If byCtrlSpace And AutoComplete.IsOpened
 		If byCtrlSpace And AutoComplete.IsOpened
 			AutoComplete.DisableUsingsFilter=Not AutoComplete.DisableUsingsFilter
 			AutoComplete.DisableUsingsFilter=Not AutoComplete.DisableUsingsFilter
 		Endif
 		Endif
 		
 		
-		AutoComplete.Show( ident,Path,FileExtension,line )
+		AutoComplete.Show( ident,Path,FileExtension,lineNum,lineStr,posInLine )
 		
 		
 		If Not AutoComplete.IsOpened Return
 		If Not AutoComplete.IsOpened Return
 		
 		
 		Local frame:=AutoComplete.Frame
 		Local frame:=AutoComplete.Frame
 		
 		
-		Local w:=frame.Width
+		Local w:=frame.Width+ScaledVal( 18 ) 'hack: 18px for scroll
 		Local h:=frame.Height
 		Local h:=frame.Height
 		
 		
 		Local cursorRect:=_codeView.CursorRect
 		Local cursorRect:=_codeView.CursorRect
 		Local scroll:=_codeView.Scroll
 		Local scroll:=_codeView.Scroll
 		Local tvFrame:=_codeView.RenderRect
 		Local tvFrame:=_codeView.RenderRect
 		Local yy:=tvFrame.Top+cursorRect.Top-scroll.y
 		Local yy:=tvFrame.Top+cursorRect.Top-scroll.y
-		yy+=30 'magic offset :)
+		yy+=ScaledVal( 26 ) 'magic offset :)
 		Local xx:=tvFrame.Left+cursorRect.Left-scroll.x'+100
 		Local xx:=tvFrame.Left+cursorRect.Left-scroll.x'+100
-		xx+=46 'magic
+		xx+=ScaledVal( 46 ) 'magic
 		frame.Left=xx
 		frame.Left=xx
 		frame.Right=frame.Left+w
 		frame.Right=frame.Left+w
 		frame.Top=yy
 		frame.Top=yy
 		frame.Bottom=frame.Top+h
 		frame.Bottom=frame.Top+h
 		' fit dialog into window
 		' fit dialog into window
 		If frame.Bottom > MainWindow.RenderRect.Bottom
 		If frame.Bottom > MainWindow.RenderRect.Bottom
-			
-			Local dy:=frame.Bottom-MainWindow.RenderRect.Bottom-128
-			frame.Top+=dy
-			frame.Bottom+=dy
-			frame.Left+=50
-			frame.Right+=50
+			Local dy:=frame.Bottom-MainWindow.RenderRect.Bottom-ScaledVal( 128 )
+			frame.MoveBy( ScaledVal( 50 ),dy )
 		Endif
 		Endif
 		AutoComplete.Frame=frame
 		AutoComplete.Frame=frame
 		
 		
@@ -1208,6 +1215,7 @@ Class CodeDocument Extends Ted2Document
 	Field _parser:ICodeParser
 	Field _parser:ICodeParser
 	Field _prevLine:=-1
 	Field _prevLine:=-1
 	Field _prevScope:CodeItem
 	Field _prevScope:CodeItem
+	Field _parsingEnabled:Bool
 	
 	
 	Field _toolBar:ToolBarExt
 	Field _toolBar:ToolBarExt
 	Field _content:DockingView
 	Field _content:DockingView
@@ -1302,12 +1310,15 @@ Class CodeDocument Extends Ted2Document
 	
 	
 	Method OnLoad:Bool() Override
 	Method OnLoad:Bool() Override
 	
 	
-		_parser=ParsersManager.Get( FileExtension )
-	
 		Local text:=stringio.LoadString( Path )
 		Local text:=stringio.LoadString( Path )
 		
 		
 		_doc.Text=text
 		_doc.Text=text
 		
 		
+		_parser=ParsersManager.Get( FileExtension )
+		_parsingEnabled=Not ParsersManager.IsFake( _parser )
+		
+		ParsingDoc() 'start parsing right after loading, not by timer
+		
 		Return True
 		Return True
 	End
 	End
 	
 	
@@ -1333,7 +1344,11 @@ Class CodeDocument Extends Ted2Document
 	End
 	End
 	
 	
 	Method OnLineChanged:Void( prevLine:Int,newLine:Int )
 	Method OnLineChanged:Void( prevLine:Int,newLine:Int )
-	
+		
+		If AutoComplete.IsOpened Then AutoComplete.Hide()
+		
+		If Not _parsingEnabled Return
+		
 		Local scope:=_parser.GetScope( Path,_codeView.LineNumAtCursor+1 )	
 		Local scope:=_parser.GetScope( Path,_codeView.LineNumAtCursor+1 )	
 		If scope And scope <> _prevScope
 		If scope And scope <> _prevScope
 			Local classs := (_prevScope And scope.IsLikeClass And scope = _prevScope.Parent)
 			Local classs := (_prevScope And scope.IsLikeClass And scope = _prevScope.Parent)
@@ -1343,7 +1358,6 @@ Class CodeDocument Extends Ted2Document
 			_prevScope = scope
 			_prevScope = scope
 		Endif
 		Endif
 		
 		
-		If AutoComplete.IsOpened Then AutoComplete.Hide()
 	End
 	End
 	
 	
 	Method UpdateCodeTree()
 	Method UpdateCodeTree()
@@ -1351,7 +1365,55 @@ Class CodeDocument Extends Ted2Document
 		_treeView.Fill( FileExtension,Path )
 		_treeView.Fill( FileExtension,Path )
 	End
 	End
 	
 	
-	Method BgParsing( pathOnDisk:String )
+	Field _timeTextChanged:=0
+	Field _timeDocParsed:=0
+	Method ParsingOnTextChanged()
+		
+		If Not _parsingEnabled Return
+		
+		_timeTextChanged=Millisecs()
+		
+		If Not _timer Then _timer=New Timer( 1,Lambda()
+		
+			If _parsing Return
+			
+			Local msec:=Millisecs()
+			If msec<_timeDocParsed+1000 Return
+			If _timeTextChanged=0 Or msec<_timeTextChanged+1000 Return
+			_timeTextChanged=0
+			
+			ParsingDoc()
+		
+		End )
+		
+	End
+	
+	Method ParsingDoc()
+		
+		If _parsing Return
+		
+		_parsing=True
+		
+		New Fiber( Lambda()
+		
+			Local tmp:=MainWindow.AllocTmpPath( "_mx2cc_parse_",".monkey2" )
+			Local file:=StripDir( Path )
+			
+			SaveString( _doc.Text,tmp )
+			
+			ParsingFile( tmp )
+		
+			DeleteFile( tmp )
+			
+			_parsing=False
+			
+			_timeDocParsed=Millisecs()
+			
+		End )
+		
+	End
+	
+	Method ParsingFile( pathOnDisk:String )
 		
 		
 		If MainWindow.IsTerminating Return
 		If MainWindow.IsTerminating Return
 		
 		
@@ -1363,6 +1425,10 @@ Class CodeDocument Extends Ted2Document
 		
 		
 		If errors
 		If errors
 			
 			
+			If errors="#"
+				Return
+			Endif
+			
 			Local arr:=errors.Split( "~n" )
 			Local arr:=errors.Split( "~n" )
 			For Local s:=Eachin arr
 			For Local s:=Eachin arr
 				Local i:=s.Find( "] : Error : " )
 				Local i:=s.Find( "] : Error : " )
@@ -1396,38 +1462,7 @@ Class CodeDocument Extends Ted2Document
 		' -----------------------------------
 		' -----------------------------------
 		' catch for parsing
 		' catch for parsing
 		
 		
-		If FileExtension <> ".monkey2" Return
-
-		
-		If _timer _timer.Cancel()
-		
-		_timer=New Timer( 0.5,Lambda()
-		
-			If _parsing Return
-			
-			_parsing=True
-			
-			New Fiber( Lambda()
-			
-				Local tmp:=MainWindow.AllocTmpPath( "_mx2cc_parse_",".monkey2" )
-				Local file:=StripDir( Path )
-				'Print "parsing:"+file+" ("+tmp+")"
-				
-				SaveString( _doc.Text,tmp )
-			
-				BgParsing( tmp )
-				
-				'Print "finished:"+file
-				
-				DeleteFile( tmp )
-				
-				_timer.Cancel()
-				
-				_timer=Null
-				_parsing=False
-				
-			End )
-		End )
+		ParsingOnTextChanged()
 		
 		
 	End
 	End
 	
 	
@@ -1466,7 +1501,7 @@ Class CodeDocument Extends Ted2Document
 		Local event:=New KeyEvent( EventType.KeyDown,_codeView,Key.Tab,Key.Tab,Modifier.None,"~t" )
 		Local event:=New KeyEvent( EventType.KeyDown,_codeView,Key.Tab,Key.Tab,Modifier.None,"~t" )
 		_codeView.OnKeyEvent( event )
 		_codeView.OnKeyEvent( event )
 	End
 	End
-				
+	
 End
 End
 
 
 
 
@@ -1719,3 +1754,7 @@ Class NavCode
 	
 	
 End
 End
 
 
+Function ScaledVal:Int( val:Int )
+	
+	Return val*App.Theme.Scale.x
+End

+ 7 - 0
parser/CodeItem.monkey2

@@ -34,10 +34,17 @@ End
 
 
 Class CodeItem
 Class CodeItem
 	
 	
+	Field nspace:NSpace
+	
 	Method New( ident:String )
 	Method New( ident:String )
 		_ident=ident
 		_ident=ident
 	End
 	End
 	
 	
+	Method OnRemoved()
+		
+		If nspace Then nspace.items.Remove( Self )
+	End
+	
 	Property Ident:String()
 	Property Ident:String()
 		Return _ident
 		Return _ident
 	Setter( value:String )
 	Setter( value:String )

+ 268 - 26
parser/Monkey2Parser.monkey2

@@ -121,6 +121,8 @@ Class Monkey2Parser Extends CodeParserPlugin
 		' start parsing process
 		' start parsing process
 		Local str:=StartParsing( pathOnDisk,isModule )
 		Local str:=StartParsing( pathOnDisk,isModule )
 		
 		
+		If Not str Return "#" 'special kind of error
+		
 '		If Not isModule
 '		If Not isModule
 '			Print "-----"
 '			Print "-----"
 '			Print str
 '			Print str
@@ -133,7 +135,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 		
 		
 		' return errors
 		' return errors
 		If hasErrors Return (i > 0) ? str.Slice( 0,i ) Else str
 		If hasErrors Return (i > 0) ? str.Slice( 0,i ) Else str
-		If i=-1 Return "" ' not a valid json
+		If i=-1 Return "#" ' not a valid json
 		
 		
 		'----------
 		'----------
 		
 		
@@ -153,8 +155,8 @@ Class Monkey2Parser Extends CodeParserPlugin
 			Items.AddAll( items )
 			Items.AddAll( items )
 			
 			
 			For Local i:=Eachin items
 			For Local i:=Eachin items
-				i.Namespac=nspace
 				i.IsModuleMember=isModule
 				i.IsModuleMember=isModule
+				NSpace.AddItem( nspace,i )
 			Next
 			Next
 			'Print "file parsed: "+filePath+", items.count: "+items.Count()
 			'Print "file parsed: "+filePath+", items.count: "+items.Count()
 		Endif
 		Endif
@@ -351,9 +353,14 @@ Class Monkey2Parser Extends CodeParserPlugin
 	
 	
 	Method ItemAtScope:CodeItem( ident:String,filePath:String,docLine:Int )
 	Method ItemAtScope:CodeItem( ident:String,filePath:String,docLine:Int )
 		
 		
-		Local result:=New Stack<CodeItem>
-		GetItemsInternal( ident,filePath,docLine,result,_lastUsingsFilter,1 )
-		Return (Not result.Empty) ? result[0] Else Null
+		Local opts:=New ParserRequestOptions
+		opts.results=New Stack<CodeItem>
+		opts.ident=ident
+		opts.filePath=filePath
+		opts.docLineNum=docLine
+		opts.usingsFilter=_lastUsingsFilter
+		GetItemsInternal( opts,1 )
+		Return (Not opts.results.Empty) ? opts.results[0] Else Null
 	End
 	End
 	
 	
 	Method RefineRawType( item:CodeItem )
 	Method RefineRawType( item:CodeItem )
@@ -367,9 +374,9 @@ Class Monkey2Parser Extends CodeParserPlugin
 		Return Null
 		Return Null
 	End
 	End
 	
 	
-	Method GetItemsForAutocomplete( ident:String,filePath:String,docLine:Int,target:Stack<CodeItem>,usingsFilter:Stack<String> =Null )
+	Method GetItemsForAutocomplete( options:ParserRequestOptions )
 		
 		
-		GetItemsInternal( ident,filePath,docLine,target,usingsFilter,-1 )
+		GetItemsInternal( options )
 	End
 	End
 	
 	
 	
 	
@@ -388,7 +395,14 @@ Class Monkey2Parser Extends CodeParserPlugin
 		_types=New String[](".monkey2")
 		_types=New String[](".monkey2")
 	End
 	End
 	
 	
-	Method GetItemsInternal( ident:String,filePath:String,docLine:Int,target:Stack<CodeItem>,usingsFilter:Stack<String> =Null,resultLimit:Int=-1 )
+	Method GetItemsInternal( options:ParserRequestOptions,resultLimit:Int=-1 )
+		
+		Local ident:=options.ident
+		Local filePath:=options.filePath
+		Local docLineNum:=options.docLineNum
+		Local docLineStr:=options.docLineStr
+		Local target:=options.results
+		Local usingsFilter:=options.usingsFilter
 		
 		
 		_lastUsingsFilter=usingsFilter
 		_lastUsingsFilter=usingsFilter
 		
 		
@@ -399,7 +413,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 		Local onlyOne:=(idents.Length=1)
 		Local onlyOne:=(idents.Length=1)
 	
 	
 		'check current scope
 		'check current scope
-		Local rootScope:=GetScope( filePath,docLine )
+		Local rootScope:=GetScope( filePath,docLineNum )
 		Local scope:=rootScope
 		Local scope:=rootScope
 		
 		
 		'If scope Print scope.Text
 		'If scope Print scope.Text
@@ -414,7 +428,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 		Local items:=New Stack<CodeItem>
 		Local items:=New Stack<CodeItem>
 		Local fullyMatched:CodeItem=Null
 		Local fullyMatched:CodeItem=Null
 		
 		
-		'Print "idents: "+firstIdent+" - "+lastIdent
+		'Print "idents: "+firstIdent+" - "+lastIdent+" - "+ident
 		
 		
 		If isSelf Or isSuper
 		If isSelf Or isSuper
 			
 			
@@ -445,7 +459,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 							Continue
 							Continue
 						Endif
 						Endif
 						' additional checking for the first ident
 						' additional checking for the first ident
-						If IsLocalMember( i ) And i.ScopeStartPos.x > docLine
+						If IsLocalMember( i ) And i.ScopeStartPos.x > docLineNum
 							'Print "cont3: "+i.Ident
 							'Print "cont3: "+i.Ident
 							Continue
 							Continue
 						Endif
 						Endif
@@ -492,7 +506,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 			item=_aliases[firstIdent]
 			item=_aliases[firstIdent]
 			If item
 			If item
 				
 				
-				If CheckUsingsFilter( item,usingsFilter )
+				If CheckUsingsFilter( item.Namespac,usingsFilter )
 					target.Add( item )
 					target.Add( item )
 					If resultLimit>0 And target.Length=resultLimit Return
 					If resultLimit>0 And target.Length=resultLimit Return
 				Endif
 				Endif
@@ -501,7 +515,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 				
 				
 				For Local i:=Eachin Items
 				For Local i:=Eachin Items
 					
 					
-					If Not CheckUsingsFilter( i,usingsFilter )
+					If Not CheckUsingsFilter( i.Namespac,usingsFilter )
 						'Print "skip 1 "+i.Ident
 						'Print "skip 1 "+i.Ident
 						Continue
 						Continue
 					Endif
 					Endif
@@ -517,7 +531,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 						Continue
 						Continue
 					Endif
 					Endif
 					
 					
-					If IsLocalMember( i ) And i.ScopeStartPos.x > docLine
+					If IsLocalMember( i ) And i.ScopeStartPos.x > docLineNum
 						'Print "skip 4 "+i.Ident
 						'Print "skip 4 "+i.Ident
 						Continue
 						Continue
 					Endif
 					Endif
@@ -551,6 +565,71 @@ Class Monkey2Parser Extends CodeParserPlugin
 		'If item Print "item: "+item.Scope+", kind: "+item.KindStr
 		'If item Print "item: "+item.Scope+", kind: "+item.KindStr
 		'DebugStop()
 		'DebugStop()
 		
 		
+		' check namespace qualifier
+		If item = Null
+			
+			Local s:=ident
+			If s.EndsWith( "." ) Then s=s.Slice( 0,s.Length-1 )
+			Local tuple:=NSpace.Find( s,False,usingsFilter )
+			Local ns := tuple ? (tuple.Item1 ? tuple.Item1 Else tuple.Item2) Else Null
+			If ns
+				' check ident after namespace
+				Local needFind:=""
+				Local stripped:=NSpace.StripNSpace( s,ns )
+				If stripped<>s
+					Local i:=stripped.Find( "." )
+					If i>0
+						needFind=stripped.Slice( 0,i )
+					Else
+						needFind=stripped
+					Endif
+				Endif
+				' grab all items from namespace
+				For Local i:=Eachin ns.items
+					If i.Access<>AccessMode.Public_ And i.FilePath<>filePath Continue
+					If needFind And i.Ident<>needFind Continue
+					If needFind
+						item=i
+						Exit
+					Else
+						target.Add( i )
+						If resultLimit>0 And target.Length=resultLimit Return
+					Endif
+				Next
+				' also grab all children namespaces
+				For Local i:=Eachin ns.nspaces
+					' dirty, create fake code items
+					Local code:=New CodeItem( i.name )
+					target.Add( code )
+					' don't check limit here
+					'If resultLimit>0 And target.Length=resultLimit Return
+				Next
+				
+			Elseif onlyOne
+				
+				Local filter:=usingsFilter
+				' don't filter namespaces for 'using xxx.yyy' section
+				If docLineStr.Trim().ToLower().StartsWith( "using " )
+					filter=Null
+				Endif
+				' grab all namespaces by ident
+				For Local n:=Eachin NSpace.ALL.Values.All()
+					Local r:NSpace
+					If n.name.StartsWith( firstIdent )
+						r=n
+					Else
+						r=n.GetNSpace( firstIdent,True,True )
+					Endif
+					If r And CheckUsingsFilter( r.FullName,filter )
+						' dirty, create fake code items
+						Local code:=New CodeItem( r.name )
+						target.Add( code )
+					Endif
+				Next
+				
+			Endif
+		Endif
+		
 		' var1.var2.var3...
 		' var1.var2.var3...
 		If Not onlyOne And item <> Null
 		If Not onlyOne And item <> Null
 			
 			
@@ -620,7 +699,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 						Endif
 						Endif
 						' extensions can be placed in different namespaces
 						' extensions can be placed in different namespaces
 						If i.IsExtension
 						If i.IsExtension
-							If Not CheckUsingsFilter( i,usingsFilter )
+							If Not CheckUsingsFilter( i.Namespac,usingsFilter )
 								Continue
 								Continue
 							Endif
 							Endif
 						Endif
 						Endif
@@ -665,7 +744,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 		item.IsExtension=True
 		item.IsExtension=True
 		list.Add( item )
 		list.Add( item )
 	End
 	End
-
+	
 	Method RemoveExtensions( filePath:String )
 	Method RemoveExtensions( filePath:String )
 		
 		
 		For Local list:=Eachin ExtraItemsMap.Values.All()
 		For Local list:=Eachin ExtraItemsMap.Values.All()
@@ -700,13 +779,11 @@ Class Monkey2Parser Extends CodeParserPlugin
 		
 		
 		If Not _enabled Return ""
 		If Not _enabled Return ""
 		
 		
-		Local proc:=ProcessReader.Obtain( pathOnDisk )
+		Local proc:=New ProcessReader( pathOnDisk )
 		
 		
 		Local cmd:=_mx2ccPath+" makeapp -parse -geninfo ~q"+pathOnDisk+"~q"
 		Local cmd:=_mx2ccPath+" makeapp -parse -geninfo ~q"+pathOnDisk+"~q"
 		Local str:=proc.Run( cmd )
 		Local str:=proc.Run( cmd )
 		
 		
-		ProcessReader.Recycle( proc )
-		
 		Return str
 		Return str
 	End
 	End
 	
 	
@@ -933,17 +1010,18 @@ Class Monkey2Parser Extends CodeParserPlugin
 		
 		
 	End
 	End
 	
 	
-	Method CheckUsingsFilter:Bool( item:CodeItem,usingsFilter:StringStack )
+	Function CheckUsingsFilter:Bool( nspace:String,usingsFilter:StringStack )
 		
 		
 		If Not usingsFilter Or usingsFilter.Empty Return True
 		If Not usingsFilter Or usingsFilter.Empty Return True
+		If Not nspace Return True
 		
 		
 		For Local u:=Eachin usingsFilter
 		For Local u:=Eachin usingsFilter
 			If u.EndsWith( ".." )
 			If u.EndsWith( ".." )
 				u=u.Slice( 0,u.Length-2 )
 				u=u.Slice( 0,u.Length-2 )
-				If item.Namespac=u Return True
-				If item.Namespac.StartsWith( u+"." ) Return True
+				If nspace=u Return True
+				If nspace.StartsWith( u+"." ) Return True
 			Else
 			Else
-				If item.Namespac = u Return True
+				If nspace=u Return True
 			Endif
 			Endif
 		Next
 		Next
 		Return False
 		Return False
@@ -1171,6 +1249,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 		
 		
 		For Local i:=Eachin list
 		For Local i:=Eachin list
 			Items.Remove( i )
 			Items.Remove( i )
+			i.OnRemoved()
 		Next
 		Next
 		
 		
 		ItemsMap.Remove( path )
 		ItemsMap.Remove( path )
@@ -1198,13 +1277,178 @@ Struct Chars
 	Const DIGIT_0:=48
 	Const DIGIT_0:=48
 	Const DIGIT_9:=57
 	Const DIGIT_9:=57
 	Const AT:=64
 	Const AT:=64
-	Const GRID:=35
+	Const GRID:=35 ' #
 	Const TAB:=9
 	Const TAB:=9
 	Const SPACE:=32
 	Const SPACE:=32
 	
 	
 End
 End
 
 
 
 
+Class NSpace
+	
+	Field parent:NSpace
+	Field name:String
+	Field items:=New Stack<CodeItem>
+	Field nspaces:=New Stack<NSpace>
+	
+	Property NestedLevel:Int()
+		
+		Local level:=0
+		Local par:=parent
+		While par
+			level+=1
+			par=par.parent
+		Wend
+		Return level
+	End
+	
+	Property FullName:String()
+	
+		Local s:=name
+		Local par:=parent
+		While par
+			s=par.name+"."+s
+			par=par.parent
+		Wend
+		Return s
+	End
+	
+	Method GetNSpace:NSpace( name:String,nested:Bool=False,startsWith:Bool=False )
+		
+		Return GetNSpaceInternal( nspaces,name,nested,startsWith )
+	End
+	
+	Const ALL:=New StringMap<NSpace>
+	Const ALL_PARTS:=New Stack<NSpace>
+	
+	Function StripNSpace:String( str:String,ns:NSpace )
+		
+		Local name:=""
+		While ns
+			name=ns.name+"."+name
+			If str.StartsWith( name ) Return str.Slice( name.Length )
+			ns=ns.parent
+		Wend
+		Return str
+	End
+	
+	Function Find:Tuple2<NSpace,NSpace>( fullNameWithDots:String,wholeMatched:Bool=False,usingsFilter:StringStack=Null )
+		
+		Local parts:=fullNameWithDots.Split( "." )
+		
+		If wholeMatched
+			
+			Local ns:=ALL[parts[0]]
+			If Not ns Return Null
+		
+			For Local i:=1 Until parts.Length
+				ns=ns.GetNSpace( parts[i] )
+				If Not ns Exit
+			Next
+			
+			Return New Tuple2<NSpace,NSpace>( ns,Null )
+			
+		Endif
+		
+		' not whole matched
+		Local list:=New Stack<NSpace>
+		Local name:=parts[0]
+		' find all nspaces by first part
+		For Local n:=Eachin ALL.Values.All()
+			Local r:NSpace
+			If n.name=name
+				r=n
+			Else
+				r=n.GetNSpace( name,True )
+			Endif
+			If r Then list.Add( r )
+		Next
+		If list.Empty Return Null
+		
+		list.Sort( Lambda:Int( n1:NSpace,n2:NSpace )
+			Return n1.NestedLevel<=>n2.NestedLevel
+		End )
+		
+		Local lastNs:NSpace
+		For Local i:=1 Until parts.Length
+			For Local k:=0 Until list.Length
+				Local n:=list[k]
+				If Not n Continue
+				Local r:=n.GetNSpace( parts[i] )
+				If r=Null And lastNs=Null
+					lastNs=n
+				Endif
+				list.Set( k,r ) ' "r" can be null here
+			Next
+		Next
+		
+		Local ns:NSpace
+		For Local n:=Eachin list
+			If n And Monkey2Parser.CheckUsingsFilter( n.FullName,usingsFilter )
+				ns=n
+				Exit
+			Endif
+		Next
+		
+		Return New Tuple2<NSpace,NSpace>( ns,lastNs )
+		
+	End
+	
+	Function AddItem( nspace:String,item:CodeItem )
+	
+		item.Namespac=nspace
+		Local parts:=nspace.Split( "." )
+		' root
+		Local ns:NSpace=Null,prev:NSpace=Null
+		Local sumName:=""
+		' hierarchy
+		For Local part:=Eachin parts
+			sumName+=part
+			If ns=Null
+				' add root part into map
+				ns=GetOrCreate<NSpace>( ALL,part )
+			Else
+				Local i:=prev.GetNSpace( part )
+				If i
+					ns=i
+				Else
+					ns=New NSpace
+					ns.parent=prev
+					prev.nspaces.AddUnique( ns )
+				Endif
+			Endif
+			ns.name=part
+			If sumName=nspace
+				ns.items.Add( item )
+				item.nspace=ns
+				Exit
+			Endif
+			sumName+="."
+			prev=ns
+		Next
+	
+	End
+	
+	
+	Private
+	
+	Method GetNSpaceInternal:NSpace( nspaces:Stack<NSpace>,name:String,nested:Bool=False,startsWith:Bool=False )
+	
+		For Local n:=Eachin nspaces
+			If (startsWith And n.name.StartsWith( name )) Or n.name=name Return n
+		Next
+		If nested
+			For Local n:=Eachin nspaces
+				Local r:=GetNSpaceInternal( n.nspaces,name,True,startsWith )
+				If r Return r
+			Next
+		Endif
+		Return Null
+	End
+	
+End
+
+
 Private
 Private
 
 
 Function GetLiteralType:String( typeIdent:String )
 Function GetLiteralType:String( typeIdent:String )
@@ -1273,5 +1517,3 @@ Struct Flags
 	Const DECL_IFACEMEMBER:=$080000
 	Const DECL_IFACEMEMBER:=$080000
 	
 	
 End
 End
-
-

+ 23 - 5
parser/Parser.monkey2

@@ -12,7 +12,7 @@ Interface ICodeParser
 	Method GetScope:CodeItem( docPath:String,docLine:Int )
 	Method GetScope:CodeItem( docPath:String,docLine:Int )
 	Method ItemAtScope:CodeItem( ident:String,filePath:String,docLine:Int )
 	Method ItemAtScope:CodeItem( ident:String,filePath:String,docLine:Int )
 	
 	
-	Method GetItemsForAutocomplete( ident:String,filePath:String,docLine:Int,target:Stack<CodeItem>,usingsFilter:Stack<String> =Null )
+	Method GetItemsForAutocomplete( options:ParserRequestOptions )
 	Method CheckStartsWith:Bool( ident1:String,ident2:String )
 	Method CheckStartsWith:Bool( ident1:String,ident2:String )
 	
 	
 	Method GetItem:CodeItem( ident:String )
 	Method GetItem:CodeItem( ident:String )
@@ -33,7 +33,7 @@ Class ParsersManager
 		For Local p:=Eachin plugins
 		For Local p:=Eachin plugins
 			If p.CheckFileTypeSuitability( fileType ) Then Return p
 			If p.CheckFileTypeSuitability( fileType ) Then Return p
 		Next
 		Next
-		Return _empty
+		Return _fake
 	End
 	End
 
 
 	Function DisableAll()
 	Function DisableAll()
@@ -44,10 +44,15 @@ Class ParsersManager
 		Next
 		Next
 	End
 	End
 	
 	
+	Function IsFake:Bool( parser:ICodeParser )
+		
+		Return parser=_fake
+	End
+	
 	
 	
 	Private
 	Private
 	
 	
-	Global _empty:=New EmptyParser
+	Global _fake:=New FakeParser
 	
 	
 End
 End
 
 
@@ -59,9 +64,22 @@ Function StripGenericType:String( ident:String )
 End
 End
 
 
 
 
+Class ParserRequestOptions Final
+	
+	Field ident:String
+	Field filePath:String
+	Field docLineNum:Int
+	Field results:Stack<CodeItem>
+	Field usingsFilter:Stack<String>
+	Field docLineStr:String
+	Field docPosInLine:Int
+	
+End
+
+
 Private
 Private
 
 
-Class EmptyParser Implements ICodeParser
+Class FakeParser Implements ICodeParser
 
 
 	Property Items:Stack<CodeItem>()
 	Property Items:Stack<CodeItem>()
 		Return _items
 		Return _items
@@ -97,7 +115,7 @@ Class EmptyParser Implements ICodeParser
 	End
 	End
 	Method RefineRawType( item:CodeItem )
 	Method RefineRawType( item:CodeItem )
 	End
 	End
-	Method GetItemsForAutocomplete( ident:String,filePath:String,docLine:Int,target:Stack<CodeItem>,usingsFilter:Stack<String> =Null )
+	Method GetItemsForAutocomplete( options:ParserRequestOptions )
 	End
 	End
 	Method CheckStartsWith:Bool( ident1:String,ident2:String )
 	Method CheckStartsWith:Bool( ident1:String,ident2:String )
 		Return False
 		Return False

+ 9 - 2
syntax/CodeFormatter.monkey2

@@ -4,10 +4,13 @@ Namespace ted2go
 
 
 Interface ICodeFormatter
 Interface ICodeFormatter
 
 
-	Method Format( document:CodeTextView,all:Bool )
+	Method FormatWord( document:CodeTextView,customCursor:Int=-1 )
+	Method FormatLine( document:CodeTextView,line:Int )
 	
 	
 End
 End
+#Rem
 
 
+#End
 
 
 'base wrapper for code formatter
 'base wrapper for code formatter
 Class CodeFormatterPlugin Extends PluginDependsOnFileType Implements ICodeFormatter
 Class CodeFormatterPlugin Extends PluginDependsOnFileType Implements ICodeFormatter
@@ -49,7 +52,11 @@ Private
 
 
 Class EmptyFormatter Implements ICodeFormatter
 Class EmptyFormatter Implements ICodeFormatter
 	
 	
-	Method Format( document:CodeTextView,all:Bool )
+	Method FormatWord( document:CodeTextView,customCursor:Int=-1 )
+		'do nothing
+	End
+	
+	Method FormatLine( document:CodeTextView,line:Int )
 		'do nothing
 		'do nothing
 	End
 	End
 	
 	

+ 48 - 13
syntax/Monkey2Formatter.monkey2

@@ -3,7 +3,7 @@ Namespace ted2go
 
 
 
 
 Class Monkey2CodeFormatter Extends CodeFormatterPlugin
 Class Monkey2CodeFormatter Extends CodeFormatterPlugin
-
+	
 	Property Name:String() Override
 	Property Name:String() Override
 		Return "Monkey2CodeFormatter"
 		Return "Monkey2CodeFormatter"
 	End
 	End
@@ -18,10 +18,10 @@ Class Monkey2CodeFormatter Extends CodeFormatterPlugin
 		_types=New String[](".monkey2")
 		_types=New String[](".monkey2")
 	End
 	End
 	
 	
-	Method Format( view:CodeTextView, all:Bool )
-	
+	Method FormatWord( view:CodeTextView,customCursor:Int=-1 )
+		
 		Local doc:=view.Document
 		Local doc:=view.Document
-		Local cursor:=view.Cursor
+		Local cursor:=(customCursor<>-1) ? customCursor Else view.Cursor
 		
 		
 		'ignore comments...
 		'ignore comments...
 		'
 		'
@@ -30,10 +30,10 @@ Class Monkey2CodeFormatter Extends CodeFormatterPlugin
 		
 		
 		Local text:=doc.Text
 		Local text:=doc.Text
 		Local start:=cursor
 		Local start:=cursor
-		Local term:=all ? text.Length Else start
-
+		Local term:=text.Length
+		
 		'find start of ident
 		'find start of ident
-		'		
+		'
 		While start And IsIdent( text[start-1] )
 		While start And IsIdent( text[start-1] )
 			start-=1
 			start-=1
 		Wend
 		Wend
@@ -55,7 +55,7 @@ Class Monkey2CodeFormatter Extends CodeFormatterPlugin
 			While i And text[i-1]<=32
 			While i And text[i-1]<=32
 				i-=1
 				i-=1
 			Wend
 			Wend
-			If Not i Or text[i-1]<>35 Return
+			If Not i Or text[i-1]<>Chars.GRID Return
 			i-=1
 			i-=1
 			While i And text[i-1]<>10
 			While i And text[i-1]<>10
 				i-=1
 				i-=1
@@ -63,22 +63,57 @@ Class Monkey2CodeFormatter Extends CodeFormatterPlugin
 			Wend
 			Wend
 			'
 			'
 		Endif
 		Endif
-
+		
 		'find end of ident
 		'find end of ident
 		Local ends:=start
 		Local ends:=start
 		'
 		'
 		While ends<term And IsIdent( text[ends] ) And text[ends]<>10
 		While ends<term And IsIdent( text[ends] ) And text[ends]<>10
 			ends+=1
 			ends+=1
 		Wend
 		Wend
-		If ends=start return
-
+		If ends=start Return
+		
 		Local ident:=text.Slice( start,ends )
 		Local ident:=text.Slice( start,ends )
-
+		
 		Local kw:=view.Keywords.Get( ident )
 		Local kw:=view.Keywords.Get( ident )
 		
 		
 		If Not kw Or kw=ident Return
 		If Not kw Or kw=ident Return
 		
 		
 		doc.ReplaceText( start,ends,kw )
 		doc.ReplaceText( start,ends,kw )
 	End
 	End
-
+	
+	Method FormatLine( view:CodeTextView,line:Int )
+		
+		Local doc:=view.Document
+		
+		'ignore comments...
+		'
+		Local state:=doc.LineState( line )
+		If state & 255 <> 255 Return
+		
+		Local text:=doc.Text
+		Local i:=doc.StartOfLine( line )
+		Local term:=doc.EndOfLine( line )+1 ' grab \n char too
+		
+		Local identStart:=-1
+		
+		While i<term
+			
+			Local isIdent:=IsIdent( text[i] )
+			Local isLastPart:=(i=term-1)
+			If isIdent
+				If identStart=-1 Then identStart=i
+			Endif
+			If (Not isIdent Or isLastPart) And identStart<>-1 ' end of ident
+				Local ident:=text.Slice( identStart,i )
+				Local kw:=view.Keywords.Get( ident )
+				If kw And kw<>ident
+					doc.ReplaceText( identStart,i,kw )
+				Endif
+				identStart=-1
+			Endif
+			i+=1
+		Wend
+		
+	End
+	
 End
 End

+ 15 - 0
testing/ParserTests.monkey2

@@ -4,6 +4,19 @@ Namespace test2go
 
 
 Private
 Private
 
 
+
+Class TestTheSame
+	
+	Property TestTheSame:TestTheSame()
+		Return Null
+	End
+	
+	Method Test()
+		
+	End
+	
+End
+
 Struct Vec2i Extension
 Struct Vec2i Extension
 	
 	
 	Const One := New Vec2i( 1,1 )
 	Const One := New Vec2i( 1,1 )
@@ -15,6 +28,8 @@ Function vTest( v:Vec2i,e:Entity )
 	
 	
 	Local ok:=RequestOkay()
 	Local ok:=RequestOkay()
 	
 	
+	std.filesystem.AppDir()
+	filesystem.AppDir()
 End
 End
 
 
 
 

+ 25 - 0
utils/Utils.monkey2

@@ -230,6 +230,31 @@ Function DoInNotMainFiber( work:Void() )
 	End
 	End
 End
 End
 
 
+Function GetOrCreate<T>:T( map:StringMap<T>,key:String )
+	
+	Local item:=map[key]
+	If Not item
+		item=New T
+		map[key]=item
+	Endif
+	Return item
+End
+
+'Function SplitToCombinations:String[]( str:String,splitter:String="." )
+'	
+'	
+'End
+
+
+Class Stack<T> Extension
+	
+	Method AddUnique( value:T )
+		
+		If Not Self.Contains( value ) Then Self.Add( value )
+	End
+	
+End
+
 
 
 Struct Recti Extension
 Struct Recti Extension
 	
 	

+ 13 - 3
view/AutocompleteView.monkey2

@@ -149,7 +149,7 @@ Class AutocompleteDialog Extends NoTitleDialog
 		
 		
 	End
 	End
 	
 	
-	Method Show( ident:String,filePath:String,fileType:String,docLine:Int )
+	Method Show( ident:String,filePath:String,fileType:String,docLineNum:Int,docLineStr:String,docPosInLine:Int )
 		
 		
 		Local dotPos:=ident.FindLast( "." )
 		Local dotPos:=ident.FindLast( "." )
 		
 		
@@ -249,7 +249,17 @@ Class AutocompleteDialog Extends NoTitleDialog
 			Endif
 			Endif
 			
 			
 			_listForExtract.Clear()
 			_listForExtract.Clear()
-			parser.GetItemsForAutocomplete( ident,filePath,docLine,_listForExtract,usings )
+			
+			Global opts:=New ParserRequestOptions
+			opts.ident=ident
+			opts.filePath=filePath
+			opts.docLineNum=docLineNum
+			opts.docLineStr=docLineStr
+			opts.docPosInLine=docPosInLine
+			opts.results=_listForExtract
+			opts.usingsFilter=usings
+			
+			parser.GetItemsForAutocomplete( opts )
 			
 			
 			CodeItemsSorter.SortByType( _listForExtract,True )
 			CodeItemsSorter.SortByType( _listForExtract,True )
 		Endif
 		Endif
@@ -319,7 +329,7 @@ Class AutocompleteDialog Extends NoTitleDialog
 	
 	
 	Method OnThemeChanged() Override
 	Method OnThemeChanged() Override
 		
 		
-		_view.MaxSize=_etalonMaxSize*App.Theme.Scale
+		_view.MaxSize=(App.Theme.Scale.x>1) ? _etalonMaxSize*App.Theme.Scale Else _etalonMaxSize
 	End
 	End
 	
 	
 	Private
 	Private

+ 52 - 19
view/CodeTextView.monkey2

@@ -147,9 +147,9 @@ Class CodeTextView Extends TextView
 		
 		
 		While n >= start
 		While n >= start
 			
 			
-			If text[n] = 46 'dot
+			If text[n] = Chars.DOT 'dot
 				
 				
-			ElseIf Not (IsIdent( text[n] ) Or text[n] = 35) '35 => #
+			ElseIf Not (IsIdent( text[n] ) Or text[n] = Chars.GRID) '#
 				Exit
 				Exit
 			Endif
 			Endif
 			
 			
@@ -297,6 +297,33 @@ Class CodeTextView Extends TextView
 	
 	
 	Protected
 	Protected
 	
 	
+	Method CheckFormat( event:KeyEvent,key:Key )
+		
+		Select event.Type
+		
+			Case EventType.KeyChar
+				
+				If IsIdent( event.Text[0] )
+					_typing=True
+				Else
+					If _typing Then FormatWord()
+				Endif
+		
+			Case EventType.KeyDown
+				
+				Select key
+		
+					Case Key.Tab
+						If _typing Then FormatWord() ' like for Key.Space
+		
+					Case Key.Backspace,Key.KeyDelete,Key.Enter,Key.KeypadEnter
+						_typing=True
+		
+				End
+		
+		End
+	End
+	
 	Method OnContentMouseEvent( event:MouseEvent ) Override
 	Method OnContentMouseEvent( event:MouseEvent ) Override
 		
 		
 		Select event.Type
 		Select event.Type
@@ -353,12 +380,6 @@ Class CodeTextView Extends TextView
 			
 			
 			Case EventType.KeyChar
 			Case EventType.KeyChar
 				
 				
-				If IsIdent( event.Text[0] )
-					_typing=True
-				Else
-					If _typing Then DoFormat( False )
-				Endif
-				
 				' select next char in overwrite mode
 				' select next char in overwrite mode
 				If Cursor=Anchor And _overwriteMode
 				If Cursor=Anchor And _overwriteMode
 				
 				
@@ -367,6 +388,7 @@ Class CodeTextView Extends TextView
 						SelectText( Cursor,Cursor+1 )
 						SelectText( Cursor,Cursor+1 )
 					Endif
 					Endif
 				Endif
 				Endif
+			
 		End
 		End
 		
 		
 		Super.OnKeyEvent( event )
 		Super.OnKeyEvent( event )
@@ -380,8 +402,6 @@ Class CodeTextView Extends TextView
 	
 	
 	Protected
 	Protected
 	
 	
-	Field _typing:Bool
-	
 	Method OnCut( wholeLine:Bool=False )
 	Method OnCut( wholeLine:Bool=False )
 	
 	
 		If wholeLine
 		If wholeLine
@@ -536,12 +556,6 @@ Class CodeTextView Extends TextView
 		Return result
 		Return result
 	End
 	End
 	
 	
-	Method DoFormat( all:Bool )
-	
-		_typing=False
-		If Formatter Then Formatter.Format( Self,all )
-	End
-	
 	Method OnThemeChanged() Override
 	Method OnThemeChanged() Override
 		
 		
 		Super.OnThemeChanged()
 		Super.OnThemeChanged()
@@ -641,18 +655,37 @@ Class CodeTextView Extends TextView
 	Field _overwriteMode:Bool
 	Field _overwriteMode:Bool
 	Field _extraSelStart:Int=-1,_extraSelEnd:Int
 	Field _extraSelStart:Int=-1,_extraSelEnd:Int
 	Field _extraSelColor:Color=Color.DarkGrey
 	Field _extraSelColor:Color=Color.DarkGrey
+	Field _storedCursor:Int
+	Field _typing:Bool
 	
 	
 	Method OnCursorMoved()
 	Method OnCursorMoved()
 		
 		
 		Local line:=Document.FindLine( Cursor )
 		Local line:=Document.FindLine( Cursor )
 		If line <> _line
 		If line <> _line
+			If _typing Then FormatLine( _line )
+			
 			LineChanged( _line,line )
 			LineChanged( _line,line )
 			_line=line
 			_line=line
 		Endif
 		Endif
-				
-		'If Cursor <> Anchor Return
-		'DoFormat( True )
 		
 		
+		_storedCursor=Cursor
+	End
+	
+	Method FormatWord( customCursor:Int=-1 )
+	
+		_typing=False
+		If Formatter
+			Local cur:=(customCursor<>-1) ? customCursor Else _storedCursor
+			Formatter.FormatWord( Self,cur )
+		Endif
+	End
+	
+	Method FormatLine( line:Int )
+	
+		_typing=False
+		If Formatter
+			Formatter.FormatLine( Self,line )
+		Endif
 	End
 	End
 	
 	
 End
 End