Browse Source

Squashed 'src/ted2go/' changes from 7b67f8da..5d3be9da

5d3be9da Removed Finalize keyword.
0171e00d Added padding for table with modules info (last item was half-visible).
b26aa784 Updated module manager domain and app version.
c56225d7 Merge branch 'dev'
97857908 Added language keyword 'Finalize'.
c6366015 Output tab improvements: button "clear all"; text filter field; stop scrolling-to-end if we scrolled up.
392cb498 Completion - added new sorting rule: set less priority if first char capitalizing isn't equals.
4d469639 Update README.md
9bd27ceb Start search on text changed if text's length is 2+ chars.
1108daa5 Added new action "Debug" into main menu and toolbar, that run app alwayw in debug mode ignoring debug/release switcher.
704caa01 Fixed consoles / browsers sizes when them are invisible - don't store zero-sized values.
bd6c372d Don't store browser and console sizes if them are hidden.

git-subtree-dir: src/ted2go
git-subtree-split: 5d3be9daf859e26e3306510cce00ca830a9c7ee6
Mark Sibly 8 years ago
parent
commit
5ff6caa132

+ 77 - 18
MainWindow.monkey2

@@ -53,8 +53,45 @@ Class MainWindowInstance Extends Window
 			SaveState()
 		End
 
+		'Build tab
+		
 		_buildConsole=New ConsoleExt
+		
+		'Output tab
+		
 		_outputConsole=New ConsoleExt
+		Local bar:=New ToolBarExt
+		bar.MaxSize=New Vec2i( 300,30 )
+		
+		bar.AddIconicButton(
+			ThemeImages.Get( "outputbar/clean.png" ),
+			Lambda()
+				_outputConsole.ClearAll()
+			End,
+			"Clear all" )
+		
+		'bar.AddSeparator()
+		'bar.AddSeparator()
+			
+		Local label:=New Label( "Filter:" )
+		bar.AddView( label,"left" )
+		Local editFilter:=New TextField()
+		editFilter.Style=GetStyle( "TextFieldBordered" )
+		editFilter.CursorType=CursorType.Line
+		editFilter.CursorBlinkRate=2.5
+		bar.AddView( editFilter,"left",200 )
+		editFilter.TextChanged+=Lambda()
+		
+			Local t:=editFilter.Text
+			_outputConsole.SetFilter( t )
+		End
+		
+		_outputConsoleView=New DockingView
+		_outputConsoleView.AddView( bar,"top" )
+		_outputConsoleView.ContentView=_outputConsole
+		
+		
+		'Find tab
 		
 		_findConsole=New TreeViewExt
 		_findConsole.NodeClicked+=Lambda( node:TreeView.Node )
@@ -79,7 +116,7 @@ Class MainWindowInstance Extends Window
 		
 		_helpView=New HtmlViewExt
 		_helpConsole=New DockingView
-		Local bar:=New ToolBarExt
+		bar=New ToolBarExt
 		bar.MaxSize=New Vec2i( 300,30 )
 		bar.AddIconicButton(
 			ThemeImages.Get( "docbar/home.png" ),
@@ -102,7 +139,7 @@ Class MainWindowInstance Extends Window
 			"Forward" )
 		bar.AddSeparator()
 		bar.AddSeparator()
-		Local label:=New Label
+		label=New Label
 		bar.AddView( label,"left" )
 		
 		_helpView.Navigated+=Lambda( url:String )
@@ -252,6 +289,8 @@ Class MainWindowInstance Extends Window
 		_buildMenu.AddAction( _buildActions.buildAndRun )
 		_buildMenu.AddAction( _buildActions.build )
 		_buildMenu.AddAction( _buildActions.semant )
+		_buildMenu.AddAction( _buildActions.debugApp )
+		_buildMenu.AddSeparator()
 		_buildMenu.AddSubMenu( _buildActions.targetMenu )
 		_buildMenu.AddSeparator()
 		_buildMenu.AddAction( _forceStop )
