Date
1 - 18 of 18
Trying to move away from Finder...
Jean-Christophe Helary <jean.christophe.helary@...>
I'm slowly trying to move away from Finder but I have problems finding equivalents for trivial things that I'm doing, like: tell application "Finder" to set default_location to (target of front window) as alias tell application "Finder" to set originals_folder to (folder "originaux" of project_folder) Any advice ? Jean-Christophe Helary ----------------------------------------------- @brandelune http://mac4translators.blogspot.com |
|
Michael Grant
What are you using in place of Finder? It remains one of the most scriptable applications, and I’ve found that I can replicate most of the functions of alternatives like Path Finder (at least the ones I’m interested in) in Finder
with AppleScript.
Michael
Get Outlook for iOS
From: applescript@apple-dev.groups.io <applescript@apple-dev.groups.io> on behalf of Jean-Christophe Helary <jean.christophe.helary@...>
Sent: Wednesday, November 1, 2017 6:48:18 AM To: applescript@apple-dev.groups.io Subject: [applescript] Trying to move away from Finder... I'm slowly trying to move away from Finder but I have problems finding equivalents for trivial things that I'm doing, like:
tell
application "Finder"
to set default_location
to (target
of front window)
as alias
tell
application "Finder"
to set originals_folder
to (folder "originaux"
of project_folder)
Any advice ?
Jean-Christophe Helary
----------------------------------------------- @brandelune http://mac4translators.blogspot.com |
|
Jean-Christophe Helary <jean.christophe.helary@...>
There are places where I need Finder scripting because I use Finder (for ex to get its front window), but for the rest: working with paths, folders and files on a programatic level, I'd rather not refer to Finder (or whatever application I'd be using instead). The reason is that, as I found out the other day (cf a thread on the SD forum), there are plenty of areas where you need undocumented domain knowledge to be really proficient or not surprised by the behavior of scriptable apps, and I'm loosing a lot of time with that. By the way, I think I found an equivalent to:
It took me a lot of time too, it is not as short or seemingly elegant as the above, but it works: tell application "System Events" to set originals_folder to item 1 of (items of project_folder whose name is "originaux") Jean-Christophe Helary ----------------------------------------------- @brandelune http://mac4translators.blogspot.com |
|
Shane Stanley
On 2 Nov 2017, at 9:53 am, Jean-Christophe Helary <jean.christophe.helary@...> wrote:
Well you could always use: tell application "System Events" to set originals_folder to folder "originaux" of project_folder Or use "item" instead of "folder". However, what it leaves you with is a System Events folder, which is a class only recognised by System Events. So if you're going to be using it within System Events, fine -- otherwise you could use something like: tell application "System Events" to set originals_folder to path of folder "originaux" of project_folder which returns an HFS path (or use "POSIX path of..." for a POSIX path). --
Shane Stanley <sstanley@...> |
|
Christopher Stone
On 11/01/2017, at 17:53, Jean-Christophe Helary <jean.christophe.helary@...> wrote:
By the way, I think I found an equivalent to: Hey Jean-Christophe, There are times when System Events will do things faster than the Finder: ------------------------------------------------------------------------------ tell application "Finder" tell front window if exists then set frontWindow to its target as alias end if end tell end tell # Almost instant on my ~/Downloads folder. tell application "System Events" disk items of frontWindow whose name contains "key" end tell # Approximately 7 seconds on my ~/Downloads folder tell application "Finder" (items of frontWindow whose name contains "key") as alias list end tell ------------------------------------------------------------------------------ And there are times when System Events will do things the Finder won't do: ------------------------------------------------------------------------------ set hfPath to path to home folder -- alias tell application "System Events" set hfPath to POSIX path of hfPath -- POSIX Path end tell tell application "System Events" set hfPath to POSIX path of disk item "~/" -- POSIX Path end tell ------------------------------------------------------------------------------ The thing to do is to use the best tool for the job, and that's very often the Finder. -- Best Regards, Chris |
|
Shane Stanley
On 2 Nov 2017, at 10:29 am, Christopher Stone <listmeister@...> wrote:
Defining best can be the issue, though. I suspect what most scripters really want is a single tool that may not be the fastest at everything, but is reliable, straight-forward to use, and fast enough. There was a time when the Finder was mostly just that. Sadly, it now isn't, especially in terms of performance, so there's often a need to look elsewhere. That's where System Events was supposed to come in: it should have taken over the file management side of things, leaving Finder scripting for where you wanted to deal with Finder-specific issues, like window state or selections. But System Events comes up short not least because it is largely limited to its own item/file/folder classes -- there's no equivalent to things like the Finder's "as alias list", so getting stuff out of it is more challenging than it should be. And it has its own quirks (a trivial example: it returns the wrong name for files containing a / character). AppleScriptObjC offers the file manager, which is reliable and very fast -- but the learning curve is obviously substantial. It can be mitigated substantially by using libraries, but it's obviously not for everyone. -- Shane Stanley <sstanley@...> <www.macosxautomation.com/applescript/apps/>, <latenightsw.com> |
|
Jean-Christophe Helary <jean.christophe.helary@...>
I was going to write something like that but considering my "level" in AS it would have sounded more like a sad rant than anything else so I gave up. But, yes, that's my feeling, plus the fact that there is very little application specific documentation. It's really hard to make an informed decision.
Honestly, anything is better than quirks and lack of documentation. Anyway, the beginning of this discussion was about moving dialog calls outside of application tell blocks, I'll complete that first and then, I'll eventually check how to convert the file managing parts to ASOC. Thank you all for your replies. Jean-Christophe Helary ----------------------------------------------- @brandelune http://mac4translators.blogspot.com |
|
Jean-Christophe Helary <jean.christophe.helary@...>
Thank you Shane.
Trying to understand the code below (while trying to understand the Foundation documentation in Xcode):
It looks like you are calling a handler (fileURLWithPath) that belongs to whatever |NSURL| is (are the || required ?) and that "|NSURL|" belongs to "current application", with the parameter default_location. Checking the Foundation documentation, I find that fileURLWithPath is a "Type Method" for the "NSURL" class. Is it the same "|NSURL|" as above? So I guess I can use other "Type Methods" instead of fileURLWithPath to produce different results, right? As long as the parameter type corresponds to what the method requests (here, fileURLWithPath requests a "path" and I'm guessing the only valid path for a NSURL parameter is a POSIX path). Why call "current application" here ? What is its role here ?
Does that mean that the "set default_location_url to" command created an instance of NSURL and that I can use relevant instance methods on it? The Foundation documentation also mentions "URLBy I know I should not have thrown away my Objective-C book. I can't find a page that explains the difference between Instance Method, Type Method (and there is seemingly also a Class Method thing)...
Ok, now I guessed that "NSFileManager" was a class, and I was right... Good :-) But why not use the "|NSFileManager|" syntax that you used above? Now, "defaultManager()" looks like it won't take a parameter, but the Foundation documentation says that defaultManager is a "Type Property", so I'm not sure what to do with that information and how to interpret what the code does. But in the end, we get an instance of the class NSFileManager's in fileManager, correct? So we can use the instance method "createDirectoryAtURL" on it. The Foundation documentation shows something like: createDirectoryAtURL:withIntermediateDirectories:attributes:error: And the way you write it shows how to make sense of that notation:
Here again, you use a " | ... | " notation, for "|error|" this time. Why? Checking localizedDescription, I see that it is an Instance Property, so I guess it means it the property of an instance of the class NSError, that is automatically returned by createDirectoryAtURL and set to theError. I'm not sure what to do with (missing value) and (reference) though. Is (missing value) just a way to say that you don't set that parameter? The documentation for (reference) as a value for |error| is much less clear. I mean, not clear at all. createDirectoryAtURL returns YES or NO depending on whether the directory was created or not, so I guess YES and NO are automatically considered as boolean? I was not aware of the Applescript error statement (except in "on error"), so here theError's localizedDescription() returns something that needs to be changed to text so that error can display it.
Also, the documentation for the options is not super clear. Not sure what a "shallow enumeration" is... And I guess we are not interested in the error message here...
It's slowly beginning to make sense... Plus we have a super sunny afternoon here, so I guess I'm blessed... Ok, here we use URLByAppendingPathComponent again, this time by adding not an arbitrary string like we did when we created new_folder_url's but by adding the lastPathComponent() of the URL of one of the contents of the "originaux" folder. lastPathComponent is an Instance Property. It looks like the syntax for all the properties we've had so far was property() and not property. Now we have a (fileManager's moveItemAtURL:one_url...), why is it between parens and not on it's own like a normal statement? I guess that's all for the time being... Sorry for the number of questions and comments, etc. Also, I do have your book on ASOC, so if answers are to be found there (sorry I was focusing on the Foundation doc here), don't hesitate to give a pointer instead. Jean-Christophe Helary ----------------------------------------------- @brandelune http://mac4translators.blogspot.com |
|
Shane Stanley
On 2 Nov 2017, at 3:50 pm, Jean-Christophe Helary <jean.christophe.helary@...> wrote:
The pipes around NSURL are used because there's a terminology clash with a fairly common scripting addition that unfortunately uses the Cocoa class name. Preceding it by "current application's " is just the way to refer to a Cocoa class. The term "type method" is a relatively new Swiftian thing -- these were traditionally called "class methods", because the target of them is the class itself (as opposed to "instance methods", which are targeted at instances of the class).
It's just the file type used in Cocoa -- like AppleScript uses aliases of file references. You can do a lot of this with POSIX paths instead, but having a file object is more efficient. (And as of 10.11, they can be coerced to aliases or files).
It returns an instance of NSFileManager (one that is shared throughout the host application). You need an instance before you can call any instance methods. When a Cocoa method takes no arguments (that is, has no colon), you use parentheses in AppleScript.
Right.
"missing value" is essentially nil or NULL. Many out arguments (and some others) are optional.
Well, yes, it does :-) --
Shane Stanley <sstanley@...> |
|
Jean-Christophe Helary <jean.christophe.helary@...>
Well, that was definitely time well spent on my side, and thank you *very much* for the thorough reply. This is going to become a very colorful blog post... :-) I guess it will take me a bit more time to be able to read ASOC and make sens of everything, as for *writing* it I have no idea... But well, there is a start to everything. Now, I think you wrote about that in a different thread, but I'm not sure, it is about the scope of ASOC as an automation tool. Is it better to see it as a replacement for System Events/Scripting Additions, ie, faceless code that glues things together between applications, and use standard AS for accessing the application's automation features, is that correct ? I'm going back to work now, it'll take some time to process all that. Jean-Christophe
Jean-Christophe Helary ----------------------------------------------- @brandelune http://mac4translators.blogspot.com |
|
Shane Stanley
On 2 Nov 2017, at 4:59 pm, Jean-Christophe Helary <jean.christophe.helary@...> wrote:
Pretty much. There are exceptions, but it's mostly useful for file/date/string/image manipulation. File manipulation is a biggie simply because the alternatives aren't so hot. I should also mention that my FileManagerLib here: <https://www.macosxautomation.com/applescript/apps/Script_Libs.html> wraps a lot of this stuff in a library. It's just undegoing a bit of a rev now… -- Shane Stanley <sstanley@...> <www.macosxautomation.com/applescript/apps/>, <latenightsw.com> |
|
Shane, thanks for mentioning, and thus reminding me of, this great library of yours.
One of the things I really like is that it automatically handles all types of file/folder references.
From the ReadMe:
Where files or folders are required as parameters, you can pass aliases, files, HFS paths and POSIX paths. POSIX paths should not be quoted, and a leading ~ will be expanded.
You mentioned "It's just undegoing a bit of a rev now…". Does that mean we should expect an update soon?
Care to share what the key changes are?
Best Regards,
Jim Underwood
aka JMichaelTX
I should also mention that my FileManagerLib here: <https://www.macosxautomation.com/applescript/apps/Script_Libs.html> wraps a lot of this stuff in a library. It's just undegoing
a bit of a rev now…
--
Shane Stanley <sstanley@...>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>
|
|
Shane Stanley
On 3 Nov 2017, at 6:43 am, Jim Underwood <JMichael@...> wrote:
Yes, within days. I'm looking for volunteers to test the new stuff. Care to share what the key changes are?Some clean-up and better trapping of problems. Also handlers for getting the contents of folders, including recursively. Plus a couple of sorting handlers. -- Shane Stanley <sstanley@...> <www.macosxautomation.com/applescript/apps/>, <latenightsw.com> |
|
Ray Robertson
Nice! I’m pretty swamped at the moment, but could likely test this weekend. <hand raised> Ray |
|
Michael Grant
Unless I'm missing the point here — entirely possible! — for whatever it's worth you actually don't need Finder *or* System Events for this particular task. The following does nicely, without any tell block: set hfPath to POSIX path of (path to home folder) (Not sure if this is built into the language itself or part of Standard Additions.) Michael On Wed, Nov 1, 2017 at 6:29 PM, Christopher Stone <listmeister@...> wrote:
|
|
Christopher Stone
On 11/22/2017, at 22:24, Michael Grant <mgrant@...> wrote:
Unless I'm missing the point here — entirely possible! — for whatever it's worth you actually don't need Finder *or* System Events for this particular task. The following does nicely, without any tell block: Hey Michael, Eh? Oh, yeah — you're right. The POSIX Path coercion will work on aliases, hfs-paths, FURLs...
The only direct way of doing so is to use System Events, and SEV has gotten fast enough that I don't mind using it for public code. On my own system I use a handler that does this far faster than System Events. ------------------------------------------------------------------------------ on expandTilde(_path) if _path is "~" or _path is "~/" then set _path to POSIX path of (path to home folder as text) else if _path starts with "~/" then set _path to (POSIX path of (path to home folder as text)) & text 3 thru -1 of _path else error "Bad path string!" end if end expandTilde ------------------------------------------------------------------------------ AppleScriptObjC too has a method for expanding a tilde-path that's not especially arcane: ------------------------------------------------------------------------------ use AppleScript version "2.4" use framework "Foundation" use scripting additions set bPath to "~/Desktop" set pathString to current application's NSString's stringWithString:bPath set newPath to pathString's stringByExpandingTildeInPath() as string ------------------------------------------------------------------------------ Or as a one-liner: ------------------------------------------------------------------------------ set expandedPathString to (current application's NSString's stringWithString:bPath)'s stringByExpandingTildeInPath() as string ------------------------------------------------------------------------------ -- Best Regards, Chris |
|
2551phil
I find this way slightly easier to remember (and type): use AppleScript version "2.4" use scripting additions use framework "Foundation" set usr to current application's NSUserName() as text set homePath to "/Users/" & usr Best Phil @sqwarq |
|
Christopher Stone
On 11/23/2017, at 09:33, 2551phil <2551phil@...> wrote:
Hey Phil, Remember? Type? I keep stuff like that in my snippets library, so they're a couple of keystrokes away. :) Still... Good to know. -- Take Care, Chris |
|