improve custom terminal settings (#137)
- custom terminal on Windows now require explicit enablement - customizable terminal arguments pattern and its auto detection - move hard-coded terminals to resource files
This commit is contained in:
parent
660cd63532
commit
52c5ea4caf
|
@ -265,6 +265,7 @@ void CompilerManager::run(
|
||||||
sharedMemoryId,
|
sharedMemoryId,
|
||||||
localizePath(filename)
|
localizePath(filename)
|
||||||
} + splitProcessCommand(arguments);
|
} + splitProcessCommand(arguments);
|
||||||
|
if (pSettings->environment().useCustomTerminal()) {
|
||||||
auto [filename, args, fileOwner] = wrapCommandForTerminalEmulator(
|
auto [filename, args, fileOwner] = wrapCommandForTerminalEmulator(
|
||||||
pSettings->environment().terminalPathForExec(),
|
pSettings->environment().terminalPathForExec(),
|
||||||
pSettings->environment().terminalArgumentsPattern(),
|
pSettings->environment().terminalArgumentsPattern(),
|
||||||
|
@ -274,6 +275,11 @@ void CompilerManager::run(
|
||||||
execRunner = new ExecutableRunner(filename, args, workDir);
|
execRunner = new ExecutableRunner(filename, args, workDir);
|
||||||
execRunner->setShareMemoryId(sharedMemoryId);
|
execRunner->setShareMemoryId(sharedMemoryId);
|
||||||
mTempFileOwner = std::move(fileOwner);
|
mTempFileOwner = std::move(fileOwner);
|
||||||
|
} else {
|
||||||
|
//delete when thread finished
|
||||||
|
execRunner = new ExecutableRunner(execArgs[0], execArgs.mid(1), workDir);
|
||||||
|
execRunner->setShareMemoryId(sharedMemoryId);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//delete when thread finished
|
//delete when thread finished
|
||||||
execRunner = new ExecutableRunner(filename,splitProcessCommand(arguments),workDir);
|
execRunner = new ExecutableRunner(filename,splitProcessCommand(arguments),workDir);
|
||||||
|
|
|
@ -3,5 +3,7 @@
|
||||||
<file alias="autolink.json">resources/autolink.json</file>
|
<file alias="autolink.json">resources/autolink.json</file>
|
||||||
<file alias="codesnippets.json">resources/codesnippets.json</file>
|
<file alias="codesnippets.json">resources/codesnippets.json</file>
|
||||||
<file alias="autolink-xdg.json">resources/autolink-xdg.json</file>
|
<file alias="autolink-xdg.json">resources/autolink-xdg.json</file>
|
||||||
|
<file alias="terminal-windows.json">resources/terminal-windows.json</file>
|
||||||
|
<file alias="terminal-unix.json">resources/terminal-unix.json</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -27,6 +27,9 @@
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -3608,146 +3611,46 @@ void Settings::Environment::doLoad()
|
||||||
mDefaultOpenFolder = QDir::currentPath();
|
mDefaultOpenFolder = QDir::currentPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
using AP = TerminalEmulatorArgumentsPattern;
|
|
||||||
struct TerminalSearchItem {
|
|
||||||
QString appName;
|
|
||||||
AP argsPattern;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
const TerminalSearchItem terminals[] {
|
# if defined (__aarch64__) || defined(_M_ARM64) || defined (_M_ARM64EC)
|
||||||
/* explicitly installed terminals */
|
// the only native MinGW toolchain (LLVM-MinGW) does not have local codepage support
|
||||||
|
// prefer UTF-8 compatible OpenConsole.exe
|
||||||
/* system */
|
mUseCustomTerminal = boolValue("use_custom_terminal", true);
|
||||||
{"conhost.exe", AP::ImplicitSystem}, // dummy for system default
|
# else // x86 or x64
|
||||||
|
mUseCustomTerminal = boolValue("use_custom_terminal", false);
|
||||||
/* will not actually be searched, just a list for users who dig into here */
|
# endif
|
||||||
{"conhost.exe", AP::MinusMinusAppendArgs}, // yes, it accepts GNU-style (--) arguments
|
#else // UNIX
|
||||||
{"wt.exe", AP::MinusMinusAppendArgs}, // generally okay, but “Test” does not work
|
mUseCustomTerminal = true;
|
||||||
{"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
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto checkAndSetTerminalPath = [this](const TerminalSearchItem &searchItem) -> bool {
|
#ifdef Q_OS_WINDOWS
|
||||||
#define DO_CHECK_AND_SET do { \
|
QString terminalListFilename(":/config/terminal-windows.json");
|
||||||
if (termPathInfo.isFile() && termPathInfo.isReadable() && termPathInfo.isExecutable()) { \
|
#else // UNIX
|
||||||
mTerminalPath = searchItem.appName; \
|
QString terminalListFilename(":/config/terminal-unix.json");
|
||||||
mTerminalArgumentsPattern = searchItem.argsPattern; \
|
#endif
|
||||||
return true; \
|
QFile terminalListFile(terminalListFilename);
|
||||||
} \
|
if (!terminalListFile.open(QFile::ReadOnly))
|
||||||
} while (0)
|
throw FileError(QObject::tr("Can't open file '%1' for read.")
|
||||||
|
.arg(terminalListFilename));
|
||||||
switch (getPathUnixExecSemantics(searchItem.appName)) {
|
QByteArray terminalListContent = terminalListFile.readAll();
|
||||||
case UnixExecSemantics::Absolute: {
|
QJsonDocument terminalListDocument(QJsonDocument::fromJson(terminalListContent));
|
||||||
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
|
|
||||||
|
|
||||||
// check saved terminal path
|
// check saved terminal path
|
||||||
QString savedTerminalPath = stringValue("terminal_path", "");
|
QString savedTerminalPath = stringValue("terminal_path", "");
|
||||||
int savedArgsPattern_ = intValue("terminal_arguments_pattern",
|
QString savedArgsPattern = stringValue("terminal_arguments_pattern", "");
|
||||||
#ifdef Q_OS_MACOS
|
bool terminalSet = checkAndSetTerminal(savedTerminalPath, savedArgsPattern);
|
||||||
// macOS: old versions have set Terminal.app as default terminal
|
|
||||||
// fallback to temp file to work with Terminal.app for smooth migration
|
// determing terminal (if not set yet) and build predefined arguments pattern map from our list
|
||||||
int(AP::WriteCommandLineToTempFileThenTempFilename)
|
for (const auto &terminalGroup: terminalListDocument.array()) {
|
||||||
#else
|
const QJsonArray &terminals = terminalGroup.toObject()["terminals"].toArray();
|
||||||
int(AP::MinusEAppendArgs) // Linux: keep old behaviour
|
for (const auto &terminal_: terminals) {
|
||||||
#endif
|
const QJsonObject &terminal = terminal_.toObject();
|
||||||
);
|
const QString &path = terminal["path"].toString();
|
||||||
AP savedArgsPattern = static_cast<AP>(savedArgsPattern_);
|
const QString &executable = QFileInfo(path).fileName();
|
||||||
if (!checkAndSetTerminalPath(TerminalSearchItem{savedTerminalPath, savedArgsPattern})) {
|
const QString &pattern = terminal["argsPattern"].toString();
|
||||||
// if saved terminal path is invalid, try determing terminal from our list
|
mPredefinedTerminalArgumentsPattern[executable] = pattern;
|
||||||
for (auto terminal: terminals) {
|
if (!terminalSet)
|
||||||
if (checkAndSetTerminalPath(terminal))
|
terminalSet = checkAndSetTerminal(path, pattern);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3835,12 +3738,12 @@ void Settings::Environment::setAStylePath(const QString &aStylePath)
|
||||||
mAStylePath = aStylePath;
|
mAStylePath = aStylePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalEmulatorArgumentsPattern Settings::Environment::terminalArgumentsPattern() const
|
QString Settings::Environment::terminalArgumentsPattern() const
|
||||||
{
|
{
|
||||||
return mTerminalArgumentsPattern;
|
return mTerminalArgumentsPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::Environment::setTerminalArgumentsPattern(const TerminalEmulatorArgumentsPattern &argsPattern)
|
void Settings::Environment::setTerminalArgumentsPattern(const QString &argsPattern)
|
||||||
{
|
{
|
||||||
mTerminalArgumentsPattern = argsPattern;
|
mTerminalArgumentsPattern = argsPattern;
|
||||||
}
|
}
|
||||||
|
@ -3895,6 +3798,89 @@ void Settings::Environment::setIconZoomFactor(double newIconZoomFactor)
|
||||||
mIconZoomFactor = newIconZoomFactor;
|
mIconZoomFactor = newIconZoomFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMap<QString, QString> Settings::Environment::predefinedTerminalArgumentsPattern() const
|
||||||
|
{
|
||||||
|
return mPredefinedTerminalArgumentsPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::Environment::setPredefinedTerminalArgumentsPattern(const QMap<QString, QString> &newPredefinedTerminalArgumentsPattern)
|
||||||
|
{
|
||||||
|
mPredefinedTerminalArgumentsPattern = newPredefinedTerminalArgumentsPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<QString> Settings::Environment::queryPredefinedTerminalArgumentsPattern(const QString &executable) const
|
||||||
|
{
|
||||||
|
auto it = mPredefinedTerminalArgumentsPattern.find(executable);
|
||||||
|
if (it != mPredefinedTerminalArgumentsPattern.end())
|
||||||
|
return std::make_unique<QString>(*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()
|
void Settings::Environment::doSave()
|
||||||
{
|
{
|
||||||
//Appearance
|
//Appearance
|
||||||
|
@ -3910,7 +3896,10 @@ void Settings::Environment::doSave()
|
||||||
saveValue("current_folder",mCurrentFolder);
|
saveValue("current_folder",mCurrentFolder);
|
||||||
saveValue("default_open_folder",mDefaultOpenFolder);
|
saveValue("default_open_folder",mDefaultOpenFolder);
|
||||||
saveValue("terminal_path",mTerminalPath);
|
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("asyle_path",mAStylePath);
|
||||||
|
|
||||||
saveValue("hide_non_support_files_file_view",mHideNonSupportFilesInFileView);
|
saveValue("hide_non_support_files_file_view",mHideNonSupportFilesInFileView);
|
||||||
|
|
|
@ -575,8 +575,8 @@ public:
|
||||||
QString AStylePath() const;
|
QString AStylePath() const;
|
||||||
void setAStylePath(const QString &aStylePath);
|
void setAStylePath(const QString &aStylePath);
|
||||||
|
|
||||||
TerminalEmulatorArgumentsPattern terminalArgumentsPattern() const;
|
QString terminalArgumentsPattern() const;
|
||||||
void setTerminalArgumentsPattern(const TerminalEmulatorArgumentsPattern &argsPattern);
|
void setTerminalArgumentsPattern(const QString &argsPattern);
|
||||||
|
|
||||||
bool useCustomIconSet() const;
|
bool useCustomIconSet() const;
|
||||||
void setUseCustomIconSet(bool newUseCustomIconSet);
|
void setUseCustomIconSet(bool newUseCustomIconSet);
|
||||||
|
@ -593,7 +593,22 @@ public:
|
||||||
double iconZoomFactor() const;
|
double iconZoomFactor() const;
|
||||||
void setIconZoomFactor(double newIconZoomFactor);
|
void setIconZoomFactor(double newIconZoomFactor);
|
||||||
|
|
||||||
|
QJsonArray availableTerminals() const;
|
||||||
|
void setAvailableTerminals(const QJsonArray &availableTerminals);
|
||||||
|
|
||||||
|
QMap<QString, QString> predefinedTerminalArgumentsPattern() const;
|
||||||
|
void setPredefinedTerminalArgumentsPattern(const QMap<QString, QString> &newPredefinedTerminalArgumentsPattern);
|
||||||
|
// it should be `std::optional<QString>`.
|
||||||
|
// `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<QString> queryPredefinedTerminalArgumentsPattern(const QString &executable) const;
|
||||||
|
|
||||||
|
bool useCustomTerminal() const;
|
||||||
|
void setUseCustomTerminal(bool newUseCustomTerminal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool checkAndSetTerminal(QString terminalPath, QString argsPattern);
|
||||||
|
bool updateTerminalList();
|
||||||
|
|
||||||
//Appearance
|
//Appearance
|
||||||
QString mTheme;
|
QString mTheme;
|
||||||
|
@ -609,7 +624,9 @@ public:
|
||||||
QString mDefaultOpenFolder;
|
QString mDefaultOpenFolder;
|
||||||
QString mTerminalPath;
|
QString mTerminalPath;
|
||||||
QString mAStylePath;
|
QString mAStylePath;
|
||||||
TerminalEmulatorArgumentsPattern mTerminalArgumentsPattern;
|
QString mTerminalArgumentsPattern;
|
||||||
|
QMap<QString, QString> mPredefinedTerminalArgumentsPattern;
|
||||||
|
bool mUseCustomTerminal;
|
||||||
bool mHideNonSupportFilesInFileView;
|
bool mHideNonSupportFilesInFileView;
|
||||||
bool mOpenFilesInSingleInstance;
|
bool mOpenFilesInSingleInstance;
|
||||||
// _Base interface
|
// _Base interface
|
||||||
|
|
|
@ -22,21 +22,16 @@
|
||||||
#include "../compiler/executablerunner.h"
|
#include "../compiler/executablerunner.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
EnvironmentProgramsWidget::EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent) :
|
EnvironmentProgramsWidget::EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent) :
|
||||||
SettingsWidget(name,group,parent),
|
SettingsWidget(name,group,parent),
|
||||||
ui(new Ui::EnvironmentProgramsWidget)
|
ui(new Ui::EnvironmentProgramsWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
QFont monoFont(DEFAULT_MONO_FONT);
|
ui->labelCmdPreviewResult->setFont(QFont(DEFAULT_MONO_FONT));
|
||||||
ui->rbImplicitSystem->setFont(monoFont);
|
#ifndef Q_OS_WINDOWS
|
||||||
ui->rbMinusEAppendArgs->setFont(monoFont);
|
ui->grpUseCustomTerminal->setCheckable(false);
|
||||||
ui->rbMinusXAppendArgs->setFont(monoFont);
|
|
||||||
ui->rbMinusMinusAppendArgs->setFont(monoFont);
|
|
||||||
ui->rbMinusEAppendCommandLine->setFont(monoFont);
|
|
||||||
ui->rbWriteCommandLineToTempFileThenTempFilename->setFont(monoFont);
|
|
||||||
#ifndef Q_OS_MACOS
|
|
||||||
hideMacosSpecificPattern();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,68 +40,67 @@ EnvironmentProgramsWidget::~EnvironmentProgramsWidget()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentProgramsWidget::hideMacosSpecificPattern()
|
auto EnvironmentProgramsWidget::resolveExecArguments(const QString &terminalPath, const QString &argsPattern)
|
||||||
|
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>
|
||||||
{
|
{
|
||||||
ui->rbWriteCommandLineToTempFileThenTempFilename->setVisible(false);
|
QString terminalPathForExec;
|
||||||
ui->rbWriteCommandLineToTempFileThenTempFilename->setEnabled(false);
|
if (getPathUnixExecSemantics(terminalPath) == UnixExecSemantics::RelativeToCwd) {
|
||||||
ui->pbWriteCommandLineToTempFileThenTempFilename->setVisible(false);
|
QDir appDir(pSettings->dirs().appDir());
|
||||||
ui->pbWriteCommandLineToTempFileThenTempFilename->setEnabled(false);
|
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"});
|
auto [filename, arguments, fileOwner] = resolveExecArguments(terminalPath, argsPattern);
|
||||||
ExecutableRunner runner(filename, arguments, "", nullptr);
|
for (auto &arg : arguments)
|
||||||
runner.start();
|
arg = escapeArgument(arg, false);
|
||||||
runner.wait();
|
|
||||||
|
ui->labelCmdPreviewResult->setText(escapeArgument(filename, true) + " " + arguments.join(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnvironmentProgramsWidget::autoDetectAndUpdateArgumentsPattern(const QString &terminalPath)
|
||||||
|
{
|
||||||
|
const QString &executable = QFileInfo(terminalPath).fileName();
|
||||||
|
const std::unique_ptr<QString> &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()
|
void EnvironmentProgramsWidget::doLoad()
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
ui->grpUseCustomTerminal->setChecked(pSettings->environment().useCustomTerminal());
|
||||||
|
#endif
|
||||||
ui->txtTerminal->setText(pSettings->environment().terminalPath());
|
ui->txtTerminal->setText(pSettings->environment().terminalPath());
|
||||||
switch (pSettings->environment().terminalArgumentsPattern()) {
|
ui->txtArgsPattern->setText(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentProgramsWidget::doSave()
|
void EnvironmentProgramsWidget::doSave()
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
pSettings->environment().setUseCustomTerminal(ui->grpUseCustomTerminal->isChecked());
|
||||||
|
#endif
|
||||||
pSettings->environment().setTerminalPath(ui->txtTerminal->text());
|
pSettings->environment().setTerminalPath(ui->txtTerminal->text());
|
||||||
if (ui->rbImplicitSystem->isChecked())
|
pSettings->environment().setTerminalArgumentsPattern(ui->txtArgsPattern->text());
|
||||||
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().save();
|
pSettings->environment().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentProgramsWidget::updateIcons(const QSize &)
|
void EnvironmentProgramsWidget::updateIcons(const QSize &)
|
||||||
{
|
{
|
||||||
pIconsManager->setIcon(ui->btnChooseTerminal,IconsManager::ACTION_FILE_OPEN_FOLDER);
|
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()
|
void EnvironmentProgramsWidget::on_btnChooseTerminal_clicked()
|
||||||
|
@ -118,64 +112,34 @@ void EnvironmentProgramsWidget::on_btnChooseTerminal_clicked()
|
||||||
tr("All files (%1)").arg(ALL_FILE_WILDCARD));
|
tr("All files (%1)").arg(ALL_FILE_WILDCARD));
|
||||||
if (!filename.isEmpty() && fileExists(filename) ) {
|
if (!filename.isEmpty() && fileExists(filename) ) {
|
||||||
ui->txtTerminal->setText(filename);
|
ui->txtTerminal->setText(filename);
|
||||||
|
autoDetectAndUpdateArgumentsPattern(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentProgramsWidget::on_txtTerminal_textChanged(const QString &terminalPath)
|
void EnvironmentProgramsWidget::on_txtTerminal_textChanged(const QString &terminalPath)
|
||||||
{
|
{
|
||||||
QString terminalPathForExec;
|
const QString &argsPattern = ui->txtArgsPattern->text();
|
||||||
if (getPathUnixExecSemantics(terminalPath) == UnixExecSemantics::RelativeToCwd) {
|
updateCommandPreview(terminalPath, argsPattern);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,12 @@ class EnvironmentProgramsWidget : public SettingsWidget
|
||||||
public:
|
public:
|
||||||
explicit EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent = nullptr);
|
explicit EnvironmentProgramsWidget(const QString& name, const QString& group, QWidget *parent = nullptr);
|
||||||
~EnvironmentProgramsWidget();
|
~EnvironmentProgramsWidget();
|
||||||
void hideMacosSpecificPattern();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void testTerminal(const TerminalEmulatorArgumentsPattern &pattern);
|
auto resolveExecArguments(const QString &terminalPath, const QString &argsPatter)
|
||||||
|
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>;
|
||||||
|
void updateCommandPreview(const QString &terminalPath, const QString &argsPatter);
|
||||||
|
void autoDetectAndUpdateArgumentsPattern(const QString &terminalPath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::EnvironmentProgramsWidget *ui;
|
Ui::EnvironmentProgramsWidget *ui;
|
||||||
|
@ -47,12 +49,9 @@ protected:
|
||||||
private slots:
|
private slots:
|
||||||
void on_btnChooseTerminal_clicked();
|
void on_btnChooseTerminal_clicked();
|
||||||
void on_txtTerminal_textChanged(const QString &terminalPath);
|
void on_txtTerminal_textChanged(const QString &terminalPath);
|
||||||
void on_pbImplicitSystem_clicked();
|
void on_txtArgsPattern_textChanged(const QString &argsPattern);
|
||||||
void on_pbMinusEAppendArgs_clicked();
|
void on_btnAutoDetectArgsPattern_clicked();
|
||||||
void on_pbMinusXAppendArgs_clicked();
|
void on_btnTest_clicked();
|
||||||
void on_pbMinusMinusAppendArgs_clicked();
|
|
||||||
void on_pbMinusEAppendCommandLine_clicked();
|
|
||||||
void on_pbWriteCommandLineToTempFileThenTempFilename_clicked();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ENVIRONMENTPROGRAMSWIDGET_H
|
#endif // ENVIRONMENTPROGRAMSWIDGET_H
|
||||||
|
|
|
@ -13,10 +13,36 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="grpUseCustomTerminal">
|
||||||
|
<property name="title">
|
||||||
|
<string>Use custom terminal</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="txtTerminal"/>
|
<widget class="QLineEdit" name="txtTerminal"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="txtArgsPattern">
|
||||||
|
<property name="text">
|
||||||
|
<string>$term -e $argv</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="labelArgsPattern">
|
||||||
|
<property name="text">
|
||||||
|
<string>Args. pattern</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="QToolButton" name="btnChooseTerminal">
|
<widget class="QToolButton" name="btnChooseTerminal">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -28,148 +54,59 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QToolButton" name="btnAutoDetectArgsPattern">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Auto Detect Terminal Arguments Pattern</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/images/newlook24/087-update.png</normaloff>:/icons/images/newlook24/087-update.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="labelTerminal">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Terminal</string>
|
<string>Terminal</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="3">
|
<item row="2" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QLabel" name="labelCmdPreview">
|
||||||
<property name="title">
|
|
||||||
<string>Terminal emulator arguments pattern</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbImplicitSystem">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>sh -c "echo hello; sleep 3"</string>
|
<string>Cmd. preview</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="2" column="1">
|
||||||
<spacer name="horizontalSpacer">
|
<widget class="QLabel" name="labelCmdPreviewResult">
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QPushButton" name="pbImplicitSystem">
|
|
||||||
<property name="text">
|
|
||||||
<string>Test</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbMinusEAppendArgs">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>term -e sh -c "echo hello; sleep 3"</string>
|
<string>term -e sh -c "echo hello; sleep 3"</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QPushButton" name="pbMinusEAppendArgs">
|
|
||||||
<property name="text">
|
|
||||||
<string>Test</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbMinusXAppendArgs">
|
|
||||||
<property name="text">
|
|
||||||
<string>term -x sh -c "echo hello; sleep 3"</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2">
|
<item row="2" column="2">
|
||||||
<widget class="QPushButton" name="pbMinusXAppendArgs">
|
<widget class="QToolButton" name="btnTest">
|
||||||
<property name="text">
|
<property name="toolTip">
|
||||||
<string>Test</string>
|
<string>Test Command</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbMinusMinusAppendArgs">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>term -- sh -c "echo hello; sleep 3"</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="icon">
|
||||||
</item>
|
<iconset resource="../icons.qrc">
|
||||||
<item row="3" column="2">
|
<normaloff>:/icons/images/newlook24/069-run.png</normaloff>:/icons/images/newlook24/069-run.png</iconset>
|
||||||
<widget class="QPushButton" name="pbMinusMinusAppendArgs">
|
|
||||||
<property name="text">
|
|
||||||
<string>Test</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbMinusEAppendCommandLine">
|
|
||||||
<property name="text">
|
|
||||||
<string>term -e "sh -c \"echo hello; sleep 3\""</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="2">
|
|
||||||
<widget class="QPushButton" name="pbMinusEAppendCommandLine">
|
|
||||||
<property name="text">
|
|
||||||
<string>Test</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QRadioButton" name="rbWriteCommandLineToTempFileThenTempFilename">
|
|
||||||
<property name="text">
|
|
||||||
<string>term /tmp/redpanda_XXXXXX.command</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QPushButton" name="pbWriteCommandLineToTempFileThenTempFilename">
|
|
||||||
<property name="text">
|
|
||||||
<string>Test</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0" colspan="3">
|
|
||||||
<widget class="QLabel" name="lExpectedBahavior0">
|
|
||||||
<property name="text">
|
|
||||||
<string>On clicking “Test” for the correct pattern, the terminal emulator</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0" colspan="3">
|
|
||||||
<widget class="QLabel" name="lExpectedBahavior1">
|
|
||||||
<property name="text">
|
|
||||||
<string>• pops up;</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="0" colspan="3">
|
|
||||||
<widget class="QLabel" name="lExpectedBahavior2">
|
|
||||||
<property name="text">
|
|
||||||
<string>• shows “hello”; and</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0" colspan="3">
|
|
||||||
<widget class="QLabel" name="lExpectedBahavior3">
|
|
||||||
<property name="text">
|
|
||||||
<string>• quits in 3 seconds.</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2">
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
|
|
|
@ -1958,52 +1958,32 @@
|
||||||
<source>All files (%1)</source>
|
<source>All files (%1)</source>
|
||||||
<translation>Todos os arquivos (%1)</translation>
|
<translation>Todos os arquivos (%1)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Terminal emulator arguments pattern</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>sh -c "echo hello; sleep 3"</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Test</source>
|
|
||||||
<translation type="unfinished">Testar</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>term -e sh -c "echo hello; sleep 3"</source>
|
<source>term -e sh -c "echo hello; sleep 3"</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>term -x sh -c "echo hello; sleep 3"</source>
|
<source>Auto Detect Terminal Arguments Pattern</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>term -- sh -c "echo hello; sleep 3"</source>
|
<source>Test Command</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>term -e "sh -c \"echo hello; sleep 3\""</source>
|
<source>$term -e $argv</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>On clicking “Test” for the correct pattern, the terminal emulator</source>
|
<source>Use custom terminal</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>• pops up;</source>
|
<source>Args. pattern</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>• shows “hello”; and</source>
|
<source>Cmd. preview</source>
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>• quits in 3 seconds.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>term /tmp/redpanda_XXXXXX.command</source>
|
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -7077,6 +7057,14 @@
|
||||||
<source>Replaces lcall/ljmp with acall/ajmp</source>
|
<source>Replaces lcall/ljmp with acall/ajmp</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Auto Detection Failed</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Failed to detect terminal arguments pattern for “%1”.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RegisterModel</name>
|
<name>RegisterModel</name>
|
||||||
|
|
|
@ -2670,103 +2670,74 @@ Are you really want to continue?</oldsource>
|
||||||
<source>Editors share one code parser</source>
|
<source>Editors share one code parser</source>
|
||||||
<translation>编辑器共享同一个代码分析器</translation>
|
<translation>编辑器共享同一个代码分析器</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context><context>
|
||||||
<context>
|
<name>EnvironmentProgramsWidget</name>
|
||||||
<name>EnvironmentProgramsWidget</name>
|
<message>
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="14"/>
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="14"/>
|
||||||
<source>Form</source>
|
<source>Form</source>
|
||||||
<translation>表单</translation>
|
<translation>表单</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="23"/>
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="20"/>
|
||||||
|
<source>Use custom terminal</source>
|
||||||
|
<translation>使用自定义终端</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="49"/>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="63"/>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="98"/>
|
||||||
<source>...</source>
|
<source>...</source>
|
||||||
<translation>...</translation>
|
<translation>...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="34"/>
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="81"/>
|
||||||
|
<source>Cmd. preview</source>
|
||||||
|
<translation>命令行预览</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="60"/>
|
||||||
|
<source>Auto Detect Terminal Arguments Pattern</source>
|
||||||
|
<translation>自动检测终端参数模式</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="74"/>
|
||||||
<source>Terminal</source>
|
<source>Terminal</source>
|
||||||
<translation>终端</translation>
|
<translation>终端</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="41"/>
|
|
||||||
<source>Terminal emulator arguments pattern</source>
|
|
||||||
<translation>终端模拟器参数模式</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="54"/>
|
|
||||||
<source>sh -c "echo hello; sleep 3"</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="74"/>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="95"/>
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="95"/>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="116"/>
|
<source>Test Command</source>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="137"/>
|
<translation>测试命令</translation>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="158"/>
|
</message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="179"/>
|
<message>
|
||||||
<source>Test</source>
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="35"/>
|
||||||
<translation>测试</translation>
|
<source>$term -e $argv</source>
|
||||||
</message>
|
<translation type="unfinished"></translation>
|
||||||
<message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="42"/>
|
||||||
|
<source>Args. pattern</source>
|
||||||
|
<translation>参数模式</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="88"/>
|
<location filename="../settingsdialog/environmentprogramswidget.ui" line="88"/>
|
||||||
<source>term -e sh -c "echo hello; sleep 3"</source>
|
<source>term -e sh -c "echo hello; sleep 3"</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="109"/>
|
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="108"/>
|
||||||
<source>term -x sh -c "echo hello; sleep 3"</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="130"/>
|
|
||||||
<source>term -- sh -c "echo hello; sleep 3"</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="151"/>
|
|
||||||
<source>term -e "sh -c \"echo hello; sleep 3\""</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="172"/>
|
|
||||||
<source>term /tmp/redpanda_XXXXXX.command</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="186"/>
|
|
||||||
<source>On clicking “Test” for the correct pattern, the terminal emulator</source>
|
|
||||||
<translation>点击正确的模式对应的 “测试” 按钮,终端模拟器将会</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="193"/>
|
|
||||||
<source>• pops up;</source>
|
|
||||||
<translation>• 弹出;</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="200"/>
|
|
||||||
<source>• shows “hello”; and</source>
|
|
||||||
<translation>• 显示 “hello”;</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.ui" line="207"/>
|
|
||||||
<source>• quits in 3 seconds.</source>
|
|
||||||
<translation>• 并在 3 秒后关闭。</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="109"/>
|
|
||||||
<source>Choose Terminal Program</source>
|
<source>Choose Terminal Program</source>
|
||||||
<translation>选择终端程序</translation>
|
<translation>选择终端程序</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="59"/>
|
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="110"/>
|
||||||
<source>All files (%1)</source>
|
<source>All files (%1)</source>
|
||||||
<translation>所有文件 (%1)</translation>
|
<translation>所有文件 (%1)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>All files (*.*)</source>
|
<source>All files (*.*)</source>
|
||||||
<translation type="vanished">所有文件 (*.*)</translation>
|
<translation type="vanished">所有文件 (*.*)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EnvironmentShortcutModel</name>
|
<name>EnvironmentShortcutModel</name>
|
||||||
|
@ -9633,6 +9604,16 @@ Are you really want to continue?</oldsource>
|
||||||
<source>Error when writing file "%1".</source>
|
<source>Error when writing file "%1".</source>
|
||||||
<translation>在写入文件“%1”时出错。</translation>
|
<translation>在写入文件“%1”时出错。</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="74"/>
|
||||||
|
<source>Auto Detection Failed</source>
|
||||||
|
<translation>自动检测失败</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settingsdialog/environmentprogramswidget.cpp" line="75"/>
|
||||||
|
<source>Failed to detect terminal arguments pattern for “%1”.</source>
|
||||||
|
<translation>无法检测适用于 “%1” 的终端参数模式。</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RegisterModel</name>
|
<name>RegisterModel</name>
|
||||||
|
|
|
@ -1791,52 +1791,32 @@
|
||||||
<source>All files (%1)</source>
|
<source>All files (%1)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Terminal emulator arguments pattern</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>sh -c "echo hello; sleep 3"</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Test</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>term -e sh -c "echo hello; sleep 3"</source>
|
<source>term -e sh -c "echo hello; sleep 3"</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>term -x sh -c "echo hello; sleep 3"</source>
|
<source>Auto Detect Terminal Arguments Pattern</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>term -- sh -c "echo hello; sleep 3"</source>
|
<source>Test Command</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>term -e "sh -c \"echo hello; sleep 3\""</source>
|
<source>$term -e $argv</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>On clicking “Test” for the correct pattern, the terminal emulator</source>
|
<source>Use custom terminal</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>• pops up;</source>
|
<source>Args. pattern</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>• shows “hello”; and</source>
|
<source>Cmd. preview</source>
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>• quits in 3 seconds.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>term /tmp/redpanda_XXXXXX.command</source>
|
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
@ -6602,6 +6582,14 @@
|
||||||
<source>Replaces lcall/ljmp with acall/ajmp</source>
|
<source>Replaces lcall/ljmp with acall/ajmp</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Auto Detection Failed</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Failed to detect terminal arguments pattern for “%1”.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>RegisterModel</name>
|
<name>RegisterModel</name>
|
||||||
|
|
|
@ -723,49 +723,51 @@ QString escapeArgument(const QString &arg, [[maybe_unused]] bool isFirstArg)
|
||||||
#endif
|
#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<QString, QStringList, std::unique_ptr<QTemporaryFile>>
|
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>
|
||||||
{
|
{
|
||||||
switch (argsPattern) {
|
QStringList wrappedArgs;
|
||||||
case TerminalEmulatorArgumentsPattern::ImplicitSystem:
|
std::unique_ptr<QTemporaryFile> temproryFile;
|
||||||
default: {
|
for (const QString &patternItem : argsPattern) {
|
||||||
return {argsWithArgv0[0], argsWithArgv0.mid(1), nullptr};
|
if (patternItem == "$term")
|
||||||
}
|
wrappedArgs.push_back(terminal);
|
||||||
case TerminalEmulatorArgumentsPattern::MinusEAppendArgs: {
|
else if (patternItem == "$argv")
|
||||||
return {terminal, QStringList{"-e"} + argsWithArgv0, nullptr};
|
wrappedArgs.append(payloadArgsWithArgv0);
|
||||||
}
|
else if (patternItem == "$command") {
|
||||||
case TerminalEmulatorArgumentsPattern::MinusXAppendArgs: {
|
|
||||||
return {terminal, QStringList{"-x"} + argsWithArgv0, nullptr};
|
|
||||||
}
|
|
||||||
case TerminalEmulatorArgumentsPattern::MinusMinusAppendArgs: {
|
|
||||||
return {terminal, QStringList{"--"} + argsWithArgv0, nullptr};
|
|
||||||
}
|
|
||||||
case TerminalEmulatorArgumentsPattern::MinusEAppendCommandLine: {
|
|
||||||
QStringList escapedArgs;
|
QStringList escapedArgs;
|
||||||
for (int i = 0; i < argsWithArgv0.length(); i++) {
|
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||||
auto &arg = argsWithArgv0[i];
|
auto &arg = payloadArgsWithArgv0[i];
|
||||||
auto escaped = escapeArgument(arg, i == 0);
|
auto escaped = escapeArgument(arg, i == 0);
|
||||||
escapedArgs.append(escaped);
|
escapedArgs.append(escaped);
|
||||||
}
|
}
|
||||||
return {terminal, QStringList{"-e", escapedArgs.join(' ')}, nullptr};
|
wrappedArgs.push_back(escapedArgs.join(' '));
|
||||||
}
|
} else if (patternItem == "$tmpfile") {
|
||||||
case TerminalEmulatorArgumentsPattern::WriteCommandLineToTempFileThenTempFilename: {
|
temproryFile = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.command");
|
||||||
auto fileOwner = std::make_unique<QTemporaryFile>(QDir::tempPath() + "/redpanda_XXXXXX.command");
|
if (temproryFile->open()) {
|
||||||
if (fileOwner->open()) {
|
|
||||||
QStringList escapedArgs;
|
QStringList escapedArgs;
|
||||||
for (int i = 0; i < argsWithArgv0.length(); i++) {
|
for (int i = 0; i < payloadArgsWithArgv0.length(); i++) {
|
||||||
auto &arg = argsWithArgv0[i];
|
auto &arg = payloadArgsWithArgv0[i];
|
||||||
auto escaped = escapeArgument(arg, i == 0);
|
auto escaped = escapeArgument(arg, i == 0);
|
||||||
escapedArgs.append(escaped);
|
escapedArgs.append(escaped);
|
||||||
}
|
}
|
||||||
fileOwner->write(escapedArgs.join(' ').toUtf8());
|
temproryFile->write(escapedArgs.join(' ').toUtf8());
|
||||||
fileOwner->write(QString('\n').toUtf8());
|
temproryFile->write("\n");
|
||||||
fileOwner->flush();
|
temproryFile->flush();
|
||||||
}
|
QFile(temproryFile->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
||||||
QFile(fileOwner->fileName()).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
|
|
||||||
return {terminal, QStringList{fileOwner->fileName()}, std::move(fileOwner)};
|
|
||||||
}
|
}
|
||||||
|
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<QString, QStringList, std::unique_ptr<QTemporaryFile>>
|
||||||
|
{
|
||||||
|
return wrapCommandForTerminalEmulator(terminal, splitProcessCommand(argsPattern), payloadArgsWithArgv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString defaultShell()
|
QString defaultShell()
|
||||||
|
|
|
@ -121,16 +121,6 @@ enum class UnixExecSemantics {
|
||||||
SearchInPath,
|
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);
|
FileType getFileType(const QString& filename);
|
||||||
QStringList splitProcessCommand(const QString& cmd);
|
QStringList splitProcessCommand(const QString& cmd);
|
||||||
|
|
||||||
|
@ -189,7 +179,10 @@ QStringList getExecutableSearchPaths();
|
||||||
|
|
||||||
QString escapeArgument(const QString &arg, bool isFirstArg);
|
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<QString, QStringList, std::unique_ptr<QTemporaryFile>>;
|
||||||
|
|
||||||
|
auto wrapCommandForTerminalEmulator(const QString &terminal, const QString &argsPattern, const QStringList &payloadArgsWithArgv0)
|
||||||
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>;
|
-> std::tuple<QString, QStringList, std::unique_ptr<QTemporaryFile>>;
|
||||||
|
|
||||||
QString defaultShell();
|
QString defaultShell();
|
||||||
|
|
Loading…
Reference in New Issue