@@ -313,7 +352,7 @@ Class MainWindowInstance Extends Window
 		_browsersTabView.AddTab( "Help",_helpTree,False )
 		
 		_consolesTabView.AddTab( "Build",_buildConsole,True )
-		_consolesTabView.AddTab( "Output",_outputConsole,False )
+		_consolesTabView.AddTab( "Output",_outputConsoleView,False )
 		_consolesTabView.AddTab( "Docs",_helpConsole,False )
 		_consolesTabView.AddTab( "Find",_findConsole,False )
 		
@@ -506,10 +545,12 @@ Class MainWindowInstance Extends Window
 	Method StoreConsoleVisibility()
 		
 		_storedConsoleVisible=_consolesTabView.Visible
+		_consoleVisibleCounter=0
 	End
 	
 	Method RestoreConsoleVisibility()
 	
+		If _consoleVisibleCounter > 0 Return
 		_consolesTabView.Visible=_storedConsoleVisible
 		RequestRender()
 	End
@@ -540,7 +581,7 @@ Class MainWindowInstance Extends Window
 		Local pos:=tv.Cursor-tv.Document.StartOfLine( line )
 		line+=1
 		pos+=1
-		_statusBar.SetLineInfo( "Ln : "+line+"  Col : "+pos )
+		_statusBar.SetLineInfo( "Ln : "+line+"    Col : "+pos )
 	End
 	
 	Method ShowStatusBarProgress( cancelCallback:Void(),cancelIconOnly:Bool=False )
@@ -572,6 +613,7 @@ Class MainWindowInstance Extends Window
 		Local buildTitle:=GetActionTextWithShortcut( _buildActions.build )
 		Local checkTitle:=GetActionTextWithShortcut( _buildActions.semant )
 		Local findTitle:=GetActionTextWithShortcut( _findActions.find )
+		Local debugTitle:=GetActionTextWithShortcut( _buildActions.debugApp )
 		
 		_toolBar=New ToolBarExt
 		_toolBar.Style=GetStyle( "MainToolBar" )
@@ -588,6 +630,7 @@ Class MainWindowInstance Extends Window
 		_toolBar.AddIconicButton( ThemeImages.Get( "toolbar/check.png" ),_buildActions.semant.Triggered,checkTitle )
 		_toolBar.AddIconicButton( ThemeImages.Get( "toolbar/build.png" ),_buildActions.build.Triggered,buildTitle )
 		_toolBar.AddIconicButton( ThemeImages.Get( "toolbar/run.png" ),_buildActions.buildAndRun.Triggered,runTitle )
+		_toolBar.AddIconicButton( ThemeImages.Get( "toolbar/debug.png" ),_buildActions.debugApp.Triggered,debugTitle )
 		_toolBar.AddSeparator()
 		
 		Local act:=Lambda()
@@ -642,7 +685,7 @@ Class MainWindowInstance Extends Window
 	
 	Method ShowOutputConsole( vis:Bool=True )
 		If vis _consolesTabView.Visible=True
-		_consolesTabView.CurrentView=_outputConsole
+		_consolesTabView.CurrentView=_outputConsoleView
 	End
 	
 	Method ShowHelpView()
@@ -801,14 +844,18 @@ Class MainWindowInstance Extends Window
 		
 		jobj["windowRect"]=ToJson( Frame )
 		
-		jobj["browserSize"]=New JsonNumber( Int( _contentView.GetViewSize( _browsersTabView ) ) )
-		jobj["browserVisible"]=New JsonBool( _browsersTabView.Visible )
+		Local vis:Bool
+		vis=_browsersTabView.Visible
+		jobj["browserVisible"]=New JsonBool( vis )
 		jobj["browserTab"]=New JsonString( GetBrowsersTabAsString() )
+		If vis Then _browsersSize=Int( _contentView.GetViewSize( _browsersTabView ) )
+		If _browsersSize > 0 Then jobj["browserSize"]=New JsonNumber( _browsersSize )
 		
