Skip to content

Instantly share code, notes, and snippets.

@nall
Created December 15, 2010 19:44
Show Gist options
  • Save nall/742496 to your computer and use it in GitHub Desktop.
Save nall/742496 to your computer and use it in GitHub Desktop.
Shell that allows predefining environment variables before invoking another specified shell
-- `menu_click`, by Jacob Rus, September 2006
--
-- Accepts a list of form: `{"Finder", "View", "Arrange By", "Date"}`
-- Execute the specified menu item. In this case, assuming the Finder
-- is the active application, arranging the frontmost folder by date.
on menu_click(mList)
local appName, topMenu, r
-- Validate our input
if mList's length < 3 then error "Menu list is not long enough"
-- Set these variables for clarity and brevity later on
set {appName, topMenu} to (items 1 through 2 of mList)
set r to (items 3 through (mList's length) of mList)
-- This overly-long line calls the menu_recurse function with
-- two arguments: r, and a reference to the top-level menu
tell application "System Events" to my menu_click_recurse(r, ((process appName)'s ¬
(menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))
end menu_click
on menu_click_recurse(mList, parentObject)
local f, r
-- `f` = first item, `r` = rest of items
set f to item 1 of mList
if mList's length > 1 then set r to (items 2 through (mList's length) of mList)
-- either actually click the menu item, or recurse again
tell application "System Events"
if mList's length is 1 then
click parentObject's menu item f
else
my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
end if
end tell
end menu_click_recurse
#include <stdio.h> // fprintf
#include <string.h> // strtok
#include <unistd.h> // gettop
#include <inttypes.h> // uint32_t
#define VERSION "1.0"
void addDefine(char* define)
{
char* defineCopy = strdup(define);
char* name = strtok(defineCopy, "=");
char* value = strtok(NULL, "");
char* empty = "";
value = (value == NULL) ? strdup(empty) : strdup(value);
setenv(name, value);
free(defineCopy);
free(value);
}
void usage(int rc)
{
fprintf(stderr, "usage: nallsh [-v] [-h] [-d <name=value>] [-s <shell>] [-a <shell argument>]\n");
fprintf(stderr, "\t-v prints the version and exits\n");
fprintf(stderr, "\t-h prints this usage and exits\n");
fprintf(stderr, "\t-d defines an evironment variable with specified name and value. If\n");
fprintf(stderr, "\t value is not specified, the empty string is used\n");
fprintf(stderr, "\t-s species the shell. It should be a full path\n");
fprintf(stderr, "\t-a specifies a shell argument. -l is a common argument to specify a\n");
fprintf(stderr, "\t but check your particular shell's documentation.\n");
exit(rc);
}
int main(int argc, char** argv)
{
char* shell = 0;
char* shellargs[1024];
uint32_t curArg = 1; // We backfill argument 0 after we know the shell
int flag = 0;
while((flag = getopt(argc, argv, "d:s:a:vh")) != -1)
{
switch(flag)
{
case 'd':
{
addDefine(optarg);
break;
}
case 's':
{
shell = optarg;
break;
}
case 'a':
{
shellargs[curArg] = optarg;
++curArg;
break;
}
case 'v':
{
printf("nallsh v%s\n", VERSION);
exit(0);
}
case 'h':
{
usage(0);
}
default:
{
usage(1);
}
}
}
shellargs[curArg] = (char*)0;
int rc = 0;
if(shell == 0)
{
fprintf(stderr, "Must specify shell with -s <shell>\n");
rc = 1;
}
shellargs[0] = shell;
rc = execv(shell, shellargs);
fprintf(stderr, "Couldn't exec shell '%s'. rc = %d\n", shell, rc);
exit(rc);
}
-- rename this file based on your Terminal profile name
property MenuClick : load script POSIX file "/INSERT_PATH_TO/MenuClick.scpt"
tell application "Terminal" to activate
tell MenuClick
menu_click({"Terminal", "Shell", "New Window", "INSERT_YOUR_PROJECT_HERE"})
end tell
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment