Skip to content

Commit

Permalink
Improvement for #40, can now pass commands to new terminals via -x sw…
Browse files Browse the repository at this point in the history
…itch
  • Loading branch information
gnunn1 committed Jan 21, 2016
1 parent 7885cc9 commit 831007e
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 78 deletions.
7 changes: 4 additions & 3 deletions source/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,22 @@ int main(string[] args) {
trace("Reading command parameters...");
CommandParameters cp = CommandParameters(args);
if (!cp.exit) {
trace("Creating app");
auto terminixApp = new Terminix(cp);
//Bypass GTK command line handling since we handle it ourselves
string[] tempArgs;
int result;
try {
trace("Running application...");
if (cp.command.length > 0) {
if (cp.action.length > 0) {
string id = environment["TERMINIX_ID"];
if (id.length == 0) {
writeln("You must execute a command within a running instance of terminix");
return 2;
} else {
trace("Sending command");
trace(format("Sending command=%s, cmdLine=%s", cp.action, cp.cmdLine));
terminixApp.register(null);
terminixApp.executeCommand(cp.command, id);
terminixApp.executeCommand(cp.action, id, cp.cmdLine);
return 0;
}
} else {
Expand Down
50 changes: 40 additions & 10 deletions source/gx/terminix/application.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import gio.MenuModel;
import gio.Settings : GSettings = Settings;
import gio.SimpleAction;

import glib.ShellUtils;
import glib.Variant : GVariant = Variant;
import glib.VariantType : GVariantType = VariantType;

Expand Down Expand Up @@ -188,12 +189,9 @@ private:
}
}

void createAppWindow(bool onActivate = false) {
void createAppWindow() {
AppWindow window = new AppWindow(this);
if (onActivate)
window.initialize(cp);
else
window.initialize();
window.initialize();
window.showAll();
}

Expand All @@ -209,7 +207,8 @@ private:

void onAppActivate(GioApplication app) {
trace("Activate App Signal");
createAppWindow(true);
createAppWindow();
cp.clear();
}

void onAppStartup(GioApplication app) {
Expand Down Expand Up @@ -242,6 +241,12 @@ private:
}

void executeCommand(GVariant value, SimpleAction sa) {
//Clear command parameters at end of command
//Only set them temporarily so if a terminal is created
//as a result of the action it can inherit them. The
//command line parameters are sent by the remote Application
//and packed into the value parameter.
scope (exit) {cp.clear();}
ulong l;
string command = value.getChildValue(0).getString(l);
if (command.length == 0) {
Expand All @@ -253,7 +258,11 @@ private:
error("Terminal UUID was not sent for command, cannot resolve");
return;
}
trace(format("Command Received, command=%s, terminalID=%s", command, terminalUUID));
string cmdLine = value.getChildValue(2).getString(l);
string[] args;
ShellUtils.shellParseArgv(cmdLine, args);
cp = CommandParameters(args);
trace(format("Command Received, command=%s, terminalID=%s, cmdLine=%s", command, terminalUUID, cmdLine));
//Get action name
string prefix;
string actionName;
Expand Down Expand Up @@ -284,7 +293,7 @@ public:
this.addOnActivate(&onAppActivate);
this.addOnStartup(&onAppStartup);
this.addOnShutdown(&onAppShutdown);
GVariant param = new GVariant([new GVariant("None"), new GVariant("None")]);
GVariant param = new GVariant([new GVariant("None"), new GVariant("None"), new GVariant("None")]);
trace("Registering command action with type " ~ param.getType().peekString());
registerAction(this, ACTION_PREFIX, ACTION_COMMAND, null, &executeCommand, param.getType(), param);
terminix = this;
Expand All @@ -298,8 +307,8 @@ public:
*
* See https://wiki.gnome.org/HowDoI/GtkApplication
*/
void executeCommand(string command, string terminalID) {
GVariant[] param = [new GVariant(command), new GVariant(terminalID)];
void executeCommand(string command, string terminalID, string cmdLine) {
GVariant[] param = [new GVariant(command), new GVariant(terminalID), new GVariant(cmdLine)];
activateAction(ACTION_COMMAND, new GVariant(param));
}

Expand Down Expand Up @@ -392,6 +401,27 @@ public:
return !warnedVTEConfigIssue && gsGeneral.getBoolean(SETTINGS_WARN_VTE_CONFIG_ISSUE_KEY);
}

/**
* Even those these are parameters passed on the command-line
* they are used by the terminal when it is created as a global
* override.
*
* Originally I was passing command line parameters to the terminal
* via the heirarchy App > AppWindow > Session > Terminal but this
* is unwiedly. It's also not feasible when supporting using the
* command line to create terminals in the current instance since
* that uses actions and it's not feasible to pass these via the
* action mechanism.
*
* When a terminal is created, it will check this global overrides and
* use it where applicaable. The application is responsible for setiing
* and clearing these overrides around the terminal creation. Since GTK
* is single threaded this works fine.
*/
CommandParameters getGlobalOverrides() {
return cp;
}

/**
* Shows a dialog when a VTE configuration issue is detected.
* See Issue #34 and https://github.com/gnunn1/terminix/wiki/VTE-Configuration-Issue
Expand Down
50 changes: 11 additions & 39 deletions source/gx/terminix/appwindow.d
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,13 @@ private:
write(filename, json);
session.filename = filename;
}

/**
* Creates a new session based on parameters, user is not prompted
*/
void createSession(string name, string profileUUID) {
createNewSession(name, profileUUID, Util.getHomeDir());
}

public:

Expand All @@ -575,38 +582,17 @@ public:
}

void initialize() {
if (terminix.getGlobalOverrides().session.length > 0) {
loadSession(terminix.getGlobalOverrides().session);
return;
}
//Create an initial session using default session name and profile
createSession(_(DEFAULT_SESSION_NAME), prfMgr.getDefaultProfile());
}

void initialize(Session session) {
addSession(session);
}

/**
* intialize the session based on the command line parameters
*/
void initialize(CommandParameters cp) {
trace("Initializing with command line parameters");
if (cp.session.length > 0) {
loadSession(cp.session);
return;
}
string profile;
if (cp.profileName.length > 0) {
profile = prfMgr.getProfileUUIDFromName(cp.profileName);
}
if (profile.length == 0) {
profile = prfMgr.getDefaultProfile();
}

string workingDir;
if (cp.workingDir.length > 0)
workingDir = cp.workingDir;
else
workingDir = Util.getHomeDir();
createSession(_(DEFAULT_SESSION_NAME), profile, workingDir);
}

/**
* Activates the specified sessionUUID
Expand Down Expand Up @@ -665,20 +651,6 @@ public:
createSession(_(DEFAULT_SESSION_NAME), prfMgr.getDefaultProfile());
}
}

/**
* Creates a new session based on parameters, user is not prompted
*/
void createSession(string name, string profileUUID) {
createNewSession(name, profileUUID, Util.getHomeDir());
}

/**
* Creates a new session based on parameters, user is not prompted
*/
void createSession(string name, string profileUUID, string workingDir) {
createNewSession(name, profileUUID, workingDir);
}
}

// ***************************************************************************
Expand Down
95 changes: 73 additions & 22 deletions source/gx/terminix/cmdparams.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module gx.terminix.cmdparams;
import std.experimental.logger;
import std.getopt;
import std.stdio;
import std.string;

import gx.i18n.l10n;

Expand All @@ -11,32 +12,82 @@ import gx.i18n.l10n;
*/
struct CommandParameters {

string workingDir;
string profileName;
string session;
string command;
private:
string _workingDir;
string _profileName;
string _session;
string _action;
string _execute;
string _cmdLine;

bool exit = false;
int exitCode = 0;
bool _exit = false;
int _exitCode = 0;

public:

this(string[] args) {
auto results = getopt(args,
"working-directory|w", _("Set the working directory of the terminal"), &workingDir,
"profile|p", _("Set the starting profile"), &profileName,
"session|s", _("Open the specified session"), &session,
"command|c",_("Send a command to current instance"), &command);

if (results.helpWanted) {
defaultGetoptPrinter("Terminix Usage:\n\tterminix [OPTIONS]\n\nAvailable options are:\n", results.options);
writeln("Note that the session option is not compatible with profile and working-directory options");
exit = true;
_cmdLine.length = 0;
//Start from 1 to skip executable
foreach(i, arg; args[1..$]) {
if (i > 0) _cmdLine ~=" ";
if (arg.indexOf(" ") > 0) arg ="\"" ~ arg ~ "\"";
_cmdLine ~= arg;
}
try {
auto results = getopt(args,
"working-directory|w", _("Set the working directory of the terminal"), &_workingDir,
"profile|p", _("Set the starting profile"), &_profileName,
"session|s", _("Open the specified session"), &_session,
"action|a",_("Send an action to current Terminix instance"), &_action,
"execute|x",_("Execute the passed command"), &_execute);
if (results.helpWanted) {
defaultGetoptPrinter("Terminix Usage:\n\tterminix [OPTIONS]\n\nAvailable options are:\n", results.options);
writeln("Note that the session option is not compatible with profile and working-directory options");
_exitCode = 0;
_exit = true;
}

if (session.length > 0 && (profileName.length > 0 || workingDir.length > 0)) {
writeln(_("You cannot load a session and set a profile/working directory, please choose one or the other"));
exitCode = 1;
exit = true;
}
trace("Command Line Options:\n\tworkingDirectory: " ~ workingDir);
if (_session.length > 0 && (_profileName.length > 0 || _workingDir.length > 0)) {
writeln(_("You cannot load a session and set a profile/working directory, please choose one or the other"));
_exitCode = 1;
_exit = true;
}
trace("Command Line Options:\n\tworkingDirectory: " ~ _workingDir);
trace("Command Line Options:\n\tprofileName: " ~ _profileName);
} catch (GetOptException e) {
writeln("Unexpected error occurred when parsing command line parameters, error was:");
writeln("\t" ~ e.msg);
writeln();
writeln("Exiting terminix");
_exitCode = 1;
_exit = true;
}
}

void clear() {
_workingDir.length = 0;
_profileName.length = 0;
_session.length = 0;
_action.length = 0;
_execute.length = 0;
_exitCode = 0;
_cmdLine.length = 0;
_exit = false;
}

@property string workingDir() {return _workingDir;}

@property string profileName() {return _profileName;}

@property string session() {return _session;}

@property string action() {return _action;}

@property string execute() {return _execute;}

@property string cmdLine() {return _cmdLine;}

@property bool exit() {return _exit;}

@property int exitCode() {return _exitCode;}
}
25 changes: 21 additions & 4 deletions source/gx/terminix/terminal/terminal.d
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import gx.i18n.l10n;
import gx.util.array;

import gx.terminix.application;
import gx.terminix.cmdparams;
import gx.terminix.common;
import gx.terminix.constants;
import gx.terminix.encoding;
Expand Down Expand Up @@ -863,11 +864,18 @@ private:
* Spawns the child process in the Terminal depending on the Profile
* command options.
*/
void spawnTerminalProcess(string initialPath) {
void spawnTerminalProcess(string workingDir) {
CommandParameters overrides = terminix.getGlobalOverrides();
if (overrides.workingDir.length > 0) workingDir = overrides.workingDir;

GSpawnFlags flags = GSpawnFlags.SEARCH_PATH_FROM_ENVP;
string shell = vte.getUserShell();
string[] args;
if (gsProfile.getBoolean(SETTINGS_PROFILE_USE_CUSTOM_COMMAND_KEY)) {
if (overrides.execute.length > 0) {
trace("Overriding the command from command prompt: " ~ overrides.execute);
ShellUtils.shellParseArgv(overrides.execute, args);
flags = flags | GSpawnFlags.SEARCH_PATH;
} else if (gsProfile.getBoolean(SETTINGS_PROFILE_USE_CUSTOM_COMMAND_KEY)) {
ShellUtils.shellParseArgv(gsProfile.getString(SETTINGS_PROFILE_CUSTOM_COMMAND_KEY), args);
flags = flags | GSpawnFlags.SEARCH_PATH;
} else {
Expand All @@ -880,7 +888,7 @@ private:
string[] envv = ["TERMINIX_ID="~terminalUUID];
foreach(arg; args) trace("Argument: " ~ arg);
try {
bool result = vte.spawnSync(VtePtyFlags.DEFAULT, initialPath, args, envv, flags, null, null, gpid, null);
bool result = vte.spawnSync(VtePtyFlags.DEFAULT, workingDir, args, envv, flags, null, null, gpid, null);
if (!result) {
string msg = _("Unexpected error occurred, no additional information available");
error(msg);
Expand Down Expand Up @@ -1169,8 +1177,17 @@ public:
initColors();
_terminalUUID = randomUUID().toString();
_profileUUID = profileUUID;
// Check if profile is overriden globally
trace("Override profile name " ~ terminix.getGlobalOverrides().profileName);
if (terminix.getGlobalOverrides().profileName.length > 0) {
string newProfileUUID = prfMgr.getProfileUUIDFromName(terminix.getGlobalOverrides().profileName);
if (newProfileUUID.length > 0) {
_profileUUID = newProfileUUID;
trace("Overriding profile with global: " ~ _profileUUID);
}
}
gsSettings = new GSettings(SETTINGS_ID);
gsProfile = prfMgr.getProfileSettings(profileUUID);
gsProfile = prfMgr.getProfileSettings(_profileUUID);
gsShortcuts = new GSettings(SETTINGS_PROFILE_KEY_BINDINGS_ID);
gsDesktop = new GSettings(SETTINGS_DESKTOP_ID);
gsDesktop.addOnChanged(delegate(string key, GSettings) {
Expand Down

0 comments on commit 831007e

Please sign in to comment.