-		jobj["consoleSize"]=New JsonNumber( Int( _contentView.GetViewSize( _consolesTabView ) ) )
-		jobj["consoleVisible"]=New JsonBool( _consolesTabView.Visible )
+		vis=_consolesTabView.Visible
+		jobj["consoleVisible"]=New JsonBool( vis )
 		jobj["consoleTab"]=New JsonString( GetConsolesTabAsString() )
-		
+		If vis Then _consolesSize=Int( _contentView.GetViewSize( _consolesTabView ) ) 
+		If _consolesSize > 0 Then jobj["consoleSize"]=New JsonNumber( _consolesSize )
 		
 		Local recent:=New JsonArray
 		For Local path:=Eachin _recentFiles
@@ -889,11 +936,17 @@ Class MainWindowInstance Extends Window
 	
 	Method LoadState( jobj:JsonObject )
 	
-		If jobj.Contains( "browserSize" ) _contentView.SetViewSize( _browsersTabView,jobj.GetNumber( "browserSize" ) )
+		If jobj.Contains( "browserSize" )
+			_browsersSize=Int( jobj.GetNumber( "browserSize" ) )
+			_contentView.SetViewSize( _browsersTabView,_browsersSize )
+		Endif
 		If jobj.Contains( "browserVisible" ) _browsersTabView.Visible=jobj.GetBool( "browserVisible" )
 		If jobj.Contains( "browserTab" ) SetBrowsersTabByString( jobj.GetString( "browserTab" ) )
 		
-		If jobj.Contains( "consoleSize" ) _contentView.SetViewSize( _consolesTabView,jobj.GetNumber( "consoleSize" ) )
+		If jobj.Contains( "consoleSize" )
+			_consolesSize=Int( jobj.GetNumber( "consoleSize" ) )
+			_contentView.SetViewSize( _consolesTabView,_consolesSize )
+		Endif
 		If jobj.Contains( "consoleVisible" ) _consolesTabView.Visible=jobj.GetBool( "consoleVisible" )
 		If jobj.Contains( "consoleTab" ) SetConsolesTabByString( jobj.GetString( "consoleTab" ) )
 		
@@ -953,6 +1006,7 @@ Class MainWindowInstance Extends Window
 					_browsersTabView.Visible=Not _browsersTabView.Visible
 				Else
 					_consolesTabView.Visible=Not _consolesTabView.Visible
+					_consoleVisibleCounter+=1
 				Endif
 			Case Key.Keypad1
 			End
@@ -987,8 +1041,9 @@ Class MainWindowInstance Extends Window
 	Field _helpActions:HelpActions
 	Field _viewActions:ViewActions
 	
-	Field _buildConsole:Console
-	Field _outputConsole:Console
+	Field _buildConsole:ConsoleExt
+	Field _outputConsole:ConsoleExt
+	Field _outputConsoleView:DockingView
 	Field _helpView:HtmlViewExt
 	Field _helpConsole:DockingView
 	Field _findConsole:TreeViewExt
@@ -1017,8 +1072,8 @@ Class MainWindowInstance Extends Window
 	
 	Field _themesMenu:MenuExt
 	
-	Field _theme:String="default"
-	Field _themeScale:Float=1
+	Field _theme:="default"
+	Field _themeScale:=1.0
 	
 	Field _contentView:DockingView
 	Field _contentLeftView:DockingView
@@ -1033,8 +1088,12 @@ Class MainWindowInstance Extends Window
 	Field _statusBar:StatusBarView
 	Field _ovdMode:=False
 	Field _storedConsoleVisible:Bool
+	Field _consoleVisibleCounter:=0
 	Field _isTerminating:Bool
 	Field _enableSaving:Bool
+	Field _browsersSize:=0,_consolesSize:=0
+	
+	
 	
 	Method ToJson:JsonValue( rect:Recti )
 		Return New JsonArray( New JsonValue[]( New JsonNumber( rect.min.x ),New JsonNumber( rect.min.y ),New JsonNumber( rect.max.x ),New JsonNumber( rect.max.y ) ) )
