Przeglądaj źródła

Squashed 'src/ted2go/' changes from c00d1a952..e1a83698e

e1a83698e Merge branch 'dev'
1592aa5be Fixed FogNear in 3d template.
0d413ebfe Added supporter into special thanks.
2df1b06b6 Cleanups.
a1f016a54 Fixed bug - tab continue dragging after being drag-n-dropped.
1c814ceba Now Examples loading when user open the tab first time.
2867ff9b1 Cleanups.
9de2cbd0e "Clean project" action now also deletes .mx2 folders.
37f9c5642 Fixes in parser - now it try to parse locked file if current file is inside of the same project.
756e6bf1c Improved searching folders with examples - skip *system* folders like bin / native / .buildv / etc.
72e8a8ba8 Added new tab "Examples" that collected special folders: bananas, tests and examples.
946749c92 Added *properties* section at the bottom of Source tab.
cf34f2ea4 Fixes in parser according to mx2cc_v1.15.
ee850711f Improved docs searching system!
f1c7ea14c Not fully implemented highlighting of code items - it works very slow.
c38374719 Added feature "Goto Next/Previous scope" by Alt+Up/Down.
757fa6ed4 Fixed theme colors for docs - now it depends on theme, dark docs for dark themes.
a8659127c New command Ctrl+W to expand seletion under cursor. It tries to intelligent select words.
3ca895558 Fixes in parsing system.
883b03a07 Docs tab - added action button "Show in Explorer".
839758d31 Fixed #144 - "c/c++ apostrophe handling".
970469b62 Done #142 - "Move treeview selected row color into theme."
0b4d499d3 Fixed #136 - "console output bug with windows style EOLs".
c3c80a812 Fixed #148 - "Skip searching in .mx2 folders ".
c9f2b20e0 Try to *parse* wnen *semant* can't work.
54e16d534 Fixed indentation fixer. :) (#136)
488698543 Improved parsing and code completion.
b8d6060c0 Fixed crash when app lost and got focus.
b0503461d Fixed case when Source tree collapse nodes after parse completed.
d06d092db Fixed #146 - Don't jump to error by pressing on error line in build console.
d6eb1e82a Fixed incorrect parsing behavior.
8ff42a57c Fixed renaming bug (#141)
d6eb0ee61 Fixes in parsing

git-subtree-dir: src/ted2go
git-subtree-split: e1a83698eaac705ac20a9692930404df68885661
Mark Sibly 7 lat temu
rodzic
commit
0ab8b8637d
47 zmienionych plików z 1580 dodań i 537 usunięć
  1. 75 41
      MainWindow.monkey2
  2. 98 7
      PathsProvider.monkey2
  3. 8 2
      Ted2.monkey2
  4. 8 3
      action/BuildActions.monkey2
  5. 18 5
      action/EditActions.monkey2
  6. 1 1
      action/FileActions.monkey2
  7. 5 2
      action/FindActions.monkey2
  8. 31 6
      action/GotoActions.monkey2
  9. 2 2
      action/TabActions.monkey2
  10. 1 1
      assets/aboutTed2Go.html
  11. 36 0
      assets/docsPriority.txt
  12. 1 1
      assets/newfiles/Simple_Mojo3d_App.monkey2
  13. 1 0
      assets/themes/default-tmp.json
  14. 14 1
      assets/themes/ted2-default.json
  15. 41 11
      assets/themes/themes.json
  16. 29 0
      di/DiSetup.monkey2
  17. 1 1
      dialog/FindInFilesDialog.monkey2
  18. 142 16
      document/CodeDocument.monkey2
  19. 3 2
      document/DocumentManager.monkey2
  20. 14 1
      document/Ted2Document.monkey2
  21. 42 3
      parser/CodeItem.monkey2
  22. 97 53
      parser/CodeParsing.monkey2
  23. 41 76
      parser/Monkey2Parser.monkey2
  24. 8 8
      syntax/CppHighlighter.monkey2
  25. 5 3
      syntax/Highlighter.monkey2
  26. 7 3
      syntax/Monkey2Highlighter.monkey2
  27. 2 0
      testing/async.cpp
  28. 0 0
      theme/ThemeImages.monkey2
  29. 51 0
      theme/ThemesInfo.monkey2
  30. 25 0
      utils/TextUtils.monkey2
  31. 17 10
      utils/Utils.monkey2
  32. 19 0
      utils/ViewUtils.monkey2
  33. 40 20
      view/AutocompleteView.monkey2
  34. 5 5
      view/CodeGutterView.monkey2
  35. 18 17
      view/CodeTextView.monkey2
  36. 27 10
      view/CodeTreeView.monkey2
  37. 10 1
      view/ConsoleViewExt.monkey2
  38. 229 0
      view/ExamplesView.monkey2
  39. 135 70
      view/HelpTreeView.monkey2
  40. 35 8
      view/HtmlViewExt.monkey2
  41. 1 1
      view/Monkey2TreeView.monkey2
  42. 15 13
      view/ProjectBrowserView.monkey2
  43. 60 25
      view/ProjectView.monkey2
  44. 17 13
      view/TabViewExt.monkey2
  45. 41 2
      view/TextViewExt.monkey2
  46. 25 18
      view/TreeViewExt.monkey2
  47. 79 75
      view/Undock.monkey2

+ 75 - 41
MainWindow.monkey2

@@ -138,6 +138,14 @@ Class MainWindowInstance Extends Window
 			"Word wrap" )
 			"Word wrap" )
 		it.ToggleMode=True
 		it.ToggleMode=True
 		
 		
+		Local tbAct:=New Action( " \r " )
+		tbAct.Triggered+=Lambda()
+			_outputConsole.ProcessingRtChar=Not _outputConsole.ProcessingRtChar
+		End
+		Local tb:=New ToolButtonExt( tbAct,"Processing \r char at the beginning of lines" )
+		tb.ToggleMode=True
+		bar.AddView( tb )
+		
 		_outputConsoleView=New DockingView
 		_outputConsoleView=New DockingView
 		_outputConsoleView.AddView( bar,"top" )
 		_outputConsoleView.AddView( bar,"top" )
 		_outputConsoleView.ContentView=_outputConsole
 		_outputConsoleView.ContentView=_outputConsole
@@ -163,6 +171,18 @@ Class MainWindowInstance Extends Window
 		_docsConsole=New DockingView
 		_docsConsole=New DockingView
 		bar=New ToolBarExt
 		bar=New ToolBarExt
 		bar.MaxSize=New Vec2i( 300,30 )
 		bar.MaxSize=New Vec2i( 300,30 )
+		
+		_helpSwitcher=New ToolButtonExt( New Action( ">" ) )
+		bar.AddView( _helpSwitcher,"left" )
+		bar.AddView( New SpacerView( 30,0 ),"left" ) ' right offset
+		
+		_helpSwitcher.Clicked=Lambda()
+		
+			_helpTree.Visible=Not _helpTree.Visible
+			_helpSwitcher.Text=_helpTree.Visible ? "<" Else ">"
+			_helpSwitcher.Hint=_helpTree.Visible ? "Hide docs index" Else "Show docs index"
+		End
+		
 		bar.AddIconicButton(
 		bar.AddIconicButton(
 			ThemeImages.Get( "docbar/home.png" ),
 			ThemeImages.Get( "docbar/home.png" ),
 			Lambda()
 			Lambda()
@@ -182,9 +202,18 @@ Class MainWindowInstance Extends Window
 				_helpView.Forward()
 				_helpView.Forward()
 			End,
 			End,
 			"Forward" )
 			"Forward" )
+		Local explorerAct:=New Action( " [*] " )
+		explorerAct.Triggered+=Lambda()
+			Local url:=_helpView.Url
+			requesters.OpenUrl( url )
+		End
+		Local explorerBtn:=New ToolButtonExt( explorerAct,"Show in Explorer" )
+		bar.AddView( explorerBtn )
+		
 		bar.AddSeparator()
 		bar.AddSeparator()
 		bar.AddSeparator()
 		bar.AddSeparator()
 		label=New Label
 		label=New Label
+		label.Style=App.Theme.GetStyle( "HelpPageAddress" )
 		
 		
 		bar.ContentView=label
 		bar.ContentView=label
 		
 		
@@ -194,20 +223,11 @@ Class MainWindowInstance Extends Window
 		End
 		End
 		
 		
 		_helpTree=Di.Resolve<HelpTreeView>()
 		_helpTree=Di.Resolve<HelpTreeView>()
-		_docsConsole.AddView( _helpTree,"right",200,True )
+		_docsConsole.AddView( _helpTree,"left",200,True )
 		
 		
 		_docsConsole.AddView( bar,"top" )
 		_docsConsole.AddView( bar,"top" )
 		_docsConsole.ContentView=_helpView
 		_docsConsole.ContentView=_helpView
 		
 		
-		_helpSwitcher=New ToolButtonExt( New Action( "<" ) )
-		bar.AddView( New SpacerView( 6,0 ),"right" ) ' right offset
-		bar.AddView( _helpSwitcher,"right" )
-		_helpSwitcher.Clicked=Lambda()
-		
-			_helpTree.Visible=Not _helpTree.Visible
-			_helpSwitcher.Text=_helpTree.Visible ? ">" Else "<"
-			_helpSwitcher.Hint=_helpTree.Visible ? "Hide docs index" Else "Show docs index"
-		End
 		_helpTree.Visible=False
 		_helpTree.Visible=False
 		_helpSwitcher.Clicked() 'show at startup
 		_helpSwitcher.Clicked() 'show at startup
 		
 		
@@ -223,6 +243,10 @@ Class MainWindowInstance Extends Window
 			_buildActions.GotoError( errors[0] )
 			_buildActions.GotoError( errors[0] )
 		End
 		End
 		
 		
+		' ExamplesView
+		'
+		_examplesView=Di.Resolve<ExamplesView>()
+		
 		' ProjectView
 		' ProjectView
 		'
 		'
 		_projectView=Di.Resolve<ProjectView>()
 		_projectView=Di.Resolve<ProjectView>()
@@ -281,7 +305,7 @@ Class MainWindowInstance Extends Window
 		_tabMenu.AddAction( _buildActions.lockBuildFile )
 		_tabMenu.AddAction( _buildActions.lockBuildFile )
 		_tabMenu.AddAction( _projectView.setMainFile )
 		_tabMenu.AddAction( _projectView.setMainFile )
 		_tabMenu.AddSeparator()
 		_tabMenu.AddSeparator()
-		_tabMenu.AddAction( "Open on Desktop" ).Triggered=Lambda()
+		_tabMenu.AddAction( "Show in Explorer" ).Triggered=Lambda()
 			
 			
 			Local path:=_docsManager.CurrentDocument?.Path
 			Local path:=_docsManager.CurrentDocument?.Path
 			If path
 			If path
@@ -361,6 +385,7 @@ Class MainWindowInstance Extends Window
 		_editMenu.AddAction( _editActions.paste )
 		_editMenu.AddAction( _editActions.paste )
 		_editMenu.AddSeparator()
 		_editMenu.AddSeparator()
 		_editMenu.AddAction( _editActions.selectAll )
 		_editMenu.AddAction( _editActions.selectAll )
+		_editMenu.AddAction( _editActions.selectWord )
 		_editMenu.AddSeparator()
 		_editMenu.AddSeparator()
 		' Edit -- Text
 		' Edit -- Text
 		Local subText:=New MenuExt( "Text" )
 		Local subText:=New MenuExt( "Text" )
@@ -374,6 +399,7 @@ Class MainWindowInstance Extends Window
 		Local subComment:=New MenuExt( "Comment" )
 		Local subComment:=New MenuExt( "Comment" )
 		subComment.AddAction( _editActions.comment )
 		subComment.AddAction( _editActions.comment )
 		subComment.AddAction( _editActions.uncomment )
 		subComment.AddAction( _editActions.uncomment )
+		
 		_editMenu.AddSubMenu( subComment )
 		_editMenu.AddSubMenu( subComment )
 		' Edit -- Convert case
 		' Edit -- Convert case
 		Local subCase:=New MenuExt( "Convert case" )
 		Local subCase:=New MenuExt( "Convert case" )
@@ -404,6 +430,9 @@ Class MainWindowInstance Extends Window
 		_gotoMenu.AddSeparator()
 		_gotoMenu.AddSeparator()
 		_gotoMenu.AddAction( _gotoActions.goBack )
 		_gotoMenu.AddAction( _gotoActions.goBack )
 		_gotoMenu.AddAction( _gotoActions.goForward )
 		_gotoMenu.AddAction( _gotoActions.goForward )
+		_gotoMenu.AddSeparator()
+		_gotoMenu.AddAction( _gotoActions.prevScope )
+		_gotoMenu.AddAction( _gotoActions.nextScope )
 		
 		
 		'View menu
 		'View menu
 		'
 		'
@@ -695,14 +724,6 @@ Class MainWindowInstance Extends Window
 		Return _isTerminating
 		Return _isTerminating
 	End
 	End
 	
 	
-	Property ThemeName:String()
-		
-		Return _theme
-	Setter( value:String )
-		
-		_theme=value
-	End
-	
 	Property AboutPagePath:String()
 	Property AboutPagePath:String()
 		
 		
 		Local path:=Prefs.MonkeyRootPath+"ABOUT.HTML"
 		Local path:=Prefs.MonkeyRootPath+"ABOUT.HTML"
@@ -728,6 +749,8 @@ Class MainWindowInstance Extends Window
 		End )
 		End )
 		future.Get()
 		future.Get()
 		
 		
+		CodeParsing.DeleteTempFiles()
+		
 		App.Terminate()
 		App.Terminate()
 	End
 	End
 
 
@@ -1210,7 +1233,7 @@ Class MainWindowInstance Extends Window
 	
 	
 	Method UpdateHelpTree()
 	Method UpdateHelpTree()
 		
 		
-		_helpTree.Update( True )
+		_helpTree.Update()
 	End
 	End
 	
 	
 	Method ShowBananasShowcase()
 	Method ShowBananasShowcase()
@@ -1320,7 +1343,7 @@ Class MainWindowInstance Extends Window
 		
 		
 		SaveUndockTabsState( jobj )
 		SaveUndockTabsState( jobj )
 		If _isTerminating UndockWindow.RestoreUndock()
 		If _isTerminating UndockWindow.RestoreUndock()
-			
+		
 		SaveTabsState( jobj )
 		SaveTabsState( jobj )
 		
 		
 		Local jdocs:=New JsonObject
 		Local jdocs:=New JsonObject
@@ -1341,7 +1364,7 @@ Class MainWindowInstance Extends Window
 		End
 		End
 		jobj["recentProjects"]=recent
 		jobj["recentProjects"]=recent
 		
 		
-		jobj["theme"]=New JsonString( ThemeName )
+		jobj["theme"]=New JsonString( ThemesInfo.ActiveThemePath )
 		
 		
 		jobj["themeScale"]=New JsonNumber( App.Theme.Scale.y )
 		jobj["themeScale"]=New JsonNumber( App.Theme.Scale.y )
 		
 		
@@ -1462,7 +1485,15 @@ Class MainWindowInstance Extends Window
 		_tabsWrap.AddTab( "Output",_outputConsoleView )
 		_tabsWrap.AddTab( "Output",_outputConsoleView )
 		_tabsWrap.AddTab( "Docs",_docsConsole )
 		_tabsWrap.AddTab( "Docs",_docsConsole )
 		_tabsWrap.AddTab( "Find",_findConsole )
 		_tabsWrap.AddTab( "Find",_findConsole )
+		_tabsWrap.AddTab( "Examples",_examplesView )
 		
 		
+		' load examples when user open Examples tab
+		Local tab:=_tabsWrap.tabs["Examples"]
+		tab.ActiveChanged+=Lambda()
+			If tab.IsActive
+				_examplesView.Init()
+			Endif
+		End
 	End
 	End
 	
 	
 	Method ArrangeElements()
 	Method ArrangeElements()
@@ -1502,7 +1533,7 @@ Class MainWindowInstance Extends Window
 		' defaults
 		' defaults
 		Local s:="Source"
 		Local s:="Source"
 		places["left"]=New StringStack( s.Split( "," ) )
 		places["left"]=New StringStack( s.Split( "," ) )
-		s="Project,Debug"
+		s="Project,Debug,Examples"
 		places["right"]=New StringStack( s.Split( "," ) )
 		places["right"]=New StringStack( s.Split( "," ) )
 		s="Build,Output,Docs,Find"
 		s="Build,Output,Docs,Find"
 		places["bottom"]=New StringStack( s.Split( "," ) )
 		places["bottom"]=New StringStack( s.Split( "," ) )
@@ -1528,7 +1559,7 @@ Class MainWindowInstance Extends Window
 					Next
 					Next
 					'
 					'
 					Local tab:=_tabsWrap.tabs[key]
 					Local tab:=_tabsWrap.tabs[key]
-					If tab Then 
+					If tab Then
 						_tabsWrap.docks[edge].AddTab( tab )
 						_tabsWrap.docks[edge].AddTab( tab )
 						'set view visible
 						'set view visible
 						If vistabs And vistabs<>JsonValue.NullValue
 						If vistabs And vistabs<>JsonValue.NullValue
@@ -1573,6 +1604,11 @@ Class MainWindowInstance Extends Window
 			dock.Visible=dock.Visible And (dock.NumTabs>0)
 			dock.Visible=dock.Visible And (dock.NumTabs>0)
 		Next
 		Next
 		
 		
+		Local val:=Json_FindValue( jobj.Data,"tabsDocks/sourcesInnerListHeight" )
+		If val
+			Local size:=Max( 50,Int(val.ToNumber()) )
+			_docBrowser.PropertiesViewHeight=size
+		Endif
 	End
 	End
 	
 	
 	Method SaveTabsState( jobj:JsonObject )
 	Method SaveTabsState( jobj:JsonObject )
@@ -1590,11 +1626,13 @@ Class MainWindowInstance Extends Window
 			jj[edge+"Visible"]=New JsonBool( dock.Visible )
 			jj[edge+"Visible"]=New JsonBool( dock.Visible )
 			jj[edge+"Size"]=New JsonString( _tabsWrap.GetDockSize( dock ) )
 			jj[edge+"Size"]=New JsonString( _tabsWrap.GetDockSize( dock ) )
 		Next
 		Next
+		
+		jj["sourcesInnerListHeight"]=New JsonNumber( _docBrowser.PropertiesViewHeight )
 	End
 	End
 	
 	
 	Method LoadUndockTabsState( jobj:JsonObject ) 
 	Method LoadUndockTabsState( jobj:JsonObject ) 
-				
-		Local edges:=DraggableTabs.Edges	
+		
+		Local edges:=DraggableTabs.Edges
 		For Local edge:=Eachin edges
 		For Local edge:=Eachin edges
 			Local dock:=_tabsWrap.docks[edge]
 			Local dock:=_tabsWrap.docks[edge]
 			For Local i:=Eachin dock.TabsNames
 			For Local i:=Eachin dock.TabsNames
@@ -1606,10 +1644,10 @@ Class MainWindowInstance Extends Window
 			Next
 			Next
 		Next
 		Next
 	End
 	End
-		
+	
 	Method SaveUndockTabsState( jobj:JsonObject )
 	Method SaveUndockTabsState( jobj:JsonObject )
 		
 		
-		If( UndockWindow._undockWindows.Length )	
+		If( UndockWindow._undockWindows.Length )
 			Local jj:=New JsonObject
 			Local jj:=New JsonObject
 			jobj["undockTabs"]=jj
 			jobj["undockTabs"]=jj
 			For Local i:=Eachin UndockWindow._undockWindows
 			For Local i:=Eachin UndockWindow._undockWindows
@@ -1649,7 +1687,7 @@ Class MainWindowInstance Extends Window
 			Next
 			Next
 		End
 		End
 		
 		
-		If jobj.Contains( "theme" ) ThemeName=jobj.GetString( "theme" )
+		If jobj.Contains( "theme" ) ThemesInfo.ActiveThemePath=jobj.GetString( "theme" )
 		
 		
 		If jobj.Contains( "themeScale" )
 		If jobj.Contains( "themeScale" )
 			Local sc:=jobj.GetNumber( "themeScale" )
 			Local sc:=jobj.GetNumber( "themeScale" )
@@ -1777,9 +1815,10 @@ Class MainWindowInstance Extends Window
 	Field _helpView:HtmlViewExt
 	Field _helpView:HtmlViewExt
 	Field _docsConsole:DockingView
 	Field _docsConsole:DockingView
 	Field _findConsole:TreeViewExt
 	Field _findConsole:TreeViewExt
+	Field _examplesView:ExamplesView
 	
 	
 	Field _projectView:ProjectView
 	Field _projectView:ProjectView
-	Field _docBrowser:DockingView
+	Field _docBrowser:DocBrowserView
 	Field _debugView:DebugView
 	Field _debugView:DebugView
 	Field _helpTree:HelpTreeView
 	Field _helpTree:HelpTreeView
 	Field _helpSwitcher:ToolButtonExt
 	Field _helpSwitcher:ToolButtonExt
