From 85153a606e339b0a928e53e6a197d29804d8cb28 Mon Sep 17 00:00:00 2001 From: Mark Sibly Date: Thu, 8 Mar 2018 12:59:02 +1300 Subject: [PATCH] Squashed 'src/ted2go/' changes from 795d6240..43463bbc 43463bbc Merge branch 'dev' 0aa04b88 Updated 3d template file. 2c72b18b Added patron info (#115) 9f8950c9 Changed SourceCodePro.ttf to SourceCodePro.otf due to missing 'missing' glyph. 30b71654 Merge branch 'dev' a5e6ac96 Improved removing whitespaced trailings. bd606b5e Added "Remove lines trailing" feature (enabled by default). fde8e555 Bump app version. 814ecffd Improved support of array type in code completion and code tree view. 1bf57792 Now storing latest opened tab in prefs dialog. c14b7280 Added "Rename folder", and open a *folder* by "open file on desktop". a80fe7e2 Updated special thanks. d40bf4d4 Added shortcut (Ctrl+Shift+D) for duplicate line or selection (#90) e32dfab7 Added some preprocessor directives. 799ef412 Improved "fix indentation" logic. 8b747870 Added shortcut text for "Stop process" button in status bar. 652924fa Completion list - some colors added into theme file (#103) 7ab83d27 Removed IRC stuff (#105) ab276f07 Improved "spaces as tabs" convertion. (#98) 2476c50b More work on tabulation. 2d7a16b6 New feature - using spaces as tabs! (almost done) 64219e7c Disabled tabs undocking until there is no support for multi-window apps. 8fb4bf2d Merge branch 'master' into dev a21bf249 Themes fixes by Hezkore. cad986d0 Fix wrong View size afer restart and reload Undock Window (#112) 3599a22a Merge branch 'v2.8.1' into dev 86369138 Fixed tabs moving after drag-n-drop them. c67124bc Undock tabs v2 (#109) b82b1c29 View Mod (#108) ba39705c Fixed text. 8e6d4cf4 Fixed #101 - make locked latest file just opened by double-click (via extension association). 052102d7 Updated mojo3d app template. 846935d1 Added ".glb" support to ted2go. 1267a050 Fixed SceneDocument to work with new mojo3d. 4d2d9577 Added a record to console about building cancellation. 720be2dc Close pop-up parameter hints by Escape. d580b2ae Fixed #92 - minor focus issue. da00ab0b Added jumping to error line right from Console view. git-subtree-dir: src/ted2go git-subtree-split: 43463bbcb22a7ad759e82972a9bacd317d3bcc86 --- MainWindow.monkey2 | 191 +++++------- Prefs.monkey2 | 38 +-- README.md | 1 + Ted2.monkey2 | 5 +- action/FileActions.monkey2 | 12 + action/TabActions.monkey2 | 78 +++++ assets/aboutTed2Go.html | 2 +- assets/fonts/SourceCodePro-Medium.otf | Bin 0 -> 145516 bytes assets/newfiles/Simple_Mojo3d_App.monkey2 | 42 ++- assets/themes/irc/blink.png | Bin 123 -> 0 bytes assets/themes/irc/important.png | Bin 119 -> 0 bytes assets/themes/irc/notice.png | Bin 120 -> 0 bytes assets/themes/ted2-default.json | 5 +- assets/themes/theme-hollow.json | 14 +- assets/themes/theme-prime-base.json | 4 +- dialog/PrefsDialog.monkey2 | 82 ++--- document/CodeDocument.monkey2 | 280 +++++++++++++---- document/Monkey2Document.monkey2 | 30 +- document/SceneDocument.monkey2 | 2 +- eventfilter/Monkey2KeyEventFilter.monkey2 | 27 ++ parser/CodeItem.monkey2 | 2 + parser/Monkey2Parser.monkey2 | 56 ++-- testing/ParserTests.monkey2 | 4 +- utils/TextUtils.monkey2 | 65 ++++ utils/Utils.monkey2 | 71 ++++- view/AutocompleteView.monkey2 | 23 +- view/CodeTextView.monkey2 | 361 ++++++++++++++++++++-- view/ListViewExt.monkey2 | 9 +- view/ProjectView.monkey2 | 40 ++- view/StatusBarView.monkey2 | 4 +- view/TabViewExt.monkey2 | 34 +- view/Undock.monkey2 | 88 ++++++ 32 files changed, 1169 insertions(+), 401 deletions(-) create mode 100644 action/TabActions.monkey2 create mode 100644 assets/fonts/SourceCodePro-Medium.otf delete mode 100644 assets/themes/irc/blink.png delete mode 100644 assets/themes/irc/important.png delete mode 100644 assets/themes/irc/notice.png create mode 100644 utils/TextUtils.monkey2 create mode 100644 view/Undock.monkey2 diff --git a/MainWindow.monkey2 b/MainWindow.monkey2 index fd15a693..1615e6f4 100644 --- a/MainWindow.monkey2 +++ b/MainWindow.monkey2 @@ -11,8 +11,6 @@ Namespace ted2go #Import "assets/fonts/@/fonts" -#Import "assets/themes/irc/@/themes/irc" - Global MainWindow:MainWindowInstance @@ -68,29 +66,21 @@ Class MainWindowInstance Extends Window OnFileDropped( path ) End - + _docsManager.DocumentAdded+=Lambda( doc:Ted2Document ) AddRecentFile( doc.Path ) + + Local codeDoc:=Cast( doc ) + If codeDoc Then codeDoc.AnalyzeIndentation() + SaveState() End - + _docsManager.DocumentRemoved+=Lambda( doc:Ted2Document ) If IsTmpPath( doc.Path ) DeleteFile( doc.Path ) SaveState() End - 'IRC tab - - _ircView=New IRCView - _ircView.introScreen.Text="Hang out with other Monkey 2 users" - _ircView.introScreen.OnNickChange+=Lambda( nick:String ) - Prefs.IrcNickname=nick - End - - SetupChatTab() - - If Prefs.IrcConnect Then _ircView.introScreen.Connect() - 'Build tab _buildConsole=New ConsoleExt @@ -243,6 +233,7 @@ Class MainWindowInstance Extends Window _findActions=New FindActions( _docsManager,_projectView,_findConsole ) _helpActions=New HelpActions _viewActions=New ViewActions( _docsManager ) + _tabActions=New TabActions( _tabsWrap.AllDocks ) _tabMenu=New Menu _tabMenu.AddAction( _fileActions.close ) @@ -363,6 +354,10 @@ Class MainWindowInstance Extends Window _gotoMenu.AddAction( _viewActions.goBack ) _gotoMenu.AddAction( _viewActions.goForward ) + 'View menu + ' + _viewMenu=New MenuExt( "View" ) + TabActions.CreateMenu( _viewMenu ) 'Build menu ' _forceStop=New Action( "Force Stop" ) @@ -435,6 +430,7 @@ Class MainWindowInstance Extends Window _menuBar.AddMenu( _editMenu ) _menuBar.AddMenu( _findMenu ) _menuBar.AddMenu( _gotoMenu ) + _menuBar.AddMenu( _viewMenu ) _menuBar.AddMenu( _buildMenu ) _menuBar.AddMenu( _windowMenu ) _menuBar.AddMenu( _helpMenu ) @@ -443,7 +439,7 @@ Class MainWindowInstance Extends Window _buildConsoleView=New DockingView _buildConsoleView.ContentView=_buildConsole - _statusBar=New StatusBarView + _statusBar=New StatusBarView( "Stop process ("+_forceStop.HotKeyText+")" ) _contentView=New DockingView _contentView.AddView( _menuBar,"top" ) @@ -469,12 +465,16 @@ Class MainWindowInstance Extends Window End Field PrefsChanged:Void() + Method OnPrefsChanged() ArrangeElements() - PrefsChanged() - SetupChatTab() + For Local doc:=Eachin _docsManager.OpenDocuments + doc.TextView?.TabStop=Prefs.EditorTabSize + Next + + PrefsChanged() _projectView.SingleClickExpanding=Prefs.MainProjectSingleClickExpanding End @@ -623,7 +623,6 @@ Class MainWindowInstance Extends Window SaveState() _enableSaving=False OnForceStop() ' kill build process if started - If _ircView Then _ircView.Quit("Closing Ted2Go") ' waiting for started processes if any ParsersManager.DisableAll() @@ -1223,6 +1222,9 @@ Class MainWindowInstance Extends Window jobj["windowRect"]=ToJson( _storedSize ) jobj["windowState"]=New JsonNumber( Int(state) ) + SaveUndockTabsState( jobj ) + If _isTerminating UndockWindow.RestoreUndock() + SaveTabsState( jobj ) Local jdocs:=New JsonObject @@ -1298,9 +1300,8 @@ Class MainWindowInstance Extends Window SizeChanged() Endif - UpdateIrcIcon() - Rendered( canvas ) + End Method OnInit() @@ -1361,93 +1362,6 @@ Class MainWindowInstance Extends Window _resized=True End - Method SetupChatTab() - - If Not _ircView Return - - _ircView.ircHandler.OnMessage+=Self.OnChatMessage - - Local intro:=_ircView.introScreen - - If intro.IsConnected Return - - Local nick:=Prefs.IrcNickname - Local server:=Prefs.IrcServer - Local port:=Prefs.IrcPort - Local rooms:=Prefs.IrcRooms - intro.AddOnlyServer( nick,server,server,port,rooms ) - - End - - Method OnChatTabActiveChanged() - - Local tab:=_tabsWrap.tabs["Chat"] - - If Not tab.IsActive Return - - tab.Icon=Null - - _ircNotifyIcon=0 - - HideHint() - - End - - Method OnChatMessage( message:IRCMessage, container:IRCMessageContainer, server:IRCServer ) - - If message.type<>"PRIVMSG" Or _tabsWrap.tabs["Chat"].IsActive Return - - 'Show notice icon - If message.text.Contains(server.nickname) Then - - If _ircNotifyIcon<=1 Then - - _ircNotifyIcon=2 - - Local mentionStr:String - mentionStr=server.nickname+" was mentioned by " - mentionStr+=message.fromUser+" in " - mentionStr+=container.name - - Local dock:=_tabsWrap.tabs["Chat"].CurrentHolder '_tabsWrap.docks["bottom"] - ShowHint( mentionStr, New Vec2i( 0, -GetStyle( "Hint" ).Font.Height*4 ), dock, 20000 ) - - Endif - - Else - - If _ircNotifyIcon<=0 Then _ircNotifyIcon=1 - - Endif - - End - - Method UpdateIrcIcon() - - If _ircNotifyIcon<=0 Then Return - - Local time:Int=Int(Millisecs()*0.0025) - - If time=_ircIconBlink Then Return - _ircIconBlink=time - - Local tab:=_tabsWrap.tabs["Chat"] - - If time Mod 2 Then - Select _ircNotifyIcon - - Case 1 - tab.Icon=App.Theme.OpenImage( "irc/notice.png" ) - - Case 2 - tab.Icon=App.Theme.OpenImage( "irc/important.png" ) - End - Else - tab.Icon=App.Theme.OpenImage( "irc/blink.png" ) - Endif - - End - Method InitTabs() If Not _tabsWrap.tabs.Empty Return @@ -1459,9 +1373,7 @@ Class MainWindowInstance Extends Window _tabsWrap.AddTab( "Output",_outputConsoleView ) _tabsWrap.AddTab( "Docs",_docsConsole ) _tabsWrap.AddTab( "Find",_findConsole ) - _tabsWrap.AddTab( "Chat",_ircView ) - _tabsWrap.tabs["Chat"].ActiveChanged+=OnChatTabActiveChanged End Method ArrangeElements() @@ -1503,7 +1415,7 @@ Class MainWindowInstance Extends Window places["left"]=New StringStack( s.Split( "," ) ) s="Project,Debug" places["right"]=New StringStack( s.Split( "," ) ) - s="Build,Output,Docs,Find,Chat" + s="Build,Output,Docs,Find" places["bottom"]=New StringStack( s.Split( "," ) ) Global actives:=New StringMap @@ -1517,6 +1429,7 @@ Class MainWindowInstance Extends Window ' put views For Local edge:=Eachin edges Local val:=Json_FindValue( jobj.Data,"tabsDocks/"+edge+"Tabs" ) + Local vistabs:=Json_FindValue( jobj.Data,"tabsDocks/"+edge+"TabsVisible" ) If val And val<>JsonValue.NullValue For Local v:=Eachin val.ToArray().All() Local key:=v.ToString() @@ -1526,7 +1439,16 @@ Class MainWindowInstance Extends Window Next ' Local tab:=_tabsWrap.tabs[key] - If tab Then _tabsWrap.docks[edge].AddTab( tab ) + If tab Then + _tabsWrap.docks[edge].AddTab( tab ) + 'set view visible + If vistabs And vistabs<>JsonValue.NullValue + For Local vt:=Eachin vistabs.ToArray().All() + If key=vt.ToString() Then tab.Visible=True; Exit + tab.Visible=False + Next + End + End Next Endif Next @@ -1574,16 +1496,45 @@ Class MainWindowInstance Extends Window For Local edge:=Eachin edges Local dock:=_tabsWrap.docks[edge] jj[edge+"Tabs"]=JsonArray.FromStrings( dock.TabsNames ) + jj[edge+"TabsVisible"]=JsonArray.FromStrings( dock.TabsVisible ) jj[edge+"Active"]=New JsonString( dock.ActiveName ) jj[edge+"Visible"]=New JsonBool( dock.Visible ) jj[edge+"Size"]=New JsonString( _tabsWrap.GetDockSize( dock ) ) Next End + Method LoadUndockTabsState( jobj:JsonObject ) + + Local edges:=DraggableTabs.Edges + For Local edge:=Eachin edges + Local dock:=_tabsWrap.docks[edge] + For Local i:=Eachin dock.TabsNames + Local val:=Json_FindValue( jobj.Data,"undockTabs/"+i ) + If val + Local _undockWindow:=UndockWindow.NewUndock( _tabsWrap.tabs[i] ) + _undockWindow.SetUndockFrame( ToRecti( val ) ) + End + Next + Next + End + + Method SaveUndockTabsState( jobj:JsonObject ) + + If( UndockWindow._undockWindows.Length ) + Local jj:=New JsonObject + jobj["undockTabs"]=jj + For Local i:=Eachin UndockWindow._undockWindows + If i._visible jj[i.Title]=ToJson( i.Frame ) + Next + End + End + Method LoadState( jobj:JsonObject ) LoadTabsState( jobj ) + LoadUndockTabsState( jobj ) + If jobj.Contains( "docsTab" ) Local jdocs:=jobj.GetObject( "docsTab" ) Local size:=jdocs.GetString( "indexerSize" ) @@ -1677,15 +1628,15 @@ Class MainWindowInstance Extends Window If event.Modifiers & Modifier.Shift dock=_tabsWrap.docks["left"] - If dock.NumTabs>0 Then dock.Visible=Not dock.Visible + If dock.NumTabs>0 And dock.VisibleTabs Then dock.Visible=Not dock.Visible dock=_tabsWrap.docks["right"] - If dock.NumTabs>0 Then dock.Visible=Not dock.Visible + If dock.NumTabs>0 And dock.VisibleTabs Then dock.Visible=Not dock.Visible Else ' bottom dock dock=_tabsWrap.docks["bottom"] - If dock.NumTabs>0 Then dock.Visible=Not dock.Visible + If dock.NumTabs>0 And dock.VisibleTabs Then dock.Visible=Not dock.Visible _consoleVisibleCounter+=1 Endif @@ -1728,8 +1679,8 @@ Class MainWindowInstance Extends Window Field _buildActions:BuildActions Field _helpActions:HelpActions Field _viewActions:ViewActions + Field _tabActions:TabActions - Field _ircView:IRCView Field _buildConsole:ConsoleExt Field _buildConsoleView:DockingView Field _outputConsole:ConsoleExt @@ -1744,14 +1695,10 @@ Class MainWindowInstance Extends Window Field _helpTree:HelpTreeView Field _helpSwitcher:ToolButtonExt - 'Field _ircTabView:TabView Field _docsTabView:TabViewExt Field _consolesTabView2:TabView Field _browsersTabView2:TabView - Field _ircNotifyIcon:Int - Field _ircIconBlink:Int - Field _forceStop:Action Field _tabMenu:Menu @@ -1760,6 +1707,7 @@ Class MainWindowInstance Extends Window Field _editMenu:MenuExt Field _findMenu:MenuExt Field _gotoMenu:MenuExt + Field _viewMenu:MenuExt Field _buildMenu:MenuExt Field _windowMenu:MenuExt Field _helpMenu:MenuExt @@ -2033,6 +1981,7 @@ Class DraggableTabs Method AddTab( name:String,view:View ) tabs[name]=TabViewExt.CreateDraggableTab( name,view,_docksArray ) + tabs[name].Undockable=True End Method GetDockSize:String( dock:TabViewExt ) diff --git a/Prefs.monkey2 b/Prefs.monkey2 index eac35414..9d57789e 100644 --- a/Prefs.monkey2 +++ b/Prefs.monkey2 @@ -10,10 +10,10 @@ Class PrefsInstance Field AcKeywordsOnly:=False Field AcShowAfter:=2 Field AcUseTab:=True - Field AcUseEnter:=False + Field AcUseEnter:=True Field AcUseSpace:=False Field AcUseDot:=False - Field AcNewLineByEnter:=True + Field AcNewLineByEnter:=False Field AcStrongFirstChar:=True Field AcUseLiveTemplates:=True ' @@ -22,12 +22,6 @@ Class PrefsInstance Field MainProjectSingleClickExpanding:=False Field MainPlaceDocsAtBegin:=False ' - Field IrcNickname:String - Field IrcServer:="irc.freenode.net" - Field IrcPort:=6667 - Field IrcRooms:="#monkey2" '#mojox#mojo2d - Field IrcConnect:Bool=False - ' Field EditorToolBarVisible:=False Field EditorGutterVisible:=True Field EditorShowWhiteSpaces:=False @@ -39,6 +33,9 @@ Class PrefsInstance Field EditorAutoPairs:=True Field EditorSurroundSelection:=True Field EditorShowParamsHint:=True + Field EditorUseSpacesAsTabs:=False + Field EditorTabSize:=4 + Field EditorRemoveLinesTrailing:=False ' Field SourceSortByType:=True Field SourceShowInherited:=False @@ -58,17 +55,6 @@ Class PrefsInstance Method LoadState( json:JsonObject ) - If json.Contains( "irc" ) - - Local j2:=json["irc"].ToObject() - IrcNickname=Json_GetString( j2,"nickname",IrcNickname ) - IrcServer=Json_GetString( j2,"server",IrcServer ) - IrcPort=Json_GetInt( j2,"port",IrcPort ) - IrcRooms=Json_GetString( j2,"rooms",IrcRooms ) - IrcConnect=Json_GetBool( j2,"connect",IrcConnect ) - - Endif - If json.Contains( "main" ) Local j2:=json["main"].ToObject() @@ -108,6 +94,9 @@ Class PrefsInstance EditorAutoPairs=Json_GetBool( j2,"autoPairs",EditorAutoPairs ) EditorSurroundSelection=Json_GetBool( j2,"surroundSelection",EditorSurroundSelection ) EditorShowParamsHint=Json_GetBool( j2,"showParamsHint",EditorShowParamsHint ) + EditorUseSpacesAsTabs=Json_GetBool( j2,"useSpacesAsTabs",EditorUseSpacesAsTabs ) + EditorTabSize=Json_GetInt( j2,"tabSize",EditorTabSize ) + EditorRemoveLinesTrailing=Json_GetBool( j2,"removeLinesTrailing",EditorRemoveLinesTrailing ) Endif @@ -135,14 +124,6 @@ Class PrefsInstance j["singleClickExpanding"]=New JsonBool( MainProjectSingleClickExpanding ) j["placeDocsAtBegin"]=New JsonBool( MainPlaceDocsAtBegin ) - j=New JsonObject - json["irc"]=j - j["nickname"]=New JsonString( IrcNickname ) - j["server"]=New JsonString( IrcServer ) - j["port"]=New JsonNumber( IrcPort ) - j["rooms"]=New JsonString( IrcRooms ) - j["connect"]=New JsonBool( IrcConnect ) - j=New JsonObject json["completion"]=j j["enabled"]=New JsonBool( AcEnabled ) @@ -168,6 +149,9 @@ Class PrefsInstance j["autoPairs"]=New JsonBool( EditorAutoPairs ) j["surroundSelection"]=New JsonBool( EditorSurroundSelection ) j["showParamsHint"]=New JsonBool( EditorShowParamsHint ) + j["useSpacesAsTabs"]=New JsonBool( EditorUseSpacesAsTabs ) + j["tabSize"]=New JsonNumber( EditorTabSize ) + j["removeLinesTrailing"]=New JsonBool( EditorRemoveLinesTrailing ) j=New JsonObject json["source"]=j diff --git a/README.md b/README.md index a71467e8..e79c3d60 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Discuss on [forum page](http://monkeycoder.co.nz/forums/topic/ted2go-fork/). Support me if you like this project: * [PayPal](https://paypal.me/engor) * Payed downloading [from itch.io](https://nerobot.itch.io/ted2go) +* Become a patron [on Patreon.com](https://www.patreon.com/nerobot) ## Notes for contributors Please, take a look at code style. It based on original Ted2. diff --git a/Ted2.monkey2 b/Ted2.monkey2 index 8e9bf085..0f4ea53d 100644 --- a/Ted2.monkey2 +++ b/Ted2.monkey2 @@ -32,6 +32,7 @@ #Import "action/FindActions" #Import "action/ViewActions" #Import "action/WindowActions" +#Import "action/TabActions" #Import "dialog/FindDialog" #Import "dialog/PrefsDialog" @@ -80,6 +81,7 @@ #Import "utils/JsonUtils" #Import "utils/Utils" +#Import "utils/TextUtils" #Import "view/IRCView" #Import "view/CodeMapView" @@ -114,6 +116,7 @@ #Import "view/ViewExtensions" #Import "view/DockingViewExt" #Import "view/DraggableViewListener" +#Import "view/Undock" #Import "Tree" #Import "Tuple" @@ -135,7 +138,7 @@ Using sdl2.. Const MONKEY2_DOMAIN:="http://monkeycoder.co.nz" -Global AppTitle:="Ted2Go v2.8.1" +Global AppTitle:="Ted2Go v2.9" Function Main() diff --git a/action/FileActions.monkey2 b/action/FileActions.monkey2 index bfba116b..1b239de1 100644 --- a/action/FileActions.monkey2 +++ b/action/FileActions.monkey2 @@ -343,6 +343,8 @@ Class FileActions _prefsDialog=New PrefsDialog + ' not good place for subscribing, but it's simplier than proper one... + ' _prefsDialog.Apply+=Lambda() For Local d:=Eachin _docs.OpenDocuments @@ -353,6 +355,16 @@ Class FileActions MainWindow.OnPrefsChanged() End + ' analyze opened docs to show prompt "fix indentation?" + ' + _prefsDialog.TabulationChanged+=Lambda() + + For Local d:=Eachin _docs.OpenDocuments + Local codeDoc:=Cast( d ) + If codeDoc Then codeDoc.AnalyzeIndentation() + Next + End + _prefsDialog.ShowModal() End diff --git a/action/TabActions.monkey2 b/action/TabActions.monkey2 new file mode 100644 index 00000000..96ee20a2 --- /dev/null +++ b/action/TabActions.monkey2 @@ -0,0 +1,78 @@ +Namespace ted2go + + +Class TabActions + + Global tabs:TabViewExt[] + + Method New( _tabs:TabViewExt[] ) + + tabs=_tabs + End + + Function SwitchView( tabName:String ) + + For Local i:=Eachin tabs + Local _docks:=i.Tabs + For Local _tabb:=Eachin _docks + If _tabb.Text=tabName Then + If _tabb.Visible + _tabb.Visible=False + _tabb.View.Visible=False + 'make first tab as current + For Local firstCurrent:=Eachin _docks + If firstCurrent.Visible Then firstCurrent.CurrentHolder.MakeCurrent( firstCurrent.Text ); Exit + Next + Else + If( _tabb.View ) + _tabb.Visible=True + _tabb.View.Visible=True + _tabb.CurrentHolder.MakeCurrent( _tabb.Text ) + End + End + _tabb.CurrentHolder.Visible=_tabb.CurrentHolder.VisibleTabs + End + + Next + Next + End + + Function CreateMenu( view:MenuExt ) + + Local keynr:Int + Local tabNames:=New String[]( "Project","Debug","Source","Build","Output","Docs","Find","Chat" ) + For Local a:=Eachin tabNames + Local key:=Cast( 49+keynr ) + Local i:=view.AddAction( a ) + i.HotKey=key + i.HotKeyModifiers=Modifier.Alt + i.Triggered=Lambda() + SwitchView( a ) + End + keynr+=1 + Next + view.AddSeparator() + 'reset all tabs + Local _reset:=view.AddAction( "Reset" ) + _reset.Triggered=Lambda() + Reset() + End + End + + Function Reset() + + For Local i:=Eachin tabs + Local _docks:=i.Tabs + For Local _tabb:=Eachin _docks + If _tabb.View + _tabb.Visible=True + _tabb.View.Visible=True + _tabb.CurrentHolder.MakeCurrent( _tabb.Text ) + _tabb.CurrentHolder.Visible=_tabb.CurrentHolder.VisibleTabs + End + Next + Next + 'Undock Reset + UndockWindow.RestoreUndock() + End +End diff --git a/assets/aboutTed2Go.html b/assets/aboutTed2Go.html index e091b3ff..90d054e4 100644 --- a/assets/aboutTed2Go.html +++ b/assets/aboutTed2Go.html @@ -124,7 +124,7 @@

Third party

Special thanks

-

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.

+

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.

diff --git a/assets/fonts/SourceCodePro-Medium.otf b/assets/fonts/SourceCodePro-Medium.otf new file mode 100644 index 0000000000000000000000000000000000000000..1b42738262634e726e1459aa27255898e755edf0 GIT binary patch literal 145516 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 qfmM(!s3SNNa_b12VN+tH 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 QImo-z7}y+euC(HR02hem8UO$Q literal 0 HcmV?d00001 diff --git a/assets/newfiles/Simple_Mojo3d_App.monkey2 b/assets/newfiles/Simple_Mojo3d_App.monkey2 index b8440432..f307f971 100644 --- a/assets/newfiles/Simple_Mojo3d_App.monkey2 +++ b/assets/newfiles/Simple_Mojo3d_App.monkey2 @@ -8,63 +8,59 @@ Using std.. Using mojo.. Using mojo3d.. + Class MyWindow Extends Window Field _scene:Scene - Field _camera:Camera - Field _light:Light - Field _ground:Model - Field _donut:Model + Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable ) - + Super.New( title,width,height,flags ) + End + + Method OnCreateWindow() Override 'create (current) scene - ' _scene=New Scene - _scene.ShadowAlpha=.75 + _scene.ClearColor = New Color( 0.2, 0.6, 1.0 ) + _scene.AmbientLight = _scene.ClearColor * 0.25 + _scene.FogColor = _scene.ClearColor + _scene.FogFar = 1.0 + _scene.FogFar = 200.0 'create camera - ' _camera=New Camera( Self ) _camera.AddComponent() - _camera.Move( 0,10,-5 ) + _camera.Move( 0,2.5,-5 ) 'create light - ' _light=New Light _light.CastsShadow=True - _light.RotateX( 90 ) + _light.Rotate( 45, 45, 0 ) 'create ground - ' - Local groundBox:=New Boxf( -50,-1,-50,50,0,50 ) - Local groundMaterial:=New PbrMaterial( Color.Green ) + Local groundBox:=New Boxf( -100,-1,-100,100,0,100 ) + Local groundMaterial:=New PbrMaterial( Color.Lime ) _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial ) _ground.CastsShadow=False - 'create dount - ' - Local donutMaterial:=New PbrMaterial( Color.Brown ) + 'create donut + Local donutMaterial:=New PbrMaterial( Color.Red, 0.05, 0.2 ) _donut=Model.CreateTorus( 2,.5,48,24,donutMaterial ) - _donut.Move( 0,10,0 ) + _donut.Move( 0,2.5,0 ) End Method OnRender( canvas:Canvas ) Override - - RequestRender() + RequestRender() _donut.Rotate( .2,.4,.6 ) - _scene.Update() - _camera.Render( canvas ) - canvas.DrawText( "FPS="+App.FPS,0,0 ) End diff --git a/assets/themes/irc/blink.png b/assets/themes/irc/blink.png deleted file mode 100644 index 6494065e181438eaacefb8b3c5747f13ca9d3ae1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kCr=m0kcwN$2@(Py{{R2)C7>2% zIKhhf5R0jzw%Q6#je{&l(l=xPT92fbn$7%IM~oV0yA ReFe}Y22WQ%mvv4FO#po{C9D7d diff --git a/assets/themes/irc/notice.png b/assets/themes/irc/notice.png deleted file mode 100644 index b764212836b62ceffeeababb9773679880fc7fa1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kdrud~kcwN$2@)CsoJWsn{`>#` zzodYgn{bSw;j9@AKX}A=(-#!oFjdHI`dFCRQ2C8VYMqK&OGlVb*oGi+28O0JHX9Y^ Sp7RD8#o+1c=d#Wzp$P!64kdX2 diff --git a/assets/themes/ted2-default.json b/assets/themes/ted2-default.json index ceccbe0c..895d408f 100644 --- a/assets/themes/ted2-default.json +++ b/assets/themes/ted2-default.json @@ -13,7 +13,10 @@ "codemap-background": "transparent", "codemap-selection": "#48000000", "params-hint-common": "textview-color1", - "params-hint-selected": "textview-color4" + "params-hint-selected": "textview-color4", + "completion-list-selected": "content", + "completion-list-marked-bg": "#0fff", + "completion-list-marked-text": "textview-color4" }, "fonts":{ diff --git a/assets/themes/theme-hollow.json b/assets/themes/theme-hollow.json index b8c74d62..a2785b90 100644 --- a/assets/themes/theme-hollow.json +++ b/assets/themes/theme-hollow.json @@ -8,9 +8,9 @@ "normal":"Roboto-Medium.ttf,16", "fixedWidth":"RobotoMono-Medium.ttf,19", "small":"Roboto-Medium.ttf,14", - "editor":"MesloLGSDZ-Bold.ttf,19" + "editor":"SourceCodePro-Medium.otf,19" }, - + "colors":{ "border": "#121111", @@ -36,12 +36,12 @@ "textview-whitespaces":"bright", "textview-color0":"#FF00FF", //When is this used? - "textview-color1": "#EBDAB4", //identifiers - "textview-color2": "#FB4934", //keywords - "textview-color3": "#B8BB26", //strings - "textview-color4": "#B087D2", //numbers + "textview-color1": "#FFFBF2", //identifiers + "textview-color2": "#FA3E28", //keywords + "textview-color3": "#C4C722", //strings + "textview-color4": "#B77FE5", //numbers "textview-color5": "#6F665E", //comment - "textview-color6": "#FABD2F", //preproc + "textview-color6": "#FDBD28", //preproc "textview-color7": "#8EC07C", "windowClearColor":"darkest", diff --git a/assets/themes/theme-prime-base.json b/assets/themes/theme-prime-base.json index dbb7c99d..b510f517 100644 --- a/assets/themes/theme-prime-base.json +++ b/assets/themes/theme-prime-base.json @@ -7,9 +7,9 @@ "normal":"Roboto-Medium.ttf,16", "fixedWidth":"RobotoMono-Medium.ttf,18", "small":"Roboto-Medium.ttf,13", - "editor":"MesloLGSDZ-Bold.ttf,18" + "editor":"SourceCodePro-Medium.otf,19" }, - + "colors":{ // "accent": "", diff --git a/dialog/PrefsDialog.monkey2 b/dialog/PrefsDialog.monkey2 index d177da2e..77ac43f2 100644 --- a/dialog/PrefsDialog.monkey2 +++ b/dialog/PrefsDialog.monkey2 @@ -5,6 +5,7 @@ Namespace ted2go Class PrefsDialog Extends DialogExt Field Apply:Void() + Field TabulationChanged:Void() Method New() @@ -28,11 +29,6 @@ Class PrefsDialog Extends DialogExt docker=GetCompletionDock() tabView.AddTab( "AutoComplete",docker ) - ' Chat - ' - docker=GetChatDock() - tabView.AddTab( "IRC chat",docker ) - ' Live Templates ' docker=GetLiveTemplatesDock() @@ -49,7 +45,14 @@ Class PrefsDialog Extends DialogExt _acShowAfter.Activated+=_acShowAfter.MakeKeyView - Deactivated+=MainWindow.UpdateKeyView + Deactivated+=Lambda() + MainWindow.UpdateKeyView() + _lastTab=tabView.CurrentIndex + End + + OnShow+=Lambda() + tabView.CurrentIndex=_lastTab + End MinSize=New Vec2i( 550,500 ) MaxSize=New Vec2i( 550,600 ) @@ -80,6 +83,9 @@ Class PrefsDialog Extends DialogExt Field _editorAutoPairs:CheckButton Field _editorSurround:CheckButton Field _editorShowParamsHint:CheckButton + Field _editorUseSpacesAsTabs:CheckButton + Field _editorTabSize:TextFieldExt + Field _editorRemoveLinesTrailing:CheckButton Field _mainToolBarVisible:CheckButton Field _mainProjectIcons:CheckButton @@ -97,6 +103,9 @@ Class PrefsDialog Extends DialogExt Field _codeView:Ted2CodeTextView Field _treeView:TreeViewExt + Global _lastTab:Int + + Method OnApply() Prefs.AcEnabled=_acEnabled.Checked @@ -125,23 +134,25 @@ Class PrefsDialog Extends DialogExt Prefs.EditorAutoPairs=_editorAutoPairs.Checked Prefs.EditorSurroundSelection=_editorSurround.Checked Prefs.EditorShowParamsHint=_editorShowParamsHint.Checked + Local useSpaces:=Prefs.EditorUseSpacesAsTabs ' store + Prefs.EditorUseSpacesAsTabs=_editorUseSpacesAsTabs.Checked + size=_editorTabSize.Text.Trim() + If Not size Then size="4" 'default + Prefs.EditorTabSize=Clamp( Int(size),1,16 ) + Prefs.EditorRemoveLinesTrailing=_editorRemoveLinesTrailing.Checked Prefs.MainToolBarVisible=_mainToolBarVisible.Checked Prefs.MainProjectIcons=_mainProjectIcons.Checked Prefs.MainProjectSingleClickExpanding=_mainProjectSingleClickExpanding.Checked Prefs.MainPlaceDocsAtBegin=_mainPlaceDocsAtBegin.Checked - Prefs.IrcNickname=_chatNick.Text - Prefs.IrcServer=_chatServer.Text - Prefs.IrcPort=Int(_chatPort.Text) - Prefs.IrcRooms=_chatRooms.Text - Prefs.IrcConnect=_chatAutoConnect.Checked - App.ThemeChanged() Hide() Apply() + If Prefs.EditorUseSpacesAsTabs<>useSpaces Then TabulationChanged() + Prefs.SaveLocalState() LiveTemplates.Save() @@ -188,7 +199,7 @@ Class PrefsDialog Extends DialogExt Local docker:=New DockingView Local monkeyPathDock:=New DockingView - monkeyPathDock.AddView( New Label( "Monkey2 root folder" ),"left" ) + monkeyPathDock.AddView( New Label( "Monkey2 root folder:" ),"left" ) monkeyPathDock.AddView( _monkeyRootPath,"left" ) monkeyPathDock.AddView( btnChooseMonkeyPath,"left" ) @@ -234,6 +245,13 @@ Class PrefsDialog Extends DialogExt _editorShowParamsHint=New CheckButton( "Show parameters hint" ) _editorShowParamsHint.Checked=Prefs.EditorShowParamsHint + _editorUseSpacesAsTabs=New CheckButton( "Use spaces" ) + _editorUseSpacesAsTabs.Checked=Prefs.EditorUseSpacesAsTabs + _editorTabSize=New TextFieldExt( ""+Prefs.EditorTabSize ) + + _editorRemoveLinesTrailing=New CheckButton( "Remove whitespaced trailings on saving" ) + _editorRemoveLinesTrailing.Checked=Prefs.EditorRemoveLinesTrailing + Local path:=Prefs.EditorFontPath If Not path Then path=_defaultFont _editorFontPath=New TextFieldExt( "" ) @@ -269,12 +287,18 @@ Class PrefsDialog Extends DialogExt Local btnResetFont:=New PushButton( resetFont ) Local font:=New DockingView - font.AddView( New Label( "Font" ),"left" ) + font.AddView( New Label( "Font:" ),"left" ) font.AddView( _editorFontPath,"left" ) font.AddView( _editorFontSize,"left","45" ) font.AddView( btnChooseFont,"left" ) font.AddView( btnResetFont,"left" ) + Local tabs:=New DockingView + tabs.AddView( New Label( "Tab size:" ),"left" ) + _editorTabSize.MaxSize=New Vec2i( 100,100 ) + tabs.AddView( _editorTabSize,"left" ) + tabs.AddView( _editorUseSpacesAsTabs,"left" ) + Local docker:=New DockingView docker.AddView( New Label( " " ),"top" ) docker.AddView( _editorToolBarVisible,"top" ) @@ -287,8 +311,11 @@ Class PrefsDialog Extends DialogExt docker.AddView( _editorAutoPairs,"top" ) docker.AddView( _editorSurround,"top" ) docker.AddView( _editorShowParamsHint,"top" ) + docker.AddView( _editorRemoveLinesTrailing,"top" ) + docker.AddView( tabs,"top" ) docker.AddView( New Label( " " ),"top" ) + Return docker End @@ -340,33 +367,6 @@ Class PrefsDialog Extends DialogExt Return docker End - Method GetChatDock:DockingView() - - Local chatTable:=New TableView( 2,6 ) - _chatNick=New TextFieldExt( Prefs.IrcNickname ) - _chatServer=New TextFieldExt( Prefs.IrcServer ) - _chatPort=New TextFieldExt( ""+Prefs.IrcPort ) - _chatRooms=New TextFieldExt( Prefs.IrcRooms ) - _chatAutoConnect=New CheckButton( "Auto connect at start" ) - _chatAutoConnect.Checked=Prefs.IrcConnect - chatTable[0,0]=New Label( "Nickname" ) - chatTable[1,0]=_chatNick - chatTable[0,1]=New Label( "Server" ) - chatTable[1,1]=_chatServer - chatTable[0,2]=New Label( "Port" ) - chatTable[1,2]=_chatPort - chatTable[0,3]=New Label( "Rooms" ) - chatTable[1,3]=_chatRooms - chatTable[0,4]=_chatAutoConnect - chatTable[0,5]=New Label( "" ) 'bottom padding hack - - Local docker:=New DockingView - docker.AddView( New Label( " " ),"top" ) - docker.AddView( chatTable,"top" ) - - Return docker - End - Method GetLiveTemplatesDock:DockingView() Local treeDock:=New DockingView diff --git a/document/CodeDocument.monkey2 b/document/CodeDocument.monkey2 index 22c45a0b..f6d2f834 100644 --- a/document/CodeDocument.monkey2 +++ b/document/CodeDocument.monkey2 @@ -157,7 +157,8 @@ Class CodeDocumentView Extends Ted2CodeTextView Local indent:=Utils.GetIndent( s ) Local indentStr:=(indent > 0) ? s.Slice( 0, indent ) Else "" If indent > 0 Then s=s.Slice(indent) - Local x:=RenderStyle.Font.TextWidth( indentStr )*TabStop + indentStr=indentStr.Replace( "~t"," ".Dup(Prefs.EditorTabSize) ) + Local x:=RenderStyle.Font.TextWidth( indentStr ) Local w:=RenderStyle.Font.TextWidth( s ) DrawCurvedLine( canvas,x,x+w,(err.line+1)*LineHeight ) Next @@ -198,6 +199,53 @@ Class CodeDocumentView Extends Ted2CodeTextView ' Endif ' #Endif + Case Key.D + + Local ok:=ctrl + #If __TARGET__="macos" + ok=ok And shift + #Endif + + If ok ' duplicate line or selection + + Local cur:=Cursor,anc:=Anchor + If cur=anc ' duplicate whole line + + Local pos:=PosInLineAtCursor + Local line:=Document.FindLine( cur ) + Local s:=LineTextAtCursor + Local ends:=Document.EndOfLine( line ) + ReplaceText( ends,ends,"~n"+s ) + pos=pos+StartOfLineAtCursor + SelectText( pos,pos ) + + Else ' duplicate selection + + Local min:=Min( Cursor,Anchor ) + Local max:=Max( Cursor,Anchor ) + Local selLen:=max-min + Local s:=SelectedText + Local atEnd:=(max=Document.EndOfLine( Document.FindLine( max ) )) + If atEnd + Local minLine:=Document.FindLine( min ) + Local s0:=Document.GetLine( minLine ) + Local pos:=min-Document.StartOfLine( minLine ) + Local indent:=Min( GetIndent( s0 ),pos ) + Local indentStr:=(indent>0) ? s0.Slice( 0,indent ) Else "" + s="~n"+indentStr+s + selLen+=indentStr.Length + Endif + SelectText( max,max ) + ReplaceText( s ) + Local pos:=max+Int(atEnd) + SelectText( pos,pos+selLen ) + + Endif + + Return + + Endif + Case Key.Space If ctrl Return @@ -219,21 +267,40 @@ Class CodeDocumentView Extends Ted2CodeTextView Else -' #If __TARGET__="macos" -' If menu -' DeleteToBegin() -' Elseif ctrl -' DeleteWordBeforeCursor() -' Endif -' #Else -' If ctrl -' If shift -' DeleteToBegin() -' Else -' DeleteWordBeforeCursor() -' Endif -' Endif -' #Endif + ' remove all indent spaces by single press of Backspace + If Cursor=Anchor And Prefs.EditorUseSpacesAsTabs + + Local color:=Document.Colors[Cursor] + + ' skip comments and strings areas + If color<>Highlighter.COLOR_COMMENT And color<>Highlighter.COLOR_STRING + + Local posInLine:=PosInLineAtCursor + Local line:=LineTextAtCursor + + ' check for spaces only, tab will be removed by super class + If posInLine>0 And line[posInLine-1]=Chars.SPACE + + Local pos:=GetPosInLineAtCursorCheckingTabSize() + Local canRemoveCount:=(pos Mod Prefs.EditorTabSize) + If canRemoveCount=0 Then canRemoveCount=Prefs.EditorTabSize + Local i:=posInLine-1,counter:=canRemoveCount + + While counter>0 + If line[i]<>Chars.SPACE Exit + counter-=1 + i-=1 + Wend + If counter>1 Then counter+=1 ' don't remove space nearest to another char (is it correct?) + canRemoveCount-=counter + SelectText( Cursor,Cursor-canRemoveCount ) + + Endif + + Endif + + Endif + Endif @@ -313,7 +380,7 @@ Class CodeDocumentView Extends Ted2CodeTextView Case Key.Enter,Key.KeypadEnter 'auto indent - + Local line:=CursorLine Local text:=Document.GetLine( line ) Local indent:=GetIndent( text ) @@ -322,19 +389,23 @@ Class CodeDocumentView Extends Ted2CodeTextView 'in this case GetLine return 2 lines, and if they empty 'then we get double indent 'need to fix inside mojox - + Local beforeIndent:=(posInLine<=indent) - + If indent > posInLine Then indent=posInLine - + Local s:=(indent ? text.Slice( 0,indent ) Else "") - + + If Prefs.EditorUseSpacesAsTabs + s=s.Replace( "~t",TabStr ) + Endif + ' auto indentation If Prefs.EditorAutoIndent And Not beforeIndent text=text.Trim().ToLower() If text.StartsWith( "if" ) If Not Utils.BatchContains( text,_arrIf,True ) - s="~t"+s + s=TabStr+s Endif Elseif Utils.BatchStartsWith( text,_arrAddonIndents,True ) @@ -345,7 +416,7 @@ Class CodeDocumentView Extends Ted2CodeTextView If scope And scope.Kind=CodeItemKind.Interface_ ' nothing Else - s="~t"+s + s=TabStr+s Endif Endif Endif @@ -414,68 +485,82 @@ Class CodeDocumentView Extends Ted2CodeTextView ' live templates by tab! Local ident:=IdentBeforeCursor() - If InsertLiveTemplate( ident ) Return + If InsertLiveTemplate( ident ) Return ' exit method + + Endif + + If Cursor = Anchor And Not shift + + ' usual tab behaviour - insert tab or spaced-equivalent-of-tab + InsertTabulation() + + Else ' tab/untab selection - ' usual tab behaviour - If Not shift - ReplaceText( "~t" ) - Else - If Cursor > 0 And Document.Text[Cursor-1]=Chars.TAB - SelectText( Cursor-1,Cursor ) - ReplaceText( "" ) - Endif - Endif - - Else 'block tab/untab - Local minPos:=Min( Cursor,Anchor ) Local maxPos:=Max( Cursor,Anchor ) Local min:=Document.FindLine( minPos ) Local max:=Document.FindLine( maxPos ) - + ' if we are at the beginning of bottom line - skip it Local strt:=Document.StartOfLine( max ) If maxPos = strt max-=1 Endif - + Local lines:=New StringStack - + For Local i:=min To max lines.Push( Document.GetLine( i ) ) Next - + Local go:=True Local shiftFirst:=0,shiftLast:=0 - + Local tabStr:=TabStr + If shift - + Local changes:=0 For Local i:=0 Until lines.Length - If lines[i].StartsWith( "~t" ) + + If lines[i].StartsWith( tabStr ) ' try to remove tab or spaces + + lines[i]=lines[i].Slice( tabStr.Length )+"~n" + changes+=1 + If i=0 Then shiftFirst=-tabStr.Length + If i=lines.Length-1 Then shiftLast=-tabStr.Length + + Elseif tabStr<>"~t" And lines[i].StartsWith( "~t" ) ' for spaces-mode also try to remove tabs (mixed indentation) + lines[i]=lines[i].Slice( 1 )+"~n" changes+=1 If i=0 Then shiftFirst=-1 - if i=lines.Length-1 Then shiftLast=-1 + If i=lines.Length-1 Then shiftLast=-1 + Else + lines[i]+="~n" + Endif Next go=(changes > 0) + Else - shiftFirst=1 - shiftLast=1 + + shiftFirst=tabStr.Length + shiftLast=tabStr.Length For Local i:=0 Until lines.Length - lines[i]="~t"+lines[i]+"~n" + lines[i]=tabStr+lines[i]+"~n" Next + Endif If go + Local minStart:=Document.StartOfLine( min ) Local maxStart:=Document.StartOfLine( max ) Local maxEnd:=Document.EndOfLine( max ) - + Local p1:=minPos+shiftFirst 'absolute pos Local p2:=maxPos-maxStart+shiftLast 'pos in line SelectText( minStart,maxEnd+1 ) @@ -485,7 +570,7 @@ Class CodeDocumentView Extends Ted2CodeTextView p1=Max( p1,Document.StartOfLine( min ) ) SelectText( p1,p2 ) Endif - + Endif CheckFormat( event ) @@ -711,7 +796,8 @@ Class CodeDocumentView Extends Ted2CodeTextView Local indent:=Utils.GetIndent( s ) Local indentStr:=(indent > 0) ? s.Slice( 0, indent ) Else "" If indent > 0 Then s=s.Slice(indent) - Local x:=RenderStyle.Font.TextWidth( indentStr )*TabStop + indentStr=indentStr.Replace( "~t"," ".Dup(Prefs.EditorTabSize) ) + Local x:=RenderStyle.Font.TextWidth( indentStr ) Local w:=RenderStyle.Font.TextWidth( s ) If event.Location.x >= x And event.Location.x <= x+w Local s:=_doc.GetStringError( line ) @@ -793,7 +879,7 @@ Class CodeDocument Extends Ted2Document ' Editor _codeView=New CodeDocumentView( Self ) - _codeView.LineChanged += OnLineChanged + _codeView.LineNumChanged += OnLineChanged _doc=_codeView.Document @@ -844,10 +930,41 @@ Class CodeDocument Extends Ted2Document MainWindow.GotoCodePosition( nav.filePath,nav.pos ) End - ' update -' Monkey2Parser.OnDoneParseModules+=Lambda( deltaMs:Int ) -' UpdateCodeTree() -' End + ' fix indentation panel + ' + _fixIndentView=New DockingView + _fixIndentHint=New Label + _fixIndentButton=New Button( "Yes" ) + _fixIndentButton.Clicked=Lambda() + ' store cursor position + Local line:=_codeView.LineNumAtCursor + Local posInLine:=_codeView.PosInLineAtCursor + Local scroll:=_codeView.Scroll + ' get fixed text + Local text:=IndentationHelper.FixIndentation( _codeView.Document ) + ' replacing allow us to use undo + _codeView.SelectAll() + _codeView.ReplaceText( text ) + ' restore cursor + Local cursor:=_codeView.Document.StartOfLine( line )+posInLine + _codeView.SelectText( cursor,cursor ) + _codeView.Scroll=scroll + ' + _fixIndentView.Visible=False + End + Local fixIndentCancel:=New Button( "No" ) + fixIndentCancel.Clicked=Lambda() + + _fixIndentView.Visible=False + End + _fixIndentView.AddView( New Label( " " ),"right" ) + _fixIndentView.AddView( fixIndentCancel,"right" ) + _fixIndentView.AddView( New Label( " " ),"right" ) + _fixIndentView.AddView( _fixIndentButton,"right" ) + _fixIndentView.AddView( New Label( " " ),"right" ) + _fixIndentView.AddView( _fixIndentHint,"right" ) + _fixIndentView.Visible=False + _content.AddView( _fixIndentView,"bottom" ) ArrangeElements() End @@ -903,7 +1020,6 @@ Class CodeDocument Extends Ted2Document _browserView.AddView( bar,"top" ) - _treeView=New CodeTreeView _browserView.ContentView=_treeView @@ -922,6 +1038,37 @@ Class CodeDocument Extends Ted2Document Return _browserView End + Method AnalyzeIndentation() + + Local text:=_codeView.Text + If Not text Return + + Local useSpaces:=Prefs.EditorUseSpacesAsTabs + Local hint:="" + Local type:=IndentationHelper.AnalyzeIndentation( text ) + + Select type + Case IndentationHelper.Type.Spaces + If Not useSpaces Then hint="There is a spaced indentation found." + + Case IndentationHelper.Type.Tabs + If useSpaces Then hint="There is a tabbed indentation found." + + Case IndentationHelper.Type.Mixed + hint="There is a mixed indentation found." + + End + + If hint + Local quest:=Prefs.EditorUseSpacesAsTabs ? "Replace with spaces?" Else "Replace with tabs?" + _fixIndentHint.Text=hint+" "+quest + _fixIndentView.Visible=True + Else + _fixIndentView.Visible=False + Endif + + End + ' not multipurpose method, need to move into plugin Method PrepareForInsert:String( ident:String,text:String,addSpace:Bool,textLine:String,cursorPosInLine:Int,item:CodeItem ) @@ -1135,7 +1282,7 @@ Class CodeDocument Extends Ted2Document Method ShowAutocomplete( ident:String="",byCtrlSpace:Bool=False ) - If ident = "" Then ident=_codeView.IdentBeforeCursor() + If Not ident Then ident=_codeView.IdentBeforeCursor() Print "ident: "+ident @@ -1241,6 +1388,9 @@ Class CodeDocument Extends Ted2Document Field _codeView:CodeDocumentView Field _treeView:CodeTreeView Field _browserView:DockingView + Field _fixIndentView:DockingView + Field _fixIndentHint:Label + Field _fixIndentButton:Button Field _errors:=New Stack Field _errMap:=New IntMap @@ -1367,7 +1517,15 @@ Class CodeDocument Extends Ted2Document 'ResetErrors() - Local text:=_doc.Text + Local text:="" + + If Prefs.EditorRemoveLinesTrailing + Local linesChanged:=0 + text=RemoveWhitespacedTrailings( _doc,Varptr linesChanged ) + If linesChanged>0 Then _codeView.SetTextSilent( text ) ' set text saving cursor/anchor/scroll + Else + text=_doc.Text + Endif Local ok:=stringio.SaveString( text,Path ) @@ -1562,8 +1720,8 @@ Class CodeDocument Extends Ted2Document j-=1 Wend j+=1 - Local pair:=GetIndentBeforePos_Mx2( line,j,True ) - Local ident:=pair.Item1 + Local info:=GetIndentBeforePos_Mx2( line,j,True ) + Local ident:=info.ident 'Print "ident: "+ident'+", paramIndex: "+paramIndex+", isNew: "+isNew If ident part=New ParamsPart @@ -1573,7 +1731,7 @@ Class CodeDocument Extends Ted2Document part.ranges.Add( New Vec2i( i,0 ) ) ' check for 'New' keyword - j=pair.Item2-1 'where ident starts + j=info.pos-1 'where ident starts While j>=0 And line[j]<=32 j-=1 Wend diff --git a/document/Monkey2Document.monkey2 b/document/Monkey2Document.monkey2 index 0587e8e7..daac175b 100644 --- a/document/Monkey2Document.monkey2 +++ b/document/Monkey2Document.monkey2 @@ -354,35 +354,11 @@ Class Monkey2DocumentView Extends Ted2TextView Local ident:=IdentNearestCursor() If ident MainWindow.ShowQuickHelp( ident ) - - Case Key.F2 - New Fiber( Lambda() - - Local cmd:="~q"+MainWindow.Mx2ccPath+"~q makeapp -parse -geninfo ~q"+_doc.Path+"~q" - - Local str:=LoadString( "process::"+cmd ) - Local i:=str.Find( "{" ) - If i=-1 Return - str=str.Slice( i ) - - Local jobj:=JsonObject.Parse( str ) - If Not jobj Return - - Local jsonTree:=New JsonTreeView( jobj ) - - Local dialog:=New Dialog( "ParseInfo",jsonTree ) - dialog.AddAction( "Close" ).Triggered=dialog.Close - dialog.MinSize=New Vec2i( 512,600 ) - - dialog.Open() - - End ) - Case Key.Tab,Key.Enter If _typing Capitalize( False ) - + Case Key.Left If _typing @@ -392,7 +368,7 @@ Class Monkey2DocumentView Extends Ted2TextView Capitalize( True ) Endif Endif - + Case Key.Right If _typing @@ -402,7 +378,7 @@ Class Monkey2DocumentView Extends Ted2TextView Capitalize( True ) Endif Endif - + Case Key.Up,Key.Down Capitalize( True ) 'in cased we missed anything... diff --git a/document/SceneDocument.monkey2 b/document/SceneDocument.monkey2 index 874f2ba8..57dae068 100644 --- a/document/SceneDocument.monkey2 +++ b/document/SceneDocument.monkey2 @@ -109,7 +109,7 @@ Class SceneDocument Extends Ted2Document _camera.Near=.01 _camera.Far=10 _camera.MoveZ( -2.5 ) - + _light=New Light _light.RotateX( Pi/2 ) diff --git a/eventfilter/Monkey2KeyEventFilter.monkey2 b/eventfilter/Monkey2KeyEventFilter.monkey2 index ed63c22b..523f9abb 100644 --- a/eventfilter/Monkey2KeyEventFilter.monkey2 +++ b/eventfilter/Monkey2KeyEventFilter.monkey2 @@ -31,6 +31,33 @@ Class Monkey2KeyEventFilter Extends TextViewKeyEventFilter MainWindow.GotoDeclaration() event.Eat() + Case Key.F10 + + Print "works" + Local doc:=MainWindow.DocsManager.CurrentDocument + If Not doc Return + + New Fiber( Lambda() + + Local cmd:="~q"+MainWindow.Mx2ccPath+"~q makeapp -parse -geninfo ~q"+doc.Path+"~q" + + Local str:=LoadString( "process::"+cmd ) + Local i:=str.Find( "{" ) + If i=-1 Return + str=str.Slice( i ) + + Local jobj:=JsonObject.Parse( str ) + If Not jobj Return + + Local jsonTree:=New JsonTreeView( jobj ) + + Local dialog:=New Dialog( "ParseInfo",jsonTree ) + dialog.AddAction( "Close" ).Triggered=dialog.Close + dialog.MinSize=New Vec2i( 512,600 ) + + dialog.Open() + + End ) End diff --git a/parser/CodeItem.monkey2 b/parser/CodeItem.monkey2 index 5255df5f..edbbc0e1 100644 --- a/parser/CodeItem.monkey2 +++ b/parser/CodeItem.monkey2 @@ -427,6 +427,7 @@ Struct CodeType Field expr:String Field args:CodeType[] Field isPointer:Bool + Field isArray:Bool Property ident:String() Return _ident @@ -458,6 +459,7 @@ Struct CodeType Endif If isPointer Then _str+=" Ptr" + If isArray Then _str+="[]" Return _str End diff --git a/parser/Monkey2Parser.monkey2 b/parser/Monkey2Parser.monkey2 index ec139c61..03e7a9be 100644 --- a/parser/Monkey2Parser.monkey2 +++ b/parser/Monkey2Parser.monkey2 @@ -855,6 +855,8 @@ Class Monkey2Parser Extends CodeParserPlugin Method ParseModules() + 'Return + Local dd:=LoadDir( _modsPath ) ' pop up some modules to parse them first @@ -911,6 +913,10 @@ Class Monkey2Parser Extends CodeParserPlugin Local t:=ParseMember( jobj ) t.kind=kind2 Return t + Default + If init.Contains( "type" ) + Return ParseType( init["type"].ToObject() ) + Endif End Endif ' not found @@ -924,6 +930,7 @@ Class Monkey2Parser Extends CodeParserPlugin Local t:=New CodeType t.kind=kind t.ident=type["ident"].ToString() + t.isArray=type.Contains( "is-array" ) Return t Case "functype" @@ -1043,12 +1050,25 @@ Class Monkey2Parser Extends CodeParserPlugin Return result End - Method GetJobjType:Map( jobj:Map ) + Method ProcessArrayType( child:StringMap,parent:StringMap ) + + If parent.Contains( "kind" ) And parent["kind"].ToString()="arraytype" + child["is-array"]=New JsonBool( True ) + Endif + End + + Method GetJobjType:StringMap( jobj:Map ) Local type:Map = Null If jobj.Contains( "type" ) type=jobj["type"].ToObject() + ProcessArrayType( type,type ) + While type.Contains( "type" ) + Local t:=type + type=type["type"].ToObject() + ProcessArrayType( type,t ) + Wend Elseif jobj.Contains( "getFunc" ) type=jobj["getFunc"].ToObject()["type"].ToObject() ' properties have retType @@ -1057,9 +1077,13 @@ Class Monkey2Parser Extends CodeParserPlugin Endif Elseif jobj.Contains( "init" ) Local init:=jobj["init"].ToObject() - if init.Contains( "type" ) - type=init["type"].ToObject() - Endif + Local t:=init + While t.Contains( "type" ) + Local par:=type + t=t["type"].ToObject() + type=t + If par Then ProcessArrayType( type,par ) + Wend Endif Return type @@ -1338,30 +1362,6 @@ Class Monkey2Parser Extends CodeParserPlugin End -Struct Chars - - Const SINGLE_QUOTE:="'"[0] '39 - Const DOUBLE_QUOTE:="~q"[0] '34 - Const COMMA:=","[0] '44 - Const SEMICOLON:=";"[0] - Const DOT:="."[0] '46 - Const EQUALS:="="[0] '61 - Const LESS_BRACKET:="<"[0] '60 - Const MORE_BRACKET:=">"[0] '62 - Const OPENED_SQUARE_BRACKET:="["[0] '91 - Const CLOSED_SQUARE_BRACKET:="]"[0] '93 - Const OPENED_ROUND_BRACKET:="("[0] '40 - Const CLOSED_ROUND_BRACKET:=")"[0] '41 - Const DIGIT_0:="0"[0] '48 - Const DIGIT_9:="9"[0] '57 - Const AT:="@"[0] '64 - Const GRID:="#"[0] '35 - Const TAB:="~t"[0] '9 - Const SPACE:=" "[0] '32 - -End - - Class NSpace Field parent:NSpace diff --git a/testing/ParserTests.monkey2 b/testing/ParserTests.monkey2 index 8559fd50..762d51d1 100644 --- a/testing/ParserTests.monkey2 +++ b/testing/ParserTests.monkey2 @@ -64,8 +64,8 @@ End Global boo:=True Global multi:="Hello, - multiline - world!" + multiline + world!" Global vector:Vec2f Global globList:List diff --git a/utils/TextUtils.monkey2 b/utils/TextUtils.monkey2 new file mode 100644 index 00000000..41bf95b2 --- /dev/null +++ b/utils/TextUtils.monkey2 @@ -0,0 +1,65 @@ + +Namespace ted2go + + +Class TextUtils Final + + Function GetSpacesForTabEquivalent:String() + + If Prefs.EditorTabSize<>_storedTabSize + _storedTabSize=Prefs.EditorTabSize + _spacesForTab=" ".Dup( _storedTabSize ) + Endif + + Return _spacesForTab + End + + Function GetPosInLineCheckingTabSize:Int( line:String,posInLine:Int,tabSize:Int ) + + Local pos:=0 + For Local i:=0 Until posInLine + If line[i]=Chars.TAB + Local offset:=(pos Mod tabSize) + pos+=tabSize-offset + Else + pos+=1 + Endif + Next + + Return pos + End + + + Private + + Global _storedTabSize:=0,_spacesForTab:String + + Method New() + End + +End + + +Struct Chars + + Const SINGLE_QUOTE:="'"[0] '39 + Const DOUBLE_QUOTE:="~q"[0] '34 + Const COMMA:=","[0] '44 + Const SEMICOLON:=";"[0] + Const DOT:="."[0] '46 + Const EQUALS:="="[0] '61 + Const LESS_BRACKET:="<"[0] '60 + Const MORE_BRACKET:=">"[0] '62 + Const OPENED_SQUARE_BRACKET:="["[0] '91 + Const CLOSED_SQUARE_BRACKET:="]"[0] '93 + Const OPENED_ROUND_BRACKET:="("[0] '40 + Const CLOSED_ROUND_BRACKET:=")"[0] '41 + Const DIGIT_0:="0"[0] '48 + Const DIGIT_9:="9"[0] '57 + Const AT:="@"[0] '64 + Const GRID:="#"[0] '35 + Const TAB:="~t"[0] '9 + Const SPACE:=" "[0] '32 + Const NEW_LINE:="~n"[0] '10 + +End diff --git a/utils/Utils.monkey2 b/utils/Utils.monkey2 index 0679049d..8c3f58d0 100644 --- a/utils/Utils.monkey2 +++ b/utils/Utils.monkey2 @@ -37,7 +37,7 @@ Function GetCaseSensitivePath:String( path:String ) #Endif End -Class Utils +Class Utils Final Function ArrayContains:Bool( arr:T[],value:T ) If Not arr Return False @@ -63,13 +63,23 @@ Class Utils End Function GetIndent:Int( line:String ) + Local len:=line.Length,n:=0 - While n < len And line[n] <= 32 + While n < len And line[n] <= Chars.SPACE n+=1 Wend Return n End + + Function GetIndentAsSpaces:Int( line:String ) + Local len:=line.Length,n:=0 + While n < len And line[n] <= Chars.SPACE + n+=(line[n]=Chars.TAB) ? Prefs.EditorTabSize Else 1 + Wend + Return n + End + Function GetIndentStr:String( line:String ) Local n:=GetIndent( line ) Return (n > 0) ? line.Slice( 0,n ) Else "" @@ -172,6 +182,9 @@ Class Utils Private + Global _storedTabSize:=0,_spacesForTab:String + + Method New() End @@ -341,14 +354,40 @@ Function StripStarting:String( text:String,starts:String ) Return text.StartsWith( starts ) ? text.Slice( starts.Length ) Else text End +' +Struct IdentInfo + + Field pos:Int + Field ident:String + Field isArray:Bool + +End + #Rem monkeydocs Return ident and position in line where ident starts #End -Function GetIndentBeforePos_Mx2:Tuple2( line:String,pos:Int,withDots:Bool ) +Function GetIndentBeforePos_Mx2:IdentInfo( line:String,pos:Int,withDots:Bool ) Local n:=pos-1 While n >= 0 + ' array syntax: a[i] + If line[n]=Chars.CLOSED_SQUARE_BRACKET + Local cnt:=1 + n-=1 + While n >= 0 + If line[n]=Chars.CLOSED_SQUARE_BRACKET + cnt+=1 + Elseif line[n]=Chars.OPENED_SQUARE_BRACKET + cnt-=1 + If cnt=0 Exit + Endif + n-=1 + Wend + n-=1 + If n<0 Exit + Endif + Local more:=(line[n]=Chars.MORE_BRACKET) If line[n] = Chars.DOT Or more ' . | ?. | -> @@ -369,11 +408,35 @@ Function GetIndentBeforePos_Mx2:Tuple2( line:String,pos:Int,withDots Local s:="" Local starts:=-1 + Local arr:=False If n < pos starts=n s=line.Slice( n,pos ).Replace( "?.","." ).Replace( "->","." ) + Local i:=s.FindLast( "." ) + arr=(i>0 And s[i-1]=Chars.CLOSED_SQUARE_BRACKET) ' [i]. + If s.Find( "[" )<>-1 + n=0 + Local s2:="",cnt:=0 + While n( s,starts ) + + Local info:=New IdentInfo + info.ident=s + info.pos=starts + info.isArray=arr + + Return info End Function IsPosInsideOfQuotes_Mx2:Bool( text:String,pos:Int ) diff --git a/view/AutocompleteView.monkey2 b/view/AutocompleteView.monkey2 index 39ce71c1..0393f0cd 100644 --- a/view/AutocompleteView.monkey2 +++ b/view/AutocompleteView.monkey2 @@ -28,12 +28,23 @@ Class AutocompleteListView Extends ListViewExt Field word:String 'word to select Method New( lineHeight:Int,maxLines:Int ) + Super.New( lineHeight,maxLines ) + + OnThemeChanged() End Protected + Method OnThemeChanged() Override + + Super.OnThemeChanged() + _selColor=App.Theme.GetColor( "completion-list-selected" ) + _markedBgColor=App.Theme.GetColor( "completion-list-marked-bg" ) + _markedTextColor=App.Theme.GetColor( "completion-list-marked-text" ) + End + Method DrawItem( item:ListViewItem,canvas:Canvas,x:Float,y:Float,handleX:Float=0,handleY:Float=0 ) Override canvas.Color=App.Theme.DefaultStyle.TextColor @@ -62,19 +73,21 @@ Class AutocompleteListView Extends ListViewExt index+=1 ch = index>=len ? -1 Else word[index] clr=canvas.Color - canvas.Color=_selColor + canvas.Color=_markedBgColor canvas.DrawRect( x,y-LineHeight*handleY,w,LineHeight ) + canvas.Color=_markedTextColor + canvas.DrawText( s,x,y,handleX,handleY ) canvas.Color=clr + Else + canvas.DrawText( s,x,y,handleX,handleY ) Endif - canvas.DrawText( s,x,y,handleX,handleY ) x+=w Next End - Private - Field _selColor:=New Color( .8,.8,.8,.1 ) + Field _markedBgColor:Color,_markedTextColor:Color End @@ -514,7 +527,7 @@ Class AutocompleteDialog Extends NoTitleDialog Next 'preprocessor 'need to load it like keywords - Local s:="#If ,#Rem,#End,#Endif,#Else,#Else If ,#Import ,monkeydoc,__TARGET__,__MOBILE_TARGET__,__DESKTOP_TARGET__,__HOSTOS__,__ARCH__,#Reflect " + Local s:="#If ,#Rem,#End,#Endif,#Else,#Else If ,#Import ,#Reflect ,monkeydoc,__TARGET__,__MOBILE_TARGET__,__DESKTOP_TARGET__,__WEB_TARGET__,__HOSTOS__,__ARCH__,__DEBUG__,__RELEASE__,__CONFIG__,__MAKEDOCS__" Local arr:=s.Split( "," ) For Local i:=Eachin arr list.Add( New ListViewItem( i ) ) diff --git a/view/CodeTextView.monkey2 b/view/CodeTextView.monkey2 index 12ef6962..6147b480 100644 --- a/view/CodeTextView.monkey2 +++ b/view/CodeTextView.monkey2 @@ -8,7 +8,7 @@ Class CodeTextView Extends TextView Field Keywords:IKeywords Field Highlighter:Highlighter - Field LineChanged:Void( prevLine:Int,newLine:Int ) + Field LineNumChanged:Void( prevLine:Int,newLine:Int ) Field TextChanged:Void() Method New() @@ -21,6 +21,12 @@ Class CodeTextView Extends TextView CursorMoved += OnCursorMoved Document.TextChanged += TextChanged + TabStop=Prefs.EditorTabSize + +' LineNumChanged+=Lambda( prevLine:Int,newLine:Int ) +' +' End + ' Document.LinesModified += Lambda( first:Int,removed:Int,inserted:Int ) ' @@ -203,8 +209,8 @@ Class CodeTextView Extends TextView Method IdentBeforeCursor:String( withDots:Bool=True ) - Local pair:=GetIndentBeforePos_Mx2( LineTextAtCursor,PosInLineAtCursor,withDots ) - Return pair.Item1 + Local info:=GetIndentBeforePos_Mx2( LineTextAtCursor,PosInLineAtCursor,withDots ) + Return info.ident End Property WordAtCursor:String() @@ -394,6 +400,22 @@ Class CodeTextView Extends TextView Return _extraSelStart>=0 End + Method SetTextSilent( text:String ) + + Local curLine:=LineNumAtCursor + Local ancLine:=LineNumAtAnchor + Local curPos:=PosInLineAtCursor + Local ancPos:=PosInLineAtAnchor + Local scroll:=Scroll + + Text=text + + SelectText( Document.StartOfLine( ancLine )+ancPos,Document.StartOfLine( curLine )+curPos ) + Scroll=scroll + + End + + Protected Method CheckFormat( event:KeyEvent ) @@ -536,6 +558,30 @@ Class CodeTextView Extends TextView SelectText( Cursor,Anchor ) End + Method GetPosInLineAtCursorCheckingTabSize:Int() + + Return TextUtils.GetPosInLineCheckingTabSize( LineTextAtCursor,PosInLineAtCursor,TabStop ) + End + + Method InsertTabulation() + + Local useSpaces:=Prefs.EditorUseSpacesAsTabs + Local tabSize:=Prefs.EditorTabSize + + If useSpaces ' use spaces + + Local pos:=GetPosInLineAtCursorCheckingTabSize() + Local chars:=(pos Mod tabSize) + ReplaceText( " ".Dup( tabSize-chars ) ) + + Else ' use tabs + + ReplaceText( "~t" ) + + Endif + + End + Method SmartCopySelected() ' here we strip indents from all lines - the same as in first-line indent @@ -699,50 +745,55 @@ Class CodeTextView Extends TextView Super.OnRenderContent( canvas,clip ) End + Property TabStr:String() + + Return Prefs.EditorUseSpacesAsTabs ? TextUtils.GetSpacesForTabEquivalent() Else "~t" + End + Method OnRenderLine( canvas:Canvas,line:Int ) Override Super.OnRenderLine( canvas,line ) ' draw whitespaces + ' If Not _showWhiteSpaces Return Local text:=Document.Text - Local colors:=Document.Colors - Local r:Recti Local start:=Document.StartOfLine( line ) + Local ending:=Document.EndOfLine( line ) + Local right:=0 + Local lineStr:=Document.GetLine( line ) + + canvas.Color=_whitespacesColor For Local word:=Eachin WordIterator.ForLine( Self,line ) - If text[word.Index]=9 ' tab - - Local ind:=word.Index-1 - Local cnt:=0 - ' ckeck tab width - While ind>=start - If text[ind]=9 Exit - cnt+=1 - ind-=1 - Wend - - cnt = cnt Mod TabStop - - canvas.Color=_whitespacesColor - - Local len:=word.Length - - r=word.Rect - Local x0:=r.Left,y0:=r.Top+1,y1:=y0+r.Height + Local atEnd:=(word.Index+word.Length=ending) + + If text[word.Index]=Chars.TAB Or (text[word.Index]=Chars.SPACE And (word.Length>=TabStop Or atEnd)) ' indent chars - Local xx:=x0 + (cnt=0 ? _tabw Else Float(TabStop-cnt)/Float(TabStop)*_tabw) + Local wordStr:=text.Slice( word.Index,word.Index+word.Length ) + wordStr=wordStr.Replace( "~t",TextUtils.GetSpacesForTabEquivalent() ) - Local after:=word.Index+len - If after < text.Length And text[after] > 32 Then len-=1 + Local i1:=word.Index-start + Local i2:=i1+word.Length + i1=TextUtils.GetPosInLineCheckingTabSize( lineStr,i1,TabStop ) + i2=TextUtils.GetPosInLineCheckingTabSize( lineStr,i2,TabStop ) + If atEnd Then i2+=1 - For Local i:=0 Until len - canvas.DrawLine( xx,y0,xx,y1 ) - xx+=_tabw + Local r:=word.Rect + Local x0:=right,y0:=r.Top+1,y1:=y0+r.Height + For Local i:=i1+1 Until i2 + If i Mod TabStop = 0 + Local dx:=Float(i-i1)*_charw + canvas.DrawLine( x0+dx,y0,x0+dx,y1 ) + Endif Next + Endif + + right=word.Rect.Right + Next End @@ -752,7 +803,8 @@ Class CodeTextView Extends TextView Super.OnValidateStyle() Local style:=RenderStyle - _tabw=style.Font.TextWidth( "X" )*TabStop + _charw=style.Font.TextWidth( "X" ) + _tabw=_charw*TabStop End @@ -761,7 +813,7 @@ Class CodeTextView Extends TextView Field _line:Int Field _whitespacesColor:Color Field _showWhiteSpaces:Bool - Field _tabw:Int + Field _tabw:Int,_charw:Int Field _overwriteMode:Bool Field _extraSelStart:Int=-1,_extraSelEnd:Int Field _extraSelColor:Color=Color.DarkGrey @@ -774,7 +826,7 @@ Class CodeTextView Extends TextView If line <> _line If _typing Then FormatLine( _line ) - LineChanged( _line,line ) + LineNumChanged( _line,line ) _line=line Endif @@ -828,3 +880,246 @@ Function FixNumpadKeys:Key( event:KeyEvent ) Endif Return key End + + +Function RemoveWhitespacedTrailings:String( doc:TextDocument,linesChanged:Int Ptr ) + + Local text:=doc.Text + Local numLines:=doc.NumLines + Local result:="" + Local index:=0,changes:=0 + + For Local line:=0 Until numLines + + Local start:=doc.StartOfLine( line ) + Local ends:=doc.EndOfLine( line ) + Local i:=ends-1 + + Local color:=doc.Colors[i] + If color=Highlighter.COLOR_STRING Or color=Highlighter.COLOR_COMMENT Continue + + While i>=start And text[i]<=Chars.SPACE + i-=1 + Wend + i+=1 + + If i=ends Continue ' have no trailing + If i=start Continue ' skip whole-whitespaced line + + If i>index + result+=text.Slice( index,i ) + changes+=1 + Endif + index=ends ' skip trailing part of text + + Next + + If changes=0 + result=text + Elseif indexChars.SPACE Or atEnd ' end of indentation + + If k>0 + Local indentStr:=line.Slice( 0,k ) + + Local spaces:=(indentStr.Find( tabAsSpacesStr )<>-1) + Local tabs:=(indentStr.Find( "~t" )<>-1) + + spacesCount+=Int(spaces) + tabsCount+=Int(tabs) + + If spacesCount>0 And tabsCount>0 Return Type.Mixed + + Endif + + Exit + + Endif + Next + Next + + If spacesCount>0 + Return Type.Spaces + Elseif tabsCount>0 + Return Type.Tabs + Endif + + Return Type.None + End + + Function FixIndentation:String( document:TextDocument ) + + Local text:=document.Text + Local useSpaces:=Prefs.EditorUseSpacesAsTabs + Local tabSize:=Prefs.EditorTabSize + Local tabAsSpacesStr:=TextUtils.GetSpacesForTabEquivalent() + Local minIndent:=useSpaces ? 1 Else 2 ' minimum 1 tab or 2 spaces + + ' will work with single lines + Local lines:=New StringStack( text.Split( "~n" ) ) + + For Local lineIndex:=0 Until lines.Length + + Local line:=lines[lineIndex] + + Local lineLen:=line.Length + If lineLen=0 Continue + + ' trim endings of lines + Local s:=line.TrimEnd() + If s ' don't trim whitespaced lines + line=s + lines[lineIndex]=line + Endif + + Local start:=document.StartOfLine( lineIndex ) + Local lineStr:="" ' our new content of line + Local indentStart:=-1,textStart:=0 + Local replaced:=0 + + ' processing each line + For Local k:=0 Until lineLen + + Local char:=line[k] + Local atEnd:=(k=lineLen-1) + Local isText:=(char>Chars.SPACE) + + If isText Or atEnd' end of indentation + + Local color:=document.Colors[start+k-1] + + ' skip comments and strings areas - checking of colors isn't good but works + Local skip:=(color=Highlighter.COLOR_COMMENT Or color=Highlighter.COLOR_STRING) + + If atEnd + If indentStart=-1 Then indentStart=k ' if there is the only tab in line + If Not isText Then k+=1 + Endif + + ' indentation found + If Not skip And indentStart<>-1 And k-indentStart>=minIndent + + replaced+=1 + + ' if there is a part of text before indent + If textStart<>-1 + lineStr+=line.Slice( textStart,indentStart ) + textStart=k + Endif + ' processing indent depending on "tabs or spaces" option + Local indentStr:=line.Slice( indentStart,k ) + + ' tabs --> spaces + If useSpaces + + ' the first tab can be 1 to 4 spaces + If indentStr[0]=Chars.TAB + Local pos:=TextUtils.GetPosInLineCheckingTabSize( line,indentStart,Prefs.EditorTabSize ) + Local chars:=(pos Mod tabSize) + Local spaces:=" ".Dup( tabSize-chars ) + If indentStr.Length=1 + ' single tab - just convert into spaces + indentStr=spaces + Else + ' convert first part + add (4*tabsCount) spaces + indentStr=spaces+indentStr.Slice( 1 ).Replace( "~t",tabAsSpacesStr ) + Endif + Else + ' starts with not a tab - don't know what to do exactly + ' so convert all tabs into spaces equivalent + indentStr=indentStr.Replace( "~t",tabAsSpacesStr ) + Endif + + 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 ) + Endif + + Endif + + lineStr+=indentStr + + Endif + + If atEnd And (isText Or skip) + + If replaced=0 ' if do nothing with line + lineStr=line + Elseif textStart<>-1 ' if there is a last part of line + lineStr+=line.Slice( textStart,k+1 ) + textStart=0 + Endif + + Endif + + indentStart=-1 + + Elseif indentStart=-1 + + indentStart=k ' store the nearest like-a-space position of indent + + Endif + Next + + lines[lineIndex]=lineStr ' apply resulting string + + Next + + Return lines.Join( "~n" ) + End + + + Private + + Method New() + End + +End diff --git a/view/ListViewExt.monkey2 b/view/ListViewExt.monkey2 index 19297689..c58d2719 100644 --- a/view/ListViewExt.monkey2 +++ b/view/ListViewExt.monkey2 @@ -53,9 +53,6 @@ Class ListViewExt Extends ScrollableView _lineHeightEtalon=lineHeight _maxLines=maxLines - _selColor=App.Theme.GetColor( "content" ) - _hoverColor=App.Theme.GetColor( "knob" ) - OnThemeChanged() End @@ -173,9 +170,12 @@ Class ListViewExt Extends ScrollableView Protected + Field _selColor:Color + Method OnThemeChanged() Override _lineH=_lineHeightEtalon*App.Theme.Scale.y + _selColor=App.Theme.GetColor( "content" ) End Method SelectPrevInternal( ensureVis:Bool ) @@ -246,7 +246,7 @@ Class ListViewExt Extends ScrollableView Endif k+=1 Next - + End Method OnMeasureContent:Vec2i() Override @@ -332,7 +332,6 @@ Class ListViewExt Extends ScrollableView Field _visibleCount:Int Field _maxLines:Int Field _selIndex:Int - Field _selColor:Color,_hoverColor:Color Field _width:Int,_height:Int Field _moveCyclic:Bool Field _dh:Float diff --git a/view/ProjectView.monkey2 b/view/ProjectView.monkey2 index d1e68e7f..9eab01e1 100644 --- a/view/ProjectView.monkey2 +++ b/view/ProjectView.monkey2 @@ -387,8 +387,6 @@ Class ProjectView Extends ScrollView d.ShowModal() End - menu.AddSeparator() - menu.AddAction( "New file" ).Triggered=Lambda() Local file:=RequestString( "New file name:" ) @@ -421,6 +419,34 @@ Class ProjectView Extends ScrollView browser.Refresh( node ) End + menu.AddSeparator() + + menu.AddAction( "Rename folder" ).Triggered=Lambda() + + Local oldName:=StripDir( path ) + Local name:=RequestString( "Enter new name:","Ranaming '"+oldName+"'",oldName ) + If Not name Or name=oldName Return + + Local i:=path.Slice( 0,path.Length-1 ).FindLast( "/" ) + If i<>-1 + + Local newPath:=path.Slice( 0,i+1 )+name + + If DirectoryExists( newPath ) + Alert( "Folder already exists! Path: '"+newPath+"'" ) + Return + Endif + + Local ok:=(libc.rename( path,newPath )=0) + If ok + browser.Refresh( node.Parent ) + Return + Endif + + Alert( "Failed to rename folder: '"+path+"'" ) + Endif + End + menu.AddAction( "Delete" ).Triggered=Lambda() DeleteItem( browser,path,node ) @@ -508,12 +534,12 @@ Class ProjectView Extends ScrollView menu.AddAction( "Open on Desktop" ).Triggered=Lambda() - requesters.OpenUrl( path ) + requesters.OpenUrl( ExtractDir( path ) ) End menu.AddSeparator() - menu.AddAction( "Rename" ).Triggered=Lambda() + menu.AddAction( "Rename file" ).Triggered=Lambda() Local oldName:=StripDir( path ) Local name:=RequestString( "Enter new name:","Ranaming '"+oldName+"'",oldName ) @@ -526,10 +552,8 @@ Class ProjectView Extends ScrollView Return Endif - If CopyFile( path,newPath ) - - DeleteFile( path ) - + Local ok:=(libc.rename( path,newPath )=0) + If ok browser.Refresh( node.Parent ) Return Endif diff --git a/view/StatusBarView.monkey2 b/view/StatusBarView.monkey2 index 69675694..e0d0570e 100644 --- a/view/StatusBarView.monkey2 +++ b/view/StatusBarView.monkey2 @@ -6,7 +6,7 @@ Class StatusBarView Extends DockingView Field Cancelled:Void() - Method New() + Method New( stopProcessHint:String="Stop process" ) Style=GetStyle( "StatusBar" ) @@ -37,7 +37,7 @@ Class StatusBarView Extends DockingView act.Triggered=OnCancel _progressCancel=New ToolButtonExt( act,"" ) - _progressCancel.Hint="Stop process" + _progressCancel.Hint=stopProcessHint _progressCancel.Style=GetStyle( "StatusBarButton" ) AddView( _progressCancel,"right" ) diff --git a/view/TabViewExt.monkey2 b/view/TabViewExt.monkey2 index 0c306f2b..bc89bb29 100644 --- a/view/TabViewExt.monkey2 +++ b/view/TabViewExt.monkey2 @@ -176,6 +176,30 @@ Class TabViewExt Extends DockingView Implements IDraggableHolder Return _tabs.Length End + #rem monkeydoc Number of visible tabs + #end + Property VisibleTabs:Int() + + Local num:Int + For Local t:=Eachin _tabs + If t.Visible num+=1 + Next + Return num + End + + #rem monkeydoc Give string array of Visible tab names + #end + Property TabsVisible:String[]() + + Local arr:=New String[NumTabs] + For Local i:=0 Until _tabs.Length + If _tabs[i].Visible + arr[i]=_tabs[i].Text + End + Next + Return arr + End + #rem monkeydoc The current index. #end Property CurrentIndex:Int() @@ -270,7 +294,7 @@ Class TabViewExt Extends DockingView Implements IDraggableHolder tab.RightClicked=Lambda() MakeCurrent( tab,True ) - + 'If tab.Undockable Then UndockWindow.NewUndock( tab ) RightClicked() End @@ -570,6 +594,13 @@ Class TabButtonExt Extends TabButton Implements IDraggableItem Return _parentDock.ActiveName=Text End + 'undockable? + Property Undockable:Bool() + Return _undockable + Setter( value:Bool ) + _undockable=value + End + Method SetLockedState( locked:Bool ) _locked=locked @@ -607,6 +638,7 @@ Class TabButtonExt Extends TabButton Implements IDraggableItem Field _possibleParentDocks:TabViewExt[] Field _locked:Bool Field _closable:Bool + Field _undockable:Bool End diff --git a/view/Undock.monkey2 b/view/Undock.monkey2 new file mode 100644 index 00000000..f7189890 --- /dev/null +++ b/view/Undock.monkey2 @@ -0,0 +1,88 @@ +Namespace ted2go + +Class UndockWindow Extends Window + + Field _storeView:View + Field _storeTabbutton:TabButtonExt + Field _storeIndex:Int + Field _visible:Int + + Global _undockWindows:=New Stack + + 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 + + _window._storeTabbutton=_tabbutton + _window._storeView=_tabbutton.CurrentHolder.CurrentView + _window._storeIndex=_tabbutton.CurrentHolder.CurrentIndex + + _tabbutton.CurrentHolder.SetTabView( _window._storeIndex, Null ) + If Not _tabbutton.CurrentHolder.VisibleTabs _tabbutton.CurrentHolder.Visible=False + + 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() + 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 + + Method OnWindowEvent( event:WindowEvent ) Override + + Select event.Type + Case EventType.WindowClose + CloseWindow() + Default + Super.OnWindowEvent( event ) + End + End + + 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 + + Function RestoreUndock() + + For Local i:=Eachin _undockWindows + i.CloseWindow() + _undockWindows.RemoveEach( i ) + Next + If _undockWindows.Length RestoreUndock() + End +End \ No newline at end of file