@@ -1215,7 +1274,7 @@ Class MainWindowInstance Extends Window
 	Method GetConsolesTabAsString:String()
 		
 		Select _consolesTabView.CurrentView
-			Case _outputConsole
+			Case _outputConsoleView
 				Return "output"
 			Case _buildConsole
 				Return "build"
@@ -1232,7 +1291,7 @@ Class MainWindowInstance Extends Window
 		Local view:View
 		Select value
 			Case "output"
-				view=_outputConsole
+				view=_outputConsoleView
 			Case "build"
 				view=_buildConsole
 			Case "docs"

+ 2 - 1
Prefs.monkey2

@@ -9,9 +9,10 @@ Class Prefs
 	Global AcShowAfter:=2
 	Global AcUseTab:=True
 	Global AcUseEnter:=False
-	Global AcUseSpace:=True
+	Global AcUseSpace:=False
 	Global AcUseDot:=False
 	Global AcNewLineByEnter:=True
+	Global AcStrongFirstChar:=True
 	'
 	Global MainToolBarVisible:=True
 	Global MainProjectTabsRight:=True

+ 1 - 1
README.md

@@ -1,5 +1,5 @@
 # Ted2Go
-My custom version of Ted2 IDE.
+An IDE for Monkey2 programming language.
 
 ## Benefits & Goals
 * Autocompletion for keywords, modules and user's code (WIP).

+ 1 - 1
Ted2.monkey2

@@ -109,7 +109,7 @@ Using mojox..
 Using tinyxml2..
 
 
-Global AppTitle:="Ted2Go v2.3.1"
+Global AppTitle:="Ted2Go v2.3.2"
 
 
 Function Main()

+ 23 - 5
action/BuildActions.monkey2

@@ -34,6 +34,7 @@ End
 Class BuildActions Implements IModuleBuilder
 
 	Field buildAndRun:Action
+	Field debugApp:Action
 	Field build:Action
 	Field semant:Action
 	Field buildSettings:Action
@@ -49,7 +50,7 @@ Class BuildActions Implements IModuleBuilder
 	
 	Field PreBuild:Void()
 	
-	Method New( docs:DocumentManager,console:Console,debugView:DebugView )
+	Method New( docs:DocumentManager,console:ConsoleExt,debugView:DebugView )
 	
 		_docs=docs
 		_console=console
@@ -60,7 +61,7 @@ Class BuildActions Implements IModuleBuilder
 			If doc=_locked _locked=Null
 		End
 		
-		buildAndRun=New Action( "Build and run" )
+		buildAndRun=New Action( "Run" )
 #If __TARGET__="macos"
 		buildAndRun.HotKey=Key.R
 		buildAndRun.HotKeyModifiers=Modifier.Menu
@@ -69,8 +70,16 @@ Class BuildActions Implements IModuleBuilder
 #Endif
 		buildAndRun.Triggered=OnBuildAndRun
 		
+		debugApp=New Action( "Debug" )
+#If __TARGET__="macos"
+		debugApp.HotKey=Key.D
+		debugApp.HotKeyModifiers=Modifier.Menu
+#Else
+		debugApp.HotKey=Key.F8
+#Endif
+		debugApp.Triggered=OnDebugApp
 
-		build=New Action( "Build only" )
+		build=New Action( "Build" )
 #If __TARGET__="macos"
 		build.HotKey=Key.B
 		build.HotKeyModifiers=Modifier.Menu
@@ -79,7 +88,7 @@ Class BuildActions Implements IModuleBuilder
 #Endif
 		build.Triggered=OnBuild
 		
-		semant=New Action( "Check app" )
+		semant=New Action( "Check" )
 #If __TARGET__="macos"
 		semant.HotKey=Key.R
 		semant.HotKeyModifiers=Modifier.Menu|Modifier.Shift
@@ -330,7 +339,7 @@ Class BuildActions Implements IModuleBuilder
 	Private
 	
 	Field _docs:DocumentManager
-	Field _console:Console
+	Field _console:ConsoleExt
 	Field _debugView:DebugView
 	
 	Field _locked:CodeDocument
