From 09114eea8a39d56f1cfb3e1721007551d3a66836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 7 Jul 2022 01:20:24 -0300 Subject: [PATCH] ecode: More terminal improvements. --- TODO.md | 2 - projects/linux/ee.creator.user | 6 +- .../eterm/terminal/terminaldisplay.hpp | 2 + .../eterm/terminal/terminalemulator.hpp | 2 + .../eterm/include/eterm/ui/uiterminal.hpp | 2 + .../src/eterm/terminal/terminaldisplay.cpp | 6 +- src/modules/eterm/src/eterm/ui/uiterminal.cpp | 4 ++ src/tools/ecode/appconfig.cpp | 55 ++++++++++++------- src/tools/ecode/appconfig.hpp | 3 +- src/tools/ecode/ecode.cpp | 21 ++++--- src/tools/ecode/ecode.hpp | 2 +- 11 files changed, 70 insertions(+), 35 deletions(-) diff --git a/TODO.md b/TODO.md index b447aa9a0..d78338252 100644 --- a/TODO.md +++ b/TODO.md @@ -17,8 +17,6 @@ Detect errors and log them. * Add LSP support. -* Add terminal support. - ## UI Editor * Integrate the `UICodeEditor` into the editor in order to be able to edit the layouts and CSS in app. diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 5f8e07e46..74f4e6ea5 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -267,7 +267,7 @@ ../../projects/mingw32 - -e config=debug_x86 + -e config=debug_x86_64 make.sh true GenericProjectManager.GenericMakeStep @@ -302,7 +302,7 @@ ../../projects/mingw32 - -e config=release_x86 + -e config=release_x86_64 make.sh true GenericProjectManager.GenericMakeStep diff --git a/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp b/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp index 8b4db4185..abefd49d5 100644 --- a/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp @@ -233,6 +233,8 @@ class TerminalDisplay : public ITerminalDisplay { void popEventCallback( const Uint32& id ); + Float getLineHeight() const; + protected: EE::Window::Window* mWindow; std::vector mBuffer; diff --git a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp index e3b833cdd..f35aa769e 100644 --- a/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminalemulator.hpp @@ -156,6 +156,8 @@ class TerminalEmulator final { inline int getNumRows() const { return mTerm.row; } + inline int getHistorySize() const { return mTerm.histi; } + int write( const char* buf, size_t buflen ); void printscreen( const TerminalArg* ); diff --git a/src/modules/eterm/include/eterm/ui/uiterminal.hpp b/src/modules/eterm/include/eterm/ui/uiterminal.hpp index aa9ce6169..d511f86d9 100644 --- a/src/modules/eterm/include/eterm/ui/uiterminal.hpp +++ b/src/modules/eterm/include/eterm/ui/uiterminal.hpp @@ -70,6 +70,8 @@ class UITerminal : public UIWidget { * This allows the user to use all the keybindings in the terminal. */ void setExclusiveMode( bool exclusiveMode ); + bool isUsingCustomTitle() const; + protected: std::string mTitle; bool mIsCustomTitle{ false }; diff --git a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp index ee5795b9f..82a38a380 100644 --- a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp @@ -543,6 +543,10 @@ void TerminalDisplay::popEventCallback( const Uint32& id ) { mCallbacks.erase( it ); } +Float TerminalDisplay::getLineHeight() const { + return mFont->getFontHeight( mFontSize ); +} + void TerminalDisplay::update() { if ( mFocus && isBlinkingCursor() && mClock.getElapsedTime().asSeconds() > 0.7 ) { mMode ^= MODE_BLINK; @@ -934,7 +938,7 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) { if ( mFrameBuffer ) mFrameBuffer->bind(); - auto fontSize = (Float)mFont->getFontHeight( mFontSize ); + auto fontSize = mFont->getFontHeight( mFontSize ); auto spaceCharAdvanceX = mFont->getGlyph( 'A', mFontSize, false ).advance; float x = 0.0f; diff --git a/src/modules/eterm/src/eterm/ui/uiterminal.cpp b/src/modules/eterm/src/eterm/ui/uiterminal.cpp index 5a800934f..37d4c7fa1 100644 --- a/src/modules/eterm/src/eterm/ui/uiterminal.cpp +++ b/src/modules/eterm/src/eterm/ui/uiterminal.cpp @@ -159,6 +159,10 @@ void UITerminal::setExclusiveMode( bool exclusiveMode ) { mExclusiveMode = exclusiveMode; } +bool UITerminal::isUsingCustomTitle() const { + return mIsCustomTitle; +} + Uint32 UITerminal::onTextInput( const TextInputEvent& event ) { mTerm->onTextInput( event.getChar() ); return 1; diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index a69fa651c..230fe838e 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -1,11 +1,14 @@ #include "appconfig.hpp" +#include "ecode.hpp" #include "thirdparty/json.hpp" #include #include #include #include +#include using namespace EE::Network; +using namespace eterm::UI; using json = nlohmann::json; namespace ecode { @@ -237,14 +240,24 @@ json saveNode( Node* node ) { std::vector files; for ( size_t i = 0; i < tabWidget->getTabCount(); ++i ) { Node* ownedWidget = tabWidget->getTab( i )->getOwnedWidget(); - if ( ownedWidget && ownedWidget->isType( UI_TYPE_CODEEDITOR ) ) { + if ( !ownedWidget ) + continue; + if ( ownedWidget->isType( UI_TYPE_CODEEDITOR ) ) { UICodeEditor* editor = ownedWidget->asType(); if ( !editor->getDocument().getFilePath().empty() ) { json f; + f["type"] = "editor"; f["path"] = editor->getDocument().getFilePath(); f["selection"] = editor->getDocument().getSelection().toString(); files.emplace_back( f ); } + } else if ( ownedWidget->isType( UI_TYPE_TERMINAL ) ) { + UITerminal* term = ownedWidget->asType(); + json f; + f["type"] = "terminal"; + if ( term->isUsingCustomTitle() ) + f["title"] = term->getTitle(); + files.emplace_back( f ); } } res["type"] = "tabwidget"; @@ -289,24 +302,28 @@ void AppConfig::saveProject( std::string projectFolder, UICodeEditorSplitter* ed } static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr pool, - json j, UITabWidget* curTabWidget ) { + json j, UITabWidget* curTabWidget, ecode::App* app ) { if ( j["type"] == "tabwidget" ) { Int64 currentPage = j["current_page"]; size_t totalToLoad = j["files"].size(); for ( const auto& file : j["files"] ) { - std::string path( file["path"] ); - TextRange selection( TextRange::fromString( file["selection"] ) ); - editorSplitter->loadAsyncFileFromPathInNewTab( - path, pool, - [curTabWidget, selection, totalToLoad, currentPage]( UICodeEditor* editor, - const std::string& ) { - editor->getDocument().setSelection( selection ); - editor->scrollToCursor(); - if ( curTabWidget->getTabCount() == totalToLoad ) - curTabWidget->setTabSelected( - eeclamp( currentPage, 0, curTabWidget->getTabCount() - 1 ) ); - }, - curTabWidget ); + if ( !file.contains( "type" ) || file["type"] == "editor" ) { + std::string path( file["path"] ); + TextRange selection( TextRange::fromString( file["selection"] ) ); + editorSplitter->loadAsyncFileFromPathInNewTab( + path, pool, + [curTabWidget, selection, totalToLoad, currentPage]( UICodeEditor* editor, + const std::string& ) { + editor->getDocument().setSelection( selection ); + editor->scrollToCursor(); + if ( curTabWidget->getTabCount() == totalToLoad ) + curTabWidget->setTabSelected( + eeclamp( currentPage, 0, curTabWidget->getTabCount() - 1 ) ); + }, + curTabWidget ); + } else if ( file["type"] == "terminal" ) { + app->createNewTerminal( file.contains( "title" ) ? file["title"] : "" ); + } } } else if ( j["type"] == "splitter" ) { UISplitter* splitter = editorSplitter->split( @@ -317,9 +334,9 @@ static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr if ( nullptr == splitter ) return; - loadDocuments( editorSplitter, pool, j["first"], curTabWidget ); + loadDocuments( editorSplitter, pool, j["first"], curTabWidget, app ); UITabWidget* tabWidget = splitter->getLastWidget()->asType(); - loadDocuments( editorSplitter, pool, j["last"], tabWidget ); + loadDocuments( editorSplitter, pool, j["last"], tabWidget, app ); splitter->setSplitPartition( StyleSheetLength( j["split"] ) ); } @@ -327,7 +344,7 @@ static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* editorSplitter, const std::string& configPath, ProjectDocumentConfig& docConfig, - std::shared_ptr pool ) { + std::shared_ptr pool, ecode::App* app ) { FileSystem::dirAddSlashAtEnd( projectFolder ); std::string projectsPath( configPath + "projects" + FileSystem::getOSSlash() ); MD5::Result hash = MD5::fromString( projectFolder ); @@ -356,7 +373,7 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed if ( j.is_discarded() ) return; loadDocuments( editorSplitter, pool, j, - editorSplitter->tabWidgetFromWidget( editorSplitter->getCurWidget() ) ); + editorSplitter->tabWidgetFromWidget( editorSplitter->getCurWidget() ), app ); } else { // Old format bool found; diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index 2d3d03506..685186ced 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -18,6 +18,7 @@ using namespace EE::System; using namespace EE::Window; namespace ecode { +class App; enum class PanelPosition { Left, Right }; @@ -124,7 +125,7 @@ struct AppConfig { void loadProject( std::string projectFolder, UICodeEditorSplitter* editorSplitter, const std::string& configPath, ProjectDocumentConfig& docConfig, - std::shared_ptr pool ); + std::shared_ptr pool, ecode::App* app ); }; } // namespace ecode diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 8fe01a1ff..0184e0582 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1701,7 +1701,8 @@ void App::onDocumentCursorPosChange( UICodeEditor*, TextDocument& doc ) { void App::updateDocInfo( TextDocument& doc ) { if ( mConfig.editor.showDocInfo && mDocInfoText && mEditorSplitter->curEditorExistsAndFocused() ) { - mDocInfoText->setVisible( true ); + if ( mDocInfo ) + mDocInfo->setVisible( true ); mDocInfoText->setText( String::format( "line: %lld / %lu col: %lld %s", doc.getSelection().start().line() + 1, doc.linesCount(), mEditorSplitter->getCurEditor()->getCurrentColumnCount(), @@ -1723,9 +1724,9 @@ void App::syncProjectTreeWithEditor( UICodeEditor* editor ) { } void App::onWidgetFocusChange( UIWidget* widget ) { - if ( mConfig.editor.showDocInfo && mDocInfoText ) { - mDocInfoText->setVisible( widget && widget->isType( UI_TYPE_CODEEDITOR ) ); - } + if ( mConfig.editor.showDocInfo && mDocInfoText ) + mDocInfo->setVisible( widget && widget->isType( UI_TYPE_CODEEDITOR ) ); + updateDocumentMenu(); if ( widget && !widget->isType( UI_TYPE_CODEEDITOR ) ) { if ( widget->isType( UI_TYPE_TERMINAL ) ) @@ -1993,7 +1994,7 @@ void App::fullscreenToggle() { ->setActive( !mWindow->isWindowed() ); } -void App::createNewTerminal() { +void App::createNewTerminal( const std::string& title ) { UIWidget* curWidget = mEditorSplitter->getCurWidget(); if ( !curWidget ) return; @@ -2006,8 +2007,11 @@ void App::createNewTerminal() { } } UITerminal* term = UITerminal::New( mFontMonoNerdFont ? mFontMonoNerdFont : mFontMono, - PixelDensity::dpToPx( 11 ), Sizef( 16, 16 ) ); - mEditorSplitter->createWidgetInTabWidget( tabWidget, term, "Shell", true ); + PixelDensity::dpToPx( 11 ), Sizef( 16, 16 ), "", {}, + !mCurrentProject.empty() ? mCurrentProject : "" ); + mEditorSplitter->createWidgetInTabWidget( tabWidget, term, title.empty() ? "Shell" : title, + true ); + term->setTitle( title ); term->addEventListener( Event::OnTitleChange, [&]( const Event* event ) { if ( event->getNode() != mEditorSplitter->getCurWidget() ) return; @@ -2949,7 +2953,8 @@ void App::loadFolder( const std::string& path ) { mCurrentProject = rpath; loadDirTree( rpath ); - mConfig.loadProject( rpath, mEditorSplitter, mConfigPath, mProjectDocConfig, mThreadPool ); + mConfig.loadProject( rpath, mEditorSplitter, mConfigPath, mProjectDocConfig, mThreadPool, + this ); mFileSystemModel = FileSystemModel::New( rpath, FileSystemModel::Mode::FilesAndDirectories, { true, true, true } ); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 3b63418cd..5202b081b 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -80,7 +80,7 @@ class App : public UICodeEditorSplitter::Client { NotificationCenter* getNotificationCenter() const; - void createNewTerminal(); + void createNewTerminal( const std::string& title = "" ); std::map getAppKeybindings();