@@ -1804,8 +1843,6 @@ Class MainWindowInstance Extends Window
 	Field _editorMenu:MenuExt
 	Field _editorMenu:MenuExt
 	Field _themesMenu:MenuExt
 	Field _themesMenu:MenuExt
 	
 	
-	Field _theme:="default"
-	
 	Field _contentView:DockingView
 	Field _contentView:DockingView
 	
 	
 	Field _recentFiles:=New StringStack
 	Field _recentFiles:=New StringStack
@@ -1944,20 +1981,17 @@ Class MainWindowInstance Extends Window
 	
 	
 		Local menu:=New MenuExt( text )
 		Local menu:=New MenuExt( text )
 		
 		
-		Local themes:=JsonObject.Load( "theme::themes.json" )
-		If Not themes Return menu
-		
-		For Local it:=Eachin themes
-			Local name:=it.Key
-			Local value:=it.Value.ToString()
+		For Local i:=0 Until ThemesInfo.GetCount()
+			Local name:=ThemesInfo.GetNameAt( i )
+			Local path:=ThemesInfo.GetPathAt( i )
 			menu.AddAction( name ).Triggered=Lambda()
 			menu.AddAction( name ).Triggered=Lambda()
 				
 				
-				If value=ThemeName Return
+				If path=ThemesInfo.ActiveThemePath Return
 				
 				
-				ThemeName=value
+				ThemesInfo.ActiveThemePath=path
 				Local sc:=App.Theme.Scale.x
 				Local sc:=App.Theme.Scale.x
 				
 				
-				App.Theme.Load( _theme,New Vec2f( sc ) )
+				App.Theme.Load( path,New Vec2f( sc ) )
 				SaveState()
 				SaveState()
 			End
 			End
 		Next
 		Next

+ 98 - 7
PathsProvider.monkey2

@@ -4,22 +4,34 @@ Namespace ted2go
 
 
 Class PathsProvider
 Class PathsProvider
 	
 	
+	Const MX2_TMP:=".mx2"
+	
 	Function GetActiveMainFilePath:String( checkCurrentDoc:Bool=True,showNoMainFileAlert:Bool=False )
 	Function GetActiveMainFilePath:String( checkCurrentDoc:Bool=True,showNoMainFileAlert:Bool=False )
 		
 		
 		If _customBuildProject
 		If _customBuildProject
-			If showNoMainFileAlert Then ProjectView.CheckMainFilePath( _customBuildProject )
+			If showNoMainFileAlert Then ProjectView.CheckMainFilePath( _customBuildProject,True )
 			Return _customBuildProject.MainFilePath
 			Return _customBuildProject.MainFilePath
 		Endif
 		Endif
 		
 		
-		Local path:=MainWindow.DocsManager.LockedDocument?.Path
+		Local lockedDoc:=docsManager().LockedDocument
+		Local path:=lockedDoc?.Path
 		If Not path
 		If Not path
-			Local proj:=GetActiveProject()
+			If checkCurrentDoc
+				path=docsManager().CurrentDocument?.Path
+			Endif
+			Local proj:=projView().ActiveProject
 			If proj
 			If proj
-				If showNoMainFileAlert Then ProjectView.CheckMainFilePath( proj )
-				Return proj.MainFilePath
+				If showNoMainFileAlert Then ProjectView.CheckMainFilePath( proj,True )
+				If proj.MainFilePath
+					path=proj.MainFilePath
+				Endif
 			Endif
 			Endif
 		Endif
 		Endif
-		If Not path And checkCurrentDoc Then path=MainWindow.DocsManager.CurrentDocument?.Path
+		
+		If Not CodeParsing.IsFileBuildable( path )
+			'If showNoMainFileAlert Then Alert( "Unsupported file format - "+ExtractExt( path )+"!~nFile must have .monkey2 extension to be buildable.","Build error" )
+			path=""
+		Endif
 		
 		
 '		Print "locked: "+_docsManager.LockedDocument?.Path
 '		Print "locked: "+_docsManager.LockedDocument?.Path
 '		Print "active: "+_projectView.ActiveProject?.MainFilePath
 '		Print "active: "+_projectView.ActiveProject?.MainFilePath
@@ -28,11 +40,71 @@ Class PathsProvider
 		Return path
 		Return path
 	End
 	End
 	
 	
+	Function GetMainFileOfDocument:String( path:String )
+		
+		'Print "GetFilePathToParse: "+path
+		
+		' is it a module file?
+		'
+		Local modsDir:=Prefs.MonkeyRootPath+"modules/"
+		' excluding of tests dirs
+		'
+		If path.StartsWith( modsDir ) And path.Find( "/tests/")=-1
+			Local i1:=modsDir.Length
+			Local i2:=path.Find( "/",i1+1 )
+			If i2<>-1
+				Local modName:=path.Slice( i1,i2 )
+				' main file of a module
+				'
+				path=modsDir+modName+"/"+modName+".monkey2"
+			Endif
+		Else
+			' is it a project file?
+			'
+			Local proj:=ProjectView.FindProject( path )
+			If proj
+				Local showNote:=True
+				If proj.MainFilePath
+					path=proj.MainFilePath
+				Else
+					Local lockedProj:Monkey2Project
+					Local lockedPath:=docsManager().LockedDocument?.Path
+					If lockedPath And lockedPath<>path
+						lockedProj=ProjectView.FindProject( lockedPath )
+						If lockedProj And lockedProj=proj
+							' will parse locked file coz it's the same project as current file
+							path=lockedPath
+							showNote=False
+						Endif
+					Endif
+				Endif
+				If showNote Then ProjectView.CheckMainFilePath( proj,False )
+			Endif
+		Endif
+		
+		Return path
+	End
+	
 	Function SetCustomBuildProject( proj:Monkey2Project )
 	Function SetCustomBuildProject( proj:Monkey2Project )
 	
 	
 		_customBuildProject=proj
 		_customBuildProject=proj
 	End
 	End
 	
 	
+	Function GetGeninfoPath:String( filePath:String )
+		
+		Return ExtractDir( filePath )+MX2_TMP+"/"+StripDir( StripExt( filePath ) )+".geninfo"
+	End
+	
+	Function GetTempFilePathForParsing:String( srcPath:String )
+		
+		Local dir:=ExtractDir( srcPath )+MX2_TMP+"/"
+		CreateDir( dir )
+		Local name:=StripDir( srcPath )
+		
+		Return dir+name
+	End
+	
+	
 	Private
 	Private
 	
 	
 	Global _customBuildProject:Monkey2Project
 	Global _customBuildProject:Monkey2Project
@@ -41,6 +113,25 @@ Class PathsProvider
 	
 	
 		If _customBuildProject Return _customBuildProject
 		If _customBuildProject Return _customBuildProject
 	
 	
-		Return MainWindow.ProjView.ActiveProject
+		Return projView().ActiveProject
+	End
+	
+	Function projView:ProjectView()
+		
+		Global _projView:ProjectView
+		If Not _projView Then _projView=Di.Resolve<ProjectView>()
+		
+		Return _projView
+	End
+	
+	Function docsManager:DocumentManager()
+		
+		Global _docsManager:DocumentManager
+		If Not _docsManager
+			' dirty but better than MainWindow.DocsManager
+			_docsManager=Di.Resolve<DocumentManager>()
+		Endif
+		
+		Return _docsManager
 	End
 	End
 End
 End

+ 8 - 2
Ted2.monkey2

@@ -85,6 +85,7 @@
 #Import "utils/JsonUtils"
 #Import "utils/JsonUtils"
 #Import "utils/Utils"
 #Import "utils/Utils"
 #Import "utils/TextUtils"
 #Import "utils/TextUtils"
+#Import "utils/ViewUtils"
 
 
 #Import "view/CodeMapView"
 #Import "view/CodeMapView"
 #Import "view/CodeTextView"
 #Import "view/CodeTextView"
@@ -120,12 +121,15 @@
 #Import "view/DraggableViewListener"
 #Import "view/DraggableViewListener"
 #Import "view/Undock"
 #Import "view/Undock"
 #Import "view/TextViewExt"
 #Import "view/TextViewExt"
+#Import "view/ExamplesView"
+
+#Import "theme/ThemeImages"
+#Import "theme/ThemesInfo"
 
 
 #Import "PathsProvider"
 #Import "PathsProvider"
 #Import "Tree"
 #Import "Tree"
 #Import "Tuple"
 #Import "Tuple"
 #Import "Plugin"
 #Import "Plugin"
-#Import "ThemeImages"
 #Import "Prefs"
 #Import "Prefs"
 #Import "ProcessReader"
 #Import "ProcessReader"
 #Import "LiveTemplates"
 #Import "LiveTemplates"
@@ -146,7 +150,7 @@ Using sdl2..
 
 
 Const MONKEY2_DOMAIN:="http://monkeycoder.co.nz"
 Const MONKEY2_DOMAIN:="http://monkeycoder.co.nz"
 
 
-Global AppTitle:="Ted2Go v2.11"
+Global AppTitle:="Ted2Go v2.12"
 
 
 
 
 Function Main()
 Function Main()
@@ -175,6 +179,8 @@ Function Main()
 	
 	
 	Prefs.LoadState( jobj )
 	Prefs.LoadState( jobj )
 	
 	
+	ThemesInfo.Load( "theme::themes.json" )
+	
 	'initial theme
 	'initial theme
 	'
 	'
 	If Not jobj.Contains( "theme" ) jobj["theme"]=New JsonString( "theme-hollow" )
 	If Not jobj.Contains( "theme" ) jobj["theme"]=New JsonString( "theme-hollow" )

+ 8 - 3
action/BuildActions.monkey2

@@ -132,7 +132,7 @@ Class BuildActions Implements IModuleBuilder
 		_releaseConfig.Clicked+=Lambda()
 		_releaseConfig.Clicked+=Lambda()
 			_buildConfig="release"
 			_buildConfig="release"
 		End
 		End
-		_buildConfig="debug"
+		_buildConfig="release"
 
 
 		group=New CheckGroup
 		group=New CheckGroup
 
 
@@ -264,12 +264,14 @@ Class BuildActions Implements IModuleBuilder
 		While Not _errors.Empty And _errors.First.removed
 		While Not _errors.Empty And _errors.First.removed
 			_errors.RemoveFirst()
 			_errors.RemoveFirst()
 		Wend
 		Wend
-	
+		
 		Local idle:=Not _console.Running
 		Local idle:=Not _console.Running
 		Local canbuild:=idle And FilePathToBuild And _buildTarget
 		Local canbuild:=idle And FilePathToBuild And _buildTarget
 		
 		
 		build.Enabled=canbuild
 		build.Enabled=canbuild
 		buildAndRun.Enabled=canbuild
 		buildAndRun.Enabled=canbuild
+		semant.Enabled=canbuild
+		debugApp.Enabled=canbuild
 		nextError.Enabled=Not _errors.Empty
 		nextError.Enabled=Not _errors.Empty
 		updateModules.Enabled=idle
 		updateModules.Enabled=idle
 		rebuildHelp.Enabled=idle
 		rebuildHelp.Enabled=idle
@@ -336,7 +338,10 @@ Class BuildActions Implements IModuleBuilder
 	Method GotoError( err:BuildError )
 	Method GotoError( err:BuildError )
 		
 		
 		Local targetPath:=GetCaseSensitivePath( err.path )
 		Local targetPath:=GetCaseSensitivePath( err.path )
-		_docs.CurrentCodeDocument?.JumpToPosition( targetPath,New Vec2i( err.line,0 ) )
+		Local doc:=_docs.OpenDocument( targetPath,True,True )
+		If doc
+			_docs.CurrentCodeDocument.JumpToPosition( targetPath,New Vec2i( err.line,0 ) )
+		Endif
 	End
 	End
 	
 	
 	
 	

+ 18 - 5
action/EditActions.monkey2

@@ -10,6 +10,7 @@ Class EditActions
 	Field copy:Action
 	Field copy:Action
 	Field paste:Action
 	Field paste:Action
 	Field selectAll:Action
 	Field selectAll:Action
+	Field selectWord:Action
 	Field wordWrap:Action
 	Field wordWrap:Action
 	' Edit -- Text
 	' Edit -- Text
 	Field textDeleteWordForward:Action
 	Field textDeleteWordForward:Action
@@ -25,14 +26,14 @@ Class EditActions
 	Field uncomment:Action
 	Field uncomment:Action
 	
 	
 	Method New( docs:DocumentManager )
 	Method New( docs:DocumentManager )
-	
+		
 		_docs=docs
 		_docs=docs
 		
 		
 		undo=New Action( "Undo" )
 		undo=New Action( "Undo" )
 		undo.Triggered=OnUndo
 		undo.Triggered=OnUndo
 		undo.HotKey=Key.Z
 		undo.HotKey=Key.Z
 		undo.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
 		undo.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
-
+		
 		redo=New Action( "Redo" )
 		redo=New Action( "Redo" )
 		redo.Triggered=OnRedo
 		redo.Triggered=OnRedo
 #If __TARGET__="macos"
 #If __TARGET__="macos"
@@ -47,22 +48,27 @@ Class EditActions
 		cut.Triggered=OnCut
 		cut.Triggered=OnCut
 		cut.HotKey=Key.X
 		cut.HotKey=Key.X
 		cut.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
 		cut.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
-
+		
 		copy=New Action( "Copy" )
 		copy=New Action( "Copy" )
 		copy.Triggered=OnCopy
 		copy.Triggered=OnCopy
 		copy.HotKey=Key.C
 		copy.HotKey=Key.C
 		copy.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
 		copy.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
-
+		
 		paste=New Action( "Paste" )
 		paste=New Action( "Paste" )
 		paste.Triggered=OnPaste
 		paste.Triggered=OnPaste
 		paste.HotKey=Key.V
 		paste.HotKey=Key.V
 		paste.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
 		paste.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
-
+		
 		selectAll=New Action( "Select all" )
 		selectAll=New Action( "Select all" )
 		selectAll.Triggered=OnSelectAll
 		selectAll.Triggered=OnSelectAll
 		selectAll.HotKey=Key.A
 		selectAll.HotKey=Key.A
 		selectAll.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
 		selectAll.HotKeyModifiers=Modifier.Menu|Modifier.Ignore
 		
 		
+		selectWord=New Action( "Select word" )
+		selectWord.Triggered=OnSelectWord
+		selectWord.HotKey=Key.W
+		selectWord.HotKeyModifiers=Modifier.Control
+		
 		wordWrap=New Action( "Toggle word wrap" )
 		wordWrap=New Action( "Toggle word wrap" )
 		wordWrap.Triggered=OnWordWrap
 		wordWrap.Triggered=OnWordWrap
 		wordWrap.HotKey=Key.Z
 		wordWrap.HotKey=Key.Z
@@ -242,6 +248,13 @@ Class EditActions
 		If tv tv.SelectAll()
 		If tv tv.SelectAll()
 	End
 	End
 	
 	
+	Method OnSelectWord()
+		
+		Local tv:=Cast<TextView>( App.KeyView )
+		
+		If tv tv.SelectWord()
+	End
+	
 	Method OnWordWrap()
 	Method OnWordWrap()
 	
 	
 		Local tv:=Cast<TextView>( App.KeyView )
 		Local tv:=Cast<TextView>( App.KeyView )

+ 1 - 1
action/FileActions.monkey2

@@ -37,7 +37,7 @@ Class FileActions
 		
 		
 		close=New Action( "Close tab" )
 		close=New Action( "Close tab" )
 		close.HotKey=Key.W
 		close.HotKey=Key.W
-		close.HotKeyModifiers=Modifier.Menu
+		close.HotKeyModifiers=Modifier.Alt
 		close.Triggered=OnClose
 		close.Triggered=OnClose
 		
 		
 		closeOthers=New Action( "Close other tabs" )
 		closeOthers=New Action( "Close other tabs" )

+ 5 - 2
action/FindActions.monkey2

@@ -287,10 +287,13 @@ Class FindActions
 		
 		
 		Local result:=New FindResults
 		Local result:=New FindResults
 		
 		
-		'Local counter:=1
+		Local tmpFolder:=PathsProvider.MX2_TMP+"/"
 		Local doc:=New TextDocument 'use it to get line number
 		Local doc:=New TextDocument 'use it to get line number
 		For Local f:=Eachin files
 		For Local f:=Eachin files
-		
+			
+			' skip temp-folders
+			If f.Find( tmpFolder )<>-1 Continue
+			
 			Local text:=LoadString( f )
 			Local text:=LoadString( f )
 		
 		
 			If Not caseSensitive Then text=text.ToLower()
 			If Not caseSensitive Then text=text.ToLower()

+ 31 - 6
action/GotoActions.monkey2

@@ -8,6 +8,8 @@ Class GotoActions
 	Field goForward:Action
 	Field goForward:Action
 	Field gotoLine:Action
 	Field gotoLine:Action
 	Field gotoDeclaration:Action
 	Field gotoDeclaration:Action
+	Field prevScope:Action
+	Field nextScope:Action
 	
 	
 	Method New( docs:DocumentManager )
 	Method New( docs:DocumentManager )
 		
 		
@@ -31,6 +33,21 @@ Class GotoActions
 		gotoDeclaration=New Action( "Goto definition" )
 		gotoDeclaration=New Action( "Goto definition" )
 		gotoDeclaration.Triggered=OnGotoDeclaration
 		gotoDeclaration.Triggered=OnGotoDeclaration
 		gotoDeclaration.HotKey=Key.F12
 		gotoDeclaration.HotKey=Key.F12
+		
+		prevScope=New Action( "Previous scope" )
+		prevScope.Triggered=OnPrevScope
+		#If __TARGET__<>"macos"
+		prevScope.HotKey=Key.Up
+		prevScope.HotKeyModifiers=Modifier.Alt
+		#Endif
+		
+		nextScope=New Action( "Next scope" )
+		nextScope.Triggered=OnNextScope
+		#If __TARGET__<>"macos"
+		nextScope.HotKey=Key.Down
+		nextScope.HotKeyModifiers=Modifier.Alt
+		#Endif
+		
 	End
 	End
 	
 	
 	
 	
@@ -41,17 +58,13 @@ Class GotoActions
 	Method OnGoBack()
 	Method OnGoBack()
 		
 		
 		Local doc:=Cast<CodeDocument>( _docs.CurrentDocument )
 		Local doc:=Cast<CodeDocument>( _docs.CurrentDocument )
-		If Not doc Return
-		
-		doc.GoBack()
+		doc?.GoBack()
 	End
 	End
 	
 	
 	Method OnGoForward()
 	Method OnGoForward()
 	
 	
 		Local doc:=Cast<CodeDocument>( _docs.CurrentDocument )
 		Local doc:=Cast<CodeDocument>( _docs.CurrentDocument )
-		If Not doc Return
-	
-		doc.GoForward()
+		doc?.GoForward()
 	End
 	End
 	
 	
 	Method OnGotoLine()
 	Method OnGotoLine()
@@ -64,4 +77,16 @@ Class GotoActions
 		MainWindow.GotoDeclaration()
 		MainWindow.GotoDeclaration()
 	End
 	End
 	
 	
+	Method OnPrevScope()
+		
+		Local doc:=Cast<CodeDocument>( _docs.CurrentDocument )
+		doc?.JumpToPreviousScope()
+	End
+	
+	Method OnNextScope()
+		
+		Local doc:=Cast<CodeDocument>( _docs.CurrentDocument )
+		doc?.JumpToNextScope()
+	End
+	
 End
 End

+ 2 - 2
action/TabActions.monkey2

@@ -24,7 +24,7 @@ Class TabActions
 							If firstCurrent.Visible Then firstCurrent.CurrentHolder.MakeCurrent( firstCurrent.Text ); Exit
 							If firstCurrent.Visible Then firstCurrent.CurrentHolder.MakeCurrent( firstCurrent.Text ); Exit
 						Next
 						Next
 					Else
 					Else
-						If( _tabb.View )
+						If _tabb.View
 							_tabb.Visible=True
 							_tabb.Visible=True
 							_tabb.View.Visible=True
 							_tabb.View.Visible=True
 							_tabb.CurrentHolder.MakeCurrent( _tabb.Text )
 							_tabb.CurrentHolder.MakeCurrent( _tabb.Text )
@@ -40,7 +40,7 @@ Class TabActions
 	Function CreateMenu( view:MenuExt )
 	Function CreateMenu( view:MenuExt )
 		
 		
 		Local keynr:Int
 		Local keynr:Int
-		Local tabNames:=New String[]( "Project","Debug","Source","Build","Output","Docs","Find","Chat" )
+		Local tabNames:=New String[]( "Project","Debug","Source","Build","Output","Docs","Find","Examples" )
 		For Local a:=Eachin tabNames
 		For Local a:=Eachin tabNames
 			Local key:=Cast<Key>( 49+keynr )
 			Local key:=Cast<Key>( 49+keynr )
 			Local i:=view.AddAction( a )
 			Local i:=view.AddAction( a )