@@ -569,6 +578,15 @@ Class BuildActions Implements IModuleBuilder
 		BuildApp( _buildConfig,_buildTarget,"run" )
 	End
 	
+	Method OnDebugApp()
+	
+		PreBuild()
+	
+		If _console.Running Return
+	
+		BuildApp( "debug",_buildTarget,"run" )
+	End
+	
 	Method OnBuild()
 		
 		PreBuild()

+ 18 - 5
action/FindActions.monkey2

@@ -23,7 +23,9 @@ Class FindActions
 		find.HotKeyModifiers=Modifier.Menu
 		
 		findNext=New Action( "Find next" )
-		findNext.Triggered=OnFindNext
+		findNext.Triggered=Lambda()
+			OnFindNext()
+		End
 		findNext.HotKey=Key.F3
 		
 		findPrevious=New Action( "Find previous" )
@@ -58,6 +60,12 @@ Class FindActions
 		replaceAll.Enabled=tv
 	End
 	
+	Method FindByTextChanged()
+		
+		OnFindNext( False )
+	End
+	
+	
 	Private
 	
 	Field _docs:DocumentManager
@@ -65,7 +73,7 @@ Class FindActions
 	Field _findDialog:FindDialog
 	Field _findInFilesDialog:FindInFilesDialog
 	Field _findConsole:TreeViewExt
-	
+	Field _cursorPos:=0
 	
 	Method OnFind()
 		
@@ -79,6 +87,7 @@ Class FindActions
 				Local s:=tv.Text.Slice( min,max )
 				_findDialog.SetInitialText( s )
 			Endif
+			_cursorPos=Min( tv.Cursor,tv.Anchor )
 		Endif
 	End
 	
@@ -97,7 +106,7 @@ Class FindActions
 		Endif
 	End
 	
-	Method OnFindNext()
+	Method OnFindNext( changeCursorPos:Bool=True )
 	
 		Local tv:=_docs.CurrentTextView
 		If Not tv Return
@@ -106,7 +115,11 @@ Class FindActions
 		If Not text Return
 		
 		Local tvtext:=tv.Text
-		Local cursor:=Max( tv.Anchor,tv.Cursor )
+		Local cursor:=_cursorPos
+		If changeCursorPos
+			cursor=Max( tv.Anchor,tv.Cursor )
+			_cursorPos=cursor
+		Endif
 		
 		If Not _findDialog.CaseSensitive
 			tvtext=tvtext.ToLower()
@@ -166,7 +179,7 @@ Class FindActions
 		Local root:=_findConsole.RootNode
 		root.RemoveAllChildren()
 		
-		root.Text="Finding of '"+what+"'"
+		root.Text="Results for '"+what+"'"
 		
 		Local subRoot:TreeView.Node
 		Local items:=New Stack<FileJumpData>

+ 1 - 1
assets/aboutTed2Go.html

@@ -120,7 +120,7 @@ Enjoy coding!</p>
 
 <h3>Special Thanks</h3>
 
-<p>Peter Scheutz, Matthieu Chemin, David Maziarka, Leonardo Teixeira, Jesus Perez, Mark Sibly, Philipp Moeller, Lee Wade.</p>
+<p>Sal Gunduz, Peter Scheutz, Matthieu Chemin, David Maziarka, Leonardo Teixeira, Jesus Perez, Mark Sibly, Philipp Moeller, Lee Wade.</p>
 
 </body>
 

BIN
assets/themes/outputbar/clean.png


+ 6 - 0
assets/themes/ted2-default.json

@@ -113,6 +113,12 @@
 			"extends":"ToolButton",
 			"padding":[ 0 ],
 			"skinColor":"transparent"
+		},
+		
+		"TextFieldBordered":{
+			"extends":"TextField",
+			"border":[ 1 ],
+			"borderColor":"clear"
 		}
 		
 	}

BIN
assets/themes/toolbar/check.png


+ 7 - 0
dialog/FindDialog.monkey2

