From 1cd943ae267af4a718591d15ac6b01e844279f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 7 Dec 2025 00:24:04 -0300 Subject: [PATCH] Side Panel right click context menu improvements (SpartanJ/ecode#712). Side Panel: Right click on a sub-directory and "Find in folder..." (SpartanJ/ecode#720). File Save now defaults to the most recent save location (SpartanJ/ecode#734). Side Panel: right click on a directory and open it on new window (SpartanJ/ecode#736). Build and Run: fix run in terminal on Windows 8.1 (SpartanJ/ecode#740). --- bin/assets/i18n/de.xml | 7 +-- bin/assets/i18n/en.xml | 7 +-- bin/assets/i18n/zh_CN.xml | 7 +-- include/eepp/system/filesystem.hpp | 2 +- src/eepp/system/filesystem.cpp | 4 +- src/eepp/ui/uicodeeditor.cpp | 8 +-- src/thirdparty/efsw | 2 +- src/tools/ecode/ecode.cpp | 13 +++-- src/tools/ecode/ecode.hpp | 9 +-- src/tools/ecode/globalsearchcontroller.cpp | 5 +- src/tools/ecode/globalsearchcontroller.hpp | 2 +- .../ecode/plugins/plugincontextprovider.hpp | 5 ++ src/tools/ecode/projectbuild.cpp | 2 +- src/tools/ecode/settingsmenu.cpp | 56 ++++++++++++++++--- src/tools/ecode/terminalmanager.cpp | 31 +++++++--- 15 files changed, 112 insertions(+), 48 deletions(-) diff --git a/bin/assets/i18n/de.xml b/bin/assets/i18n/de.xml index dbbb61bf8..92a435abe 100644 --- a/bin/assets/i18n/de.xml +++ b/bin/assets/i18n/de.xml @@ -561,8 +561,7 @@ Bitte die Anwendung neu starten. Einen Ordner öffnen Alle Dateien im Ordner öffnen Befehlspalette öffnen - Ordner aktueller Datei öffnen - Ordner aktueller Datei öffnen... + Ordner aktueller Datei öffnen Kontextmenü öffnen Dokumentsymbolsuche öffnen Geöffnete Dokumente @@ -574,7 +573,7 @@ in einem neuen Fenster geöffnet werden. Dateien in neuem Fenster öffnen Zuerst muss ein Ordner geöffnet werden. Ordner öffnen - Ordner öffnen... + Ordner öffnen Globale Suche öffnen In neuer horizontaler Kachel öffnen In neuem Fenster öffnen @@ -870,7 +869,7 @@ in der Baumansicht und in Öffen-/Schließdialogen aktivieren. Dateipfad und -position kopieren Ausschneiden Löschen - Überordner öffnen... + Überordner öffnen Einfügen Wiederholen Alles auswählen diff --git a/bin/assets/i18n/en.xml b/bin/assets/i18n/en.xml index f16c8e72e..1531eab40 100644 --- a/bin/assets/i18n/en.xml +++ b/bin/assets/i18n/en.xml @@ -546,8 +546,7 @@ Please restart the application. Open a Folder Open All Files in Folder Open Command Palette - Open Containing Folder - Open Containing Folder... + Open Containing Folder in File Manager Open Context Menu Open Document Symbol Search Open Documents @@ -559,7 +558,7 @@ controls whether a new window is created or not. Open Files in New Window You must first open a folder. Open Folder - Open Folder... + Open Folder in File Manager Open Global Search Open In New Horizontal Split Open In New Window @@ -855,7 +854,7 @@ the directory tree and in file dialogs to open a folder or file. Copy File Path and Position Cut Delete - Open Containing Folder... + Open Containing Folder in File Manager Paste Redo Select All diff --git a/bin/assets/i18n/zh_CN.xml b/bin/assets/i18n/zh_CN.xml index 27abd89c7..aad7cb60d 100644 --- a/bin/assets/i18n/zh_CN.xml +++ b/bin/assets/i18n/zh_CN.xml @@ -423,8 +423,7 @@ Restart ecode to see the changes. 打开一个文件 打开一个文件夹 打开命令网络 - 打开当前文件夹 - 打开当前文件夹... + 打开当前文件夹 打开上下文菜单 打开文档符号查找 打开文档 @@ -433,7 +432,7 @@ Restart ecode to see the changes. 从网络打开文件... 请先打开文件夹。 打开文件夹 - 打开文件夹... + 打开文件夹 全局搜索 在新水平分页中打开 在新窗口中打开 @@ -644,7 +643,7 @@ file in the directory tree. Copy File Path and Position Paste Delete - Open Containing Folder... + Open Containing Folder in File Manager 粘贴 重做 全选 diff --git a/include/eepp/system/filesystem.hpp b/include/eepp/system/filesystem.hpp index 647aeab85..e3715d576 100644 --- a/include/eepp/system/filesystem.hpp +++ b/include/eepp/system/filesystem.hpp @@ -74,7 +74,7 @@ class EE_API FileSystem { static bool fileWrite( const std::string& filepath, const std::vector& data ); /** Write a file in binary mode and close it. */ - static bool fileWrite( const std::string& filepath, const std::string& data ); + static bool fileWrite( const std::string& filepath, std::string_view data ); /** Deletes a file from the file system. */ static bool fileRemove( const std::string& filepath ); diff --git a/src/eepp/system/filesystem.cpp b/src/eepp/system/filesystem.cpp index 8b0bab3a9..9c3d0b713 100644 --- a/src/eepp/system/filesystem.cpp +++ b/src/eepp/system/filesystem.cpp @@ -186,8 +186,8 @@ bool FileSystem::fileWrite( const std::string& filepath, const std::vector( &data[0] ), (Uint32)data.size() ); } -bool FileSystem::fileWrite( const std::string& filepath, const std::string& data ) { - return fileWrite( filepath, (const Uint8*)data.c_str(), (Uint32)data.size() ); +bool FileSystem::fileWrite( const std::string& filepath, std::string_view data ) { + return fileWrite( filepath, (const Uint8*)data.data(), (Uint32)data.size() ); } bool FileSystem::fileRemove( const std::string& filepath ) { diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 314a102b9..fc2e7592c 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -1405,10 +1405,10 @@ void UICodeEditor::createDefaultContextMenuOptions( UIPopUpMenu* menu ) { if ( mDoc->hasFilepath() ) { menu->addSeparator(); - menuAdd( - menu, - i18n( "uicodeeditor_open_containing_folder_ellipsis", "Open Containing Folder..." ), - "folder-open", "open-containing-folder" ); + menuAdd( menu, + i18n( "uicodeeditor_open_containing_folder_in_fm", + "Open Containing Folder in File Manager" ), + "folder-open", "open-containing-folder" ); menuAdd( menu, i18n( "uicodeeditor_copy_containing_folder_path_ellipsis", diff --git a/src/thirdparty/efsw b/src/thirdparty/efsw index b81cd84d7..71e43ca3b 160000 --- a/src/thirdparty/efsw +++ b/src/thirdparty/efsw @@ -1 +1 @@ -Subproject commit b81cd84d765b255c943a93ae20b8a1d5fe7033dc +Subproject commit 71e43ca3bd9b4df7b92bcfed792c028341eb8c62 diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index da0e1c525..34826be86 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -546,7 +546,9 @@ UIFileDialog* App::saveFileDialog( UICodeEditor* editor, bool focusOnClose ) { std::string filename( editor->getDocument().getFilename() ); if ( FileSystem::fileExtension( editor->getDocument().getFilename() ).empty() ) filename += editor->getSyntaxDefinition().getFileExtension(); - std::string folderPath( FileSystem::fileRemoveFileName( editor->getDocument().getFilePath() ) ); + std::string folderPath( !mLastFileFolder.empty() ? mLastFileFolder + : FileSystem::fileRemoveFileName( + editor->getDocument().getFilePath() ) ); if ( !FileSystem::isDirectory( folderPath ) ) folderPath = getLastUsedFolder(); UIFileDialog* dialog = UIFileDialog::New( @@ -565,6 +567,7 @@ UIFileDialog* App::saveFileDialog( UICodeEditor* editor, bool focusOnClose ) { if ( !path.empty() && !FileSystem::isDirectory( path ) && FileSystem::fileWrite( path, "" ) ) { if ( editor->getDocument().save( path ) ) { + mLastFileFolder = FileSystem::fileRemoveFileName( path ); insertRecentFileAndUpdateUI( path ); updateEditorState(); } else { @@ -1540,8 +1543,8 @@ void App::onTabCreated( UITab* tab, UIWidget* ) { menuAdd( "split_top", "Split Top", "split-vertical", "split-top" ); menuAdd( "split_bottom", "Split Bottom", "split-vertical", "split-bottom" ); - menuAdd( "open_containing_folder_ellipsis", "Open Containing Folder...", "folder-open", - "open-containing-folder" ); + menuAdd( "open_containing_folder_in_fm", "Open Containing Folder in File Manager", + "folder-open", "open-containing-folder" ); menuAdd( "copy_containing_folder_path_ellipsis", "Copy Containing Folder Path...", "copy", "copy-containing-folder-path" ); @@ -2483,8 +2486,8 @@ void App::fullscreenToggle() { mSettings->updateViewMenu(); } -void App::showGlobalSearch( bool searchAndReplace ) { - mGlobalSearchController->showGlobalSearch( searchAndReplace ); +void App::showGlobalSearch( bool searchAndReplace, std::optional pathFilters ) { + mGlobalSearchController->showGlobalSearch( searchAndReplace, pathFilters ); } void App::showFindView() { diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index fdbef6e1e..cb338b500 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -124,7 +124,7 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { void downloadFileWebDialog(); - void showGlobalSearch( bool searchAndReplace ); + void showGlobalSearch( bool searchAndReplace, std::optional pathFilters = {} ); void showFindView(); @@ -504,7 +504,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { void setTheme( const std::string& path ); - void loadImageFromMedium( const std::string& path, bool isMemory, bool forcePreview = false, bool forceTab = false ); + void loadImageFromMedium( const std::string& path, bool isMemory, bool forcePreview = false, + bool forceTab = false ); void loadImageFromPath( const std::string& path ); @@ -568,6 +569,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { bool pluginsDisabled() const { return mDisablePlugins; } + void loadFolder( std::string path, bool forceNewWindow = false ); + protected: std::vector mArgs; EE::Window::Window* mWindow{ nullptr }; @@ -717,8 +720,6 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider { void saveDoc(); - void loadFolder( std::string path, bool forceNewWindow = false ); - void loadKeybindings(); void reloadKeybindings(); diff --git a/src/tools/ecode/globalsearchcontroller.cpp b/src/tools/ecode/globalsearchcontroller.cpp index c38a2a853..78f26e5e8 100644 --- a/src/tools/ecode/globalsearchcontroller.cpp +++ b/src/tools/ecode/globalsearchcontroller.cpp @@ -565,7 +565,8 @@ void GlobalSearchController::initGlobalSearchBar( mGlobalSearchTree = mGlobalSearchTreeSearch; } -void GlobalSearchController::showGlobalSearch( bool searchReplace ) { +void GlobalSearchController::showGlobalSearch( bool searchReplace, + std::optional pathFilters ) { mApp->hideLocateBar(); mApp->hideSearchBar(); mApp->hideStatusTerminal(); @@ -606,6 +607,8 @@ void GlobalSearchController::showGlobalSearch( bool searchReplace ) { searchReplace, escapeSequenceChk->isChecked() ); } } + if ( mGlobalSearchWhereInput && pathFilters ) + mGlobalSearchWhereInput->setText( *pathFilters ); updateGlobalSearchBar(); mApp->getStatusBar()->updateState(); } diff --git a/src/tools/ecode/globalsearchcontroller.hpp b/src/tools/ecode/globalsearchcontroller.hpp index 25314521f..7ea91bc03 100644 --- a/src/tools/ecode/globalsearchcontroller.hpp +++ b/src/tools/ecode/globalsearchcontroller.hpp @@ -55,7 +55,7 @@ class GlobalSearchController { void showGlobalSearch(); - void showGlobalSearch( bool searchAndReplace ); + void showGlobalSearch( bool searchAndReplace, std::optional pathFilters = {} ); void updateColorScheme( const SyntaxColorScheme& colorScheme ); diff --git a/src/tools/ecode/plugins/plugincontextprovider.hpp b/src/tools/ecode/plugins/plugincontextprovider.hpp index f9b7bde3a..8eefd1d9c 100644 --- a/src/tools/ecode/plugins/plugincontextprovider.hpp +++ b/src/tools/ecode/plugins/plugincontextprovider.hpp @@ -142,6 +142,11 @@ class PluginContextProvider { bool forcePreview = false, bool forceTab = false ) = 0; virtual void loadImageFromPath( const std::string& path ) = 0; + + virtual void loadFolder( std::string path, bool forceNewWindow = false ) = 0; + + virtual void showGlobalSearch( bool searchAndReplace, + std::optional pathFilters = {} ) = 0; }; } // namespace ecode diff --git a/src/tools/ecode/projectbuild.cpp b/src/tools/ecode/projectbuild.cpp index 4e3a81269..e67a57bbb 100644 --- a/src/tools/ecode/projectbuild.cpp +++ b/src/tools/ecode/projectbuild.cpp @@ -836,7 +836,7 @@ void ProjectBuildManager::runConfig( StatusAppOutputController* saoc ) { finalBuild.cmd = finalBuild.workingDir + finalBuild.cmd; } - auto cmd = finalBuild.cmd + " " + finalBuild.args; + auto cmd = finalBuild.cmd + ( !finalBuild.args.empty() ? ( " " + finalBuild.args ) : "" ); if ( finalBuild.runInTerminal ) { UITerminal* term = mApp->getTerminalManager()->createTerminalInSplitter( finalBuild.workingDir, "", {}, {}, false ); diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index eec714c07..9356ff2b7 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -47,9 +47,13 @@ void SettingsMenu::createSettingsMenu( App* app, UIMenuBar* menuBar ) { getKeybind( "open-file" ) ) ->setId( "open-file" ); mSettingsMenu - ->add( i18n( "open_folder_ellipsis", "Open Folder..." ), findIcon( "document-open" ), - getKeybind( "open-folder" ) ) + ->add( i18n( "open_folder_in_fm", "Open Folder in File Manager" ), + findIcon( "document-open" ), getKeybind( "open-folder" ) ) ->setId( "open-folder" ); + mSettingsMenu + ->add( i18n( "open_folder_in_new_window", "Open Folder in New ecode Window" ), + findIcon( "folder-open" ) ) + ->setId( "open-folder-in-new-window" ); mSettingsMenu ->add( i18n( "open_file_from_web_ellipsis", "Open File from Web..." ), findIcon( "download-cloud" ), getKeybind( "download-file-web" ) ) @@ -1066,7 +1070,7 @@ UIMenu* SettingsMenu::createEditMenu() { mEditMenu->addSeparator(); mEditMenu - ->add( i18n( "open_containing_folder_ellipsis", "Open Containing Folder..." ), + ->add( i18n( "open_containing_folder_in_fm", "Open Containing Folder in File Manager" ), findIcon( "folder-open" ), getKeybind( "open-containing-folder" ) ) ->setId( "open-containing-folder" ); mEditMenu @@ -2284,9 +2288,15 @@ void SettingsMenu::createProjectTreeMenu() { mProjectTreeMenu ->add( i18n( "new_folder_ellipsis", "New Folder..." ), findIcon( "folder-add" ) ) ->setId( "new_folder" ); + mProjectTreeMenu->addSeparator(); mProjectTreeMenu - ->add( i18n( "open_folder_ellipsis", "Open Folder..." ), findIcon( "folder-open" ) ) + ->add( i18n( "open_folder_in_fm", "Open Folder in File Manager" ), + findIcon( "folder-open" ) ) ->setId( "open_folder" ); + mProjectTreeMenu + ->add( i18n( "open_folder_in_new_window", "Open Folder in New ecode Window" ), + findIcon( "folder-open" ) ) + ->setId( "open-folder-in-new-window" ); mProjectTreeMenu ->add( i18n( "execute_dir_in_terminal", "Open directory in terminal" ), findIcon( "filetype-bash" ) ) @@ -2311,8 +2321,13 @@ void SettingsMenu::createProjectTreeMenu() { ->setId( "configure-ignore-files" ); } else if ( !mApp->getFileSystemModel() ) { mProjectTreeMenu - ->add( i18n( "open_folder_ellipsis", "Open Folder..." ), findIcon( "folder-open" ) ) + ->add( i18n( "open_folder_in_fm", "Open Folder in File Manager" ), + findIcon( "folder-open" ) ) ->setId( "open-folder" ); + mProjectTreeMenu + ->add( i18n( "open_folder_in_new_window", "Open Folder in New ecode Window" ), + findIcon( "folder-open" ) ) + ->setId( "open_folder_in_new_window" ); } mProjectTreeMenu->on( Event::OnItemClicked, [this]( const Event* event ) { @@ -2320,12 +2335,16 @@ void SettingsMenu::createProjectTreeMenu() { return; UIMenuItem* item = event->getNode()->asType(); std::string id( item->getId() ); + if ( id.empty() ) + return; if ( "new_file" == id || "new_file_in_place" == id ) { mApp->newFile( FileInfo( mApp->getCurrentProject() ) ); } else if ( "new_folder" == id ) { mApp->newFolder( FileInfo( mApp->getCurrentProject() ) ); } else if ( "open_folder" == id ) { Engine::instance()->openURI( mApp->getCurrentProject() ); + } else if ( "open_folder_in_new_window" == id ) { + mApp->loadFolder( mApp->getCurrentProject(), true ); } else if ( "execute_dir_in_terminal" == id ) { mApp->getTerminalManager()->createNewTerminal( "", nullptr, mApp->getCurrentProject() ); } else if ( "show-hidden-files" == id ) { @@ -2365,20 +2384,31 @@ void SettingsMenu::createProjectTreeMenu( const FileInfo& file ) { mProjectTreeMenu ->add( i18n( "new_folder_ellipsis", "New Folder..." ), findIcon( "folder-add" ) ) ->setId( "new_folder" ); + mProjectTreeMenu->addSeparator(); mProjectTreeMenu - ->add( i18n( "open_folder_ellipsis", "Open Folder..." ), findIcon( "folder-open" ) ) + ->add( i18n( "open_folder_in_fm", "Open Folder in File Manager" ), + findIcon( "folder-open" ) ) ->setId( "open_folder" ); + mProjectTreeMenu + ->add( i18n( "open_folder_in_new_window", "Open Folder in New ecode Window" ), + findIcon( "folder-open" ) ) + ->setId( "open_folder_in_new_window" ); mProjectTreeMenu ->add( i18n( "open_all_files_in_folder", "Open All Files in Folder" ), findIcon( "folder-open" ) ) ->setId( "open_all_files_in_folder" ); + mProjectTreeMenu->addSeparator(); + mProjectTreeMenu + ->add( i18n( "find_in_folder_ellipsis", "Find in Folder..." ), + findIcon( "file-search" ) ) + ->setId( "find_in_folder" ); } else { mProjectTreeMenu->add( i18n( "open_file", "Open File" ), findIcon( "document-open" ) ) ->setId( "open_file" ); mProjectTreeMenu - ->add( i18n( "open_containing_folder_ellipsis", "Open Containing Folder..." ), + ->add( i18n( "open_containing_folder_in_fm", "Open Containing Folder in File Manager" ), findIcon( "folder-open" ) ) - ->setId( "open_containing_folder" ); + ->setId( "open_containing_folder_in_fm" ); mProjectTreeMenu ->add( i18n( "new_file_in_directory_ellipsis", "New File in directory..." ), findIcon( "file-add" ) ) @@ -2464,12 +2494,20 @@ void SettingsMenu::createProjectTreeMenu( const FileInfo& file ) { } ); } else if ( "rename" == id ) { mApp->renameFile( file ); - } else if ( "open_containing_folder" == id ) { + } else if ( "open_containing_folder_in_fm" == id ) { Engine::instance()->openURI( file.getDirectoryPath() ); } else if ( "open_folder" == id ) { Engine::instance()->openURI( file.getFilepath() ); + } else if ( "open_folder_in_new_window" == id ) { + mApp->loadFolder( file.getFilepath(), true ); } else if ( "open_all_files_in_folder" == id ) { mApp->openAllFilesInFolder( file ); + } else if ( "find_in_folder" == id ) { + std::string folder = file.getFilepath(); + FileSystem::filePathRemoveBasePath( mApp->getCurrentProject(), folder ); + FileSystem::dirAddSlashAtEnd( folder ); + folder += "*"; + mApp->showGlobalSearch( false, folder ); } else if ( "show-hidden-files" == id ) { mApp->toggleHiddenFiles(); } else if ( "execute_in_terminal" == id ) { diff --git a/src/tools/ecode/terminalmanager.cpp b/src/tools/ecode/terminalmanager.cpp index 66d3c83a4..8a61004e7 100644 --- a/src/tools/ecode/terminalmanager.cpp +++ b/src/tools/ecode/terminalmanager.cpp @@ -16,7 +16,8 @@ UITerminal* TerminalManager::createTerminalInSplitter( if ( !LuaPattern::hasMatches( os, "Windows 1%d"sv ) && !LuaPattern::hasMatches( os, "Windows Server 201[69]"sv ) && !LuaPattern::hasMatches( os, "Windows Server 202%d"sv ) ) { - displayError( workingDir ); + if ( fallback ) + displayError( workingDir ); return nullptr; } #endif @@ -318,7 +319,7 @@ std::string quoteString( std::string str ) { static int openExternal( const std::string& defShell, const std::string& cmd, const std::string& scriptsPath, const std::string& workingDir ) { // This is an utility bat script based in the Geany utility script called "geany-run-helper" - static const std::string RUN_HELPER = + static const std::string_view RUN_HELPER = R"shellscript(REM USAGE: ecode-run-helper DIRECTORY AUTOCLOSE COMMAND... REM unnecessary, but we get the directory @@ -353,9 +354,9 @@ if not %autoclose%==1 pause if ( !cmd.empty() && !scriptsPath.empty() ) { std::string runHelperPath = scriptsPath + "ecode-run-helper.bat"; bool canContinue = true; - if ( !FileSystem::fileExists( runHelperPath ) ) { - if ( !FileSystem::fileWrite( runHelperPath, RUN_HELPER ) ) - canContinue = false; + if ( !FileSystem::fileExists( runHelperPath ) && + !FileSystem::fileWrite( runHelperPath, RUN_HELPER ) ) { + canContinue = false; } if ( canContinue ) { std::string cmdDir = String::trim( FileSystem::fileRemoveFileName( cmd ) ); @@ -372,6 +373,7 @@ if not %autoclose%==1 pause } std::vector options; + options.reserve( 3 ); if ( !defShell.empty() ) options.push_back( defShell ); options.push_back( "cmd" ); @@ -393,7 +395,22 @@ if not %autoclose%==1 pause #elif EE_PLATFORM == EE_PLATFORM_MACOS static int openExternal( const std::string&, const std::string& cmd, const std::string&, const std::string& workingDir ) { - static const std::string externalShell = "open -a terminal"; + + std::vector options = { "ghostty", "iTerm2", "eterm" }; + for ( const auto& option : options ) { + auto externalShell( Sys::which( option ) ); + if ( !externalShell.empty() ) { + if ( !cmd.empty() ) { + auto fcmd = externalShell + " -e \"" + cmd + "\""; + Log::info( "Running: %s", fcmd ); + return Sys::execute( fcmd, workingDir ); + } else { + return Sys::execute( externalShell, workingDir ); + } + } + } + + static const std::string externalShell = "open -a terminal --args"; if ( !cmd.empty() ) { std::string fcmd = externalShell + " \"" + cmd + "\""; Log::info( "Running: %s", fcmd ); @@ -404,7 +421,7 @@ static int openExternal( const std::string&, const std::string& cmd, const std:: #else static int openExternal( const std::string&, const std::string& cmd, const std::string&, const std::string& workingDir ) { - std::vector options = { "gnome-terminal", "konsole", "xterm", "st" }; + std::vector options = { "gnome-terminal", "konsole", "eterm", "xterm", "st" }; for ( const auto& option : options ) { auto externalShell( Sys::which( option ) ); if ( !externalShell.empty() ) {