+ 1 - 1
assets/aboutTed2Go.html

@@ -128,7 +128,7 @@ ToolBar icons were taken from <a href="https://icons8.com/icon/new-icons/win8">i
 
 
 <h3>Special thanks</h3>
 <h3>Special thanks</h3>
 
 
-<p>Second Gear Games, Dominique MIS, Rajasekaran Senthil Kumaran, abakobo, Peter Rigby, Dmitry Fadeev, James Boyd, Sam Fisher, Matthew Bowen, Mark Mcvittie, Simon Armstrong, Rudy van Etten, Hezkore, Sal Gunduz, Peter Scheutz, Matthieu Chemin, David Maziarka, Leonardo Teixeira, Jesus Perez, Mark Sibly, Philipp Moeller, Lee Wade.</p>
+<p>Jimmy Söderman, Second Gear Games, Dominique MIS, Rajasekaran Senthil Kumaran, abakobo, Peter Rigby, Dmitry Fadeev, James Boyd, Sam Fisher, Matthew Bowen, Mark Mcvittie, Simon Armstrong, Rudy van Etten, Hezkore, Sal Gunduz, Peter Scheutz, Matthieu Chemin, David Maziarka, Leonardo Teixeira, Jesus Perez, Mark Sibly, Philipp Moeller, Lee Wade.</p>
 
 
 </body>
 </body>
 
 

+ 36 - 0
assets/docsPriority.txt

@@ -0,0 +1,36 @@
+monkey
+std
+libc
+mojo
+mojo3d
+mojox
+sdl2
+httprequest
+iap
+admob
+chipmunk
+bullet
+jni
+freetype
+assimp
+emscripten
+hoedown
+android
+litehtml
+miniz
+gles20
+openal
+opengl
+reflection
+sdl2-mixer
+sqlite
+stb-image
+stb-image-write
+stb-truetype
+stb-vorbis
+theoraplayer
+tinyregex
+tinyxml2
+win32
+zlib
+thread

+ 1 - 1
assets/newfiles/Simple_Mojo3d_App.monkey2

@@ -30,7 +30,7 @@ Class MyWindow Extends Window
 		_scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
 		_scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
 		_scene.AmbientLight = _scene.ClearColor * 0.25
 		_scene.AmbientLight = _scene.ClearColor * 0.25
 		_scene.FogColor = _scene.ClearColor
 		_scene.FogColor = _scene.ClearColor
-		_scene.FogFar = 1.0
+		_scene.FogNear = 1.0
 		_scene.FogFar = 200.0
 		_scene.FogFar = 200.0
 		
 		
 		'create camera
 		'create camera

+ 1 - 0
assets/themes/default-tmp.json

@@ -15,6 +15,7 @@
 		"text-disabled": "#888",
 		"text-disabled": "#888",
 		"text-background": "#888",
 		"text-background": "#888",
 		
 		
+		"textview-color8": "#aa55bb", //code item
 		"textview-cursor":"#fff",
 		"textview-cursor":"#fff",
 		"textview-selection":"#88f",
 		"textview-selection":"#88f",
 		"textview-cursor-line":"#2000",
 		"textview-cursor-line":"#2000",

+ 14 - 1
assets/themes/ted2-default.json

@@ -16,7 +16,8 @@
 		"params-hint-selected": "textview-color4",
 		"params-hint-selected": "textview-color4",
 		"completion-list-selected": "content",
 		"completion-list-selected": "content",
 		"completion-list-marked-bg": "#0fff",
 		"completion-list-marked-bg": "#0fff",
-		"completion-list-marked-text": "textview-color4"
+		"completion-list-marked-text": "textview-color4",
+		"treeview-selected-row": "#1fff"
 	},
 	},
 
 
 	"fonts":{
 	"fonts":{
@@ -44,6 +45,10 @@
 			"extends":"TextField",
 			"extends":"TextField",
 			"skinColor":"panel"
 			"skinColor":"panel"
 		},
 		},