@@ -13,6 +13,13 @@ Class FindDialog Extends DialogExt
 		_findField.Entered+=Lambda()
 			actions.findNext.Trigger()
 		End
+		_findField.TextChanged+=Lambda(  )
+			
+			Local t:=_findField.Text
+			If t.Length > 1
+				actions.FindByTextChanged()
+			Endif
+		End
 
 		_findField.Tabbed+=_replaceField.MakeKeyView
 

+ 7 - 0
parser/CodeItem.monkey2

@@ -535,6 +535,13 @@ Struct CodeItemsSorter Final
 			Endif
 		Next
 		
+		' strong first char
+		If Prefs.AcStrongFirstChar
+			Local lower1:=IsLowercacedFirstChar( ident )
+			Local lower2:=IsLowercacedFirstChar( etalon )
+			If lower1 <> lower2 Then power-=10000
+		End
+		
 		Return power
 	End
 	

+ 1 - 0
parser/Monkey2Parser.monkey2

@@ -1004,6 +1004,7 @@ Class Monkey2Parser Extends CodeParserPlugin
 	Method CheckIdent:Bool( ident1:String,ident2:String,startsOnly:Bool,smartStarts:Bool=True )
 	
 		If ident2 = "" Return True
+		
 		If startsOnly
 			Return smartStarts ? CheckStartsWith( ident1,ident2 ) Else ident1.StartsWith( ident2 )
 		Else

+ 14 - 4
product/ModuleManager.monkey2

@@ -4,6 +4,9 @@ Namespace ted2go
 
 Private
 
+Const MONKEY2_DOMAIN:="http://monkeycoder.co.nz"
+
+
 Class Module
 	Field name:String
 	Field about:String
@@ -18,7 +21,7 @@ Public
 
 Class ModuleManager Extends Dialog
 
-	Method New( console:Console )
+	Method New( console:ConsoleExt )
 		Super.New( "Module Manager" )
 		
 		_console=console
@@ -99,13 +102,14 @@ Class ModuleManager Extends Dialog
 	Private
 	
 	'Const downloadUrl:="http://monkey2.monkey-x.com/wp-content/uploads/mx2-modules/public/"
-    Const downloadUrl:="http://monkey2.monkey-x.com/send-file?file="
-    
+    'Const downloadUrl:="http://monkey2.monkey-x.com/send-file?file="
+    Const downloadUrl:=MONKEY2_DOMAIN+"/send-file?file="
+	
 	Const downloadDir:="modules/module-manager/downloads/"
 	
 	Const backupDir:="modules/module-manager/backups/"
 	
-	Field _console:Console
+	Field _console:ConsoleExt
 	Field _docker:DockingView
 	Field _modules:=New StringMap<Module>
 	Field _filters:=New StringMap<CheckButton>
@@ -601,6 +605,12 @@ Class ModuleManager Extends Dialog
 
 		Next
 		
+		' some bottom pagdding
+		_table.Rows+=1
+		Local label:=New Label( "" )
+		label.MinSize=New Vec2i( 0,30 )
+		_table[0,_table.Rows-1]=label
+		
 		App.RequestRender()
 	
 	End

+ 1 - 1
product/Mx2ccEnv.monkey2

@@ -83,7 +83,7 @@ End
 
 Public
 
-Function EnumValidTargets:StringStack( console:Console )
+Function EnumValidTargets:StringStack( console:ConsoleExt )
 
 	LoadEnv()
 	

+ 8 - 0
utils/Utils.monkey2

@@ -2,6 +2,14 @@
 Namespace ted2go
 
 
+Function IsLowercacedFirstChar:Bool(s:String)
+	
+	If Not s Return False
+	Local s1:=s.Slice( 0,1 )
+	Return s1 = s1.ToLower()
+End
+
+
 Class Utils
 	
 	Function ArrayContains<T>:Bool( arr:T[],value:T )

+ 272 - 3
view/ConsoleViewExt.monkey2

@@ -2,21 +2,246 @@
 Namespace ted2go
 
 
