diff --git a/RedPandaIDE/compiler/compilermanager.cpp b/RedPandaIDE/compiler/compilermanager.cpp
index 44ddbe7e..f450c7fd 100644
--- a/RedPandaIDE/compiler/compilermanager.cpp
+++ b/RedPandaIDE/compiler/compilermanager.cpp
@@ -265,15 +265,21 @@ void CompilerManager::run(
sharedMemoryId,
localizePath(filename)
} + splitProcessCommand(arguments);
- auto [filename, args, fileOwner] = wrapCommandForTerminalEmulator(
- pSettings->environment().terminalPathForExec(),
- pSettings->environment().terminalArgumentsPattern(),
- execArgs
- );
- //delete when thread finished
- execRunner = new ExecutableRunner(filename, args, workDir);
- execRunner->setShareMemoryId(sharedMemoryId);
- mTempFileOwner = std::move(fileOwner);
+ if (pSettings->environment().useCustomTerminal()) {
+ auto [filename, args, fileOwner] = wrapCommandForTerminalEmulator(
+ pSettings->environment().terminalPathForExec(),
+ pSettings->environment().terminalArgumentsPattern(),
+ execArgs
+ );
+ //delete when thread finished
+ execRunner = new ExecutableRunner(filename, args, workDir);
+ execRunner->setShareMemoryId(sharedMemoryId);
+ mTempFileOwner = std::move(fileOwner);
+ } else {
+ //delete when thread finished
+ execRunner = new ExecutableRunner(execArgs[0], execArgs.mid(1), workDir);
+ execRunner->setShareMemoryId(sharedMemoryId);
+ }
} else {
//delete when thread finished
execRunner = new ExecutableRunner(filename,splitProcessCommand(arguments),workDir);
diff --git a/RedPandaIDE/defaultconfigs.qrc b/RedPandaIDE/defaultconfigs.qrc
index bdd1afea..fbdb565d 100644
--- a/RedPandaIDE/defaultconfigs.qrc
+++ b/RedPandaIDE/defaultconfigs.qrc
@@ -3,5 +3,7 @@
resources/autolink.json
resources/codesnippets.json
resources/autolink-xdg.json
+ resources/terminal-windows.json
+ resources/terminal-unix.json
diff --git a/RedPandaIDE/resources/terminal-unix.json b/RedPandaIDE/resources/terminal-unix.json
new file mode 100644
index 00000000..72d5393d
--- /dev/null
+++ b/RedPandaIDE/resources/terminal-unix.json
@@ -0,0 +1,207 @@
+[
+ {
+ "group": "User Installed",
+ "terminals": [
+ {
+ "name": "Alacritty",
+ "path": "alacritty",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "cool-retro-term",
+ "path": "cool-retro-term",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "CoreTerminal",
+ "path": "coreterminal",
+ "argsPattern": "$term -e \"$command\"",
+ "comment": "The pair of quotation mark around `$command` is only a visual symbol, not actually required."
+ },
+ {
+ "name": "iTerm2",
+ "path": "/Applications/iTerm.app/Contents/MacOS/iTerm2",
+ "argsPattern": "$term $tmpfile"
+ },
+ {
+ "name": "kermit",
+ "path": "kermit",
+ "argsPattern": "$term -e \"$command\""
+ },
+ {
+ "name": "Kitty",
+ "path": "kitty",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "ROXTerm",
+ "path": "roxterm",
+ "argsPattern": "$term -e \"$command\""
+ },
+ {
+ "name": "sakura",
+ "path": "sakura",
+ "argsPattern": "$term -e \"$command\""
+ },
+ {
+ "name": "Termit",
+ "path": "termit",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "Termite",
+ "path": "termite",
+ "argsPattern": "$term -e \"$command\""
+ },
+ {
+ "name": "Tilix",
+ "path": "tilix",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "Wayst",
+ "path": "wayst",
+ "argsPattern": "$term -e $argv"
+ }
+ ]
+ },
+ {
+ "group": "Desktop Default",
+ "terminals": [
+ {
+ "name": "Deepin Terminal",
+ "path": "deepin-terminal",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "Konsole (KDE)",
+ "path": "konsole",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "GNOME Terminal",
+ "path": "gnome-terminal",
+ "argsPattern": "$term -- $argv"
+ },
+ {
+ "name": "GNOME Terminator",
+ "path": "terminator",
+ "argsPattern": "$term -x $argv"
+ },
+ {
+ "name": "LXTerminal (LXDE)",
+ "path": "lxterminal",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "MATE Terminal",
+ "path": "mate-terminal",
+ "argsPattern": "$term -x $argv"
+ },
+ {
+ "name": "QTerminal (LXQt)",
+ "path": "qterminal",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "Terminal.app (macOS 10.14 or earlier)",
+ "path": "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal",
+ "argsPattern": "$term $tmpfile"
+ },
+ {
+ "name": "Terminal.app (macOS 10.15 or later)",
+ "path": "/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal",
+ "argsPattern": "$term $tmpfile"
+ },
+ {
+ "name": "Terminology (Enlightenment)",
+ "path": "terminology",
+ "argsPattern": "$term -e \"$command\""
+ },
+ {
+ "name": "Xfce Terminal",
+ "path": "xfce4-terminal",
+ "argsPattern": "$term -x $argv"
+ }
+ ]
+ },
+ {
+ "group": "Bundled",
+ "terminals": [
+ {
+ "name": "Alacritty (Bundled)",
+ "path": "./alacritty",
+ "argsPattern": "$term -e $argv"
+ }
+ ]
+ },
+ {
+ "group": "With minor issue",
+ "terminals": [
+ {
+ "name": "Elementary Terminal",
+ "path": "io.elementary.terminal",
+ "argsPattern": "$term -e \"$command\"",
+ "comment": "confirm to quit"
+ },
+ {
+ "name": "foot",
+ "path": "foot",
+ "argsPattern": "$term -e $argv",
+ "comment": "wayland only"
+ },
+ {
+ "name": "GNOME Console",
+ "path": "kgx",
+ "argsPattern": "$term -- $argv",
+ "comment": "confirm to quit"
+ },
+ {
+ "name": "mlterm",
+ "path": "mlterm",
+ "argsPattern": "$term -e $argv",
+ "comment": "no out of box HiDPI support"
+ },
+ {
+ "name": "st",
+ "path": "st",
+ "argsPattern": "$term -e $argv",
+ "comment": "no out of box HiDPI support"
+ },
+ {
+ "name": "urxvt",
+ "path": "urxvt",
+ "argsPattern": "$term -e $argv",
+ "comment": "no out of box HiDPI support"
+ },
+ {
+ "name": "xterm",
+ "path": "xterm",
+ "argsPattern": "$term -e $argv",
+ "comment": "no out of box HiDPI support"
+ },
+ {
+ "name": "zutty",
+ "path": "zutty",
+ "argsPattern": "$term -e $argv",
+ "comment": "no out of box HiDPI support"
+ }
+ ]
+ },
+ {
+ "group": "Unavailable",
+ "terminals": [],
+ "unavailableTerminals": {
+ "aterm": "AUR broken, unable to test",
+ "eterm": "AUR broken, unable to test",
+ "guake": "drop down terminal",
+ "hyper": "no execute support",
+ "liri-terminal": "no execute support",
+ "rxvt": "no unicode support",
+ "shellinabox": "AUR broken, unable to test",
+ "station": "no execute support",
+ "tilda": "drop down terminal",
+ "yakuake": "drop down terminal"
+ }
+ }
+]
diff --git a/RedPandaIDE/resources/terminal-windows.json b/RedPandaIDE/resources/terminal-windows.json
new file mode 100644
index 00000000..729eaf4f
--- /dev/null
+++ b/RedPandaIDE/resources/terminal-windows.json
@@ -0,0 +1,52 @@
+[
+ {
+ "group": "Bundled",
+ "terminals": [
+ {
+ "name": "UTF-8 compatible Console Host",
+ "path": "./OpenConsole.exe",
+ "argsPattern": "$term -- $argv"
+ }
+ ]
+ },
+ {
+ "group": "System",
+ "terminals": [
+ {
+ "name": "System Default",
+ "path": "",
+ "argsPattern": "$argv"
+ }
+ ]
+ },
+ {
+ "group": "Predefined arguments pattern (will not be searched)",
+ "terminals": [
+ {
+ "name": "Console Host",
+ "path": "conhost.exe",
+ "argsPattern": "$term -- $argv"
+ },
+ {
+ "name": "Windows Terminal",
+ "path": "wt.exe",
+ "argsPattern": "$term -- $argv"
+ },
+ {
+ "name": "Alacritty",
+ "path": "alacritty.exe",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "Konsole",
+ "path": "konsole.exe",
+ "argsPattern": "$term -e $argv"
+ },
+ {
+ "name": "Mintty",
+ "path": "mintty.exe",
+ "argsPattern": "$term -e $argv"
+ }
+ ]
+ }
+]
diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp
index 6587f6be..17cc6d24 100644
--- a/RedPandaIDE/settings.cpp
+++ b/RedPandaIDE/settings.cpp
@@ -27,6 +27,9 @@
#include
#include
#include
+#include
+#include
+#include
#ifdef Q_OS_LINUX
#include
#endif
@@ -3608,146 +3611,46 @@ void Settings::Environment::doLoad()
mDefaultOpenFolder = QDir::currentPath();
}
- using AP = TerminalEmulatorArgumentsPattern;
- struct TerminalSearchItem {
- QString appName;
- AP argsPattern;
- };
-
#ifdef Q_OS_WINDOWS
- const TerminalSearchItem terminals[] {
- /* explicitly installed terminals */
-
- /* system */
- {"conhost.exe", AP::ImplicitSystem}, // dummy for system default
-
- /* will not actually be searched, just a list for users who dig into here */
- {"conhost.exe", AP::MinusMinusAppendArgs}, // yes, it accepts GNU-style (--) arguments
- {"wt.exe", AP::MinusMinusAppendArgs}, // generally okay, but “Test” does not work
- {"alacritty.exe", AP::MinusEAppendArgs}, // GPU-accelerated
- {"C:/Program Files/Alacritty/alacritty.exe", AP::MinusEAppendArgs},
- {"C:/Program Files/konsole/bin/konsole.exe", AP::MinusEAppendArgs}, // generally okay, but “Test” does not work
- {"C:/Program Files/Git/usr/bin/mintty.exe", AP::MinusEAppendArgs}, // Git Mintty
- {"C:/msys64/usr/bin/mintty.exe", AP::MinusEAppendArgs}, // MSYS2 Mintty
- };
-#else
- const TerminalSearchItem terminals[] {
- /* modern, specialized or stylized terminal -- user who installed them are likely to prefer them */
- {"alacritty", AP::MinusEAppendArgs}, // GPU-accelerated
- {"kitty", AP::MinusEAppendArgs}, // GPU-accelerated
- {"wayst", AP::MinusEAppendArgs}, // GPU-accelerated
-
- {"coreterminal", AP::MinusEAppendCommandLine}, // lightweighted
- {"kermit", AP::MinusEAppendCommandLine}, // lightweighted
- {"roxterm", AP::MinusEAppendCommandLine}, // lightweighted
- {"sakura", AP::MinusEAppendCommandLine}, // lightweighted
- {"termit", AP::MinusEAppendArgs}, // Lua scripting
- {"termite", AP::MinusEAppendCommandLine}, // tiling, keyboard-centric
- {"tilix", AP::MinusEAppendArgs}, // tiling
-
- {"cool-retro-term", AP::MinusEAppendArgs}, // old CRT style
-
- /* default terminal for XDG DE -- macOS user who installed them are likely to prefer them */
- {"deepin-terminal", AP::MinusEAppendArgs}, // DDE
- {"konsole", AP::MinusEAppendArgs}, // KDE
- {"gnome-terminal", AP::MinusMinusAppendArgs}, // GNOME
- {"io.elementary.terminal", AP::MinusEAppendCommandLine}, // Pantheon (elementary OS)
- {"lxterminal", AP::MinusEAppendArgs}, // LXDE
- {"mate-terminal", AP::MinusXAppendArgs}, // MATE
- {"qterminal", AP::MinusEAppendArgs}, // LXQt
- {"terminator", AP::MinusXAppendArgs}, // tiling, also seen in SBC images
- {"terminology", AP::MinusEAppendCommandLine}, // Enlightenment
- {"xfce4-terminal", AP::MinusXAppendArgs}, // Xfce
-
- /* bundled terminal in AppImage */
- {"./alacritty", AP::MinusEAppendArgs},
-
- /* compatible, with minor issue */
- {"kgx", AP::MinusMinusAppendArgs}, // GNOME Console, confirm to quit
-
- /* compatible, without out-of-box hidpi support on Linux */
- {"mlterm", AP::MinusEAppendArgs},
- {"st", AP::MinusEAppendArgs},
- {"urxvt", AP::MinusEAppendArgs},
- {"xterm", AP::MinusEAppendArgs},
- {"zutty", AP::MinusEAppendArgs},
-
- /* macOS system */
- {"/Applications/iTerm.app/Contents/MacOS/iTerm2", AP::WriteCommandLineToTempFileThenTempFilename},
- {"/System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal", AP::WriteCommandLineToTempFileThenTempFilename},
- {"/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal", AP::WriteCommandLineToTempFileThenTempFilename},
-
- /* fallbacks */
- {"foot", AP::MinusEAppendArgs}, // Wayland only
-
- /* parameter incompatible */
- // "guake", // drop down
- // "hyper", // no execute support
- // "liri-terminal", // no execute support
- // "station", // no execute support
- // "tilda", // drop down
-
- /* incompatible -- other */
- // "aterm", // AUR broken, unable to test
- // "eterm", // AUR broken, unable to test
- // "rxvt", // no unicode support
- // "shellinabox", // AUR broken, unable to test
- };
+# if defined (__aarch64__) || defined(_M_ARM64) || defined (_M_ARM64EC)
+ // the only native MinGW toolchain (LLVM-MinGW) does not have local codepage support
+ // prefer UTF-8 compatible OpenConsole.exe
+ mUseCustomTerminal = boolValue("use_custom_terminal", true);
+# else // x86 or x64
+ mUseCustomTerminal = boolValue("use_custom_terminal", false);
+# endif
+#else // UNIX
+ mUseCustomTerminal = true;
#endif
- auto checkAndSetTerminalPath = [this](const TerminalSearchItem &searchItem) -> bool {
-#define DO_CHECK_AND_SET do { \
- if (termPathInfo.isFile() && termPathInfo.isReadable() && termPathInfo.isExecutable()) { \
- mTerminalPath = searchItem.appName; \
- mTerminalArgumentsPattern = searchItem.argsPattern; \
- return true; \
- } \
- } while (0)
-
- switch (getPathUnixExecSemantics(searchItem.appName)) {
- case UnixExecSemantics::Absolute: {
- QFileInfo termPathInfo(searchItem.appName);
- DO_CHECK_AND_SET;
- break;
- }
- case UnixExecSemantics::RelativeToCwd: {
- QDir appDir(pSettings->dirs().appDir());
- QString absoluteTerminalPath = appDir.absoluteFilePath(searchItem.appName);
- QFileInfo termPathInfo(absoluteTerminalPath);
- DO_CHECK_AND_SET;
- break;
- }
- case UnixExecSemantics::SearchInPath: {
- QStringList pathList = getExecutableSearchPaths();
- for (const QString &dir: pathList) {
- QString absoluteTerminalPath = QDir(dir).absoluteFilePath(searchItem.appName);
- QFileInfo termPathInfo(absoluteTerminalPath);
- DO_CHECK_AND_SET;
- }
- break;
- }
- }
- return false;
- };
-#undef DO_CHECK_AND_SET
+#ifdef Q_OS_WINDOWS
+ QString terminalListFilename(":/config/terminal-windows.json");
+#else // UNIX
+ QString terminalListFilename(":/config/terminal-unix.json");
+#endif
+ QFile terminalListFile(terminalListFilename);
+ if (!terminalListFile.open(QFile::ReadOnly))
+ throw FileError(QObject::tr("Can't open file '%1' for read.")
+ .arg(terminalListFilename));
+ QByteArray terminalListContent = terminalListFile.readAll();
+ QJsonDocument terminalListDocument(QJsonDocument::fromJson(terminalListContent));
// check saved terminal path
QString savedTerminalPath = stringValue("terminal_path", "");
- int savedArgsPattern_ = intValue("terminal_arguments_pattern",
-#ifdef Q_OS_MACOS
- // macOS: old versions have set Terminal.app as default terminal
- // fallback to temp file to work with Terminal.app for smooth migration
- int(AP::WriteCommandLineToTempFileThenTempFilename)
-#else
- int(AP::MinusEAppendArgs) // Linux: keep old behaviour
-#endif
- );
- AP savedArgsPattern = static_cast(savedArgsPattern_);
- if (!checkAndSetTerminalPath(TerminalSearchItem{savedTerminalPath, savedArgsPattern})) {
- // if saved terminal path is invalid, try determing terminal from our list
- for (auto terminal: terminals) {
- if (checkAndSetTerminalPath(terminal))
- break;
+ QString savedArgsPattern = stringValue("terminal_arguments_pattern", "");
+ bool terminalSet = checkAndSetTerminal(savedTerminalPath, savedArgsPattern);
+
+ // determing terminal (if not set yet) and build predefined arguments pattern map from our list
+ for (const auto &terminalGroup: terminalListDocument.array()) {
+ const QJsonArray &terminals = terminalGroup.toObject()["terminals"].toArray();
+ for (const auto &terminal_: terminals) {
+ const QJsonObject &terminal = terminal_.toObject();
+ const QString &path = terminal["path"].toString();
+ const QString &executable = QFileInfo(path).fileName();
+ const QString &pattern = terminal["argsPattern"].toString();
+ mPredefinedTerminalArgumentsPattern[executable] = pattern;
+ if (!terminalSet)
+ terminalSet = checkAndSetTerminal(path, pattern);
}
}
@@ -3835,12 +3738,12 @@ void Settings::Environment::setAStylePath(const QString &aStylePath)
mAStylePath = aStylePath;
}
-TerminalEmulatorArgumentsPattern Settings::Environment::terminalArgumentsPattern() const
+QString Settings::Environment::terminalArgumentsPattern() const
{
return mTerminalArgumentsPattern;
}
-void Settings::Environment::setTerminalArgumentsPattern(const TerminalEmulatorArgumentsPattern &argsPattern)
+void Settings::Environment::setTerminalArgumentsPattern(const QString &argsPattern)
{
mTerminalArgumentsPattern = argsPattern;
}
@@ -3895,6 +3798,89 @@ void Settings::Environment::setIconZoomFactor(double newIconZoomFactor)
mIconZoomFactor = newIconZoomFactor;
}
+QMap Settings::Environment::predefinedTerminalArgumentsPattern() const
+{
+ return mPredefinedTerminalArgumentsPattern;
+}
+
+void Settings::Environment::setPredefinedTerminalArgumentsPattern(const QMap &newPredefinedTerminalArgumentsPattern)
+{
+ mPredefinedTerminalArgumentsPattern = newPredefinedTerminalArgumentsPattern;
+}
+
+std::unique_ptr Settings::Environment::queryPredefinedTerminalArgumentsPattern(const QString &executable) const
+{
+ auto it = mPredefinedTerminalArgumentsPattern.find(executable);
+ if (it != mPredefinedTerminalArgumentsPattern.end())
+ return std::make_unique(*it);
+ else
+ return nullptr;
+}
+
+bool Settings::Environment::useCustomTerminal() const
+{
+ return mUseCustomTerminal;
+}
+
+void Settings::Environment::setUseCustomTerminal(bool newUseCustomTerminal)
+{
+ mUseCustomTerminal = newUseCustomTerminal;
+}
+
+bool Settings::Environment::checkAndSetTerminal(QString terminalPath, QString argsPattern)
+{
+ QStringList patternItems = splitProcessCommand(argsPattern);
+
+ if (patternItems.empty() ||
+ !(patternItems.contains("$argv") || patternItems.contains("$command") || patternItems.contains("$tmpfile")) // program not referenced
+ )
+ return false;
+
+ // `term` is not referenced ("$argv"),
+ // or is not directly called ("open -app $term -args $tmpfile"),
+ // do not check terminal path
+ if (patternItems[0] != "$term") {
+ setTerminalPath(terminalPath);
+ setTerminalArgumentsPattern(argsPattern);
+ return true;
+ }
+
+#define DO_CHECK_AND_SET do { \
+ if (termPathInfo.isFile() && termPathInfo.isReadable() && termPathInfo.isExecutable()) { \
+ mTerminalPath = terminalPath; \
+ mTerminalArgumentsPattern = argsPattern; \
+ return true; \
+ } \
+ } while (0)
+
+ switch (getPathUnixExecSemantics(terminalPath)) {
+ case UnixExecSemantics::Absolute: {
+ QFileInfo termPathInfo(terminalPath);
+ DO_CHECK_AND_SET;
+ break;
+ }
+ case UnixExecSemantics::RelativeToCwd: {
+ QDir appDir(pSettings->dirs().appDir());
+ QString absoluteTerminalPath = appDir.absoluteFilePath(terminalPath);
+ QFileInfo termPathInfo(absoluteTerminalPath);
+ DO_CHECK_AND_SET;
+ break;
+ }
+ case UnixExecSemantics::SearchInPath: {
+ QStringList pathList = getExecutableSearchPaths();
+ for (const QString &dir: pathList) {
+ QString absoluteTerminalPath = QDir(dir).absoluteFilePath(terminalPath);
+ QFileInfo termPathInfo(absoluteTerminalPath);
+ DO_CHECK_AND_SET;
+ }
+ break;
+ }
+ }
+#undef DO_CHECK_AND_SET
+
+ return false;
+}
+
void Settings::Environment::doSave()
{
//Appearance
@@ -3910,7 +3896,10 @@ void Settings::Environment::doSave()
saveValue("current_folder",mCurrentFolder);
saveValue("default_open_folder",mDefaultOpenFolder);
saveValue("terminal_path",mTerminalPath);
- saveValue("terminal_arguments_pattern",int(mTerminalArgumentsPattern));
+ saveValue("terminal_arguments_pattern",mTerminalArgumentsPattern);
+#ifdef Q_OS_WINDOWS
+ saveValue("use_custom_terminal",mUseCustomTerminal);
+#endif
saveValue("asyle_path",mAStylePath);
saveValue("hide_non_support_files_file_view",mHideNonSupportFilesInFileView);
diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h
index 6b606e4a..933bfdf2 100644
--- a/RedPandaIDE/settings.h
+++ b/RedPandaIDE/settings.h
@@ -575,8 +575,8 @@ public:
QString AStylePath() const;
void setAStylePath(const QString &aStylePath);
- TerminalEmulatorArgumentsPattern terminalArgumentsPattern() const;
- void setTerminalArgumentsPattern(const TerminalEmulatorArgumentsPattern &argsPattern);
+ QString terminalArgumentsPattern() const;
+ void setTerminalArgumentsPattern(const QString &argsPattern);
bool useCustomIconSet() const;
void setUseCustomIconSet(bool newUseCustomIconSet);
@@ -593,7 +593,22 @@ public:
double iconZoomFactor() const;
void setIconZoomFactor(double newIconZoomFactor);
+ QJsonArray availableTerminals() const;
+ void setAvailableTerminals(const QJsonArray &availableTerminals);
+
+ QMap predefinedTerminalArgumentsPattern() const;
+ void setPredefinedTerminalArgumentsPattern(const QMap &newPredefinedTerminalArgumentsPattern);
+ // it should be `std::optional`.
+ // `std::unique_ptr` is a work around for Debian 10, where Qt 5.11 doesnt recognize `CONFIG += c++17`,
+ // and macOS, where official Qt 5.15 is built against macOS 10.13 and `std::optional` is explicitly disabled.
+ std::unique_ptr queryPredefinedTerminalArgumentsPattern(const QString &executable) const;
+
+ bool useCustomTerminal() const;
+ void setUseCustomTerminal(bool newUseCustomTerminal);
+
private:
+ bool checkAndSetTerminal(QString terminalPath, QString argsPattern);
+ bool updateTerminalList();
//Appearance
QString mTheme;
@@ -609,7 +624,9 @@ public:
QString mDefaultOpenFolder;
QString mTerminalPath;
QString mAStylePath;
- TerminalEmulatorArgumentsPattern mTerminalArgumentsPattern;
+ QString mTerminalArgumentsPattern;
+ QMap mPredefinedTerminalArgumentsPattern;
+ bool mUseCustomTerminal;
bool mHideNonSupportFilesInFileView;
bool mOpenFilesInSingleInstance;
// _Base interface
diff --git a/RedPandaIDE/settingsdialog/environmentprogramswidget.cpp b/RedPandaIDE/settingsdialog/environmentprogramswidget.cpp
index 43fbc57d..e0a8c630 100644
--- a/RedPandaIDE/settingsdialog/environmentprogramswidget.cpp
+++ b/RedPandaIDE/settingsdialog/environmentprogramswidget.cpp
@@ -22,21 +22,16 @@
#include "../compiler/executablerunner.h"
#include
+#include
EnvironmentProgramsWidget::EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent) :
SettingsWidget(name,group,parent),
ui(new Ui::EnvironmentProgramsWidget)
{
ui->setupUi(this);
- QFont monoFont(DEFAULT_MONO_FONT);
- ui->rbImplicitSystem->setFont(monoFont);
- ui->rbMinusEAppendArgs->setFont(monoFont);
- ui->rbMinusXAppendArgs->setFont(monoFont);
- ui->rbMinusMinusAppendArgs->setFont(monoFont);
- ui->rbMinusEAppendCommandLine->setFont(monoFont);
- ui->rbWriteCommandLineToTempFileThenTempFilename->setFont(monoFont);
-#ifndef Q_OS_MACOS
- hideMacosSpecificPattern();
+ ui->labelCmdPreviewResult->setFont(QFont(DEFAULT_MONO_FONT));
+#ifndef Q_OS_WINDOWS
+ ui->grpUseCustomTerminal->setCheckable(false);
#endif
}
@@ -45,68 +40,67 @@ EnvironmentProgramsWidget::~EnvironmentProgramsWidget()
delete ui;
}
-void EnvironmentProgramsWidget::hideMacosSpecificPattern()
+auto EnvironmentProgramsWidget::resolveExecArguments(const QString &terminalPath, const QString &argsPattern)
+ -> std::tuple>
{
- ui->rbWriteCommandLineToTempFileThenTempFilename->setVisible(false);
- ui->rbWriteCommandLineToTempFileThenTempFilename->setEnabled(false);
- ui->pbWriteCommandLineToTempFileThenTempFilename->setVisible(false);
- ui->pbWriteCommandLineToTempFileThenTempFilename->setEnabled(false);
+ QString terminalPathForExec;
+ if (getPathUnixExecSemantics(terminalPath) == UnixExecSemantics::RelativeToCwd) {
+ QDir appDir(pSettings->dirs().appDir());
+ terminalPathForExec = appDir.absoluteFilePath(terminalPath);
+ } else
+ terminalPathForExec = terminalPath;
+
+ QString shell = defaultShell();
+ QStringList payloadArgs{shell, "-c", "echo hello; sleep 3"};
+ return wrapCommandForTerminalEmulator(terminalPathForExec, argsPattern, payloadArgs);
}
-void EnvironmentProgramsWidget::testTerminal(const TerminalEmulatorArgumentsPattern &pattern)
+void EnvironmentProgramsWidget::updateCommandPreview(const QString &terminalPath, const QString &argsPattern)
{
- auto [filename, arguments, fileOwner] = wrapCommandForTerminalEmulator(ui->txtTerminal->text(), pattern, {defaultShell(), "-c", "echo hello; sleep 3"});
- ExecutableRunner runner(filename, arguments, "", nullptr);
- runner.start();
- runner.wait();
+ auto [filename, arguments, fileOwner] = resolveExecArguments(terminalPath, argsPattern);
+ for (auto &arg : arguments)
+ arg = escapeArgument(arg, false);
+
+ ui->labelCmdPreviewResult->setText(escapeArgument(filename, true) + " " + arguments.join(' '));
+}
+
+void EnvironmentProgramsWidget::autoDetectAndUpdateArgumentsPattern(const QString &terminalPath)
+{
+ const QString &executable = QFileInfo(terminalPath).fileName();
+ const std::unique_ptr &pattern = pSettings->environment().queryPredefinedTerminalArgumentsPattern(executable);
+ if (pattern != nullptr)
+ ui->txtArgsPattern->setText(*pattern);
+ else
+ QMessageBox::warning(nullptr,
+ QObject::tr("Auto Detection Failed"),
+ QObject::tr("Failed to detect terminal arguments pattern for “%1”.").arg(executable),
+ QMessageBox::Ok);
}
void EnvironmentProgramsWidget::doLoad()
{
+#ifdef Q_OS_WINDOWS
+ ui->grpUseCustomTerminal->setChecked(pSettings->environment().useCustomTerminal());
+#endif
ui->txtTerminal->setText(pSettings->environment().terminalPath());
- switch (pSettings->environment().terminalArgumentsPattern()) {
- case TerminalEmulatorArgumentsPattern::ImplicitSystem:
- ui->rbImplicitSystem->setChecked(true);
- break;
- case TerminalEmulatorArgumentsPattern::MinusEAppendArgs:
- ui->rbMinusEAppendArgs->setChecked(true);
- break;
- case TerminalEmulatorArgumentsPattern::MinusXAppendArgs:
- ui->rbMinusXAppendArgs->setChecked(true);
- break;
- case TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs:
- ui->rbMinusMinusAppendArgs->setChecked(true);
- break;
- case TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine:
- ui->rbMinusEAppendCommandLine->setChecked(true);
- break;
- case TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename:
- ui->rbWriteCommandLineToTempFileThenTempFilename->setChecked(true);
- break;
- }
+ ui->txtArgsPattern->setText(pSettings->environment().terminalArgumentsPattern());
}
void EnvironmentProgramsWidget::doSave()
{
+#ifdef Q_OS_WINDOWS
+ pSettings->environment().setUseCustomTerminal(ui->grpUseCustomTerminal->isChecked());
+#endif
pSettings->environment().setTerminalPath(ui->txtTerminal->text());
- if (ui->rbImplicitSystem->isChecked())
- pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::ImplicitSystem);
- if (ui->rbMinusEAppendArgs->isChecked())
- pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusEAppendArgs);
- if (ui->rbMinusXAppendArgs->isChecked())
- pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusXAppendArgs);
- if (ui->rbMinusMinusAppendArgs->isChecked())
- pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs);
- if (ui->rbMinusEAppendCommandLine->isChecked())
- pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine);
- if (ui->rbWriteCommandLineToTempFileThenTempFilename->isChecked())
- pSettings->environment().setTerminalArgumentsPattern(TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename);
+ pSettings->environment().setTerminalArgumentsPattern(ui->txtArgsPattern->text());
pSettings->environment().save();
}
void EnvironmentProgramsWidget::updateIcons(const QSize &)
{
pIconsManager->setIcon(ui->btnChooseTerminal,IconsManager::ACTION_FILE_OPEN_FOLDER);
+ pIconsManager->setIcon(ui->btnAutoDetectArgsPattern,IconsManager::ACTION_EDIT_SEARCH);
+ pIconsManager->setIcon(ui->btnTest,IconsManager::ACTION_RUN_RUN);
}
void EnvironmentProgramsWidget::on_btnChooseTerminal_clicked()
@@ -118,64 +112,34 @@ void EnvironmentProgramsWidget::on_btnChooseTerminal_clicked()
tr("All files (%1)").arg(ALL_FILE_WILDCARD));
if (!filename.isEmpty() && fileExists(filename) ) {
ui->txtTerminal->setText(filename);
+ autoDetectAndUpdateArgumentsPattern(filename);
}
}
void EnvironmentProgramsWidget::on_txtTerminal_textChanged(const QString &terminalPath)
{
- QString terminalPathForExec;
- if (getPathUnixExecSemantics(terminalPath) == UnixExecSemantics::RelativeToCwd) {
- QDir appDir(pSettings->dirs().appDir());
- terminalPathForExec = appDir.absoluteFilePath(terminalPath);
- } else
- terminalPathForExec = terminalPath;
- QString terminalPathEscaped = escapeArgument(terminalPathForExec, true);
- QString shell = defaultShell();
- QStringList execArgs{shell, "-c", "echo hello; sleep 3"};
-
- auto displayCommand = [this, &execArgs](const TerminalEmulatorArgumentsPattern &pattern) {
- auto [filename, arguments, fileOwner] = wrapCommandForTerminalEmulator(ui->txtTerminal->text(), pattern, execArgs);
- for (auto &arg : arguments)
- arg = escapeArgument(arg, false);
- return escapeArgument(filename, true) + " " + arguments.join(' ');
- };
-
- ui->rbImplicitSystem->setText(displayCommand(TerminalEmulatorArgumentsPattern::ImplicitSystem));
- ui->rbMinusEAppendArgs->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusEAppendArgs));
- ui->rbMinusXAppendArgs->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusXAppendArgs));
- ui->rbMinusMinusAppendArgs->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs));
- ui->rbMinusEAppendCommandLine->setText(displayCommand(TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine));
- if (ui->rbWriteCommandLineToTempFileThenTempFilename->isEnabled())
- ui->rbWriteCommandLineToTempFileThenTempFilename->setText(displayCommand(TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename));
+ const QString &argsPattern = ui->txtArgsPattern->text();
+ updateCommandPreview(terminalPath, argsPattern);
}
-void EnvironmentProgramsWidget::on_pbImplicitSystem_clicked()
+void EnvironmentProgramsWidget::on_txtArgsPattern_textChanged(const QString &argsPattern)
{
- testTerminal(TerminalEmulatorArgumentsPattern::ImplicitSystem);
+ const QString &terminalPath = ui->txtTerminal->text();
+ updateCommandPreview(terminalPath, argsPattern);
}
-void EnvironmentProgramsWidget::on_pbMinusEAppendArgs_clicked()
+void EnvironmentProgramsWidget::on_btnAutoDetectArgsPattern_clicked()
{
- testTerminal(TerminalEmulatorArgumentsPattern::MinusEAppendArgs);
+ const QString &terminalPath = ui->txtTerminal->text();
+ autoDetectAndUpdateArgumentsPattern(terminalPath);
}
-void EnvironmentProgramsWidget::on_pbMinusXAppendArgs_clicked()
+void EnvironmentProgramsWidget::on_btnTest_clicked()
{
- testTerminal(TerminalEmulatorArgumentsPattern::MinusXAppendArgs);
+ const QString &terminalPath = ui->txtTerminal->text();
+ const QString &argsPattern = ui->txtArgsPattern->text();
+ auto [filename, arguments, fileOwner] = resolveExecArguments(terminalPath, argsPattern);
+ ExecutableRunner runner(filename, arguments, "", nullptr);
+ runner.start();
+ runner.wait();
}
-
-void EnvironmentProgramsWidget::on_pbMinusMinusAppendArgs_clicked()
-{
- testTerminal(TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs);
-}
-
-void EnvironmentProgramsWidget::on_pbMinusEAppendCommandLine_clicked()
-{
- testTerminal(TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine);
-}
-
-void EnvironmentProgramsWidget::on_pbWriteCommandLineToTempFileThenTempFilename_clicked()
-{
- testTerminal(TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename);
-}
-
diff --git a/RedPandaIDE/settingsdialog/environmentprogramswidget.h b/RedPandaIDE/settingsdialog/environmentprogramswidget.h
index 11c8cbb2..ce7b80c2 100644
--- a/RedPandaIDE/settingsdialog/environmentprogramswidget.h
+++ b/RedPandaIDE/settingsdialog/environmentprogramswidget.h
@@ -31,10 +31,12 @@ class EnvironmentProgramsWidget : public SettingsWidget
public:
explicit EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent = nullptr);
~EnvironmentProgramsWidget();
- void hideMacosSpecificPattern();
private:
- void testTerminal(const TerminalEmulatorArgumentsPattern &pattern);
+ auto resolveExecArguments(const QString &terminalPath, const QString &argsPatter)
+ -> std::tuple>;
+ void updateCommandPreview(const QString &terminalPath, const QString &argsPatter);
+ void autoDetectAndUpdateArgumentsPattern(const QString &terminalPath);
private:
Ui::EnvironmentProgramsWidget *ui;
@@ -47,12 +49,9 @@ protected:
private slots:
void on_btnChooseTerminal_clicked();
void on_txtTerminal_textChanged(const QString &terminalPath);
- void on_pbImplicitSystem_clicked();
- void on_pbMinusEAppendArgs_clicked();
- void on_pbMinusXAppendArgs_clicked();
- void on_pbMinusMinusAppendArgs_clicked();
- void on_pbMinusEAppendCommandLine_clicked();
- void on_pbWriteCommandLineToTempFileThenTempFilename_clicked();
+ void on_txtArgsPattern_textChanged(const QString &argsPattern);
+ void on_btnAutoDetectArgsPattern_clicked();
+ void on_btnTest_clicked();
};
#endif // ENVIRONMENTPROGRAMSWIDGET_H
diff --git a/RedPandaIDE/settingsdialog/environmentprogramswidget.ui b/RedPandaIDE/settingsdialog/environmentprogramswidget.ui
index 91243b04..b68e9a45 100644
--- a/RedPandaIDE/settingsdialog/environmentprogramswidget.ui
+++ b/RedPandaIDE/settingsdialog/environmentprogramswidget.ui
@@ -13,163 +13,100 @@
Form
-
- -
-
-
- -
-
-
- ...
-
-
-
- :/icons/images/newlook24/053-open.png:/icons/images/newlook24/053-open.png
-
-
-
- -
-
-
- Terminal
-
-
-
- -
-
+
+
-
+
- Terminal emulator arguments pattern
+ Use custom terminal
+
+
+ true
+
+
+ true
-
-
-
-
- sh -c "echo hello; sleep 3"
-
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
- -
-
+
-
+
- Test
+ $term -e $argv
-
-
+
+
+ Args. pattern
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/icons/images/newlook24/053-open.png:/icons/images/newlook24/053-open.png
+
+
+
+ -
+
+
+ Auto Detect Terminal Arguments Pattern
+
+
+ ...
+
+
+
+ :/icons/images/newlook24/087-update.png:/icons/images/newlook24/087-update.png
+
+
+
+ -
+
+
+ Terminal
+
+
+
+ -
+
+
+ Cmd. preview
+
+
+
+ -
+
term -e sh -c "echo hello; sleep 3"
- -
-
-
- Test
-
-
-
- -
-
-
- term -x sh -c "echo hello; sleep 3"
-
-
-
-
-
-
- Test
+
+
+ Test Command
-
-
- -
-
- term -- sh -c "echo hello; sleep 3"
+ ...
-
-
- -
-
-
- Test
-
-
-
- -
-
-
- term -e "sh -c \"echo hello; sleep 3\""
-
-
-
- -
-
-
- Test
-
-
-
- -
-
-
- term /tmp/redpanda_XXXXXX.command
-
-
-
- -
-
-
- Test
-
-
-
- -
-
-
- On clicking “Test” for the correct pattern, the terminal emulator
-
-
-
- -
-
-
- • pops up;
-
-
-
- -
-
-
- • shows “hello”; and
-
-
-
- -
-
-
- • quits in 3 seconds.
+
+
+ :/icons/images/newlook24/069-run.png:/icons/images/newlook24/069-run.png
- -
+
-
Qt::Vertical
diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts
index 865c7822..11709c75 100644
--- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts
+++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts
@@ -1958,52 +1958,32 @@
Todos os arquivos (%1)
-
-
-
-
-
-
-
-
-
-
- Testar
-
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
+
@@ -7077,6 +7057,14 @@
+
+
+
+
+
+
+
+
RegisterModel
diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts
index 2acbaf5a..15a3b65e 100644
--- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts
+++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts
@@ -2670,103 +2670,74 @@ Are you really want to continue?
编辑器共享同一个代码分析器
-
-
- EnvironmentProgramsWidget
-
-
-
- 表单
-
-
-
-
- ...
-
-
-
-
- 终端
-
-
-
-
- 终端模拟器参数模式
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 测试
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 点击正确的模式对应的 “测试” 按钮,终端模拟器将会
-
-
-
-
- • 弹出;
-
-
-
-
- • 显示 “hello”;
-
-
-
-
- • 并在 3 秒后关闭。
-
-
-
-
- 选择终端程序
-
-
-
-
- 所有文件 (%1)
-
-
-
- 所有文件 (*.*)
-
+
+EnvironmentProgramsWidget
+
+
+
+ 表单
+
+
+
+
+ 使用自定义终端
+
+
+
+
+
+
+ ...
+
+
+
+
+ 命令行预览
+
+
+
+
+ 自动检测终端参数模式
+
+
+
+
+ 终端
+
+
+
+
+ 测试命令
+
+
+
+
+
+
+
+
+
+ 参数模式
+
+
+
+
+
+
+
+
+
+ 选择终端程序
+
+
+
+
+ 所有文件 (%1)
+
+
+
+ 所有文件 (*.*)
+
EnvironmentShortcutModel
@@ -9633,6 +9604,16 @@ Are you really want to continue?
在写入文件“%1”时出错。
+
+
+
+ 自动检测失败
+
+
+
+
+ 无法检测适用于 “%1” 的终端参数模式。
+
RegisterModel
diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts
index 7ff0aaff..34007e4a 100644
--- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts
+++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts
@@ -1791,52 +1791,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
+
@@ -6602,6 +6582,14 @@
+
+
+
+
+
+
+
+
RegisterModel
diff --git a/RedPandaIDE/utils.cpp b/RedPandaIDE/utils.cpp
index 95d5fe02..d43371b7 100644
--- a/RedPandaIDE/utils.cpp
+++ b/RedPandaIDE/utils.cpp
@@ -723,49 +723,51 @@ QString escapeArgument(const QString &arg, [[maybe_unused]] bool isFirstArg)
#endif
}
-auto wrapCommandForTerminalEmulator(const QString &terminal, const TerminalEmulatorArgumentsPattern &argsPattern, const QStringList &argsWithArgv0)
+auto wrapCommandForTerminalEmulator(const QString &terminal, const QStringList &argsPattern, const QStringList &payloadArgsWithArgv0)
-> std::tuple>
{
- switch (argsPattern) {
- case TerminalEmulatorArgumentsPattern::ImplicitSystem:
- default: {
- return {argsWithArgv0[0], argsWithArgv0.mid(1), nullptr};
- }
- case TerminalEmulatorArgumentsPattern::MinusEAppendArgs: {
- return {terminal, QStringList{"-e"} + argsWithArgv0, nullptr};
- }
- case TerminalEmulatorArgumentsPattern::MinusXAppendArgs: {
- return {terminal, QStringList{"-x"} + argsWithArgv0, nullptr};
- }
- case TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs: {
- return {terminal, QStringList{"--"} + argsWithArgv0, nullptr};
- }
- case TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine: {
- QStringList escapedArgs;
- for (int i = 0; i < argsWithArgv0.length(); i++) {
- auto &arg = argsWithArgv0[i];
- auto escaped = escapeArgument(arg, i == 0);
- escapedArgs.append(escaped);
- }
- return {terminal, QStringList{"-e", escapedArgs.join(' ')}, nullptr};
- }
- case TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename: {
- auto fileOwner = std::make_unique(QDir::tempPath() + "/redpanda_XXXXXX.command");
- if (fileOwner->open()) {
+ QStringList wrappedArgs;
+ std::unique_ptr temproryFile;
+ for (const QString &patternItem : argsPattern) {
+ if (patternItem == "$term")
+ wrappedArgs.push_back(terminal);
+ else if (patternItem == "$argv")
+ wrappedArgs.append(payloadArgsWithArgv0);
+ else if (patternItem == "$command") {
QStringList escapedArgs;
- for (int i = 0; i < argsWithArgv0.length(); i++) {
- auto &arg = argsWithArgv0[i];
+ for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
+ auto &arg = payloadArgsWithArgv0[i];
auto escaped = escapeArgument(arg, i == 0);
escapedArgs.append(escaped);
}
- fileOwner->write(escapedArgs.join(' ').toUtf8());
- fileOwner->write(QString('\n').toUtf8());
- fileOwner->flush();
- }
- QFile(fileOwner->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
- return {terminal, QStringList{fileOwner->fileName()}, std::move(fileOwner)};
- }
+ wrappedArgs.push_back(escapedArgs.join(' '));
+ } else if (patternItem == "$tmpfile") {
+ temproryFile = std::make_unique(QDir::tempPath() + "/redpanda_XXXXXX.command");
+ if (temproryFile->open()) {
+ QStringList escapedArgs;
+ for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
+ auto &arg = payloadArgsWithArgv0[i];
+ auto escaped = escapeArgument(arg, i == 0);
+ escapedArgs.append(escaped);
+ }
+ temproryFile->write(escapedArgs.join(' ').toUtf8());
+ temproryFile->write("\n");
+ temproryFile->flush();
+ QFile(temproryFile->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
+ }
+ wrappedArgs.push_back(temproryFile->fileName());
+ } else
+ wrappedArgs.push_back(patternItem);
}
+ if (wrappedArgs.empty())
+ return {QString(""), QStringList{}, std::move(temproryFile)};
+ return {wrappedArgs[0], wrappedArgs.mid(1), std::move(temproryFile)};
+}
+
+auto wrapCommandForTerminalEmulator(const QString &terminal, const QString &argsPattern, const QStringList &payloadArgsWithArgv0)
+ -> std::tuple>
+{
+ return wrapCommandForTerminalEmulator(terminal, splitProcessCommand(argsPattern), payloadArgsWithArgv0);
}
QString defaultShell()
diff --git a/RedPandaIDE/utils.h b/RedPandaIDE/utils.h
index 00934181..44f78503 100644
--- a/RedPandaIDE/utils.h
+++ b/RedPandaIDE/utils.h
@@ -121,16 +121,6 @@ enum class UnixExecSemantics {
SearchInPath,
};
-enum class TerminalEmulatorArgumentsPattern {
- ImplicitSystem = 0, // bash -c "echo hello, world; sleep 3"
- MinusEAppendArgs, // term -e bash -c "echo hello, world; sleep 3" # xterm-compatible
- MinusXAppendArgs, // term -x bash -c "echo hello, world; sleep 3" # some VTE-based
- MinusMinusAppendArgs, // term -- bash -c "echo hello, world; sleep 3" # gnome-terminal, kgx
- MinusEAppendCommandLine, // term -e "bash -c \"echo hello, world; sleep 3\"" # some lightweighted; alternative form for VTE-based
-
- WriteCommandLineToTempFileThenTempFilename = 6226700, // macOS Terminal.app and iTerm2.app; 6226700 is how you dial “macOS00”
-};
-
FileType getFileType(const QString& filename);
QStringList splitProcessCommand(const QString& cmd);
@@ -189,7 +179,10 @@ QStringList getExecutableSearchPaths();
QString escapeArgument(const QString &arg, bool isFirstArg);
-auto wrapCommandForTerminalEmulator(const QString &terminal, const TerminalEmulatorArgumentsPattern &argsPattern, const QStringList &argsWithArgv0)
+auto wrapCommandForTerminalEmulator(const QString &terminal, const QStringList &argsPattern, const QStringList &payloadArgsWithArgv0)
+ -> std::tuple>;
+
+auto wrapCommandForTerminalEmulator(const QString &terminal, const QString &argsPattern, const QStringList &payloadArgsWithArgv0)
-> std::tuple>;
QString defaultShell();