This looks brilliant, @JMichaelTX! Looking forward to the finished (or beta-rated) product.
P.S.
What if you want a parameter that starts with "LIST:" ?
This looks brilliant, @JMichaelTX! Looking forward to the finished (or beta-rated) product.
P.S.
What if you want a parameter that starts with "LIST:" ?
I don't see a problem. A parameter can be anything you want. "LIST:" is only used to convert a parameter line from text into a list.
If you want "LIST:" to be one of the items, then you would use:
LIST: LIST:,TEXT:,OBJECT:
etc.
Otherwise, "LIST:" appearing at the beginning of a parameter line has no effect, and is included as part of the parameter.
Make sense?
I think it is almost ready. Just been adding some more error checking. After I sleep on it, and test tomorrow, I will probably publish.
I might be having a slow day (or nightβit's the wee hours here), so my tiredness might be impeding my ability to analyse; I was considering a scenario like this:
Desired Parameter List: { "π", "LIST: Imaginary, Irrational, Algebraic", {2.718, 3.1416}, "LIST: Real, Irrational, Trascendental" }
i.e. four parameters, three of which are unary string values, and one of which (the third parameter) is a list of two numbers (which will parse, of course, into a list of two strings).
The second and third parameters are the issue; inputting the parameters like this:
π
LIST: Imaginary, Irrational, Algebraic
LIST: 2.718, 3.1416
LIST: Real, Irrational, Trascendental
would (if I'm doing this correctly) yield { "π", {"Imaginary", "Irrational", "Algebraic"}, {"2.718", "3.1416"}, ("Real", "Irrational", "Transcendental"} }
.
Obviously, this is a very minor point and artificially constructed beyond the likely real world scenarios. But I'm intrigued.
So, if you are saying that you do NOT want this parameter converted to a list, but you do want to start the parameter with "LIST:", then yes that would be a problem.
Of course, this parameter would also be converted into a list using your method, just because it contains commas.
I suppose I could implement an escape method, so you you could enter:
\LIST: Imaginary, Irrational, Algebraic
and the script would NOT convert to a list, but would remove the backslash.
If you want to retain \LIST
then you would need to enter two backslashes:
\\LIST: Imaginary, Irrational, Algebraic
So the script would need to check for this RegEx:
\\+LIST:
and then remove the first backslash.
How does that look? Think it will work? Or do you have a better suggestion?
@CJK, OK, this seems to work. Here's my test script.
Let me know if you can break it, or see any flaws.
set testParams to "first line
\\LIST: a,b,c
LIST: x,y,z"
set myList to paragraphs of testParams
my splitItems(myList, ",")
on splitItems(pList, pDelim)
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to pDelim
repeat with oItem in pList
if (oItem starts with "LIST:") then
set contents of oItem to (text items of LTrim(text 6 thru -1 of oItem))
else if (my isFoundKME("^\\\\+LIST:", oItem)) then
set contents of oItem to (text 2 thru -1 of oItem)
end if
end repeat
set AppleScript's text item delimiters to oldTID
return -- original List was updated
end splitItems
on isFoundKME(pRegEx, pString)
tell application "Keyboard Maestro Engine"
set isFound to found in pString for pRegEx with regex
end tell
return isFound
end isFoundKME
on LTrim(pString)
set len to length of pString
repeat with i from 1 to len
set iChar to character i of pString
if (iChar β " " and iChar β tab) then exit repeat
end repeat
set trimedStr to text i thru -1 of pString
end LTrim
@CJK, as long as we are in enhancement/debug mode, I went ahead and added code to convert a text number to an actual number. After crashing SD7 a few times (my bad), I finally arrived at this script.
Would appreciate it if you have time, to take a look and test it.
set testParams to "first line
\\LIST: a,b,c
LIST: 1,X,3
123.45"
set myList to paragraphs of testParams
my splitItems(myList, ",")
on splitItems(pList, pDelim)
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to pDelim
repeat with oItem in pList
if (oItem starts with "LIST:") then
set contents of oItem to (text items of LTrim(text 6 thru -1 of oItem))
repeat with oSubItem in oItem
set contents of oSubItem to my textToNum(contents of oSubItem)
end repeat
else if (my isFoundKME("^\\\\+LIST:", oItem)) then
set contents of oItem to (text 2 thru -1 of oItem)
else
set contents of oItem to my textToNum(contents of oItem)
end if
end repeat
set AppleScript's text item delimiters to oldTID
return -- original List was updated
end splitItems
on isFoundKME(pRegEx, pString)
tell application "Keyboard Maestro Engine"
set isFound to found in pString for pRegEx with regex
end tell
return isFound
end isFoundKME
on LTrim(pString)
set len to length of pString
repeat with i from 1 to len
set iChar to character i of pString
if (iChar β " " and iChar β tab) then exit repeat
end repeat
set trimedStr to text i thru -1 of pString
end LTrim
on textToNum(pString)
set numOrText to pString
try
set numOrText to numOrText as number
on error errMsg number errNum
set x to numOrText
end try
return numOrText
end textToNum
Thanks.
BTW, all of this is a bit off-topic from your OP. Would you like me to move it to a new topic?
I don't see this as off-topic at all. It certainly seems like you're implementing some great improvements/enhancements to my original action.
Only if the inline delimiter
is set to the comma
. To avoid parameterising the comma-delimited list in my action as it currently stands, one would change the inline delimiter
to something other than comma
.
The self-destruct scenario in my set up is where one has an exhaustive list of parameters that collectively make use of all the available inline delimiter
character options, but without the desire to have any inline parameterisation occur.
I'll do some testing of your scripts and get back to you. Having skimmed them, it would make more sense to me if \LIST:
were the keyword that parameterises a comma-delimited list, whilst LIST:
remained insignificant. It would be more conventional and more intuitive that way round, as it actively then tokenises an ordinary word and imbues it with a function in the mind of the user. It would also have the benefit of negating the need to test twice to determine whether the parameter string starts with "LIST:"
or starts with "\LIST:"
, as the first would be inconsequential, and the latter would be the token of interest. If you make \
a global escape character (i.e. applied to the whole string rather than only when LIST:
is involved), it too would seem to me to make more cohesive sense, and also make the programming easier as you can simply do a global replacement that substitutes a single \
for every two, negating the need for a regular expression match.
I'll let you ponder on that and you can decide to go with what you feel is best.
This is looking really good.
I've had a few hours to overlook your script, and also saw the related posts on the Late Night Software (Script Debugger) forum.
I wonder if there might be more suited to this debugging-and-enhancing stage of the AppleScript, as there seem to be some very active input from other AppleScripters, and Shane Stanley always has great input.
But, for now, I'll post my current findings and thoughts here.
You and I have quite different scripting styles when it comes to AppleScript, although I'm aware I have unorthodox preferences with my use of syntax etc. But it does make it interesting reading other people's style of coding.
The actual implementation looks all totally fine to me, with the slight exception of your LTrim()
handler, which felt a bit inefficient. Alone, this was simply more of an irk than a reason to do anything about it, but it also has two fail case scenarios:
β LTrim(" ")
returns " "
where the more appropriate return value would be ""
β‘ LTrim("")
returns an error
Whilst I'm listing debugging issues, I'll just note another two that cropped up elsewhere in the script:
β’ A parameter value of "LIST:"
(without the quotes) returns an error where the more appropraite return value would be an empty list {}
β£ Attempting to use the LIST:
token/function with leading white space isn't catered for. Therefore, a parameter value of " LIST: 1,x,3"
returns itself as a unary string value parameter, where my personal feeling is that it ought to parameterise the list
β€ textToNum()
returns 0
for the empty string where the appropriate return value would be the empty string
Your regex implementation to remove one backslash from a sequence preceding "\LIST:"
works really nicely. It made me re-consider my earlier suggestion of globalising the backslash as an escape character for the entire parameter text, hence the strikethrough text in my previous post.
I do still consider it sensible to use the backslash as a tokenising character rather than an escaping character, i.e. \LIST:
being the keyword, and not LIST:
.
[ As a side-note, you might consider using some sort of enclosing token that resembles a function call, such as \LIST:[...]
or \LIST{...}
or perhaps even just \[...]
or \{...}
, because this will enable you to further expand your efforts in the future should you decide you want to be able to parse nested lists of parameters. ]
One thing I really like is how you update the contents of the original list passed to splitItems
. I've never thought of doing this, but I think it's pretty slick.
Now I'm going to offer some small code adjustments, which I hope you feel might be improvements, but I'll leave you to decide what to keep and what to bin. Firstly, the LTrim()
handler that has two exceptional fail cases that warranted a rewrite to also improve efficiency (or, so I think, but I haven't conducted speed tests). I have two versions, each with merits and drawbacks (forgive me for renaming variables and such, but I drafted them from scratch):
on Ltrim(s)
set my text item delimiters to {null, space, tab}
set t to the text items of s as text
if t is "" then return ""
set n to the offset of (text 1 of t) in s
text n thru -1 of s
end Ltrim
The good: 1) handles a single space or an empty string appropriately; 2) bypasses the need for a repeat
loop by utilising the builtin offset
function; 3) reads more user-friendly.
The bad: 1) utilises text item delimiters
, which potentially inteferes with other parts of the script [ You and I have different coding practises here: you always reset your TIDs
after using them; I, however, never do this, as I elect to always set them directly prior to using them. Thus, you might want to adjust this handler to reset them before the handler exits, whereas my method was to adjust splitItems()
to place its TID
call immediately before text items of...
line) ]; 2) has a fail case scenario when the string passed to it starts with any leading white space followed by "null"
as its first non-whitespace substring (I have a fix for this if necessary).
Here's the second variation of the handler:
on Ltrim(s)
set s to {} & id of s
repeat while s β {} and item 1 of s is in [9, 32]
set s to rest of s
end repeat
character id s
end Ltrim
The good: 1) handles " "
and ""
appropriately; 2) utilises list manipulation rather than string manipulation, meaning it can combine progression and trimming in a single operation; 3) no fail cases identified so far; 4) reads easier.
The bad: Nothing glaring.
I think the benefits of using list manipulation over text manipulation are debatable, but perhaps you can conduct a speed test on the two (if you like, but don't bother if you don't want to. I've never done a speed test before, so perhaps I can make this my first when I have a clear plate).
Finally, I think the idea of coercing classes to their appropriate/likely intended type is a brilliant one. I wish I had thought of that when I'd made the action, as you've demonstrated it's very easy to implement. One slight issue I mentioned above is its false-positive coercion of the ""
into 0
. One solution is obvious:
on textToNum(s)
if s is "" then return ""
try
s as number
on error
s
end try
end textToNum
Shane Stanley on the LNF forum offered a lovely streamlined piece of code:
on textToNum(pString)
try
if "0123456789-." contains character 1 of pString then
set pString to pString as number
end if
end try
return pString
end textToNum
However, this doesn't coerce numeric strings that have leading white space. A call to the Ltrim()
handler might be one workaround, but it then negates the efficiency benefits his offering promised.
Some on the LNF forum also offered an ObjC flavour option, but his chosen implementation and his regex pattern leave it wide open for many fail cases. And, I don't know what your thoughts are on pulling in ObjC to do these minor tasks, even though for larger tasks, it is clearly much faster. If anything, for this KM action, my inclination (as you may have gleaned) is to use shell scripts more freely than I would typically, simply because it was necessary to retrieve the $KMPARAM_
variables this way in order to preserve non-traditional characters, including international ones and technical symbols often found in the %TriggerValue%
KM token. Plus, bash functions are usually pretty fast compared to AppleScript, though there's an overhead in calling a shell process.
But, as a flavour, one why to trim excess white space from either side of a string and from in between characters is:
do shell script "echo " & quoted form of s & " | xargs"
In fact, thinking about it, I suspect the bulk of the parameter parsing could be done with shell script quite efficiently. I'll have a think.
That's it for now. Thanks so much for working on this. You're clearly doing a great job and spinning out some really neat ideas.
If you wish to post a specific question at LNS, please feel free to do so.
The script I posted there was just to report a SD7 bug/crash, not go get help with the script itself.
I generally don't ask for help there unless I can't resolve the problem, or feel like there must be a better solution. As you may have noted, I did post a question about converting text to numbers.
No problem. I am always willing to learn new things. But then I may or may not adopt them to my core style.
Thanks for doing more exhaustive testing than I did.
I did review your solutions, but found that with just a minor mod to my script the bugs were fixed. IMO, I don't see any material inefficiencies in this script:
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on LTrim(pString)
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(* VER: 1.1 2018-06-17
PURPOSE: Remove all Spaces & Tabs From Beginning of String
PARAMETERS:
β’ pString | text | Source string
RETURNS: | text | String with No Spaces/Tabs at Beginning
AUTHOR: JMichaelTX
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*)
local trimmedStr, i, iChar
set trimmedStr to ""
set len to length of pString
if (len > 0) then
repeat with i from 1 to len
set iChar to character i of pString
if (iChar β " " and iChar β tab) then
set trimmedStr to (text i thru -1 of pString)
exit repeat
end if
end repeat
end if
return trimmedStr
end LTrim
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I think we are on the same page here.
As I looked at this, it occurred to me that if the parameter is empty, then we don't know the intended class. So I decided on missing value. Of course, if you prefer, you can just change this to ""
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on textToNum(pString)
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(* VER: 1.1 2018-06-17
PURPOSE:
PARAMETERS:
β’ pString | text | Source String
RETURNS: | number or text or missing value |
β’ Number IF string can be converted;
β’ Else source string unchanged.
β’ missing value IF empty pString
AUTHOR: JMichaelTX
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*)
if (length of pString > 0) then
try
set numOrText to pString as number
on error -- errMsg number errNum
set numOrText to pString
end try
else -- IF pString is empty
set numOrText to missing value
end if
return numOrText
end textToNum
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Well, you are the one with the original idea and implementation. So thanks go to you.
Here's my complete updated test script. As always, feel free to test and critique.
set testParams to "first line
\\LIST: a,b,c
LIST: 1,X,, , ,-3.14
123.45"
set myList to paragraphs of testParams
my splitItems(myList, ",")
set trimEmpty to my LTrim("")
set trimSpace to my LTrim(" ")
set trimNeedsTrim to my LTrim(" Needs Trim")
set trimNoneNeeded to my LTrim("No Trim Needed")
set myNum to my textToNum(" 3.14159")
--~~~~~~~~~~~~~~~~~~~~~~~~ HANDLERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on splitItems(pList, pDelim)
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(* VER: 2.0 2018-06-16
PURPOSE: (1) Split Each Item in List into a Sub-List where requested
(2) Convert Numeric Text Itens to Actual Numbers where possible
PARAMETERS:
β’ pList | list | Source list of text items
β’ pDelim | text | Delimiter to be Used for split
RETURNS: Nothing. The Original List in the Parameters is updated with changes.
AUTHOR: JMichaelTX
## REQUIRES: Keyboard Maestro Engine for RegEx
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*)
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to pDelim
repeat with oItem in pList
--- IF Item starts with "LIST:", then split text into sub-list ---
if (oItem starts with "LIST:") then
set contents of oItem to (text items of LTrim(text 6 thru -1 of oItem))
--- Convert Text Items to Numbers if Possible ---
repeat with oSubItem in oItem
set contents of oSubItem to my textToNum(contents of oSubItem)
end repeat
--- IF Item Start with one or more Backslashses (\) & "LIST:", remove first \ ---
else if (my isFoundKME("^\\\\+LIST:", oItem)) then
set contents of oItem to (text 2 thru -1 of oItem)
--- Convert Text Item to Number if Possible ---
else
set contents of oItem to my textToNum(contents of oItem)
end if
end repeat
set AppleScript's text item delimiters to oldTID
return -- original List was updated
end splitItems
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on isFoundKME(pRegEx, pString)
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(* VER: 1.0 2018-06-16
PURPOSE: Determine if RegEx is Matched in String
PARAMETERS:
β’ pRegEx | text | Regular Expression
β’ pString | text | Source string to search
RETURNS: true if match is found
AUTHOR: JMichaelTX
## REQUIRES: Keyboard Maestro Engine
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*)
tell application "Keyboard Maestro Engine"
set isFound to found in pString for pRegEx with regex
end tell
return isFound
end isFoundKME
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on LTrim(pString)
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(* VER: 1.1 2018-06-17
PURPOSE: Remove all Spaces & Tabs From Beginning of String
PARAMETERS:
β’ pString | text | Source string
RETURNS: | text | String with No Spaces/Tabs at Beginning
AUTHOR: JMichaelTX
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*)
local trimmedStr, i, iChar
set trimmedStr to ""
set len to length of pString
if (len > 0) then
repeat with i from 1 to len
set iChar to character i of pString
if (iChar β " " and iChar β tab) then
set trimmedStr to (text i thru -1 of pString)
exit repeat
end if
end repeat
end if
return trimmedStr
end LTrim
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on textToNum(pString)
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(* VER: 1.1 2018-06-17
PURPOSE:
PARAMETERS:
β’ pString | text | Source String
RETURNS: | number or text or missing value |
β’ Number IF string can be converted;
β’ Else source string unchanged.
β’ missing value IF empty pString
AUTHOR: JMichaelTX
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*)
if (length of pString > 0) then
try
set numOrText to pString as number
on error -- errMsg number errNum
set numOrText to pString
end try
else -- IF pString is empty
set numOrText to missing value
end if
return numOrText
end textToNum
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Agreed. sorry I missed this in my reply above.
So here's the updated handler:
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on splitItems(pList, pDelim)
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
(* VER: 2.1 2018-06-17
PURPOSE: (1) Split Each Item in List into a Sub-List where requested
(2) Convert Numeric Text Itens to Actual Numbers where possible
PARAMETERS:
β’ pList | list | Source list of text items
β’ pDelim | text | Delimiter to be Used for split
RETURNS: Nothing. The Original List in the Parameters is updated with changes.
AUTHOR: JMichaelTX
## REQUIRES: Keyboard Maestro Engine for RegEx
--βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
*)
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to pDelim
repeat with oItem in pList
--- IF Item starts with "LIST:", then split text into sub-list ---
if (oItem starts with "LIST:") then
if (length of oItem > 5) then
set contents of oItem to (text items of LTrim(text 6 thru -1 of oItem))
--- Convert Text Items to Numbers if Possible ---
repeat with oSubItem in oItem
set contents of oSubItem to my textToNum(contents of oSubItem)
end repeat
else -- length β€ 5
set contents of oItem to {}
end if
--- IF Item Start with one or more Backslashses (\) & "LIST:", remove first \ ---
else if (my isFoundKME("^\\\\+LIST:", oItem)) then
set contents of oItem to (text 2 thru -1 of oItem)
--- Convert Text Item to Number if Possible ---
else
set contents of oItem to my textToNum(contents of oItem)
end if
end repeat
set AppleScript's text item delimiters to oldTID
return -- original List was updated
end splitItems
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Debatable. But for now I'll have to disagree. The user has rules which must be followed (Parameter MUST START with "LIST:" ...), and I don't want to complicate the code to handle this edge case. It would just be a convenience, not loss of feature.
Sensible, but still just a design call. Since I already have it working as it, I think I'll just leave it as plain "LIST:" to invoke the list function. I think this is also easier for most users. Again, I think even using the "LIST:" function is an edge case, so it is not worth complicating the code, IMO.
OK, I think I now have covered all of your points. If I missed any, please feel free to reply.
Hi @JMichaelTX, what's the latest regarding your fork of this plug-in ? Did you carpark it whilst you deal with other projects ?
In the interim, I've created a second version of my plug-in, that implements some added functionality inspired by your ideas. Specifically, it tries to identify the most likely AppleScript type class from a string value and coerce or substitute the appropriate AppleScript object type in its place.
Do you mind if I upload my updated plug-in here, whilst crediting you for the idea ? Or would you like me to send you a copy privately so you can review it and decide if there's a potential conflict of interest ?
Or am I over-thinking this ?
Lastly, if I do upload my version 2.0, should I edit the original post and overwrite that file with the update; or should I post it as a reply to this post; or create a new post ?
Yep, just been busy with other stuff.
I've pretty much finished the plugin, I just need to write the documentation.
Feel free to go ahead and update your plugin. I don't need to review it, unless you specifically want me to. I don't see any conflict of interest.
When I get my plugin ready to publish, I will post to a new topic, with a credit/link to your plugin.
I just made a post about this:
Run AppleScript With Specified Parameters.zip (50.3 KB) [ UPDATED: 2018-09-02 ]
Fixed an issue where paths to the script file were incorrectly processed if they contained characters that have special meaning in bash without first being properly escaped.
Under the hood, some code refactoring has, in theory, made the script faster to execute, whilst also shortening the script syntactically.
@CJK, do you know if it would be possible to create a similar plugin, but for JXA scripts instead of AppleScripts?
I just did a quick test and I don't see any reason why it wouldn't be possible. I created a small JXA script:
function run(input) {
var app=Application.currentApplication()
app.includeStandardAdditions = true
return app.displayNotification(input[0], {withTitle: input[1]})
}
Then I ran it from an AppleScript:
set message to "Success!"
set title to "Hello, World"
run script "/Users/CK/Documents/Scripts/AppleScript/scripts/jxa.scpt" with parameters {message, title} in "JavaScript"
The script executed correctly:
The only issue, which as far as I can tell is a minor one, is that the script returns an error -4960, about which there appears to be no information online:
This can be handled easily enough:
try
run script "/Users/CK/Documents/Scripts/AppleScript/scripts/jxa.scpt" with parameters {message, title} in "JavaScript"
on error E number N
if N = -4960 then return
end try
However, I can't find a way as yet to obtain a return value from the JXA script through conventional means.
In fact, given this, my plugin ought to work for JXA scripts too:
JXA.scpt
is the same JavaScript script as above, and it executed correctly:
However, as I stated, there's no return value (although there's also no error -4960 from Keyboard Maestro).
Finally, I also just tested a quick mirror-version of my plugin where main.scpt
(the script that runs within the plugin itself, behind the scenes) is written in JXA rather than AppleScript. Early signs are encouraging, meaning you can create the entire plugin using only JXA, without having to rely on AppleScript at all.
@JMichaelTX, apologies for the third message relating to this query, but upon further experimentation, it appears that using osascript
to execute the JXA script is successful, without error -4960, and provides a return value.
Therefore, the plugin could make use of do shell script
to execute the JXA with parameters, however this would, of course, mean a shell process is running for the duration of the script, which is less than ideal.
However, I suspect AppleScriptObjC's OSAKit
would probably be the ultimate solution. My next iteration of this plugin was intending to convert the entire thing to ASObjC anyway, so I will make sure to test it with JXA scripts too.
No apologies are needed. Many thanks for all of your experimentation.
I agree with you that it seems like JXA should also work in this fashion.
Unfortunately, I'm consumed in a major project, so I've no time to experiment, for now.
But, "I'll be back".