-Class ConsoleExt Extends Console
+#if __TARGET__<>"emscripten"
 
+#rem monkeydoc The Console class.
+#end
+Class ConsoleExt Extends TextView
+
+	#rem monkeydoc Invoked when the console finishes executing a process.
+	#end
+	Field Finished:Void( exitCode:Int )
+	
+	#rem monkeydoc Creates a new console.
+	#end
 	Method New()
-		Super.New()
+		Style=GetStyle( "Console" )
+		
+		ReadOnly=True
+	End
+	
+	#rem monkeydoc True if the process is running.
+	#end
+	Property Running:Bool()
+
+		Return _running
+	End
+	
+	#rem monkeydoc The process.
+	#end
+	Property Process:Process()
+
+		Return _process
+	End
+	
+	#rem monkeydoc Process exit code.
+	
+	If the process is still running, -1 is returned.
+	
+	#end
+	Property ExitCode:Int()
+
+		If _process And Not _procOpen return _process.ExitCode
+
+		Return -1
+	End
+	
+	#rem monkeydoc Runs a process.
+	
+	Returns true if the process was successfully started, else false.
+	
+	Process stdout is written to the console while the process is running.
+	
+	This method waits for the process to complete, so should always be called on a fiber.
+	
+	#end
+	Method Run:Bool( cmd:String )
+	
+		If Not Start( cmd )
+			Alert( "Failed to start process '"+cmd+"'" )
+			Return False
+		Endif
+		
+		Repeat
+		
+			Local stdout:=ReadStdout()
+			If Not stdout Exit
+			
+			Write( stdout )
+		Forever
+		
+		Return True
+	End
+
+	#rem monkeydoc Starts a process.
+	
+	Returns true if the process was successfully started, else false.
+	
+	#end	
+	Method Start:Bool( cmd:String )
+	
+		If _running Return False
+		
+		Local process:=New Process
+	
+		process.Finished=Lambda()
+			_procOpen=False
+			UpdateRunning()
+		End
+		
+		process.StdoutReady=Lambda()
+		
+			Local stdout:=process.ReadStdout()
+			
+'			Print "**** CONSOLE STDOUT *****"
+'			Print stdout
+'			Print "***** END STDOUT *****"
+			
+			If Not stdout
+				If _stdout _stdoutBuf.Add( _stdout )
+				_stdoutOpen=False
+				UpdateRunning()
+				Return
+			Endif
+			
+			stdout=_stdout+(stdout.Replace( "~r~n","~n" ).Replace( "~r","~n" ))
+			
+			Local i0:=0
+			Repeat
+				Local i:=stdout.Find( "~n",i0 )
+				If i=-1
+					_stdout=stdout.Slice( i0 )
+					Exit
+				Endif
+				_stdoutBuf.Add( stdout.Slice( i0,i+1 ) )
+				i0=i+1
+			Forever
+			
+			If _stdoutWaiting And Not _stdoutBuf.Empty _stdoutWaiting.Set( True )
+			
+		End
+		
+		If Not process.Start( cmd ) Return False
+		
+		_process=process
+		
+		_running=True
+		_procOpen=True
+		_stdoutOpen=True
+
+		_stdout=""
+		_stdoutBuf.Clear()
+		_stdoutWaiting=Null
+		
+		Return True
+	End
+	
+	#rem monkeydoc Reads process stdout.
+	
+	If an empty string is returned, the process has finished.
+	
+	This method may have to wait for stdout to become available, so should always be called on a fiber.
+	
+	#end
+	Method ReadStdout:String()
+	
+		While _stdoutBuf.Empty
+		
+			If Not _stdoutOpen
+				If _procOpen
+					_stdoutWaiting=New Future<Bool>
+					_stdoutWaiting.Get()
+					_stdoutWaiting=Null
+				Endif
+				Return ""
+			Endif
+			
+			_stdoutWaiting=New Future<Bool>
+			_stdoutWaiting.Get()
+			_stdoutWaiting=Null
+		Wend
+		
+		Return _stdoutBuf.RemoveFirst()
+	End
+	
+	#rem monkeydoc Writes to process stdin.
+	#end
+	Method WriteStdin( str:String )
+	
+		If Not _procOpen Return
+	
+		_process.WriteStdin( str )
+	End
+	
+	#rem monkeydoc Terminates the process.
+	#end
+	Method Terminate()
+
+		If Not _procOpen Return
+		
+		_process.Terminate()
+	End
+	
+	#rem monkeydoc Writes text to the console.
+	#end
+	Method Write( text:String )
+	
+		_lines.Add( text )
+		AddFiltered( text )
+	End
+	
+	Method SetFilter( value:String )
+	
+		If value = _filter Return
+		
+		_filter=value
+		Clear()
+		For Local s:=Eachin _lines
+			AddFiltered( s )
+		End
+		
+		SelectText( Text.Length,Text.Length )
+	End
+	
+	Method ClearAll()
+		
+		Clear()
+		_lines.Clear()
 	End
 	
 	
 	Protected
 	
 	Method OnKeyEvent( event:KeyEvent ) Override
-		
+	
 		If CanCopy And (event.Key = Key.C Or event.Key = Key.Insert) And  event.Type = EventType.KeyDown And event.Modifiers & Modifier.Control
+		
 			Copy()
+			Return
 		Endif
 		
+		If event.Type = EventType.KeyDown
+			
+			If event.Key = Key.PageUp
+			
+				Scroll-=New Vec2i( 0,VisibleRect.Height )
+				
+			Else If event.Key = Key.PageDown
+			
+				Scroll+=New Vec2i( 0,VisibleRect.Height )
+				
+			Else If event.Modifiers & Modifier.Control
+				
+				If event.Key = Key.Home
+					SelectText( 0,0 )
+				Else If event.Key = Key.KeyEnd
+					SelectText( Text.Length,Text.Length )
+				Endif
+				
+			Endif
+		Endif
+	
+		'Super.OnKeyEvent( event )
 	End
 	
 	Method OnContentMouseEvent( event:MouseEvent ) Override
@@ -31,4 +256,48 @@ Class ConsoleExt Extends Console
 		Super.OnContentMouseEvent( event )
 	End
 	
+	
+	Private
+	
+	Field _lines:=New StringStack
+	Field _filter:=""
+	
+	Field _process:Process
+	
+	Field _running:Bool
+	Field _procOpen:Bool
+	Field _stdoutOpen:Bool
+
+	Field _stdout:String
+	Field _stdoutBuf:=New StringList
+	Field _stdoutWaiting:Future<Bool>
+	
+	Method UpdateRunning()
+	
+		If Not _running Or _procOpen Or _stdoutOpen Return
+		
+		_running=False
+		
+		Finished( _process.ExitCode )
+		
+		If _stdoutWaiting _stdoutWaiting.Set( True )
+	End
+
+	Method AddFiltered( text:String )
+		
+		If Not _filter Or text.Find( _filter) <> -1
+			Local cur:=Cursor,anc:=Anchor
+			Local sc:=Scroll
+			AppendText( text )
+			Local atBottom:=(Scroll.y-sc.y<=LineRect(Document.NumLines-1).Height) And cur=anc
+			If Not atBottom
+				Scroll=sc 'restore
+				SelectText( anc,cur )
+			Endif
+			
+		Endif
+	End
+	
 End
+
+#endif

+ 2 - 2
view/DebugView.monkey2

@@ -4,7 +4,7 @@ Namespace ted2go
 
 Class DebugView Extends DockingView
 
-	Method New( docs:DocumentManager,console:Console )
+	Method New( docs:DocumentManager,console:ConsoleExt )
 	
 		_docs=docs
 		_console=console
@@ -279,7 +279,7 @@ Class DebugView Extends DockingView
 	Field _toolBar:ToolBar
 
 	Field _docs:DocumentManager	
-	Field _console:Console
+	Field _console:ConsoleExt
 
 	Field _debugging:Bool
 	Field _stopped:Bool