+		"HelpPageAddress":{
+			"extends":"Label",
+			"font":"small"
+		},
 
 
 		"Hint":{
 		"Hint":{
 			"border":[ 1 ],
 			"border":[ 1 ],
@@ -136,6 +141,14 @@
 		"CompletionDialogContent":{
 		"CompletionDialogContent":{
 			"padding":[ 1 ]
 			"padding":[ 1 ]
 		},
 		},
+		"CompletionHint":{
+			"extends":"Label",
+			"padding":[ 3 ],
+			"borderColor": "#20000000",
+			"border":[ 0,1,0,0 ],
+			"margin":[ 0,4,0,0 ],
+			"font":"small"
+		},
 				
 				
 		"TextFieldBordered":{
 		"TextFieldBordered":{
 			"extends":"TextField",
 			"extends":"TextField",

+ 41 - 11
assets/themes/themes.json

@@ -1,12 +1,42 @@
 {
 {
-	"Classic dark":"theme-classic-dark",
-	"Overcast":"theme-overcast",
-	"Monkey 1":"theme-monkey1",
-	"Blitzed":"theme-blitzed",
-	"Basic Blue":"theme-Basic-Blue",
-	"Hollow":"theme-hollow",
-	"Prime - Red":"theme-prime-red",
-	"Prime - Blue":"theme-prime-blue",
-	"Smooth":"theme-smooth",
-	"Warm":"theme-warm"
-}
+	"Classic dark": {
+		"path": "theme-classic-dark",
+		"dark": true
+	},
+	"Overcast": {
+		"path": "theme-overcast",
+		"dark": false
+	},
+	"Monkey 1": {
+		"path": "theme-monkey1",
+		"dark": false
+	},
+	"Blitzed": {
+		"path": "theme-blitzed",
+		"dark": true
+	},
+	"Basic Blue": {
+		"path": "theme-Basic-Blue",
+		"dark": true
+	},
+	"Hollow": {
+		"path": "theme-hollow",
+		"dark": true
+	},
+	"Prime - Red": {
+		"path": "theme-prime-red",
+		"dark": true
+	},
+	"Prime - Blue": {
+		"path": "theme-prime-blue",
+		"dark": true
+	},
+	"Smooth": {
+		"path": "theme-smooth",
+		"dark": true
+	},
+	"Warm": {
+		"path": "theme-warm",
+		"dark": true
+	}
+}

+ 29 - 0
di/DiSetup.monkey2

@@ -5,6 +5,11 @@ Namespace ted2go
 '
 '
 Function SetupDiContainer()
 Function SetupDiContainer()
 	
 	
+	Di.Bind( Lambda:ExamplesView()
+		Return New ExamplesView(
+			Di.Resolve<DocumentManager>() )
+	End )
+	
 	Di.Bind( Lambda:DocsTabView()
 	Di.Bind( Lambda:DocsTabView()
 		Return New DocsTabView( TabViewFlags.DraggableTabs|TabViewFlags.ClosableTabs )
 		Return New DocsTabView( TabViewFlags.DraggableTabs|TabViewFlags.ClosableTabs )
 	End )
 	End )
@@ -67,8 +72,32 @@ Class DocsTabView Extends TabViewExt
 End
 End
 
 
 Class DocBrowserView Extends DockingView
 Class DocBrowserView Extends DockingView
+	
+	Method New()
+		
+		Super.New()
+		
+		_propView=New DockingView
+		AddView( _propView,"bottom",200,True )
+	End
+	
+	Property PropertiesViewHeight:Int()
+		Return Int(GetViewSize( _propView ))
+	Setter( value:Int )
+		SetViewSize( _propView,value )
+	End
+	
+	Property PropertiesView:DockingView()
+		Return _propView
+	End
+	
+	Private
+	
+	Field _propView:DockingView
+	
 End
 End
 
 
+
 Class BuildConsole Extends ConsoleExt
 Class BuildConsole Extends ConsoleExt
 End
 End
 
 

+ 1 - 1
dialog/FindInFilesDialog.monkey2

@@ -9,7 +9,7 @@ Class FindInFilesDialog Extends DialogExt
 		_findField=New TextFieldExt
 		_findField=New TextFieldExt
 		
 		
 		_findField.Entered+=Lambda()
 		_findField.Entered+=Lambda()
-			actions.findNext.Trigger()
+			actions.findAllInFiles.Trigger()
 		End
 		End
 		
 		
 		_projList=New ListView
 		_projList=New ListView

+ 142 - 16
document/CodeDocument.monkey2

@@ -760,7 +760,7 @@ Class CodeDocumentView Extends Ted2CodeTextView
 	
 	
 	Method ShowJsonDialog()
 	Method ShowJsonDialog()
 		
 		
-		Local cmd:=Monkey2Parser.GetParseCommand( _doc.Path )
+		Local cmd:=Monkey2Parser.GetFullParseCommand( _doc.Path )
 		If Not cmd Return
 		If Not cmd Return
 		
 		
 		New Fiber( Lambda()
 		New Fiber( Lambda()
@@ -814,7 +814,7 @@ Class CodeDocumentView Extends Ted2CodeTextView
 					Local x:=RenderStyle.Font.TextWidth( indentStr )
 					Local x:=RenderStyle.Font.TextWidth( indentStr )
 					Local w:=RenderStyle.Font.TextWidth( s )
 					Local w:=RenderStyle.Font.TextWidth( s )
 					If event.Location.x >= x And event.Location.x <= x+w
 					If event.Location.x >= x And event.Location.x <= x+w
-						Local s:=_doc.GetStringError( line )
+						Local s:=_doc.GetErrorMessageAt( line )
 						If s <> Null
 						If s <> Null
 							_doc.ShowHint_( s,event.Location )
 							_doc.ShowHint_( s,event.Location )
 						Else
 						Else
@@ -931,6 +931,7 @@ Class CodeDocument Extends Ted2Document
 		_doc.TextChanged+=Lambda()
 		_doc.TextChanged+=Lambda()
 		
 		
 			Dirty=True
 			Dirty=True
+			_changesCounter+=1
 			OnTextChanged()
 			OnTextChanged()
 			_codeView.TextChanged()
 			_codeView.TextChanged()
 		End
 		End
@@ -1006,7 +1007,7 @@ Class CodeDocument Extends Ted2Document
 	Method OnCreateBrowser:View() Override
 	Method OnCreateBrowser:View() Override
 		
 		
 		If _browserView Return _browserView
 		If _browserView Return _browserView
-			
+		
 		' sorting toolbar
 		' sorting toolbar
 		_browserView=New DockingView
 		_browserView=New DockingView
 		
 		
@@ -1046,19 +1047,31 @@ Class CodeDocument Extends Ted2Document
 		
 		
 		_treeView.SortByType=Prefs.SourceSortByType
 		_treeView.SortByType=Prefs.SourceSortByType
 		_treeView.ShowInherited=Prefs.SourceShowInherited
 		_treeView.ShowInherited=Prefs.SourceShowInherited
+		_treeView.ExpandParentsForSelected=False
 		
 		
 		' goto item from tree view
 		' goto item from tree view
-		_treeView.NodeClicked+=Lambda( node:TreeView.Node )
+		Local clickFunc:=Lambda( node:TreeView.Node )
 		
 		
 			Local codeNode:=Cast<CodeTreeNode>( node )
 			Local codeNode:=Cast<CodeTreeNode>( node )
 			Local item:=codeNode.CodeItem
 			Local item:=codeNode.CodeItem
 			JumpToPosition( item.FilePath,item.ScopeStartPos )
 			JumpToPosition( item.FilePath,item.ScopeStartPos )
-			
 		End
 		End
 		
 		
+		_treeView.NodeClicked+=clickFunc
+		
+		_treeViewInnerList=New CodeTreeView
+		_treeViewInnerList.FillNestedItems=False
+		
+		_treeViewInnerList.NodeClicked+=clickFunc
+		
 		Return _browserView
 		Return _browserView
 	End
 	End
 	
 	
+	Method OnCreateBrowserProperties:View() Override
+		
+		Return _treeViewInnerList
+	End
+	
 	Method AnalyzeIndentation()
 	Method AnalyzeIndentation()
 		
 		
 		Local text:=_codeView.Text
 		Local text:=_codeView.Text
@@ -1254,7 +1267,8 @@ Class CodeDocument Extends Ted2Document
 		_errMap[error.line]=s
 		_errMap[error.line]=s
 	End
 	End
 	
 	
-	Method GetStringError:String( line:Int )
+	Method GetErrorMessageAt:String( line:Int )
+		
 		Return _errMap[line]
 		Return _errMap[line]
 	End
 	End
 	
 	
@@ -1262,11 +1276,14 @@ Class CodeDocument Extends Ted2Document
 		
 		
 		ResetErrors()
 		ResetErrors()
 		
 		
+		'Print "OnDocumentParsed: "+Path
+		
 		If errors And Not errors.Empty
 		If errors And Not errors.Empty
+			'Print "OnDocumentParsed. errors: "+errors.Length
 			For Local err:=Eachin errors
 			For Local err:=Eachin errors
 				AddError( err )
 				AddError( err )
 			Next
 			Next
-			Return
+			'Return
 		Endif
 		Endif
 		
 		
 		UpdateCodeTree( codeItems )
 		UpdateCodeTree( codeItems )
@@ -1430,6 +1447,81 @@ Class CodeDocument Extends Ted2Document
 		_codeView.OnKeyEvent( event )
 		_codeView.OnKeyEvent( event )
 	End
 	End
 	
 	
+	Method StoreChangesCounter()
+		
+		_storedChangesCounter=_changesCounter
+	End
+	
+	Method CheckChangesCounter:Bool()
+		
+		Return _changesCounter<>_storedChangesCounter
+	End
+	
+	Method GrabCodeItems( parent:CodeItem,items:Stack<CodeItem> )
+		
+		If parent.IsLikeFunc Or parent.IsOperator Or parent.IsProperty Or parent.IsLikeClass
+			items.Add( parent )
+		Endif
+		
+		If Not (parent.Children Or parent.IsLikeClass) Return
+		
+		For Local child:=Eachin parent.Children
+			GrabCodeItems( child,items )
+		Next 
+	End
+	
+	Method JumpToPreviousScope()
+		
+		Local topItems:=_parser.ItemsMap[Path]
+		If Not topItems Return
+		
+		Local allItems:=New Stack<CodeItem>
+		For Local item:=Eachin topItems
+			GrabCodeItems( item,allItems )
+		Next
+		
+		Local curLine:=_codeView.LineNumAtCursor
+		Local newPos:=New Vec2i( -1 )
+		For Local item:=Eachin allItems
+			Local pos:=item.ScopeStartPos
+			If pos.x<curLine And pos.x>newPos.x
+				newPos=pos
+			Endif
+		Next
+		
+		If newPos.x<>curLine
+			Local pos:=_codeView.Document.StartOfLine( newPos.x )+newPos.y
+			_codeView.SelectText( pos,pos )
+			_codeView.MakeCentered()
+		Endif
+	End
+	
+	Method JumpToNextScope()
+		
+		Local topItems:=_parser.ItemsMap[Path]
+		If Not topItems Return
+		
+		Local allItems:=New Stack<CodeItem>
+		For Local item:=Eachin topItems
+			GrabCodeItems( item,allItems )
+		Next
+		
+		Local curLine:=_codeView.LineNumAtCursor
+		Local newPos:=New Vec2i( _codeView.Document.NumLines )
+		For Local item:=Eachin allItems
+			Local pos:=item.ScopeStartPos
+			If pos.x>curLine And pos.x<newPos.x
+				newPos=pos
+			Endif
+		Next
+		
+		If newPos.x<>curLine
+			Local pos:=_codeView.Document.StartOfLine( newPos.x )+newPos.y
+			_codeView.SelectText( pos,pos )
+			_codeView.MakeCentered()
+		Endif
+	End
+	
 	Property CodeView:CodeDocumentView()
 	Property CodeView:CodeDocumentView()
 		Return _codeView
 		Return _codeView
 	End
 	End
@@ -1448,6 +1540,7 @@ Class CodeDocument Extends Ted2Document
 	Field _view:DockingView
 	Field _view:DockingView
 	Field _codeView:CodeDocumentView
 	Field _codeView:CodeDocumentView
 	Field _treeView:CodeTreeView
 	Field _treeView:CodeTreeView
+	Field _treeViewInnerList:CodeTreeView
 	Field _browserView:DockingView
 	Field _browserView:DockingView
 	Field _fixIndentView:DockingView
 	Field _fixIndentView:DockingView
 	Field _fixIndentHint:Label
 	Field _fixIndentHint:Label
@@ -1465,6 +1558,7 @@ Class CodeDocument Extends Ted2Document
 	
 	
 	Field _toolBar:ToolBarExt
 	Field _toolBar:ToolBarExt
 	Field _content:DockingView
 	Field _content:DockingView
+	Field _changesCounter:Int,_storedChangesCounter:Int
 	
 	
 	Method InitParser()
 	Method InitParser()
 		
 		
@@ -1566,6 +1660,7 @@ Class CodeDocument Extends Ted2Document
 		
 		
 		_doc.Text=text
 		_doc.Text=text
 		Dirty=False
 		Dirty=False
+		_changesCounter=0
 		
 		
 		InitParser()
 		InitParser()
 		
 		
@@ -1611,9 +1706,13 @@ Class CodeDocument Extends Ted2Document
 		
 		
 		If AutoComplete.IsOpened Then AutoComplete.Hide()
 		If AutoComplete.IsOpened Then AutoComplete.Hide()
 		
 		
-		If Not _parsingEnabled Return
-		
-		OnUpdateCurrentScope()
+		' show error in status bar
+		If HasErrors
+			Local error:=GetErrorMessageAt( newLine )
+			If error
+				MainWindow.ShowStatusBarText( error )
+			Endif
+		Endif
 	End
 	End
 	
 	
 	Property CursorPos:Vec2i()
 	Property CursorPos:Vec2i()
@@ -1623,11 +1722,36 @@ Class CodeDocument Extends Ted2Document
 	
 	
 	Method OnUpdateCurrentScope()
 	Method OnUpdateCurrentScope()
 		
 		
-		'DebugStop()
+		_treeViewInnerList.RootNode.RemoveAllChildren()
+		
 		Local scope:=_parser.GetNearestScope( Path,CursorPos )
 		Local scope:=_parser.GetNearestScope( Path,CursorPos )
 		'Print ""+CursorPos+", "+scope?.KindStr+", "+scope?.Text
 		'Print ""+CursorPos+", "+scope?.KindStr+", "+scope?.Text
 		If scope
 		If scope
 			_treeView.SelectByScope( scope )
 			_treeView.SelectByScope( scope )
+			
+			Local storedScope:=scope
+			If scope.IsBlock
+				scope=CodeItem.GetNonBlockParent( scope )
+			Endif
+			If scope.IsLikeField
+				scope=CodeItem.GetNonFieldParent( scope )
+			Endif
+			
+			If Not scope Return
+			
+			If scope.NumChildren>0
+				Local st:=New Stack<CodeItem>
+				For Local child:=Eachin scope.Children
+					If Not (child.IsLikeClass Or child.IsLikeFunc Or child.IsOperator)
+						st.Add( child )
+					Endif
+				Next
+				If Not st.Empty
+					_treeViewInnerList.Fill( st,_parser )
+					MainWindow.UpdateWindow( False )
+					_treeViewInnerList.Selected=_treeViewInnerList.FindNode( _treeViewInnerList.RootNode,storedScope )
+				Endif
+			Endif
 		Endif
 		Endif
 	End
 	End
 	
 	
@@ -1683,6 +1807,10 @@ Class CodeDocument Extends Ted2Document
 	
 	
 	Method OnCursorChanged()
 	Method OnCursorChanged()
 		
 		
+		If _parsingEnabled
+			OnUpdateCurrentScope()
+		Endif
+		
 		' try to show hint for method parameters
 		' try to show hint for method parameters
 		
 		
 		If Not Prefs.EditorShowParamsHint Return
 		If Not Prefs.EditorShowParamsHint Return
@@ -1963,20 +2091,18 @@ Class CodeItemIcons
 			Case "param"
 			Case "param"
 				key="*"
 				key="*"
 			Default
 			Default
-				Local type:=item.Type
-				If (kind="field" Or kind="global") And type<>Null And type.IsLikeFunc
+				If item.IsFuncTypedField
 					key="field_func"
 					key="field_func"
 				Else
 				Else
-					If item.Ident.ToLower() = "new" Then kind="constructor"
+					If item.Ident.ToLower()="new" Then kind="constructor"
 					key=kind+"_"+item.AccessStr
 					key=kind+"_"+item.AccessStr
 				Endif
 				Endif
 		End
 		End
 		
 		
 		Local ic:=_icons[key]
 		Local ic:=_icons[key]
-		If ic = Null Then ic=_iconDefault
+		If ic=Null Then ic=_iconDefault
 		
 		
 		Return ic
 		Return ic
-		
 	End
 	End
 
 
 	Function GetKeywordsIcon:Image()
 	Function GetKeywordsIcon:Image()

+ 3 - 2
document/DocumentManager.monkey2

@@ -14,7 +14,7 @@ Class DocumentManager
 	Field DocumentRemoved:Void( doc:Ted2Document )
 	Field DocumentRemoved:Void( doc:Ted2Document )
 	Field DocumentDoubleClicked:Void( doc:Ted2Document )
 	Field DocumentDoubleClicked:Void( doc:Ted2Document )
 
 
-	Method New( tabView:TabViewExt,browser:DockingView )
+	Method New( tabView:TabViewExt,browser:DocBrowserView )
 	
 	
 		_tabView=tabView
 		_tabView=tabView
 		_browser=browser
 		_browser=browser
@@ -85,6 +85,7 @@ Class DocumentManager
 		If _currentDoc
 		If _currentDoc
 			_tabView.CurrentView=CurrentView
 			_tabView.CurrentView=CurrentView
 			_browser.ContentView=_currentDoc.BrowserView
 			_browser.ContentView=_currentDoc.BrowserView
+			_browser.PropertiesView.ContentView=_currentDoc.BrowserPropertiesView
 		Else
 		Else
 			_browser.ContentView=Null
 			_browser.ContentView=Null
 		Endif
 		Endif
@@ -345,7 +346,7 @@ Class DocumentManager
 	Private
 	Private
 	
 	
 	Field _tabView:TabViewExt
 	Field _tabView:TabViewExt
-	Field _browser:DockingView
+	Field _browser:DocBrowserView
 	Field _currentDoc:Ted2Document
 	Field _currentDoc:Ted2Document
 	Field _openDocs:=New Stack<Ted2Document>
 	Field _openDocs:=New Stack<Ted2Document>
 	Field _locked:CodeDocument
 	Field _locked:CodeDocument

+ 14 - 1
document/Ted2Document.monkey2

@@ -62,6 +62,13 @@ Class Ted2Document
 		Return _browser
 		Return _browser
 	End
 	End
 	
 	
+	Property BrowserPropertiesView:View()
+	
+		If Not _browserProperties _browserProperties=OnCreateBrowserProperties()
+		
+		Return _browserProperties
+	End
+	
 	Property TextView:TextView()
 	Property TextView:TextView()
 	
 	
 		Return OnGetTextView( View )
 		Return OnGetTextView( View )
@@ -82,7 +89,7 @@ Class Ted2Document
 	
 	
 	Method Load:Bool()
 	Method Load:Bool()
 	
 	
-		If Not OnLoad() 
+		If Not OnLoad()
 			MainWindow.ReadError( _path )
 			MainWindow.ReadError( _path )
 			Return False
 			Return False
 		Endif
 		Endif
@@ -152,6 +159,11 @@ Class Ted2Document
 		Return Null
 		Return Null
 	End
 	End
 	
 	
+	Method OnCreateBrowserProperties:View() Virtual
+	
+		Return Null
+	End
+	
 	Method OnGetTextView:TextView( view:View ) virtual
 	Method OnGetTextView:TextView( view:View ) virtual
 	
 	
 		Return Cast<TextView>( view )
 		Return Cast<TextView>( view )
@@ -169,6 +181,7 @@ Class Ted2Document
 	Field _view:View
 	Field _view:View
 	Field _fileExt:String
 	Field _fileExt:String
 	Field _browser:View
 	Field _browser:View
+	Field _browserProperties:View
 	
 	
 End
 End
 
 

+ 42 - 3
parser/CodeItem.monkey2

@@ -41,6 +41,26 @@ Class CodeItem
 		_ident=ident
 		_ident=ident
 	End
 	End
 	
 	
+	Function GetNonBlockParent:CodeItem( parent:CodeItem )
+	
+		Local par:=parent
+		While par And par.KindStr="block"
+			par=par.Parent
+		Wend
+		
+		Return par
+	End
+	
+	Function GetNonFieldParent:CodeItem( parent:CodeItem )
+	
+		Local par:=parent
+		While par And par.IsLikeField
+			par=par.Parent
+		Wend
+		
+		Return par
+	End
+	
 	Method OnRemoved()
 	Method OnRemoved()
 		
 		
 		If nspace Then nspace.items.Remove( Self )
 		If nspace Then nspace.items.Remove( Self )
@@ -215,12 +235,20 @@ Class CodeItem
 		Case CodeItemKind.Class_,CodeItemKind.Interface_,CodeItemKind.Struct_,CodeItemKind.Enum_
 		Case CodeItemKind.Class_,CodeItemKind.Interface_,CodeItemKind.Struct_,CodeItemKind.Enum_
 			Return True
 			Return True
 		End
 		End
-		Return False
+		Return _isExtension
 	End
 	End
 	
 	
 	Property IsLikeFunc:Bool()
 	Property IsLikeFunc:Bool()
 		Select _kind
 		Select _kind
-		Case CodeItemKind.Method_,CodeItemKind.Function_
+		Case CodeItemKind.Method_,CodeItemKind.Function_,CodeItemKind.Property_,CodeItemKind.Operator_
+			Return True
+		End
+		Return False
+	End
+	
+	Property IsLikeField:Bool()
+		Select _kind
+		Case CodeItemKind.Field_,CodeItemKind.Global_,CodeItemKind.Local_,CodeItemKind.Const_
 			Return True
 			Return True
 		End
 		End
 		Return False
 		Return False
@@ -236,6 +264,16 @@ Class CodeItem
 		Return _kind=CodeItemKind.Property_
 		Return _kind=CodeItemKind.Property_
 	End
 	End
 	
 	
+	Property IsBlock:Bool()
+	
+		Return _kindStr="block"
+	End
+	
+	Property IsFuncTypedField:Bool()
+		
+		Return (_kindStr="field" Or _kindStr="global") And _type<>Null And _type.IsLikeFunc
+	End
+	
 	Property IsExtension:Bool()
 	Property IsExtension:Bool()
 		Return _isExtension
 		Return _isExtension
 	Setter( value:Bool )
 	Setter( value:Bool )
@@ -419,7 +457,8 @@ Class CodeItem
 			_kind=CodeItemKind.Local_
 			_kind=CodeItemKind.Local_
 		Case "operator"
 		Case "operator"
 			_kind=CodeItemKind.Operator_
 			_kind=CodeItemKind.Operator_
-		Case "for","select","while"
+		'Case "for","select","while"
+		Case "block"
 			_kind=CodeItemKind.Inner_
 			_kind=CodeItemKind.Inner_
 		Case "alias"
 		Case "alias"
 			_kind=CodeItemKind.Alias_
 			_kind=CodeItemKind.Alias_

+ 97 - 53
parser/CodeParsing.monkey2

@@ -4,6 +4,16 @@ Namespace ted2go
 
 
 Class CodeParsing
 Class CodeParsing
 	
 	
+	Function IsFileBuildable:Bool( path:String )
+		
+		Return ExtractExt( path )=".monkey2"
+	End
+	
+	Function DeleteTempFiles()
+		
+		DocWatcher.DeleteTempFiles()
+	End
+	
 	Method New( docs:DocumentManager,projView:ProjectView )
 	Method New( docs:DocumentManager,projView:ProjectView )
 		
 		
 		_docsManager=docs
 		_docsManager=docs
@@ -63,16 +73,6 @@ Class CodeParsing
 		End
 		End
 	End
 	End
 	
 	
-'	Method Parse()
-'		
-'		Local doc:=MainWindow.LockedDocument
-'		If Not doc Then doc=Cast<CodeDocument>( _docsManager.CurrentDocument )
-'		If doc
-'			Local parser:=ParsersManager.Get( doc.CodeView.FileType )
-'			DocWatcher.TryToParse( doc,parser )
-'		Endif
-'	End
-	
 	
 	
 	Private
 	Private
 	
 	
@@ -99,6 +99,8 @@ Class CodeParsing
 	
 	
 	Method StartWatching( doc:CodeDocument )
 	Method StartWatching( doc:CodeDocument )
 		
 		
+		If Not IsFileBuildable( doc.Path ) Return
+		
 		If FindWatcher( doc ) Return ' already added
 		If FindWatcher( doc ) Return ' already added
 		
 		
 		Local watcher:=New DocWatcher( doc )
 		Local watcher:=New DocWatcher( doc )
@@ -168,6 +170,13 @@ Class DocWatcher
 		_timeTextChanged=Millisecs()
 		_timeTextChanged=Millisecs()
 	End
 	End
 	
 	
+	Function DeleteTempFiles()
+		
+		For Local path:=Eachin _tempFiles
+			DeleteFile( path )
+		Next
+	End
+	
 	Private
 	Private
 	
 	
 	Field _view:CodeDocumentView
 	Field _view:CodeDocumentView
@@ -178,6 +187,7 @@ Class DocWatcher
 	Global _timer:Timer
 	Global _timer:Timer
 	Global _parsing:Bool
 	Global _parsing:Bool
 	Global _changed:=New Stack<CodeDocument>
 	Global _changed:=New Stack<CodeDocument>
+	Global _tempFiles:=New StringStack
 	
 	
 	Method OnTextChanged()
 	Method OnTextChanged()
 		
 		
@@ -197,51 +207,78 @@ Class DocWatcher
 		
 		
 		If _parsing Return
 		If _parsing Return
 		
 		
+		' timer that watching for changed docs
+		'
 		If Not _timer Then _timer=New Timer( 1,Lambda()
 		If Not _timer Then _timer=New Timer( 1,Lambda()
 			
 			
-			If _parsing Return
+			If _parsing Or Not enabled Or _changed.Empty Return
 			
 			
 			Local msec:=Millisecs()
 			Local msec:=Millisecs()
 			If msec<_timeDocParsed+1000 Return
 			If msec<_timeDocParsed+1000 Return
 			If _timeTextChanged=0 Or msec<_timeTextChanged+1000 Return
 			If _timeTextChanged=0 Or msec<_timeTextChanged+1000 Return
 			_timeTextChanged=0
 			_timeTextChanged=0
 			
 			
-			If Not enabled Return
-			
 			_parsing=True
 			_parsing=True
 			
 			
-			Local docForParsing:CodeDocument
-			Local dirty:=New String[_changed.Length]
-			Local texts:=New String[_changed.Length]
-			For Local i:=0 Until _changed.Length
-				Local d:=_changed[i]
-				If d.Dirty
-					dirty[i]=d.Path
-					texts[i]=d.CodeView.Text
-				Endif
-				docForParsing=d ' grab latest added doc
-			Next
+			' copy docs and free list to collect new 'changes'
+			'
+			Global _docsToParse:=New Stack<CodeDocument>
+			_docsToParse.AddAll( _changed.ToArray() )
 			_changed.Clear()
 			_changed.Clear()
 			
 			
-			Local params:=New ParseFileParams
-			params.filePath=PathsProvider.GetActiveMainFilePath()
+			Global _paramsToParse:=New Stack<ParseFileParams>
 			
 			
-			For Local i:=0 Until dirty.Length
-				If dirty[i]
-					dirty[i]=Monkey2Parser.GetTempFilePathForParsing( dirty[i] )
-					SaveString( texts[i],dirty[i] )
+			For Local changedDoc:=Eachin _docsToParse
+				
+				' collect all different files to be parsed
+				'
+				Local path:=PathsProvider.GetMainFileOfDocument( changedDoc.Path )
+				Local exists:=False
+				For Local p:=Eachin _paramsToParse
+					If path=p.filePath
+						exists=True
+						Exit
+					Endif
+				Next
+				If Not exists
+					Local params:=New ParseFileParams
+					params.filePath=path
+					_paramsToParse.Add( params )
+				Endif
+				' always save all dirty files in temp before parsing
+				' check changescounter here to avoid unnecessarily re-savings
+				'
+				Local tmpPath:=PathsProvider.GetTempFilePathForParsing( changedDoc.Path )
+				If changedDoc.CheckChangesCounter() 'Or Not FileExists( tmpPath )
+					SaveString( changedDoc.TextView.Text,tmpPath )
+					changedDoc.StoreChangesCounter()
+					CollectTempFile( tmpPath )
 				Endif
 				Endif
 			Next
 			Next
 			
 			
-			Local errorStr:=parser.ParseFile( params )
+			Global _results:=New StringStack
+			
+			' parse all docs
+			'
+			For Local params:=Eachin _paramsToParse
+				Local errorStr:=parser.ParseFile( params )
+				_results.Add( errorStr )
+			Next
 			
 			
+			' maybe app is in shutdown state
+			'
 			If Not enabled Return
 			If Not enabled Return
 			
 			
-			Local errors:=New Stack<BuildError>
+			Global _errors:=New Stack<BuildError>
 			
 			
-			If errorStr And errorStr<>"#"
+			' and collect all errors
+			'
+			Local tmpFolder:=PathsProvider.MX2_TMP+"/"
+			For Local str:=Eachin _results
 				
 				
-				Local arr:=errorStr.Split( "~n" )
+				If Not str Or str="#" Continue
+				
+				Local arr:=str.Split( "~n" )
 				For Local s:=Eachin arr
 				For Local s:=Eachin arr
 					Local i:=s.Find( "] : Error : " )
 					Local i:=s.Find( "] : Error : " )
 					If i<>-1
 					If i<>-1
@@ -250,20 +287,27 @@ Class DocWatcher
 							Local path:=s.Slice( 0,j )
 							Local path:=s.Slice( 0,j )
 							Local line:=Int( s.Slice( j+2,i ) )-1
 							Local line:=Int( s.Slice( j+2,i ) )-1
 							Local msg:=s.Slice( i+12 )
 							Local msg:=s.Slice( i+12 )
-							path=path.Replace( ".mx2/","" )
+							path=path.Replace( tmpFolder,"" )
 							Local err:=New BuildError( path,line,msg )
 							Local err:=New BuildError( path,line,msg )
-							errors.Add( err )
+							_errors.Add( err )
 						Endif
 						Endif
 					Endif
 					Endif
 				Next
 				Next
-				
-			Endif
+			Next
 			
 			
-			OnDocumentParsed( docForParsing,parser,errors )
+			OnParseCompleted( parser,_errors )
 			
 			
-			For Local i:=0 Until dirty.Length
-				If dirty[i] Then DeleteFile( dirty[i] )
-			Next
+			' don't remove tmp files to avoid unnecessarily re-savings
+			'
+'			For Local changedDoc:=Eachin _docsToParse
+'				Local tmpPath:=Monkey2Parser.GetTempFilePathForParsing( changedDoc.Path )
+'				DeleteFile( tmpPath )
+'			Next
+			
+			_docsToParse.Clear()
+			_paramsToParse.Clear()
+			_errors.Clear()
+			_results.Clear()
 			
 			
 			_parsing=False
 			_parsing=False
 			
 			
@@ -273,28 +317,28 @@ Class DocWatcher
 		
 		
 	End
 	End
 	
 	
+	Function CollectTempFile( path:String )
+	
+		If Not _tempFiles.Contains( path )
+			_tempFiles.Add( path )
+		Endif
+	End
+	
 	Function UpdateDocItems( doc:CodeDocument,parser:ICodeParser )
 	Function UpdateDocItems( doc:CodeDocument,parser:ICodeParser )
 	
 	
 		Local items:=GetCodeItems( doc.Path,parser )
 		Local items:=GetCodeItems( doc.Path,parser )
 		doc.OnDocumentParsed( items,Null )
 		doc.OnDocumentParsed( items,Null )
 	End
 	End
 	
 	
-	Function OnDocumentParsed( doc:CodeDocument,parser:ICodeParser,errors:Stack<BuildError> )
-		
-		If doc
-			Local items:=GetCodeItems( doc.Path,parser )
-			doc.OnDocumentParsed( items,GetErrors( doc.Path,errors ) )
-		Endif
+	Function OnParseCompleted( parser:ICodeParser,errors:Stack<BuildError> )
 		
 		
 		Local docs:=docsForUpdate()
 		Local docs:=docsForUpdate()
 		If docs
 		If docs
-			For Local d:=Eachin docs
-				If d=doc Continue
-				Local items:=GetCodeItems( d.Path,parser )
-				d.OnDocumentParsed( items,GetErrors( d.Path,errors ) )
+			For Local doc:=Eachin docs
+				Local items:=GetCodeItems( doc.Path,parser )
+				doc.OnDocumentParsed( items,GetErrors( doc.Path,errors ) )
 			Next
 			Next
 		Endif
 		Endif
-		
 	End
 	End
 	
 	
 	Function GetErrors:Stack<BuildError>( path:String,errors:Stack<BuildError>)
 	Function GetErrors:Stack<BuildError>( path:String,errors:Stack<BuildError>)

+ 41 - 76
parser/Monkey2Parser.monkey2

@@ -42,6 +42,8 @@ Class Monkey2Parser Extends CodeParserPlugin
 		
 		
 		New Fiber( Lambda()
 		New Fiber( Lambda()
 			
 			
+			Fiber.Sleep( 1.5 )
+			
 			Local time:=Millisecs()
 			Local time:=Millisecs()
 			
 			
 			ParseModules()
 			ParseModules()
@@ -93,35 +95,41 @@ Class Monkey2Parser Extends CodeParserPlugin
 	Method ParseFile:String( params:ParseFileParams )
 	Method ParseFile:String( params:ParseFileParams )
 		
 		
 		Local filePath:=params.filePath
 		Local filePath:=params.filePath
-		'Local pathOnDisk:=params.pathOnDisk
 		Local moduleName:=params.moduleName
 		Local moduleName:=params.moduleName
 		Local geninfo:=params.geninfo
 		Local geninfo:=params.geninfo
 		
 		
-		' start parsing process
+		Local parsingData:=""
+		Local errorMessage:=""
+		
+		' start parsing process - ask mx2cc to generate .geninfo files
 		'
 		'
 		If geninfo And _enabled
 		If geninfo And _enabled
-			Local parsedPath:String
-			Local cmd:=GetParseCommand( filePath,Varptr parsedPath )
+			
+			'Print "source file: "+filePath
+			
+			Local cmd:=GetFullParseCommand( filePath )
 			
 			
 			If Not cmd Return "#"
 			If Not cmd Return "#"
 			
 			
 			Local proc:=New ProcessReader( filePath )
 			Local proc:=New ProcessReader( filePath )
 			Local str:=proc.Run( cmd )
 			Local str:=proc.Run( cmd )
 			
 			
-			If Not str Return "#" 'special kind of error
+			If Not str Return "#" ' it's special kind of error
 			
 			
 			Local hasErrors:=(str.Find( "] : Error : " ) > 0)
 			Local hasErrors:=(str.Find( "] : Error : " ) > 0)
 			
 			
-			If hasErrors Return str
+			If hasErrors
+				errorMessage=str
+			Endif
 			
 			
-			filePath=parsedPath
 		Endif
 		Endif
 		
 		
-		Local geninfoPath:=GetGeninfoPath( filePath )
+		Local geninfoPath:=PathsProvider.GetGeninfoPath( filePath )
+		
 		If Not geninfo
 		If Not geninfo
-			' is file modified?
+			' was file modified?
 			Local time:=GetFileTime( geninfoPath )
 			Local time:=GetFileTime( geninfoPath )
-			If time=0 Return Null ' file not found
+			'If time=0 Return Null ' file not found
 		
 		
 			Local last:=_filesTime[filePath]
 			Local last:=_filesTime[filePath]
 		
 		
@@ -133,14 +141,19 @@ Class Monkey2Parser Extends CodeParserPlugin
 				Return Null
 				Return Null
 			Endif
 			Endif
 		Endif
 		Endif
-		'Print "info path: "+geninfoPath
-		Local jobj:=JsonObject.Parse( LoadString( geninfoPath ),True )
 		
 		
-		If Not jobj Return "#"
+		parsingData=LoadString( geninfoPath )
+		
+		Local jobj:=JsonObject.Parse( parsingData )
+		
+		If Not jobj
+			'Print "invalid json: "+filePath
+			Return "#"
+		Endif
 		
 		
 		
 		
 		RemovePrevious( filePath )
 		RemovePrevious( filePath )
-
+		
 		Local nspace:= jobj.Contains( "namespace" ) ? jobj["namespace"].ToString() Else ""
 		Local nspace:= jobj.Contains( "namespace" ) ? jobj["namespace"].ToString() Else ""
 		
 		
 		If jobj.Contains( "members" )
 		If jobj.Contains( "members" )
@@ -190,7 +203,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 		Endif
 		Endif
 		UsingsMap[filePath]=useInfo
 		UsingsMap[filePath]=useInfo
 		
 		
-		Return Null
+		Return errorMessage
 	End
 	End
 	
 	
 	Method ParseJsonMembers( members:Stack<JsonValue>,parent:CodeItem,filePath:String,resultContainer:Stack<CodeItem>,namespac:String )
 	Method ParseJsonMembers( members:Stack<JsonValue>,parent:CodeItem,filePath:String,resultContainer:Stack<CodeItem>,namespac:String )
@@ -233,7 +246,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 					
 					
 				Case "block"
 				Case "block"
 					
 					
-					item.Ident=""+item.ScopeStartPos+"..."+item.ScopeEndPos
+					item.Ident="block{"+item.ScopeStartPos+"..."+item.ScopeEndPos+"}"
 				
 				
 				Case "property"
 				Case "property"
 					
 					
@@ -302,7 +315,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 			If kind="local"
 			If kind="local"
 				' add into parent that isn't a nested block
 				' add into parent that isn't a nested block
 				' like method/func
 				' like method/func
-				Local par:=GetNonBlockParent( parent )
+				Local par:=CodeItem.GetNonBlockParent( parent )
 				item.SetParent( par )
 				item.SetParent( par )
 			Elseif parent
 			Elseif parent
 				item.SetParent( parent )
 				item.SetParent( parent )
@@ -439,51 +452,23 @@ Class Monkey2Parser Extends CodeParserPlugin
 		
 		
 	End
 	End
 	
 	
-	Function GetParseCommand:String( filePathToParse:String,realParsedPath:String Ptr=Null )
-		
-		Local path:String
-		' is it a module file?
-		Local modsDir:=Prefs.MonkeyRootPath+"modules/"
-		If filePathToParse.StartsWith( modsDir ) And filePathToParse.Find( "/tests/")=-1
-			Local i1:=modsDir.Length
-			Local i2:=filePathToParse.Find( "/",i1+1 )
-			If i2<>-1
-				Local modName:=filePathToParse.Slice( i1,i2 )
-				path=modsDir+modName+"/"+modName+".monkey2"
-			Else
-				path=filePathToParse
-			Endif
-		Else
-			Local mainFile:=PathsProvider.GetActiveMainFilePath()
-			If mainFile
-				If GetFileType( mainFile )<>FileType.File
-					Alert( "File doesn't exists!~n"+mainFile,"Invalid main file" )
-				Endif
-				' is it a standalone file?
-				Local proj:=ProjectView.FindProject( filePathToParse )?.Folder
-				path = mainFile.StartsWith( proj ) ? mainFile Else filePathToParse
-			Else
-				path=filePathToParse
-			Endif
-		Endif
-		Print "path: "+path
-		realParsedPath[0]=path
+	Function GetSimpleParseCommand:String( filePathToParse:String )
 		
 		
-		Return path ? "~q"+MainWindow.Mx2ccPath+"~q geninfo ~q"+path+"~q" Else ""
+		Return "~q"+MainWindow.Mx2ccPath+"~q geninfo -parse ~q"+filePathToParse+"~q"
 	End
 	End
 	
 	
-	Function GetGeninfoPath:String( filePath:String )
+	Function GetFullParseCommand:String( filePathToParse:String )
 		
 		
-		Return ExtractDir( filePath )+".mx2/"+StripDir( StripExt( filePath ) )+".geninfo"
+		Return "~q"+MainWindow.Mx2ccPath+"~q geninfo -semant ~q"+filePathToParse+"~q"
 	End
 	End
 	
 	
-	Function GetTempFilePathForParsing:String( srcPath:String )
+	Function GetSuitableFilePathToParse:String( filePath:String )
 		
 		
-		Local dir:=ExtractDir( srcPath )+".mx2/"
-		CreateDir( dir )
-		Local name:=StripDir( srcPath )
+		Local tmpPath:=PathsProvider.GetTempFilePathForParsing( filePath )
+		Local t1:=GetFileTime( filePath )
+		Local t2:=GetFileTime( tmpPath )
 		
 		
-		Return dir+name
+		Return t1>t2 ? filePath Else tmpPath
 	End
 	End
 	
 	
 	
 	
@@ -1234,16 +1219,6 @@ Class Monkey2Parser Extends CodeParserPlugin
 		Return False
 		Return False
 	End
 	End
 	
 	
-	Function GetNonBlockParent:CodeItem( parent:CodeItem )
-	
-		Local par:=parent
-		While par And par.KindStr="block"
-			par=par.Parent
-		Wend
-		
-		Return par
-	End
-	
 	Function GetScopePosition:Vec2i( strPos:String )
 	Function GetScopePosition:Vec2i( strPos:String )
 		
 		
 		Local arr:=strPos.Split( ":" )
 		Local arr:=strPos.Split( ":" )
@@ -1352,17 +1327,6 @@ Class Monkey2Parser Extends CodeParserPlugin
 		' inside of item's parent
 		' inside of item's parent
 		If item.Parent.Ident = scopeClass.Ident Return True
 		If item.Parent.Ident = scopeClass.Ident Return True
 		
 		
-'		Local type:=item.Parent.Type.ident
-'		
-		' it's own class
-'		If type = scopeClass.Type.ident
-'			Return True
-'		Else
-'			' inherited
-'			Local has:=scopeClass.HasSuchSuperClass( type )
-'			If has Return item.Access = AccessMode.Protected_
-'		Endif
-		
 		Return False
 		Return False
 		
 		
 	End
 	End
@@ -1373,10 +1337,11 @@ Class Monkey2Parser Extends CodeParserPlugin
 		Local endpos:=item.ScopeEndPos
 		Local endpos:=item.ScopeEndPos
 		
 		
 		If localRule<>LOCAL_RULE_NONE And IsLocalMember( item )
 		If localRule<>LOCAL_RULE_NONE And IsLocalMember( item )
-			'cursor.x-=1 ' hacking
 			If localRule=LOCAL_RULE_SELF_SCOPE
 			If localRule=LOCAL_RULE_SELF_SCOPE
+				cursor.x-=1 ' hacking
 				Return cursor.x=srcpos.x And cursor.y>=srcpos.y
 				Return cursor.x=srcpos.x And cursor.y>=srcpos.y
 			Elseif localRule=LOCAL_RULE_PARENT_SCOPE
 			Elseif localRule=LOCAL_RULE_PARENT_SCOPE
+				
 				Return (cursor.x=srcpos.x And cursor.y>=srcpos.y) Or 
 				Return (cursor.x=srcpos.x And cursor.y>=srcpos.y) Or 
 						(cursor.x>srcpos.x And cursor.x<endpos.x)
 						(cursor.x>srcpos.x And cursor.x<endpos.x)
 			Endif
 			Endif

+ 8 - 8
syntax/CppHighlighter.monkey2

@@ -3,16 +3,16 @@ Namespace ted2go
 
 
 
 
 Class CppHighlighter Extends HighlighterPlugin
 Class CppHighlighter Extends HighlighterPlugin
-
+	
 	Property Name:String() Override
 	Property Name:String() Override
 		Return "CppHighlighter"
 		Return "CppHighlighter"
 	End
 	End
-
-		
+	
+	
 	Private
 	Private
 	
 	
 	Global _instance:=New CppHighlighter
 	Global _instance:=New CppHighlighter
-		
+	
 	Method New()
 	Method New()
 		Super.New()
 		Super.New()
 		_types=New String[]( ".cpp",".h",".hpp",".c",".js" )
 		_types=New String[]( ".cpp",".h",".hpp",".c",".js" )
@@ -21,7 +21,7 @@ Class CppHighlighter Extends HighlighterPlugin
 	End
 	End
 	
 	
 	Method HL:Int( text:String,colors:Byte[],sol:Int,eol:Int,state:Int )
 	Method HL:Int( text:String,colors:Byte[],sol:Int,eol:Int,state:Int )
-
+		
 		Local i0:=sol
 		Local i0:=sol
 		Local icolor:=0
 		Local icolor:=0
 		Local istart:=sol
 		Local istart:=sol
@@ -57,7 +57,7 @@ Class CppHighlighter Extends HighlighterPlugin
 			
 			
 			Endif
 			Endif
 			
 			
-			If state=10 
+			If state=10
 				' */  closed
 				' */  closed
 				Local pos:=text.Slice( i0-1,eol ).Find( "*/" )
 				Local pos:=text.Slice( i0-1,eol ).Find( "*/" )
 				If pos<>-1
 				If pos<>-1
@@ -83,8 +83,8 @@ Class CppHighlighter Extends HighlighterPlugin
 				color=Highlighter.COLOR_COMMENT
 				color=Highlighter.COLOR_COMMENT
 				
 				
 			Else If chr=34 Or chr=39
 			Else If chr=34 Or chr=39
-			
-				While i0<eol And text[i0]<>34 And text[i0]<>39
+				
+				While i0<eol And text[i0]<>chr
 					i0+=1
 					i0+=1
 				Wend
 				Wend
 				If i0<eol i0+=1
 				If i0<eol i0+=1

+ 5 - 3
syntax/Highlighter.monkey2

@@ -12,6 +12,7 @@ Class Highlighter
 	Const COLOR_COMMENT:=5
 	Const COLOR_COMMENT:=5
 	Const COLOR_PREPROC:=6
 	Const COLOR_PREPROC:=6
 	Const COLOR_OTHER:=7
 	Const COLOR_OTHER:=7
+	Const COLOR_CODE_ITEM:=8
 	
 	
 	'use it like a property, as readonly
 	'use it like a property, as readonly
 	Field Painter:Int( text:String,colors:Byte[],sol:Int,eol:Int,state:Int )
 	Field Painter:Int( text:String,colors:Byte[],sol:Int,eol:Int,state:Int )
@@ -20,11 +21,11 @@ End
 
 
 
 
 Class HighlighterPlugin Extends PluginDependsOnFileType
 Class HighlighterPlugin Extends PluginDependsOnFileType
-
+	
 	Property Name:String() Override
 	Property Name:String() Override
 		Return "HighlighterPlugin"
 		Return "HighlighterPlugin"
 	End
 	End
-		
+	
 	Property Highlighter:Highlighter()
 	Property Highlighter:Highlighter()
 		Return _hl
 		Return _hl
 	End
 	End
@@ -35,9 +36,10 @@ Class HighlighterPlugin Extends PluginDependsOnFileType
 	Method New()
 	Method New()
 		AddPlugin( Self )
 		AddPlugin( Self )
 	End
 	End
-		
+	
 	Field _hl:Highlighter
 	Field _hl:Highlighter
 	Field _keywords:IKeywords
 	Field _keywords:IKeywords
+	Field _parser:ICodeParser
 	
 	
 End
 End
 
 

+ 7 - 3
syntax/Monkey2Highlighter.monkey2

@@ -22,7 +22,8 @@ Class Monkey2Highlighter Extends HighlighterPlugin
 	
 	
 	Method HL:Int( text:String,colors:Byte[],sol:Int,eol:Int,state:Int )
 	Method HL:Int( text:String,colors:Byte[],sol:Int,eol:Int,state:Int )
 
 
-        If _keywords = Null Then _keywords=KeywordsManager.Get( GetMainFileType() )
+        If Not _keywords Then _keywords=KeywordsManager.Get( GetMainFileType() )
+        If Not _parser Then _parser=ParsersManager.Get( GetMainFileType() )
 
 
 		Local i0:=sol
 		Local i0:=sol
 		
 		
@@ -134,8 +135,11 @@ Class Monkey2Highlighter Extends HighlighterPlugin
 				
 				
 					color=Highlighter.COLOR_IDENT
 					color=Highlighter.COLOR_IDENT
 					
 					
-					If _keywords.Contains( id ) Then color=Highlighter.COLOR_KEYWORD
-				
+					If _keywords.Contains( id )
+						color=Highlighter.COLOR_KEYWORD
+'					Elseif _parser.GetItem( id )
+'						color=Highlighter.COLOR_CODE_ITEM
+					Endif
 				Endif
 				Endif
 				
 				
 			Else If IsDigit( chr )
 			Else If IsDigit( chr )

+ 2 - 0
testing/async.cpp

@@ -3,6 +3,8 @@
 
 
 #include <SDL.h>
 #include <SDL.h>
 
 
+bbRuntimeError( "Type '"+getName()+"' is not a pointer type" );
+
 bbInt g_mojo_app_AppInstance_AddAsyncCallback( bbFunction<void()> callback );
 bbInt g_mojo_app_AppInstance_AddAsyncCallback( bbFunction<void()> callback );
 
 
 namespace{
 namespace{

+ 0 - 0
ThemeImages.monkey2 → theme/ThemeImages.monkey2


+ 51 - 0
theme/ThemesInfo.monkey2

@@ -0,0 +1,51 @@
+
+Namespace ted2go
+
+
+Class ThemesInfo
+	
+	Global ActiveThemePath:String
+	
+	Function Load( path:String )
+		
+		_json=JsonObject.Load( path )
+		_names.Clear()
+		For Local it:=Eachin _json
+			_names.Add( it.Key )
+		Next
+	End
+	
+	Function IsActiveThemeDark:Bool()
+		
+		For Local it:=Eachin _json
+			Local jobj:=_json[it.Key].ToObject()
+			If jobj["path"].ToString()=ActiveThemePath
+				Return jobj["dark"].ToBool()
+			Endif
+		Next
+		
+		Return False
+	End
+	
+	Function GetCount:Int()
+		
+		Return _json.Count()
+	End
+	
+	Function GetNameAt:String( index:Int )
+		
+		Return _names[index]
+	End
+	
+	Function GetPathAt:String( index:Int )
+		
+		Return _json[_names[index]].ToObject()["path"].ToString()
+	End
+	
+	
+	Private
+	
+	Global _json:JsonObject
+	Global _names:=New StringStack
+	
+End

+ 25 - 0
utils/TextUtils.monkey2

@@ -45,6 +45,31 @@ Class TextUtils Final
 		Return pos
 		Return pos
 	End
 	End
 	
 	
+	Function Split:String[]( text:String,splitters:Int[] )
+		
+		Local results:=New StringStack
+		Local s:="",prev:=0
+		For Local i:=0 Until text.Length
+			Local chr:=text[i]
+			For Local splt:=Eachin splitters
+				If chr=splt
+					If s<>""
+						results.Add( text.Slice( prev,i ) )
+					Endif
+					prev=i+1
+					s=""
+					Exit
+				Else
+					s+=String.FromChar( chr )
+				Endif
+			Next
+			If i=text.Length-1
+				results.Add( text.Slice( prev,text.Length ) )
+			Endif
+		Next
+		
+		Return results.ToArray()
+	End
 	
 	
 	Private
 	Private
 	
 	

+ 17 - 10
utils/Utils.monkey2

@@ -172,9 +172,16 @@ Class Utils Final
 		Return Null
 		Return Null
 	End
 	End
 	
 	
-	Function PrintLog<T>( list:List<T>,prefix:String="" )
+	Function PrintLog<T>( items:List<T>,prefix:String="" )
 	
 	
-		For Local i:=Eachin list
+		For Local i:=Eachin items
+			Print prefix+""+i
+		End
+	End
+	
+	Function PrintLog<T>( items:Stack<T>,prefix:String="" )
+	
+		For Local i:=Eachin items
 			Print prefix+""+i
 			Print prefix+""+i
 		End
 		End
 	End
 	End
@@ -365,16 +372,16 @@ End
 
 
 #Rem monkeydocs Return ident and position in line where ident starts
 #Rem monkeydocs Return ident and position in line where ident starts
 #End
 #End
-Function GetIndentBeforePos_Mx2:IdentInfo( line:String,pos:Int,withDots:Bool )
+Function GetIndentBeforePos_Mx2:IdentInfo( line:String,posInLine:Int,withDots:Bool )
 	
 	
 	' grab whole word under cursor
 	' grab whole word under cursor
 	'
 	'
-	Local len:=line.Length
-	While pos < len And IsIdent( line[pos] )
-		pos+=1
-	Wend
+'	Local len:=line.Length
+'	While pos <= posInLine And IsIdent( line[pos] )
+'		pos+=1
+'	Wend
 	
 	
-	Local n:=pos-1
+	Local n:=posInLine-1
 	
 	
 	While n >= 0
 	While n >= 0
 	
 	
@@ -416,9 +423,9 @@ Function GetIndentBeforePos_Mx2:IdentInfo( line:String,pos:Int,withDots:Bool )
 	Local s:=""
 	Local s:=""
 	Local starts:=-1
 	Local starts:=-1
 	Local arr:=False
 	Local arr:=False
-	If n < pos
+	If n < posInLine
 		starts=n
 		starts=n
-		s=line.Slice( n,pos ).Replace( "?.","." ).Replace( "->","." )
+		s=line.Slice( n,posInLine ).Replace( "?.","." ).Replace( "->","." )
 		Local i:=s.FindLast( "." )
 		Local i:=s.FindLast( "." )
 		arr=(i>0 And s[i-1]=Chars.CLOSED_SQUARE_BRACKET) ' [i].
 		arr=(i>0 And s[i-1]=Chars.CLOSED_SQUARE_BRACKET) ' [i].
 		If s.Find( "[" )<>-1
 		If s.Find( "[" )<>-1

+ 19 - 0
utils/ViewUtils.monkey2

@@ -0,0 +1,19 @@
+
+Namespace ted2go
+
+
+' extenging of View allows us to use protected methods
+'
+Class ViewUtils Extends View Abstract
+	
+	Function SendMouseEvent( view:View,event:MouseEvent )
+		view.OnMouseEvent( event )
+	End
+	
+	Function SendMouseEvent( view:View,eventType:EventType )
+		
+		Local event:=New MouseEvent( eventType,view,App.MouseLocation,MouseButton.Left,Null,Modifier.None,1 )
+		view.OnMouseEvent( event )
+	End
+	
+End

+ 40 - 20
view/AutocompleteView.monkey2

@@ -116,10 +116,18 @@ Class AutocompleteDialog Extends NoTitleDialog
 		
 		
 		_view=New AutocompleteListView( lineHg,linesCount )
 		_view=New AutocompleteListView( lineHg,linesCount )
 		_view.MoveCyclic=True
 		_view.MoveCyclic=True
+		_view.Layout="fill"
+		
+		_hintView=New Label( "Press Ctr+Space to show more..." )
+		_hintView.Style=App.Theme.GetStyleWithDownCasting( "CompletionHint","Label" )
+		
+		Local dock:=New DockingView
+		dock.AddView( _hintView,"bottom" )
+		dock.ContentView=_view
 		
 		
 		_etalonMaxSize=New Vec2i( 500,lineHg*linesCount )
 		_etalonMaxSize=New Vec2i( 500,lineHg*linesCount )
 		
 		
-		ContentView=_view
+		ContentView=dock
 		
 		
 		_keywords=New StringMap<Stack<ListViewItem>>
 		_keywords=New StringMap<Stack<ListViewItem>>
 		_templates=New StringMap<Stack<ListViewItem>>
 		_templates=New StringMap<Stack<ListViewItem>>
@@ -182,6 +190,8 @@ Class AutocompleteDialog Extends NoTitleDialog
 		
 		
 		Local filter:=_disableUsingsFilter
 		Local filter:=_disableUsingsFilter
 		
 		
+		_hintView.Text=(_disableUsingsFilter ? "Press Ctr+Space to show less..." Else "Press Ctr+Space to show more...")
+		
 		'-----------------------------
 		'-----------------------------
 		' some optimization
 		' some optimization
 		'-----------------------------
 		'-----------------------------
@@ -234,35 +244,24 @@ Class AutocompleteDialog Extends NoTitleDialog
 		
 		
 			Local usings:Stack<String>
 			Local usings:Stack<String>
 			
 			
-			If Not _disableUsingsFilter 'And onlyOne
+			If Not _disableUsingsFilter
 				
 				
 				usings=New Stack<String>
 				usings=New Stack<String>
 				
 				
-				Local locked:=MainWindow.LockedDocument
-				Local current:=Cast<CodeDocument>( MainWindow.DocsManager.CurrentDocument )
-				
-				If Not locked Then locked=current
-				If locked
-					Local info:=parser.UsingsMap[locked.Path]
+				Local currentFile:=Cast<CodeDocument>( MainWindow.DocsManager.CurrentDocument )?.Path
+				Local mainFile:=PathsProvider.GetMainFileOfDocument( currentFile )
+				If mainFile
+					Local info:=parser.UsingsMap[mainFile]
 					If info.nspace Or info.usings
 					If info.nspace Or info.usings
 						If info.nspace Then usings.Add( info.nspace+".." )
 						If info.nspace Then usings.Add( info.nspace+".." )
 						If info.usings Then usings.AddAll( info.usings )
 						If info.usings Then usings.AddAll( info.usings )
 					Endif
 					Endif
 				Endif
 				Endif
 				
 				
-				If current And current <> locked
-					Local info:=parser.UsingsMap[current.Path]
-					If info.nspace
-						Local s:=info.nspace+".."
-						If Not usings.Contains( s ) Then usings.Add( s )
-					Endif
-					If info.usings Then usings.AddAll( info.usings )
-				Endif
-				
 				If Not usings.Contains( "monkey.." ) Then usings.Add( "monkey.." )
 				If Not usings.Contains( "monkey.." ) Then usings.Add( "monkey.." )
 			Endif
 			Endif
 			
 			
-			'Print "usings: "+usings.Join( " " )
+			'Print "usings: "+usings?.Join( " " )
 			
 			
 			_listForExtract.Clear()
 			_listForExtract.Clear()
 			
 			
@@ -362,6 +361,7 @@ Class AutocompleteDialog Extends NoTitleDialog
 	
 	
 	Field _etalonMaxSize:Vec2f
 	Field _etalonMaxSize:Vec2f
 	Field _view:AutocompleteListView
 	Field _view:AutocompleteListView
+	Field _hintView:Label
 	Field _keywords:StringMap<Stack<ListViewItem>>
 	Field _keywords:StringMap<Stack<ListViewItem>>
 	Field _templates:StringMap<Stack<ListViewItem>>
 	Field _templates:StringMap<Stack<ListViewItem>>
 	Field _lastIdentPart:String,_fullIdent:String
 	Field _lastIdentPart:String,_fullIdent:String
@@ -401,6 +401,8 @@ Class AutocompleteDialog Extends NoTitleDialog
 		
 		
 		If Not IsOpened Return
 		If Not IsOpened Return
 		
 		
+		Local ctrl:=(event.Modifiers & Modifier.Control)<>0
+		
 		Select event.Type
 		Select event.Type
 			
 			
 			Case EventType.KeyDown,EventType.KeyRepeat
 			Case EventType.KeyDown,EventType.KeyRepeat
@@ -452,7 +454,6 @@ Class AutocompleteDialog Extends NoTitleDialog
 					
 					
 				Case Key.Space
 				Case Key.Space
 					If Not templ
 					If Not templ
-						Local ctrl:=event.Modifiers & Modifier.Control
 						If Prefs.AcUseSpace And Not ctrl
 						If Prefs.AcUseSpace And Not ctrl
 							OnItemChoosen( curItem,key )
 							OnItemChoosen( curItem,key )
 							event.Eat()
 							event.Eat()
@@ -479,7 +480,9 @@ Class AutocompleteDialog Extends NoTitleDialog
 			
 			
 			Case EventType.KeyChar
 			Case EventType.KeyChar
 				
 				
-				If Not IsIdent( event.Text[0] ) Then Hide()
+				Local char:=event.Text[0]
+				Local ctrlSpace:=(ctrl And char=Chars.SPACE)
+				If Not ctrlSpace And Not IsIdent( char ) Then Hide()
 				
 				
 		End
 		End
 		
 		
@@ -571,3 +574,20 @@ Class AutocompleteDialog Extends NoTitleDialog
 	End
 	End
 	
 	
 End
 End
+
+
+Class Theme Extension
+	
+	Method GetStyleWithDownCasting:Style( name:String,name2:String=Null,name3:String=Null )
+		
+		Local style:=Self.GetStyle( name )
+		If style=Null And name2
+			style=Self.GetStyle( name2 )
+		Endif
+		If style=Null And name3
+			style=Self.GetStyle( name3 )
+		Endif
+		
+		Return style
+	End
+End

+ 5 - 5
view/CodeGutterView.monkey2

@@ -114,13 +114,13 @@ Class CodeGutterView Extends View
 			
 			
 			' show dots between each 10th
 			' show dots between each 10th
 			'
 			'
-			Local ok:=Prefs.EditorShowEvery10LineNumber And ((i+1) Mod 10 <> 0)
-			ok=ok And Not (folding And folding.folded)
-			If ok And i<>cursorLine And i<>anchorLine
+			Local drawDot:=Prefs.EditorShowEvery10LineNumber And ((i+1) Mod 10 <> 0)
+			drawDot=drawDot And Not (folding And folding.folded)
+			drawDot=drawDot And i<>cursorLine And i<>anchorLine
+			If drawDot
 				canvas.Alpha=0.5
 				canvas.Alpha=0.5
 				canvas.DrawRect( xx-4*k,hcenter-1*k,2*k,2*k )
 				canvas.DrawRect( xx-4*k,hcenter-1*k,2*k,2*k )
 				canvas.Alpha=1
 				canvas.Alpha=1
-				Continue
 			Endif
 			Endif
 			
 			
 			' show error bubble
 			' show error bubble
@@ -131,7 +131,7 @@ Class CodeGutterView Extends View
 					canvas.DrawImage( _errorIcon,xx-_errorIcon.Width,rect.Top )
 					canvas.DrawImage( _errorIcon,xx-_errorIcon.Width,rect.Top )
 					canvas.Color=textColor
 					canvas.Color=textColor
 				Endif
 				Endif
-			Else
+			Elseif Not drawDot
 				canvas.Color=(i=cursorLine Or i=anchorLine) ? textColor*1.125 Else textColor 'make selected line number little brighter
 				canvas.Color=(i=cursorLine Or i=anchorLine) ? textColor*1.125 Else textColor 'make selected line number little brighter
 				canvas.DrawText( i+1,xx,hcenter,1,.5 )
 				canvas.DrawText( i+1,xx,hcenter,1,.5 )
 			Endif
 			Endif

+ 18 - 17
view/CodeTextView.monkey2

@@ -1282,9 +1282,6 @@ Class IndentationHelper Final
 			
 			
 			Local line:=lines[lineIndex]
 			Local line:=lines[lineIndex]
 			
 			
-			Local lineLen:=line.Length
-			If lineLen=0 Continue
-			
 			' trim endings of lines
 			' trim endings of lines
 			Local s:=line.TrimEnd()
 			Local s:=line.TrimEnd()
 			If s ' don't trim whitespaced lines
 			If s ' don't trim whitespaced lines
@@ -1292,8 +1289,11 @@ Class IndentationHelper Final
 				lines[lineIndex]=line
 				lines[lineIndex]=line
 			Endif
 			Endif
 			
 			
+			Local lineLen:=line.Length
+			If lineLen=0 Continue
+			
 			Local start:=document.StartOfLine( lineIndex )
 			Local start:=document.StartOfLine( lineIndex )
-			Local lineStr:="" ' our new content of line 
+			Local lineStr:="" ' our new content of line
 			Local indentStart:=-1,textStart:=0
 			Local indentStart:=-1,textStart:=0
 			Local replaced:=0
 			Local replaced:=0
 			
 			
@@ -1317,7 +1317,7 @@ Class IndentationHelper Final
 					Endif
 					Endif
 					
 					
 					' indentation found
 					' indentation found
-					If Not skip And indentStart<>-1 And k-indentStart>=minIndent
+					If Not skip And indentStart<>-1 And (indentStart=0 Or k-indentStart>=minIndent)
 						
 						
 						replaced+=1
 						replaced+=1
 						
 						
@@ -1352,20 +1352,21 @@ Class IndentationHelper Final
 							
 							
 						Else ' spaces --> tabs
 						Else ' spaces --> tabs
 							
 							
-							indentStr=indentStr.Replace( "~t",tabAsSpacesStr ) ' avoid mixing of tabs and spaces
-							Local size:=indentStr.Length
-							Local cnt:=size/tabSize
-							Local md:=size Mod tabSize
-							indentStr=""
-							If md>1 ' convert 2+ spaces into tab
-								cnt+=1
-							Elseif md>0 ' left 1 space as is at the beginning of indent
-								indentStr+=" "
-							Endif
-							If cnt>0 ' our tabs 'replacement'
-								indentStr+="~t".Dup( cnt )
+							Local spacesCount:=0
+							For Local ch:=Eachin indentStr
+								If ch=Chars.SPACE Then spacesCount+=1
+							Next
+							Local tabsCount:=indentStr.Length-spacesCount
+							Local cnt:=spacesCount/tabSize
+							Local md:=spacesCount Mod tabSize
+							If tabsCount>0
+								tabsCount+=cnt
+							Else
+								tabsCount=cnt+(md ? 1 Else 0)
 							Endif
 							Endif
 							
 							
+							indentStr="~t".Dup( tabsCount )
+							
 						Endif
 						Endif
 						
 						
 						lineStr+=indentStr
 						lineStr+=indentStr

+ 27 - 10
view/CodeTreeView.monkey2

@@ -6,6 +6,7 @@ Class CodeTreeView Extends TreeViewExt
 	
 	
 	Field SortByType:=True
 	Field SortByType:=True
 	Field ShowInherited:=False
 	Field ShowInherited:=False
+	Field FillNestedItems:=True
 	
 	
 	Method Fill( codeItems:Stack<CodeItem>,parser:ICodeParser,expandIfOnlyOneItem:Bool=True )
 	Method Fill( codeItems:Stack<CodeItem>,parser:ICodeParser,expandIfOnlyOneItem:Bool=True )
 		
 		
@@ -39,8 +40,20 @@ Class CodeTreeView Extends TreeViewExt
 		If Not node And scope.Parent Then node=FindNode( RootNode,scope.Parent )
 		If Not node And scope.Parent Then node=FindNode( RootNode,scope.Parent )
 		If Not node Return
 		If Not node Return
 		
 		
-		node.Expanded=True
-		TreeViewExpander.ExpandParents( node )
+		'node.Expanded=True
+		'_expander.Store( node )
+		
+		Local isContainer:=(scope.IsLikeFunc Or scope.IsLikeClass)
+		
+		If Not isContainer
+			If node.Parent And node.Parent.Expanded=False
+				node=node.Parent
+			Endif
+		Endif
+		
+		If isContainer
+			TreeViewExpander.ExpandParents( node )
+		Endif
 		
 		
 		MeasureLayoutSize()
 		MeasureLayoutSize()
 		
 		
@@ -48,11 +61,6 @@ Class CodeTreeView Extends TreeViewExt
 		Selected=node
 		Selected=node
 	End
 	End
 	
 	
-	
-	Private
-	
-	Field _codeItems:Stack<CodeItem>
-	
 	Method FindNode:TreeView.Node( treeNode:TreeView.Node,item:CodeItem )
 	Method FindNode:TreeView.Node( treeNode:TreeView.Node,item:CodeItem )
 	
 	
 		Local node:=Cast<CodeTreeNode>( treeNode )
 		Local node:=Cast<CodeTreeNode>( treeNode )
@@ -70,14 +78,23 @@ Class CodeTreeView Extends TreeViewExt
 		Return Null
 		Return Null
 	End
 	End
 	
 	
-	Method AddTreeItem( item:CodeItem,node:TreeView.Node,parser:ICodeParser )
 	
 	
+	Private
+	
+	Field _codeItems:Stack<CodeItem>
+	
+	Method AddTreeItem( item:CodeItem,node:TreeView.Node,parser:ICodeParser )
+		
+		If item.IsBlock Return
+		
 		Local n:=New CodeTreeNode( item,node )
 		Local n:=New CodeTreeNode( item,node )
 		
 		
 		' restore expand state
 		' restore expand state
 		_expander.Restore( n )
 		_expander.Restore( n )
 		
 		
-		If item.Children = Null And Not ShowInherited Return
+		If Not FillNestedItems Or item.IsFuncTypedField Return
+		
+		If item.Children=Null And Not ShowInherited Return
 		
 		
 		Local list:=New Stack<CodeItem>
 		Local list:=New Stack<CodeItem>
 		
 		
@@ -106,7 +123,7 @@ Class CodeTreeView Extends TreeViewExt
 		
 		
 		Local added:=New StringStack
 		Local added:=New StringStack
 		For Local i:=Eachin list
 		For Local i:=Eachin list
-			If i.KindStr="block" Continue
+			If i.IsBlock Continue
 			Local txt:=i.Text
 			Local txt:=i.Text
 			If added.Contains( txt ) Continue
 			If added.Contains( txt ) Continue
 			added.Add( txt )
 			added.Add( txt )

+ 10 - 1
view/ConsoleViewExt.monkey2

@@ -247,6 +247,14 @@ Class ConsoleExt Extends TextView
 		_lines.Clear()
 		_lines.Clear()
 	End
 	End
 	
 	
+	Property ProcessingRtChar:Bool()
+		
+		Return _processingRt
+		
+	Setter( value:Bool )
+		
+		_processingRt=value
+	End
 	
 	
 	Protected
 	Protected
 	
 	
@@ -357,6 +365,7 @@ Class ConsoleExt Extends TextView
 	
 	
 	Field _errors:=New IntMap<ErrorInfo>
 	Field _errors:=New IntMap<ErrorInfo>
 	Field _linesRead:Int
 	Field _linesRead:Int
+	Field _processingRt:Bool
 	
 	
 	Method UpdateRunning()
 	Method UpdateRunning()
 	
 	
@@ -377,7 +386,7 @@ Class ConsoleExt Extends TextView
 			Local maxScroll:=LineRect(Document.NumLines-1).Bottom-VisibleRect.Height
 			Local maxScroll:=LineRect(Document.NumLines-1).Bottom-VisibleRect.Height
 			Local atBottom:=Scroll.y>=maxScroll And cur=anc
 			Local atBottom:=Scroll.y>=maxScroll And cur=anc
 			
 			
-			If text.StartsWith( "~r" )
+			If _processingRt And text.StartsWith( "~r" )
 				Local line:=Document.NumLines-1,dl:=0
 				Local line:=Document.NumLines-1,dl:=0
 				If Document.GetLine( line )=""
 				If Document.GetLine( line )=""
 					dl=-1
 					dl=-1

+ 229 - 0
view/ExamplesView.monkey2

@@ -0,0 +1,229 @@
+
+Namespace ted2go
+
+
+Class ExamplesView Extends DockingView
+	
+	Method New( docs:DocumentManager )
+		
+		Super.New()
+		
+		_docs=docs
+		
+		_tree=New TreeViewExt
+		
+		' load projects when first time expanding node
+		'
+		_tree.NodeExpanded+=Lambda( n:TreeView.Node )
+			
+			Local node:=GetNodeWithData( n )
+			If Not node Or node.data.loaded Return
+			node.RemoveAllChildren() ' remove dummy item
+			
+			FillNode( node,node.data.path )
+			UpdateIcons( n )
+		End
+		
+		_tree.NodeClicked+=Lambda( node:TreeView.Node )
+			
+			If Prefs.MainProjectSingleClickExpanding Then OnOpenDocument( node )
+		End
+		
+		_tree.NodeDoubleClicked+=Lambda( node:TreeView.Node )
+			
+			If Not Prefs.MainProjectSingleClickExpanding Then OnOpenDocument( node )
+		End
+		
+	End
+	
+	Method Init()
+		
+		If _inited Return
+		
+		_inited=True
+		
+		Local label:=New Label( "Collecting data..." )
+		label.Gravity=New Vec2f( 0,0 )
+		
+		ContentView=label
+		
+		LoadData()
+		
+	End
+	
+	
+	Private
+	
+	Const VALID_FOLDERS:=New String[]( "bananas","examples","tests" )
+	
+	Field _tree:TreeViewExt
+	Field _dirIcon:Image
+	Field _fileIcon:Image
+	Field _docs:DocumentManager
+	Field _inited:Bool
+	
+	Method LoadData()
+		
+		New Fiber( Lambda()
+			
+			Fiber.Sleep( 1.5 )
+			
+			Local folders:=New StringStack
+			Local path:=Prefs.MonkeyRootPath+"bananas/"
+			
+			' bananas
+			For Local file:=Eachin LoadDir( path )
+				If GetFileType( path+file )=FileType.Directory
+					folders.Add( path+file )
+				Endif
+			Next
+			
+			' other
+			CollectFolders( Prefs.MonkeyRootPath+"modules/",folders )
+			
+			For Local section:=Eachin VALID_FOLDERS
+				Local node:=New TreeViewExt.Node( section,_tree.RootNode )
+				For Local folder:=Eachin folders
+					If folder.Contains( "/"+section )
+						Local full:=folder+"/"
+						folder=folder.Replace( "/"+section,"" )
+						folder=folder.Replace( Prefs.MonkeyRootPath,"" )
+						Local subNode:=New NodeWithData<FolderData>( folder,node )
+						Local data:=New FolderData
+						data.path=full
+						subNode.data=data
+						' create dummy to show that it has children
+						New TreeViewExt.Node( "---",subNode )
+					Endif
+				Next
+			Next
+			
+			_tree.RootNode.Expanded=True
+			_tree.RootNodeVisible=False
+			
+			UpdateIcons( _tree.RootNode )
+			
+			ContentView=_tree
+		End )
+	End
+	
+	Method GetNodeWithData:NodeWithData<FolderData>( node:TreeView.Node )
+		
+		Return Cast<NodeWithData<FolderData>>( node )
+	End
+	
+	Method OnOpenDocument( n:TreeView.Node )
+		
+		Local node:=GetNodeWithData( n )
+		If node And FileExists( node.data.path )
+			_docs.OpenDocument( node.data.path,True )
+			_docs.LockBuildFile()
+		Endif
+	End
+	
+	Method OnValidateStyle() Override
+	
+		Super.OnValidateStyle()
+		
+		_dirIcon=ProjectBrowserView.GetFileTypeIcon( "._dir" )
+		_fileIcon=ProjectBrowserView.GetFileTypeIcon( "._file" )
+		
+		UpdateIcons( _tree.RootNode )
+	End
+	
+	Method UpdateIcons( n:TreeView.Node )
+		
+		Local node:=GetNodeWithData( n )
+		If node
+			Local icon:=ProjectBrowserView.GetFileTypeIcon( node.data.path )
+			If Not icon
+				icon=(GetFileType( node.data.path )=FileType.Directory) ? _dirIcon Else _fileIcon
+			Endif
+			n.Icon=icon
+		Else
+			n.Icon=(n.NumChildren>0) ? _dirIcon Else _fileIcon
+		Endif
+		
+		For Local child:=Eachin n.Children
+			UpdateIcons( child )
+		Next
+	End
+	
+	Method FillNode( n:TreeView.Node,path:String )
+		
+		Local node:=GetNodeWithData( n )
+		node.data.loaded=True
+		
+		Local dirs:=New Stack<String>
+		Local files:=New Stack<String>
+		
+		For Local f:=Eachin LoadDir( path )
+			
+			Local fpath:=path+f
+			
+			Select GetFileType( fpath )
+			Case FileType.Directory
+				' some filtering
+				If f<>PathsProvider.MX2_TMP And Not (f.Contains( ".product" ) Or f.Contains( ".buildv" ))
+					dirs.Add( f )
+				Endif
+			Default
+				files.Add( f )
+			End
+		Next
+		
+		dirs.Sort()
+		
+		If Not files.Empty
+			files.Sort()
+			dirs.AddAll( files.ToArray() )
+		Endif
+		
+		For Local file:=Eachin dirs
+			
+			Local full:=path+file
+			Local data:=New FolderData
+			data.path=full
+			
+			Local subNode:=New NodeWithData<FolderData>( file,node )
+			subNode.data=data
+			
+			If GetFileType( full )=FileType.Directory
+				FillNode( subNode,full+"/" )
+			Endif
+		Next
+	End
+	
+	Method CollectFolders( folder:String,target:StringStack )
+		
+		For Local name:=Eachin LoadDir( folder )
+			Local lowercasedName:=name.ToLower()
+			If Utils.ArrayContains( VALID_FOLDERS,lowercasedName )
+				target.Add( folder+name )
+				Continue
+			Endif
+			'If lowercasedName="src"
+			If lowercasedName="src" Or lowercasedName="include" Or lowercasedName="native" Or
+				lowercasedName="bin" Or lowercasedName="docs" Or lowercasedName=PathsProvider.MX2_TMP Or
+				lowercasedName.Contains( ".product" ) Or lowercasedName.Contains( ".buildv" )
+				Continue
+			Endif
+			Local path:=folder+name
+			If GetFileType( path )=FileType.Directory
+				CollectFolders( path+"/",target )
+			Endif
+		Next
+	End
+	
+End
+
+
+
+Private
+
+Class FolderData
+	
+	Field path:String
+	Field loaded:Bool
+	
+End

+ 135 - 70
view/HelpTreeView.monkey2

@@ -1,6 +1,9 @@
 
 
 Namespace ted2go
 Namespace ted2go
 
 
+#Import "../assets/docsPriority.txt"
+
+
 Private
 Private
 
 
 Function EnumModules:String[]()
 Function EnumModules:String[]()
@@ -83,7 +86,7 @@ Class HelpTreeView Extends TreeViewExt
 		Return RealPath( "docs/"+page )
 		Return RealPath( "docs/"+page )
 	End
 	End
 	
 	
-	Function CreateNodes( obj:JsonObject,parent:Tree.Node,indexer:StringMap<Tree.Node> )
+	Function CreateNodes( obj:JsonObject,parent:Tree.Node )
 		
 		
 		Local text:=obj["text"].ToString()
 		Local text:=obj["text"].ToString()
 		Local page:=""
 		Local page:=""
@@ -94,11 +97,10 @@ Class HelpTreeView Extends TreeViewExt
 		Endif
 		Endif
 		
 		
 		Local node:=New Tree.Node( text,parent,page )
 		Local node:=New Tree.Node( text,parent,page )
-		indexer[page.ToLower()]=node
 		
 		
 		If obj.Contains( "children" )
 		If obj.Contains( "children" )
 			For Local child:=Eachin obj["children"].ToArray()
 			For Local child:=Eachin obj["children"].ToArray()
-				CreateNodes( Cast<JsonObject>( child ),node,indexer )
+				CreateNodes( Cast<JsonObject>( child ),node )
 			Next
 			Next
 		Endif
 		Endif
 		
 		
@@ -133,10 +135,8 @@ Class HelpTreeView Extends TreeViewExt
 		Return last
 		Return last
 	End
 	End
 	
 	
-	Method Update( applyFilter:Bool=False )
+	Method Update()
 		
 		
-		_index.Clear()
-		_index2.Clear()
 		_tree.Clear()
 		_tree.Clear()
 		
 		
 		For Local modname:=Eachin EnumModules()
 		For Local modname:=Eachin EnumModules()
@@ -151,7 +151,7 @@ Class HelpTreeView Extends TreeViewExt
 				Local obj:=JsonObject.Load( index,True )
 				Local obj:=JsonObject.Load( index,True )
 				If Not obj Continue
 				If Not obj Continue
 				
 				
-				CreateNodes( obj,_tree.RootNode,_index )
+				CreateNodes( obj,_tree.RootNode )
 				
 				
 			Catch ex:Throwable
 			Catch ex:Throwable
 				
 				
@@ -159,9 +159,16 @@ Class HelpTreeView Extends TreeViewExt
 			End
 			End
 		Next
 		Next
 		
 		
-		FillTree()
+		ApplyFilter( _textField.Text )
 		
 		
-		If applyFilter Then Update( _textField.Text )
+'		For Local i1:=Eachin _tree.RootNode.Children
+'			Print i1.Text
+'			If i1.NumChildren
+'				For Local i2:=Eachin i1.Children
+'					If i2.Text.StartsWith( i1.Text ) And i2.Text<>i1.Text Print i2.Text
+'				Next
+'			Endif
+'		Next
 	End
 	End
 	
 	
 	Method RequestFocus()
 	Method RequestFocus()
@@ -183,7 +190,7 @@ Class HelpTreeView Extends TreeViewExt
 			
 			
 			Local text:=_textField.Text
 			Local text:=_textField.Text
 			
 			
-			Update( text )
+			ApplyFilter( text )
 		End
 		End
 		
 		
 		Local find:=New Label( "Find " )
 		Local find:=New Label( "Find " )
@@ -208,6 +215,8 @@ Class HelpTreeView Extends TreeViewExt
 			PageClicked( page )
 			PageClicked( page )
 		End
 		End
 		
 		
+		InitPriorityInfo()
+		
 		Update()
 		Update()
 	End
 	End
 	
 	
@@ -216,12 +225,12 @@ Class HelpTreeView Extends TreeViewExt
 	Field _textField:TextFieldExt
 	Field _textField:TextFieldExt
 	Field _matchid:Int
 	Field _matchid:Int
 	Field _matches:=New Stack<Node>
 	Field _matches:=New Stack<Node>
-	Field _index:=New Map<String,Tree.Node>
-	Field _index2:=New Map<String,Node>
 	Field _tree:=New Tree
 	Field _tree:=New Tree
+	Field _priority:=New StringMap<Int>
+	Field _filterSplittersChars:=New Int[]( Chars.DOT,Chars.SPACE )
 	
 	
 	Class Node Extends TreeView.Node
 	Class Node Extends TreeView.Node
-	
+		
 		Method New( text:String,parent:TreeView.Node,page:String )
 		Method New( text:String,parent:TreeView.Node,page:String )
 			
 			
 			Super.New( text,parent )
 			Super.New( text,parent )
@@ -239,25 +248,101 @@ Class HelpTreeView Extends TreeViewExt
 		
 		
 	End
 	End
 	
 	
-	Method FillTree()
+	Method InitPriorityInfo()
+		
+		Local t:=LoadString( "asset::docsPriority.txt",True )
+		If t Then t=t.Trim()
+		Local arr:=t.Split( "~n" )
+		For Local i:=0 Until arr.Length
+			Local key:=arr[i].Trim()
+			Local priority:=arr.Length+1-i
+			_priority[key]=priority
+		Next
+	End
+	
+	Method GetNamespacePriority:Int( nspace:String )
+		
+		Return _priority[nspace]
+	End
+	
+	Method SortFunc:Int( lhs:TreeView.Node,rhs:TreeView.Node )
+		
+		' special rule for root nodes only
+		'
+		Local p1:=lhs.Parent,p2:=rhs.Parent,cnt:=0
+		While p1
+			p1=p1.Parent
+			p2=p2.Parent
+			cnt+=1
+		Wend
+		If cnt=1
+			Local priority1:=GetNamespacePriority( lhs.Text )
+			Local priority2:=GetNamespacePriority( rhs.Text )
+			Return priority2<=>priority1
+		Endif
+		
+		' default sorting rule
+		'
+		Return lhs.Text<=>rhs.Text
+	End
+	
+	Method FillTree( filterWords:String[] )
 	
 	
 		RootNode.RemoveAllChildren()
 		RootNode.RemoveAllChildren()
 		
 		
-		FillNode( RootNode,_tree.RootNode.Children )
+		FillNode( RootNode,_tree.RootNode.Children,filterWords )
 		
 		
-		Sort()
+		Sort( filterWords.Length>0 ? SortFunc Else Null )
 		
 		
-		If RootNode.Children.Length=0
+		If RootNode.Children.Length=0 And filterWords.Length=0
 			New Node( "No docs found; you can use 'Help -- Rebuild docs'.",RootNode,"" )
 			New Node( "No docs found; you can use 'Help -- Rebuild docs'.",RootNode,"" )
 		Endif
 		Endif
 	End
 	End
 	
 	
-	Method FillNode( node:TreeView.Node,items:Stack<Tree.Node> )
+	Method CheckFilter:Bool( item:Tree.Node,filterWords:String[],lowercased:Bool=True )
+		
+		Local t:=item.Text
+		Local page:=item.GetUserData<String>()
+		
+		If lowercased
+			t=t.ToLower()
+			page=page.ToLower()
+		Endif
+		
+		Local pos:=-1,allFound:=True,inTextFound:=False
+		' all words in page path
+		For Local word:=Eachin filterWords
+			pos=page.Find( word,pos+1 )
+			If pos=-1
+				allFound=False
+				Exit
+			Endif
+			If Not inTextFound And t.Find( word )<>-1 Then inTextFound=True
+		Next
+		If allFound And inTextFound Return True
+		' and any word in node text
+		
+			
+		If item.NumChildren>0
+			For Local i:=Eachin item.Children
+				Local ok:=CheckFilter( i,filterWords,lowercased )
+				If ok Return True
+			Next
+		Endif
+		
+		Return False
+	End
+	
+	Method FillNode( node:TreeView.Node,items:Stack<Tree.Node>,filterWords:String[] )
 		
 		
 		If Not items Return
 		If Not items Return
 		
 		
 		For Local item:=Eachin items
 		For Local item:=Eachin items
 			
 			
+			If filterWords.Length>0 And Not CheckFilter( item,filterWords )
+				Continue
+			Endif
+			
 			Local page:=item.GetUserData<String>()
 			Local page:=item.GetUserData<String>()
 			
 			
 			' hack for the-same-nested 
 			' hack for the-same-nested 
@@ -269,25 +354,26 @@ Class HelpTreeView Extends TreeViewExt
 			Endif
 			Endif
 			
 			
 			Local n:=New Node( item.Text,node,page )
 			Local n:=New Node( item.Text,node,page )
-			_index2[page.ToLower()]=n
 			
 			
 			If item.NumChildren
 			If item.NumChildren
-				FillNode( n,item.Children )
+				FillNode( n,item.Children,filterWords )
 			Endif
 			Endif
 		Next
 		Next
 		
 		
 	End
 	End
 	
 	
-	Method Update( text:String )
+	Method ApplyFilter( filter:String )
 		
 		
 		RootNode.CollapseAll()
 		RootNode.CollapseAll()
 		
 		
-		text=StripEnding( text,"." )
+		filter=StripEnding( filter,"." )
 		
 		
-		text=text.ToLower()
+		filter=filter.ToLower()
 		
 		
-		Local parts:=text.Split( "." )
-		Local text2:=text.Replace( ".","-" )
+		Local filterWords:=New String[0]
+		If filter
+			filterWords=TextUtils.Split( filter,_filterSplittersChars )
+		Endif
 		
 		
 		If _tree.RootNode.NumChildren=0
 		If _tree.RootNode.NumChildren=0
 			New Node( "Click here to rebuild docs!",RootNode,"$$rebuild$$" )
 			New Node( "Click here to rebuild docs!",RootNode,"$$rebuild$$" )
@@ -296,34 +382,13 @@ Class HelpTreeView Extends TreeViewExt
 		
 		
 		_matches.Clear()
 		_matches.Clear()
 		
 		
-		For Local it:=Eachin _index2
-			
-			'Local node:=it.Value
-			Local n:=it.Value
-			
-			'Local n:=InsertNode( node )
-			
-			'If Not text Continue
-			
-			If Not text2 Or Not it.Key.Contains( text2 )
-				n.Selected=False
-				Continue
-			Endif
-			
-			n.Selected=GetSelectionState( n,parts )
-			
-			If n.Selected
-				
-				_matches.Push( n )
-				
-				Local n2:=n.Parent
-				While n2
-					n2.Expanded=True
-					n2=n2.Parent
-				Wend
-			Endif
-			
-		Next
+		FillTree( filterWords )
+		
+		If filter
+			For Local node:=Eachin RootNode.Children
+				CollectMatches( Cast<Node>( node ),_matches )
+			Next
+		Endif
 		
 		
 		RootNode.Expanded=True
 		RootNode.Expanded=True
 		
 		
@@ -333,30 +398,30 @@ Class HelpTreeView Extends TreeViewExt
 		
 		
 		If _matches.Length
 		If _matches.Length
 			
 			
+			For Local i:=Eachin _matches
+				i.Expanded=True
+				Local p:=i.Parent
+				While p
+					p.Expanded=True
+					p=p.Parent
+				Wend
+			Next
+			
 			PageClicked( _matches[0].Page )
 			PageClicked( _matches[0].Page )
 			Selected=_matches[0]
 			Selected=_matches[0]
 		Endif
 		Endif
 		
 		
 	End
 	End
 	
 	
-	Method GetSelectionState:Bool( node:TreeView.Node,parts:String[] )
-		
-		Local last:=parts.Length-1
-		Local i:=last
-		Repeat
-			Local part:=parts[i]
-			Local txt:=node.Text.ToLower()
-			If txt.Contains( part )
-				i-=1
-				If i<0 Exit 'true
-			Else
-				If i=last Return False
-			Endif
-			node=node.Parent
-			If Not node Return False
-		Forever
+	Method CollectMatches( node:Node,target:Stack<Node> )
 		
 		
-		Return True
+		If node.NumChildren=0
+			target.Add( node )
+		Else
+			For Local n:=Eachin node.Children
+				CollectMatches( Cast<Node>( n ),target )
+			Next
+		Endif
 	End
 	End
 	
 	
 	Method NextHelp()
 	Method NextHelp()

+ 35 - 8
view/HtmlViewExt.monkey2

@@ -3,7 +3,7 @@ Namespace ted2go
 
 
 
 
 Class HtmlViewExt Extends HtmlView
 Class HtmlViewExt Extends HtmlView
-
+	
 	Field Navigated:Void( url:String )
 	Field Navigated:Void( url:String )
 	
 	
 	Method New()
 	Method New()
@@ -15,18 +15,24 @@ Class HtmlViewExt Extends HtmlView
 			Go( nav.url )
 			Go( nav.url )
 			Navigated( nav.url )
 			Navigated( nav.url )
 			
 			
+			_url=nav.url
+			
 			nav.state+=1
 			nav.state+=1
-			If nav.state=1 Return 'navigated first time, so it's new page, don't touch the scroll
+			
+			UpdateCss()
+			
+			'navigated first time, so it's new page, don't touch the scroll
+			If nav.state=1
+				Return 
+			Endif
 			
 			
 			Scroll=nav.scroll
 			Scroll=nav.scroll
 			
 			
 			'wait a bit for layout
 			'wait a bit for layout
-			If _timer Then _timer.Cancel()
-			_timer=New Timer(20, Lambda()
+			New Fiber( Lambda()
+				Fiber.Sleep( 0.1 )
 				Scroll=nav.scroll
 				Scroll=nav.scroll
-				_timer.Cancel()
-				_timer=Null
-			End)
+			End )
 			
 			
 		End
 		End
 	End
 	End
@@ -58,11 +64,32 @@ Class HtmlViewExt Extends HtmlView
 		_navOps.Clear()
 		_navOps.Clear()
 	End
 	End
 	
 	
+	Property Url:String()
+		
+		Return _url
+	End
+	
 	
 	
 	Private
 	Private
 	
 	
 	Field _navOps:=New NavOps<Nav>
 	Field _navOps:=New NavOps<Nav>
-	Field _timer:Timer
+	Field _url:String
+	
+	Method OnValidateStyle() Override
+		
+		Super.OnValidateStyle()
+		
+		UpdateCss()
+	End
+	
+	Method UpdateCss()
+		
+		If ThemesInfo.IsActiveThemeDark()
+			HtmlSource=HtmlSource.Replace( "theme.css","theme-dark.css" )
+		Else
+			HtmlSource=HtmlSource.Replace( "theme-dark.css","theme.css" )
+		Endif
+	End
 	
 	
 	Method StoreScroll()
 	Method StoreScroll()
 		
 		

+ 1 - 1
view/Monkey2TreeView.monkey2

@@ -45,7 +45,7 @@ Class Monkey2TreeView Extends JsonTreeView
 	
 	
 	Method UpdateTree( path:String )
 	Method UpdateTree( path:String )
 		
 		
-		Local cmd:=Monkey2Parser.GetParseCommand( path )
+		Local cmd:=Monkey2Parser.GetFullParseCommand( path )
 		If Not cmd Return
 		If Not cmd Return
 		
 		
 		Local str:=LoadString( "process::"+cmd )
 		Local str:=LoadString( "process::"+cmd )

+ 15 - 13
view/ProjectBrowserView.monkey2

@@ -261,10 +261,10 @@ Class ProjectBrowserView Extends TreeViewExt Implements IDraggableHolder
 		projNode._project=project
 		projNode._project=project
 		UpdateProjIcon( projNode )
 		UpdateProjIcon( projNode )
 		_expander.Restore( projNode )
 		_expander.Restore( projNode )
-	
+		
 		UpdateNode( projNode )
 		UpdateNode( projNode )
 		ApplyFilter( projNode )
 		ApplyFilter( projNode )
-	
+		
 		Local mainFile:=project.MainFilePath
 		Local mainFile:=project.MainFilePath
 		If mainFile Then SetMainFile( mainFile,True )
 		If mainFile Then SetMainFile( mainFile,True )
 		
 		
@@ -328,6 +328,16 @@ Class ProjectBrowserView Extends TreeViewExt Implements IDraggableHolder
 		Endif
 		Endif
 	End
 	End
 	
 	
+	Function GetFileTypeIcon:Image( path:String )
+		
+		Local ext:=ExtractExt( path )
+		If Not ext Return Null
+		
+		UpdateFileTypeIcons()
+		
+		Return _fileTypeIcons[ext.ToLower()]
+	End
+	
 	
 	
 	Protected
 	Protected
 	
 	
@@ -398,14 +408,6 @@ Class ProjectBrowserView Extends TreeViewExt Implements IDraggableHolder
 		
 		
 	End
 	End
 	
 	
-	Method GetFileTypeIcon:Image( path:String ) Virtual
-	
-		Local ext:=ExtractExt( path )
-		If Not ext Return Null
-	
-		Return _fileTypeIcons[ext.ToLower()]
-	End
-	
 	Method OnValidateStyle() Override
 	Method OnValidateStyle() Override
 	
 	
 		Super.OnValidateStyle()
 		Super.OnValidateStyle()
@@ -538,7 +540,7 @@ Class ProjectBrowserView Extends TreeViewExt Implements IDraggableHolder
 	Method ApplyFilter( node:Node )
 	Method ApplyFilter( node:Node )
 		
 		
 		Local projNode:=FindProjectNode( node )
 		Local projNode:=FindProjectNode( node )
-		UpdateFilterItems( projNode )
+		UpdateHiddenItems( projNode )
 		
 		
 		Local list:=_filters[projNode.Text]
 		Local list:=_filters[projNode.Text]
 		If list And list.Length>0 And node.Expanded
 		If list And list.Length>0 And node.Expanded
@@ -571,7 +573,7 @@ Class ProjectBrowserView Extends TreeViewExt Implements IDraggableHolder
 		Next
 		Next
 	End
 	End
 	
 	
-	Method UpdateFilterItems( projNode:Node )
+	Method UpdateHiddenItems( projNode:Node )
 		
 		
 		Local proj:=projNode._project
 		Local proj:=projNode._project
 		If proj.IsFolderBased Return
 		If proj.IsFolderBased Return
@@ -586,7 +588,7 @@ Class ProjectBrowserView Extends TreeViewExt Implements IDraggableHolder
 		Local list:=GetOrCreate( _filters,projName )
 		Local list:=GetOrCreate( _filters,projName )
 		list.Clear()
 		list.Clear()
 		
 		
-		For Local i:=Eachin proj.Excluded
+		For Local i:=Eachin proj.Hidden
 			Local f:=New TextFilter( i )
 			Local f:=New TextFilter( i )
 			list+=f
 			list+=f
 		Next
 		Next

+ 60 - 25
view/ProjectView.monkey2

@@ -134,10 +134,14 @@ Class ProjectView Extends DockingView
 		Return _activeProject?.Name
 		Return _activeProject?.Name
 	End
 	End
 	
 	
-	Function CheckMainFilePath( proj:Monkey2Project )
+	Function CheckMainFilePath( proj:Monkey2Project,showAlert:Bool )
 		
 		
 		If Not proj.MainFilePath
 		If Not proj.MainFilePath
-			Alert( "Main file of ~q"+proj.Name+"~q project is not specified.~n~nRight click on file in Project tree~nand choose 'Set as main file'.","Build error" )
+			If showAlert
+				Alert( "Main file of ~q"+proj.Name+"~q project is not specified.~n~nRight click on file in Project tree~nand choose 'Set as main file'.","Build error" )
+			Else
+				MainWindow.ShowStatusBarText( "Main file of ~q"+proj.Name+"~q project is not specified!" )
+			Endif
 		Endif
 		Endif
 	
 	
 	End
 	End
@@ -472,17 +476,18 @@ Class ProjectView Extends DockingView
 		End )
 		End )
 	End
 	End
 	
 	
-	' Return True if there is an actual folder deletion
-	Method CleanProject:Bool( dir:String )
-	
+	' Return True if there was an actual folder deletion
+	Method CleanFolder:Bool( folder:String )
+		
 		Local succ:=0,err:=0
 		Local succ:=0,err:=0
-		Local items:=LoadDir( dir )
-		For Local i:=Eachin items
-			i=dir+"/"+i
-			If GetFileType(i)=FileType.Directory
-				If i.Contains( ".buildv" )
-					Local ok:=DeleteDir( i,True )
+		For Local i:=Eachin LoadDir( folder )
+			Local path:=folder+"/"+i
+			If GetFileType( path )=FileType.Directory
+				If i.Contains( ".buildv" ) Or i=PathsProvider.MX2_TMP
+					Local ok:=DeleteDir( path,True )
 					If ok Then succ+=1 Else err+=1
 					If ok Then succ+=1 Else err+=1
+				Else
+					CleanFolder( path )
 				Endif
 				Endif
 			Endif
 			Endif
 		Next
 		Next
@@ -542,7 +547,7 @@ Class ProjectView Extends DockingView
 			Local isFolder:=False
 			Local isFolder:=False
 			Local fileType:=GetFileType( path )
 			Local fileType:=GetFileType( path )
 			
 			
-			menu.AddAction( "Open on Desktop" ).Triggered=Lambda()
+			menu.AddAction( "Show in Explorer" ).Triggered=Lambda()
 				
 				
 				Local p:=(fileType=FileType.File) ? ExtractDir( path ) Else path
 				Local p:=(fileType=FileType.File) ? ExtractDir( path ) Else path
 				requesters.OpenUrl( p )
 				requesters.OpenUrl( p )
@@ -670,12 +675,12 @@ Class ProjectView Extends DockingView
 						CloseProject( path )
 						CloseProject( path )
 					End
 					End
 					
 					
-					menu.AddAction( "Clean (delete .buildv)" ).Triggered=Lambda()
+					menu.AddAction( "Clean (delete .buildv & .mx2)" ).Triggered=Lambda()
 						
 						
-						If Not RequestOkay( "Really delete all '.buildv' folders?" ) Return
+						If Not RequestOkay( "Really delete all '.buildv' and '.mx2' folders?" ) Return
 						
 						
-						Local changes:=CleanProject( path )
-						If changes Then browser.Refresh( node )
+						Local changed:=CleanFolder( path )
+						If changed Then browser.Refresh( node )
 					End
 					End
 				Else
 				Else
 					
 					
@@ -746,7 +751,24 @@ Class ProjectView Extends DockingView
 					Local name:=RequestString( "Enter new name:","Ranaming '"+oldName+"'",oldName )
 					Local name:=RequestString( "Enter new name:","Ranaming '"+oldName+"'",oldName )
 					If Not name Or name=oldName Return
 					If Not name Or name=oldName Return
 					
 					
-					Local newPath:=ExtractDir( path )+name
+					Local dir:=ExtractDir( path )
+					Local newPath:=dir+name
+					
+					' if just case is different
+					'
+					If name.ToLower()=oldName.ToLower()
+						Local tmpPath:=dir+Int(Rnd( 1000000,9999999 ))+name
+						' rename to temp
+						Local ok:=(libc.rename( path,tmpPath )=0)
+						If ok
+							' rename to desired
+							ok=(libc.rename( tmpPath,newPath )=0)
+							If ok
+								browser.Refresh( node.Parent )
+								Return
+							Endif
+						Endif
+					Endif
 					
 					
 					If FileExists( newPath )
 					If FileExists( newPath )
 						Alert( "File already exists! Path: '"+newPath+"'" )
 						Alert( "File already exists! Path: '"+newPath+"'" )
@@ -831,13 +853,25 @@ Class Monkey2Project
 		
 		
 		Local jobj:=New JsonObject
 		Local jobj:=New JsonObject
 		jobj[KEY_MAIN_FILE]=New JsonString
 		jobj[KEY_MAIN_FILE]=New JsonString
-		jobj[KEY_HIDDEN]=New JsonArray
+		jobj[KEY_HIDDEN]=New JsonArray( New JsonValue[]( New JsonString( ".mx2" ) ) )
 		
 		
 		SaveString( jobj.ToJson(),path )
 		SaveString( jobj.ToJson(),path )
 	End
 	End
 	
 	
 	Method New( path:String )
 	Method New( path:String )
 		
 		
+		Local isFolder:=(GetFileType( path )=FileType.Directory)
+		
+		' try to load project file if it's presented
+		'
+		If isFolder
+			Local dirName:=StripDir( path )
+			Local projPath:=StripSlashes( path )+"/"+dirName+".mx2proj"
+			If FileExists( projPath )
+				path = projPath
+			Endif
+		Endif
+		
 		_path=path
 		_path=path
 		
 		
 		If GetFileType( path )=FileType.File
 		If GetFileType( path )=FileType.File
@@ -884,20 +918,21 @@ Class Monkey2Project
 		Return _modified
 		Return _modified
 	End
 	End
 	
 	
-	Property Excluded:String[]()
+	Property Hidden:String[]()
 		
 		
-		If _modified=0 Return New String[0]
-		If _modified=_excludedTime Return _excluded
+		If _modified=0 Or Not _data Return New String[0]
+		If _modified=_hiddenTime Return _hidden
 		
 		
 		Local jarr:=_data.GetArray( KEY_HIDDEN )
 		Local jarr:=_data.GetArray( KEY_HIDDEN )
 		If Not jarr Or jarr.Empty Return New String[0]
 		If Not jarr Or jarr.Empty Return New String[0]
 		
 		
-		_excluded=New String[jarr.Length]
+		_hidden=New String[jarr.Length]
 		For Local i:=0 Until jarr.Length
 		For Local i:=0 Until jarr.Length
-			_excluded[i]=jarr[i].ToString()
+			_hidden[i]=jarr[i].ToString()
 		Next
 		Next
 		
 		
-		Return _excluded
+		_hiddenTime=_modified
+		Return _hidden
 	End
 	End
 	
 	
 	Method Save()
 	Method Save()
@@ -925,7 +960,7 @@ Class Monkey2Project
 	Field _data:JsonObject
 	Field _data:JsonObject
 	Field _isFolderBased:Bool
 	Field _isFolderBased:Bool
 	Field _modified:Int
 	Field _modified:Int
-	Field _excluded:String[],_excludedTime:Int
+	Field _hidden:String[],_hiddenTime:Int
 	
 	
 	Method OnChanged()
 	Method OnChanged()
 		
 		

+ 17 - 13
view/TabViewExt.monkey2

@@ -58,7 +58,7 @@ Class TabViewExt Extends DockingView Implements IDraggableHolder
 	Field CloseClicked:Void( index:Int )
 	Field CloseClicked:Void( index:Int )
 
 
 	#rem monkeydoc Invoked when a tab is dragged.
 	#rem monkeydoc Invoked when a tab is dragged.
-	#end	
+	#end
 	Field Dragged:Void()
 	Field Dragged:Void()
 
 
 	#rem monkeydoc Creates a new tab view.
 	#rem monkeydoc Creates a new tab view.
@@ -127,6 +127,10 @@ Class TabViewExt Extends DockingView Implements IDraggableHolder
 		Local tab:=Cast<TabButtonExt>( item )
 		Local tab:=Cast<TabButtonExt>( item )
 		RemoveTab( tab )
 		RemoveTab( tab )
 		tab.Selected=True
 		tab.Selected=True
+		
+		' stop dragging mode
+		ViewUtils.SendMouseEvent( tab,EventType.MouseUp )
+		
 		Return tab
 		Return tab
 	End
 	End
 	
 	
@@ -279,44 +283,44 @@ Class TabViewExt Extends DockingView Implements IDraggableHolder
 	End
 	End
 	
 	
 	Method AddTab( tab:TabButtonExt,makeCurrent:Bool=False,addAtBegin:Bool=False )
 	Method AddTab( tab:TabButtonExt,makeCurrent:Bool=False,addAtBegin:Bool=False )
-	
+		
 		Assert( TabIndex( tab.View )=-1,"View has already been added to TabView" )
 		Assert( TabIndex( tab.View )=-1,"View has already been added to TabView" )
 		
 		
 		TabButtonExt_Bridge.SetTabParent( tab,Self )
 		TabButtonExt_Bridge.SetTabParent( tab,Self )
-	
-		tab.Clicked=Lambda()
 		
 		
+		tab.Clicked=Lambda()
+			
 			MakeCurrent( tab,True )
 			MakeCurrent( tab,True )
-
+			
 			Clicked()
 			Clicked()
 		End
 		End
 		
 		
 		tab.RightClicked=Lambda()
 		tab.RightClicked=Lambda()
-		
+			
 			MakeCurrent( tab,True )
 			MakeCurrent( tab,True )
 			'If tab.Undockable Then UndockWindow.NewUndock( tab )
 			'If tab.Undockable Then UndockWindow.NewUndock( tab )
 			RightClicked()
 			RightClicked()
 		End
 		End
 		
 		
 		tab.DoubleClicked=Lambda()
 		tab.DoubleClicked=Lambda()
-		
+			
 			MakeCurrent( tab,True )
 			MakeCurrent( tab,True )
 			
 			
 			DoubleClicked()
 			DoubleClicked()
 		End
 		End
 		
 		
 		tab.Dragged=Lambda( v:Vec2i )
 		tab.Dragged=Lambda( v:Vec2i )
-		
+			
 			If Not (_flags & TabViewFlags.DraggableTabs) Return
 			If Not (_flags & TabViewFlags.DraggableTabs) Return
-
+			
 			Local mx:=_tabBar.MouseLocation.x
 			Local mx:=_tabBar.MouseLocation.x
 			If mx<0 Return
 			If mx<0 Return
 			
 			
 			Local w:=tab.Bounds.Width
 			Local w:=tab.Bounds.Width
-
+			
 			Local x:=0,i:=_tabs.Length
 			Local x:=0,i:=_tabs.Length
 			For Local j:=0 Until i
 			For Local j:=0 Until i
-
+				
 				If mx<x+w
 				If mx<x+w
 					i=j
 					i=j
 					Exit
 					Exit
@@ -330,7 +334,7 @@ Class TabViewExt Extends DockingView Implements IDraggableHolder
 			
 			
 			Local i2:=_tabs.FindIndex( tab )
 			Local i2:=_tabs.FindIndex( tab )
 			If i=i2 Return
 			If i=i2 Return
-
+			
 			If i>i2 i-=1
 			If i>i2 i-=1
 			
 			
 			_tabs.Erase( i2 )
 			_tabs.Erase( i2 )
@@ -340,7 +344,7 @@ Class TabViewExt Extends DockingView Implements IDraggableHolder
 			For Local view:=Eachin _tabs
 			For Local view:=Eachin _tabs
 				_tabBar.AddView( view )
 				_tabBar.AddView( view )
 			Next
 			Next
-
+			
 			RequestRender()
 			RequestRender()
 			
 			
 			Dragged()
 			Dragged()

+ 41 - 2
view/TextViewExt.monkey2

@@ -804,6 +804,45 @@ Class TextView Extends ScrollableView
 		SelectText( 0,_doc.TextLength )
 		SelectText( 0,_doc.TextLength )
 	End
 	End
 	
 	
+	Method SelectWord()
+		
+		' this method tries to intelligent expand
+		' selection under cursor
+		'
+		Local line:=Document.FindLine( _cursor )
+		Local i1:=Document.StartOfLine( line )
+		Local i2:=Document.EndOfLine( line )
+		Local cur:=_cursor
+		Local anc:=Max( _anchor-1,i1 )
+		Local chr:=(anc>i1) ? Text[anc] Else Text[cur]
+		If Text[cur]=Chars.SPACE And chr<>Chars.SPACE
+			i2=cur
+		Endif
+		If Text[anc]=Chars.SPACE And (IsIdent( Text[cur] ) Or Text[cur]=Chars.DOT)
+			i1=anc+1
+			chr=Text[cur]
+		Endif
+		Local isIdent:=IsIdent( chr )
+		If isIdent
+			While anc>=i1 And IsIdent( Text[anc] )
+				anc-=1
+			Wend
+			While cur<i2 And IsIdent( Text[cur] )
+				cur+=1
+			Wend
+		Else
+			While anc>=i1 And Not IsIdent( Text[anc] )
+				anc-=1
+			Wend
+			While cur<i2 And Not IsIdent( Text[cur] )
+				cur+=1
+			Wend
+		Endif
+		If anc<>_anchor Then anc+=1
+		
+		SelectText( anc,cur )
+	End
+	
 	#rem monkeydoc Performs a cut.
 	#rem monkeydoc Performs a cut.
 	#end
 	#end
 	Method Cut()
 	Method Cut()
@@ -1589,9 +1628,9 @@ Class TextView Extends ScrollableView
 		
 		
 		SelectionColor=App.Theme.GetColor( "textview-selection" )
 		SelectionColor=App.Theme.GetColor( "textview-selection" )
 		
 		
-		Local colors:=New Color[8]
+		Local colors:=New Color[9]
 		
 		
-		For Local i:=0 Until 8
+		For Local i:=0 Until colors.Length
 			colors[i]=App.Theme.GetColor( "textview-color"+i )
 			colors[i]=App.Theme.GetColor( "textview-color"+i )
 		Next
 		Next
 		
 		

+ 25 - 18
view/TreeViewExt.monkey2

@@ -11,6 +11,8 @@ Class TreeViewExt Extends TreeView
 	Field NodeCollapsed:Void( node:Node )
 	Field NodeCollapsed:Void( node:Node )
 	Field SelectedChanged:Void( selNode:Node )
 	Field SelectedChanged:Void( selNode:Node )
 	
 	
+	Field ExpandParentsForSelected:=True
+	
 	Method New()
 	Method New()
 		
 		
 		Super.New()
 		Super.New()
@@ -49,7 +51,7 @@ Class TreeViewExt Extends TreeView
 			OnCollapsed( node,True )
 			OnCollapsed( node,True )
 		End
 		End
 		
 		
-		_selColor=App.Theme.GetColor( "panel" )
+		OnThemeChanged()
 	End
 	End
 	
 	
 	Property Selected:TreeView.Node()
 	Property Selected:TreeView.Node()
@@ -149,9 +151,15 @@ Class TreeViewExt Extends TreeView
 		If n Then Selected=n
 		If n Then Selected=n
 	End
 	End
 	
 	
-	Method Sort()
-	
-		SortNode( RootNode )
+	Method Sort( func:Int( lhs:TreeView.Node,rhs:TreeView.Node )=Null )
+		
+		If func=Null
+			func=Lambda:Int( lhs:TreeView.Node,rhs:TreeView.Node )
+				Return lhs.Text<=>rhs.Text
+			End
+		Endif
+		
+		SortNode( RootNode,func )
 	End
 	End
 	
 	
 	
 	
@@ -161,7 +169,7 @@ Class TreeViewExt Extends TreeView
 	
 	
 	Method OnThemeChanged() Override
 	Method OnThemeChanged() Override
 		
 		
-		_selColor=App.Theme.GetColor( "panel" )
+		_selColor=App.Theme.GetColor( "treeview-selected-row" )
 	End
 	End
 	
 	
 	Method OnRenderContent( canvas:Canvas ) Override
 	Method OnRenderContent( canvas:Canvas ) Override
@@ -271,13 +279,15 @@ Class TreeViewExt Extends TreeView
 	Method EnsureVisible( node:TreeView.Node )
 	Method EnsureVisible( node:TreeView.Node )
 	
 	
 		If Not node Return
 		If Not node Return
-	
-		Local n:=node.Parent
-		While n
-			n.Expanded=True
-			n=n.Parent
-		Wend
-	
+		
+		If ExpandParentsForSelected
+			Local n:=node.Parent
+			While n
+				n.Expanded=True
+				n=n.Parent
+			Wend
+		Endif
+		
 		' scroll Y only
 		' scroll Y only
 		Local scroll:=Scroll
 		Local scroll:=Scroll
 		Super.EnsureVisible( node.Rect )
 		Super.EnsureVisible( node.Rect )
@@ -285,24 +295,21 @@ Class TreeViewExt Extends TreeView
 		Scroll=scroll
 		Scroll=scroll
 	End
 	End
 	
 	
-	Method SortNode( node:TreeView.Node )
+	Method SortNode( node:TreeView.Node,func:Int( lhs:TreeView.Node,rhs:TreeView.Node ) )
 		
 		
 		If node.Children.Length=0 Return
 		If node.Children.Length=0 Return
 		
 		
 		Local children:=New Stack<TreeView.Node>
 		Local children:=New Stack<TreeView.Node>
 		children+=node.Children
 		children+=node.Children
 		
 		
-		children.Sort( Lambda:Int( lhs:TreeView.Node,rhs:TreeView.Node )
-			
-			Return lhs.Text<=>rhs.Text
-		End )
+		children.Sort( func )
 		
 		
 		node.RemoveAllChildren()
 		node.RemoveAllChildren()
 		
 		
 		For Local n:=Eachin children
 		For Local n:=Eachin children
 			node.AddChild( n )
 			node.AddChild( n )
 			
 			
-			SortNode( n )
+			SortNode( n,func )
 		Next
 		Next
 	End
 	End
 	
 	

+ 79 - 75
view/Undock.monkey2

@@ -1,88 +1,92 @@
+
 Namespace ted2go
 Namespace ted2go
 
 
+
 Class UndockWindow Extends Window
 Class UndockWindow Extends Window
+	
+	Field _storeView:View
+	Field _storeTabbutton:TabButtonExt
+	Field _storeIndex:Int
+	Field _visible:Int
+	
+	Global _undockWindows:=New Stack<UndockWindow>
+	
+	Method New()
+	
+		Super.New( "Undock Window", MainWindow.Width/2, MainWindow.Height/2, WindowFlags.Resizable | WindowFlags.HighDPI | WindowFlags.Center )
+		Self.UpdateWindow( True )
+		_undockWindows.Push( Self )
+	End
+	
+	Function NewUndock:UndockWindow( _tabbutton:TabButtonExt )
 		
 		
-		Field _storeView:View
-		Field _storeTabbutton:TabButtonExt
-		Field _storeIndex:Int
-		Field _visible:Int
-		
-		Global _undockWindows:=New Stack<UndockWindow>
-		
-		Method New()
-		
-			Super.New( "Undock Window", MainWindow.Width/2, MainWindow.Height/2, WindowFlags.Resizable | WindowFlags.HighDPI | WindowFlags.Center )
-			Self.UpdateWindow( True )
-			_undockWindows.Push( Self )
-		End
-		
-		Function NewUndock:UndockWindow( _tabbutton:TabButtonExt )
-			
-			Local _window:UndockWindow
-		
-			For Local dw:=Eachin _undockWindows
-				If(dw.Title=_tabbutton.Text)_window=dw;Exit
-			Next
-				
-			If Not (_window) _window=New UndockWindow
-			
-			_tabbutton.CurrentHolder.MakeCurrent( _tabbutton.Text )
-			_window.Title=_tabbutton.Text
-			_tabbutton.Visible=False
+		Local _window:UndockWindow
+	
+		For Local dw:=Eachin _undockWindows
+			If dw.Title=_tabbutton.Text Then _window=dw ; Exit
+		Next
 		
 		
-			_window._storeTabbutton=_tabbutton
-			_window._storeView=_tabbutton.CurrentHolder.CurrentView
-			_window._storeIndex=_tabbutton.CurrentHolder.CurrentIndex
+		If Not _window Then _window=New UndockWindow
 		
 		
-			_tabbutton.CurrentHolder.SetTabView( _window._storeIndex, Null )
-			If Not _tabbutton.CurrentHolder.VisibleTabs _tabbutton.CurrentHolder.Visible=False
+		_tabbutton.CurrentHolder.MakeCurrent( _tabbutton.Text )
+		_window.Title=_tabbutton.Text
+		_tabbutton.Visible=False
+	
+		_window._storeTabbutton=_tabbutton
+		_window._storeView=_tabbutton.CurrentHolder.CurrentView
+		_window._storeIndex=_tabbutton.CurrentHolder.CurrentIndex
+	
+		_tabbutton.CurrentHolder.SetTabView( _window._storeIndex, Null )
+		If Not _tabbutton.CurrentHolder.VisibleTabs Then _tabbutton.CurrentHolder.Visible=False
+	
+		For Local mk:=Eachin _tabbutton.CurrentHolder.Tabs
+			If mk.Visible Then _tabbutton.CurrentHolder.MakeCurrent( mk.Text )
+		Next
 		
 		
-			For Local mk:=Eachin _tabbutton.CurrentHolder.Tabs
-				If mk.Visible _tabbutton.CurrentHolder.MakeCurrent( mk.Text )
-			Next
+		_window.ContentView=_window._storeView
+		_window._visible=True
+		_window.Activated()
 		
 		
-			_window.ContentView=_window._storeView
-			_window._visible=True
-			_window.Activated()
-			Return _window
-		End
-			
-		Method SetUndockFrame( _frame:Recti )
-			
-			SDL_SetWindowPosition( Self.Window.SDLWindow, _frame.X, _frame.Y )
-			SDL_SetWindowSize( Self.Window.SDLWindow, _frame.Width, _frame.Height )
-			Self.Restore()
-			Local event:=New WindowEvent( EventType.WindowMoved, Self )
-			SendWindowEvent( event )
-		End
+		Return _window
+	End
+	
+	Method SetUndockFrame( _frame:Recti )
 		
 		
-		Method OnWindowEvent( event:WindowEvent ) Override
+		SDL_SetWindowPosition( Self.Window.SDLWindow, _frame.X, _frame.Y )
+		SDL_SetWindowSize( Self.Window.SDLWindow, _frame.Width, _frame.Height )
+		Self.Restore()
+		Local event:=New WindowEvent( EventType.WindowMoved, Self )
+		SendWindowEvent( event )
+	End
+	
+	Method OnWindowEvent( event:WindowEvent ) Override
 		
 		
-			Select event.Type
-				Case EventType.WindowClose
-					CloseWindow()
-				Default
-					Super.OnWindowEvent( event )
-			End
+		Select event.Type
+			Case EventType.WindowClose
+				CloseWindow()
+			Default
+				Super.OnWindowEvent( event )
 		End
 		End
+	End
+	
+	Method CloseWindow()
 		
 		
-		Method CloseWindow()
-			
-			Local view:=ContentView
-			ContentView=Null
-			_storeTabbutton.CurrentHolder.SetTabView( _storeIndex, view )
-			_storeTabbutton.Visible=True
-			If Not _storeTabbutton.CurrentHolder.Visible _storeTabbutton.CurrentHolder.Visible=True
-			SDL_HideWindow( Self.Window.SDLWindow )
-			Self._visible=False
-		End
+		Local view:=ContentView
+		ContentView=Null
+		_storeTabbutton.CurrentHolder.SetTabView( _storeIndex, view )
+		_storeTabbutton.Visible=True
+		If Not _storeTabbutton.CurrentHolder.Visible Then _storeTabbutton.CurrentHolder.Visible=True
+		SDL_HideWindow( Self.Window.SDLWindow )
+		Self._visible=False
+	End
+	
+	Function RestoreUndock()
 		
 		
-		Function RestoreUndock()
-
-			For Local i:=Eachin _undockWindows
-				i.CloseWindow()
-				_undockWindows.RemoveEach( i )
-			Next
-			If _undockWindows.Length RestoreUndock()		
-		End	
-End
+		For Local i:=Eachin _undockWindows
+			i.CloseWindow()
+			_undockWindows.RemoveEach( i )
+		Next
+		If _undockWindows.Length Then RestoreUndock()
+	End
+	
+End