Problem…
Since MacPerl is no longer supported on 64bit perl, I am trying alternative frameworks to control Terminal.app.
I am trying the ScriptingBridge, but have run into a problem passing an enumerated string to the closeSaving method using the PerlObjCBridge.
I want to call:
typedef enum {
TerminalSaveOptionsYes = 'yes ' /* Save the file. */,
TerminalSaveOptionsNo = 'no ' /* Do not save the file. */,
TerminalSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
} TerminalSaveOptions;
- (void) closeSaving:(TerminalSaveOptions)saving savingIn:(NSURL *)savingIn; // Close a document.
Attempted Solution…
I have tried:
#!/usr/bin/perl
use strict;
use warnings;
use Foundation;
# Load the ScriptingBridge framework
NSBundle->bundleWithPath_('/System/Library/Frameworks/ScriptingBridge.framework')->load;
@SBApplication::ISA = qw(PerlObjCBridge);
# Set up scripting bridge for Terminal.app
my $terminal = SBApplication->applicationWithBundleIdentifier_("com.apple.terminal");
# Open a new window, get back the tab
my $tab = $terminal->doScript_in_('exec sleep 60', undef);
warn "Opened tty: ".$tab->tty->UTF8String; # Yes, it is a tab
# Now try to close it
# Simple idea
eval { $tab->closeSaving_savingIn_('no ', undef) }; warn $@ if $@;
# Try passing a string ref
my $no = 'no ';
eval { $tab->closeSaving_savingIn_(\$no, undef) }; warn $@ if $@;
# Ok - get a pointer to the string
my $pointer = pack("P4", $no);
eval { $tab->closeSaving_savingIn_($pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$pointer, undef) }; warn $@ if $@;
# Try a pointer decodes as an int, like PerlObjCBridge uses
my $int_pointer = unpack("L!", $pointer);
eval { $tab->closeSaving_savingIn_($int_pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$int_pointer, undef) }; warn $@ if $@;
# Aaarrgghhhh....
As you can see, all my guesses at how to pass the enumerated string fail.
Before you flame me…
- I know that I could use another language (ruby, python, cocoa) to do this but that would require translating the rest of the code.
- I might be able to use CamelBones, but I don’t want to assume my users have it installed.
- I could also use the NSAppleScript framework (assuming I went to the trouble of finding the Tab and Window IDs) but it seems odd to have to resort to it for just this one call.
enumdoes not name string constants; it namesintconstants. Each of these names is of anintvalue.So, try packing as
aorIinstead. Or, do both: Pack asa, then unpack asIand pass that number.