diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index 623791748..518227204 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -37,6 +37,10 @@ struct DocumentContentChange { class EE_API TextDocument { public: + static bool isTextDocummentCommand( std::string_view cmd ); + + static bool isTextDocummentCommand( String::HashType cmdHash ); + enum class UndoRedo { Undo, Redo }; enum class IndentType { IndentSpaces, IndentTabs }; diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index 6e26bacd8..a7795b9fa 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -920,6 +920,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { std::vector mPluginTopSpaces; Float mPluginsTopSpace{ 0 }; Uint64 mLastExecuteEventId{ 0 }; + String::HashType mLastCmdHash{ 0 }; Text mLineTextCache; size_t mJumpLinesLength{ 5 }; UIIcon* mFileLockIcon{ nullptr }; diff --git a/include/eepp/ui/uiconsole.hpp b/include/eepp/ui/uiconsole.hpp index da8430bce..8cac7eac2 100644 --- a/include/eepp/ui/uiconsole.hpp +++ b/include/eepp/ui/uiconsole.hpp @@ -189,6 +189,7 @@ class EE_API UIConsole : public UIWidget, Float mQuakeModeHeightPercent{ 0.6f }; #endif Uint64 mLastExecuteEventId{ 0 }; + String::HashType mLastCmdHash{ 0 }; UIPopUpMenu* mCurrentMenu{ nullptr }; size_t mMenuIconSize{ 16 }; diff --git a/include/eepp/ui/uitextinput.hpp b/include/eepp/ui/uitextinput.hpp index 66ae3323a..28b94f770 100644 --- a/include/eepp/ui/uitextinput.hpp +++ b/include/eepp/ui/uitextinput.hpp @@ -145,6 +145,7 @@ class EE_API UITextInput : public UITextView, public TextDocument::Client { size_t mMenuIconSize{ 16 }; UIPopUpMenu* mCurrentMenu{ nullptr }; Uint64 mLastExecuteEventId{ 0 }; + String::HashType mLastCmdHash{ 0 }; HintDisplay mHintDisplay{ HintDisplay::Always }; void resetWaitCursor(); diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 92a14addb..a1c5f2c4b 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -26,6 +26,16 @@ namespace EE { namespace UI { namespace Doc { static constexpr char DEFAULT_NON_WORD_CHARS[] = " \t\n/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"; +static UnorderedSet TEXT_DOCUMENT_COMMANDS = {}; + +bool TextDocument::isTextDocummentCommand( std::string_view cmd ) { + return TEXT_DOCUMENT_COMMANDS.contains( String::hash( cmd ) ); +} + +bool TextDocument::isTextDocummentCommand( String::HashType cmdHash ) { + return TEXT_DOCUMENT_COMMANDS.contains( cmdHash ); +} + bool TextDocument::isNonWord( String::StringBaseType ch ) const { return mNonWordChars.find_first_of( ch ) != String::InvalidPos; } @@ -3793,6 +3803,11 @@ void TextDocument::initializeCommands() { mCommands["unescape"] = [this] { unescape(); }; mCommands["to-base64"] = [this] { toBase64(); }; mCommands["from-base64"] = [this] { fromBase64(); }; + + if ( TEXT_DOCUMENT_COMMANDS.empty() ) { + for ( const auto& [cmd, _] : mCommands ) + TEXT_DOCUMENT_COMMANDS.insert( String::hash( cmd ) ); + } } TextRange TextDocument::getTopMostCursor() { diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 2cfdd77a3..6b9763c03 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -1078,7 +1078,8 @@ Uint32 UICodeEditor::onTextInput( const TextInputEvent& event ) { input->isMetaPressed() || ( input->isLeftAltPressed() && !input->isLeftControlPressed() ) ) return 0; - if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() ) + if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() && + !TextDocument::isTextDocummentCommand( mLastCmdHash ) ) return 0; mDoc->textInput( event.getText() ); @@ -1291,11 +1292,16 @@ Uint32 UICodeEditor::onKeyDown( const KeyEvent& event ) { // Allow copy selection on locked mode if ( !mLocked || mUnlockedCmd.find( cmd ) != mUnlockedCmd.end() ) { mDoc->execute( cmd, this ); + mLastCmdHash = String::hash( cmd ); mLastExecuteEventId = getUISceneNode()->getWindow()->getInput()->getEventsSentId(); return 1; } } + return 0; +} + +Uint32 UICodeEditor::onKeyUp( const KeyEvent& event ) { if ( isEnabledFlashCursor() && event.getSanitizedMod() == KeyMod::getDefaultModifier() ) { if ( mModDownCount == 0 ) mModDownClock.restart(); @@ -1312,10 +1318,6 @@ Uint32 UICodeEditor::onKeyDown( const KeyEvent& event ) { mModDownClock.restart(); } - return 0; -} - -Uint32 UICodeEditor::onKeyUp( const KeyEvent& event ) { mLastActivity.restart(); for ( auto& plugin : mPlugins ) if ( plugin->onKeyUp( this, event ) ) diff --git a/src/eepp/ui/uiconsole.cpp b/src/eepp/ui/uiconsole.cpp index 3e2009fe3..583e0423b 100644 --- a/src/eepp/ui/uiconsole.cpp +++ b/src/eepp/ui/uiconsole.cpp @@ -920,6 +920,7 @@ Uint32 UIConsole::onKeyDown( const KeyEvent& event ) { std::string cmd = mKeyBindings.getCommandFromKeyBind( { event.getKeyCode(), event.getMod() } ); if ( !cmd.empty() ) { mDoc.execute( cmd ); + mLastCmdHash = String::hash( cmd ); mLastExecuteEventId = getUISceneNode()->getWindow()->getInput()->getEventsSentId(); return 1; } @@ -935,7 +936,8 @@ Uint32 UIConsole::onTextInput( const TextInputEvent& event ) { input->isMetaPressed() || ( input->isLeftAltPressed() && !input->isLeftControlPressed() ) ) return 0; - if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() ) + if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() && + !TextDocument::isTextDocummentCommand( mLastCmdHash ) ) return 0; const String& text = event.getText(); diff --git a/src/eepp/ui/uitextinput.cpp b/src/eepp/ui/uitextinput.cpp index 9e626a729..4418e3acf 100644 --- a/src/eepp/ui/uitextinput.cpp +++ b/src/eepp/ui/uitextinput.cpp @@ -770,6 +770,7 @@ Uint32 UITextInput::onKeyDown( const KeyEvent& event ) { // Allow copy selection on locked mode if ( mAllowEditing ) { mDoc.execute( cmd ); + mLastCmdHash = String::hash( cmd ); mLastExecuteEventId = getUISceneNode()->getWindow()->getInput()->getEventsSentId(); return 1; } @@ -788,7 +789,8 @@ Uint32 UITextInput::onTextInput( const TextInputEvent& event ) { input->isMetaPressed() || ( input->isLeftAltPressed() && !input->isLeftControlPressed() ) ) return 0; - if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() ) + if ( mLastExecuteEventId == getUISceneNode()->getWindow()->getInput()->getEventsSentId() && + !TextDocument::isTextDocummentCommand( mLastCmdHash ) ) return 0; const String& text = event.getText(); diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 015a1ab69..0f8197f85 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1786,67 +1786,73 @@ std::map App::getDefaultKeybindings() { std::map App::getLocalKeybindings() { return { { { KEY_RETURN, KEYMOD_LALT | KEYMOD_LCTRL }, "fullscreen-toggle" }, - { { KEY_F3, KEYMOD_NONE }, "repeat-find" }, - { { KEY_F3, KEYMOD_SHIFT }, "find-prev" }, - { { KEY_F12, KEYMOD_NONE }, "console-toggle" }, - { { KEY_F, KeyMod::getDefaultModifier() }, "find-replace" }, - { { KEY_Q, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "close-app" }, - { { KEY_O, KeyMod::getDefaultModifier() }, "open-file" }, - { { KEY_W, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "download-file-web" }, - { { KEY_O, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-folder" }, - { { KEY_F11, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "debug-widget-tree-view" }, - { { KEY_K, KeyMod::getDefaultModifier() }, "open-locatebar" }, - { { KEY_P, KeyMod::getDefaultModifier() }, "open-command-palette" }, - { { KEY_F, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-global-search" }, - { { KEY_L, KeyMod::getDefaultModifier() }, "go-to-line" }, + { { KEY_F3, KEYMOD_NONE }, "repeat-find" }, { { KEY_F3, KEYMOD_SHIFT }, "find-prev" }, + { { KEY_F12, KEYMOD_NONE }, "console-toggle" }, + { { KEY_F, KeyMod::getDefaultModifier() }, "find-replace" }, + { { KEY_Q, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "close-app" }, + { { KEY_O, KeyMod::getDefaultModifier() }, "open-file" }, + { { KEY_W, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "download-file-web" }, + { { KEY_O, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-folder" }, + { { KEY_F11, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "debug-widget-tree-view" }, + { { KEY_K, KeyMod::getDefaultModifier() }, "open-locatebar" }, + { { KEY_P, KeyMod::getDefaultModifier() }, "open-command-palette" }, + { { KEY_F, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-global-search" }, + { { KEY_L, KeyMod::getDefaultModifier() }, "go-to-line" }, #if EE_PLATFORM == EE_PLATFORM_MACOS - { { KEY_M, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "menu-toggle" }, + { { KEY_M, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "menu-toggle" }, #else - { { KEY_M, KeyMod::getDefaultModifier() }, "menu-toggle" }, + { { KEY_M, KeyMod::getDefaultModifier() }, "menu-toggle" }, #endif - { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "save-all" }, - { { KEY_F9, KEYMOD_LALT }, "switch-side-panel" }, - { { KEY_J, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-left" }, - { { KEY_L, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-right" }, - { { KEY_I, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-top" }, - { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-bottom" }, - { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-swap" }, - { { KEY_T, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "reopen-closed-tab" }, - { { KEY_1, KEYMOD_LALT }, "toggle-status-locate-bar" }, - { { KEY_2, KEYMOD_LALT }, "toggle-status-global-search-bar" }, - { { KEY_3, KEYMOD_LALT }, "toggle-status-terminal" }, - { { KEY_4, KEYMOD_LALT }, "toggle-status-build-output" }, - { { KEY_5, KEYMOD_LALT }, "toggle-status-app-output" }, - { { KEY_B, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-start-cancel" }, - { { KEY_C, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-cancel" }, - { { KEY_R, KeyMod::getDefaultModifier() }, "project-build-and-run" }, - { { KEY_O, KEYMOD_LALT | KEYMOD_SHIFT }, "show-open-documents" }, - { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-workspace-symbol-search" }, - { { KEY_P, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-document-symbol-search" }, - { { KEY_N, KEYMOD_SHIFT | KEYMOD_LALT }, "create-new-window" }, + { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "save-all" }, + { { KEY_F9, KEYMOD_LALT }, "switch-side-panel" }, + { { KEY_J, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-left" }, + { { KEY_L, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-right" }, + { { KEY_I, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-top" }, + { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-bottom" }, + { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-swap" }, + { { KEY_T, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "reopen-closed-tab" }, + { { KEY_1, KEYMOD_LALT }, "toggle-status-locate-bar" }, + { { KEY_2, KEYMOD_LALT }, "toggle-status-global-search-bar" }, + { { KEY_3, KEYMOD_LALT }, "toggle-status-terminal" }, + { { KEY_4, KEYMOD_LALT }, "toggle-status-build-output" }, + { { KEY_5, KEYMOD_LALT }, "toggle-status-app-output" }, + { { KEY_B, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, + "project-build-start-cancel" }, + { { KEY_C, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-cancel" }, + { { KEY_R, KeyMod::getDefaultModifier() }, "project-build-and-run" }, + { { KEY_O, KEYMOD_LALT | KEYMOD_SHIFT }, "show-open-documents" }, + { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, + "open-workspace-symbol-search" }, + { { KEY_P, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, + "open-document-symbol-search" }, + { { KEY_N, KEYMOD_SHIFT | KEYMOD_LALT }, "create-new-window" }, }; } // Old keybindings will be rebinded to the new keybindings when they are still set to the old // keybindind std::map App::getMigrateKeybindings() { - return { { "fullscreen-toggle", "alt+return" }, { "switch-to-tab-1", "alt+1" }, - { "switch-to-tab-2", "alt+2" }, { "switch-to-tab-3", "alt+3" }, - { "switch-to-tab-4", "alt+4" }, { "switch-to-tab-5", "alt+5" }, - { "switch-to-tab-6", "alt+6" }, { "switch-to-tab-7", "alt+7" }, - { "switch-to-tab-8", "alt+8" }, { "switch-to-tab-9", "alt+9" }, - { "switch-to-last-tab", "alt+0" }, + return { + { "fullscreen-toggle", "alt+return" }, { "switch-to-tab-1", "alt+1" }, + { "switch-to-tab-2", "alt+2" }, { "switch-to-tab-3", "alt+3" }, + { "switch-to-tab-4", "alt+4" }, { "switch-to-tab-5", "alt+5" }, + { "switch-to-tab-6", "alt+6" }, { "switch-to-tab-7", "alt+7" }, + { "switch-to-tab-8", "alt+8" }, { "switch-to-tab-9", "alt+9" }, + { "switch-to-last-tab", "alt+0" }, #if EE_PLATFORM == EE_PLATFORM_MACOS - { "menu-toggle", "mod+shift+m" }, + { "menu-toggle", "mod+shift+m" }, #endif - { "lock-toggle", "mod+shift+l" }, { "debug-widget-tree-view", "f11" }, - { "project-build-and-run", "f5" }, { "project-build-start", "mod+shift+b" } }; + { "lock-toggle", "mod+shift+l" }, { "debug-widget-tree-view", "f11" }, + { "project-build-and-run", "f5" }, { + "project-build-start", "mod+shift+b" + } + }; } std::vector App::getUnlockedCommands() { @@ -2482,7 +2488,8 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { } editor->on( Event::OnClose, [this, editor]( auto ) { - if ( editor->hasClass( NOT_UNIQUE_FILENAME ) ) + if ( SceneManager::existsSingleton() && !SceneManager::instance()->isShuttingDown() && + editor->hasClass( NOT_UNIQUE_FILENAME ) ) updateNonUniqueTabTitles(); } ); @@ -3491,9 +3498,10 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe mConfig.windowState.pixelDensity = pidelDensity > 0 ? pidelDensity - : ( mConfig.windowState.pixelDensity > 0 ? mConfig.windowState.pixelDensity - : currentDisplay->getPixelDensity() > 2 ? currentDisplay->getPixelDensity() / 2 - : currentDisplay->getPixelDensity() ); + : ( mConfig.windowState.pixelDensity > 0 + ? mConfig.windowState.pixelDensity + : currentDisplay->getPixelDensity() > 2 ? currentDisplay->getPixelDensity() / 2 + : currentDisplay->getPixelDensity() ); #else mConfig.windowState.pixelDensity = pidelDensity > 0 diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index 0c6140140..39cdc4d34 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -742,6 +742,9 @@ UIMenu* SettingsMenu::createDocumentMenu() { mApp->getConfig().workspace.sessionSnapshot = item->isActive(); } else if ( "allow_flash_cursor" == id ) { mApp->getConfig().editor.flashCursor = item->isActive(); + mSplitter->forEachEditor( [this]( UICodeEditor* editor ) { + editor->setEnableFlashCursor( mApp->getConfig().editor.flashCursor ); + } ); } else if ( "tab_stops" == id ) { mApp->getConfig().doc.tabStops = item->isActive(); mSplitter->forEachEditor( [this]( UICodeEditor* editor ) {