Very interesting! I am on a Mac but I never got into AppleScript. I would want to add a little bit of logic to allow file names starting with the ID and falling back to content search, but I see how your script demonstrates the essential concept.
The big value I see in using this "protocol" approach is that it liberates us from hacking individual editors. If ANY editor can issue a file request for zkn:ID, then we can handle the logic in the protocol handler to control EVERY editor's behavior!
Still, the unclear part to me is, once my editor has opened a zettel through its zkn: link, what happens when I modify that buffer in the editor? How does it know where to Save the buffer? If someone figures that out, then all we need is implementation.
Thanks for linking to that AppleScript post, @ctietze .
The point is that the protocol handler – e.g., Christian's Apple Script – is calling the editor in a way that the editor knows where the file is located. For The Archive just by delegating to the protocol of The Archive, for Sublime Text (a former use case of mine) by providing the file location (i.e., the path in the file system) to the subl executable1. You can then simply save with the editors normal save commands.
I implemented my zettel://-Handler via AppleScript in a python-script (see this comment in another thread and could easily implement the ID with a complex search-fallback strategy as you describe it. This is probably also possible directly in Apple Script, but I'm not sure whether Apple Script is the best language for doing all kinds of file and string operations.
In Christian's Apple Script you could simply replace the line do shell script "open -a VLC " & quoted form of file_URL with do shell script "subl -w " & quoted form of file_URL. ↩︎
I don't know anything about Windows and Linux in that regard. Instructions or research results in separate threads/discussions would be much appreciated by everyone around here!
I would be very interested in porting my approach to iOS, ideally using Pythonista or Workflow If someone knows how to implement custom url-schemes (not pythonista://) on iOS without writing a complete iOS app, please let me know.
@rhubarb said:
The point is that the protocol handler – e.g., Christian's Apple Script – is calling the editor in a way that the editor knows where the file is located...
[^1]: In Christian's Apple Script you could simply replace the line do shell script "open -a VLC " & quoted form of file_URL with do shell script "subl -w " & quoted form of file_URL.
But doesn't this put the handler in charge of sending every request to the same application (VLC or Sublime)? What I had in mind was a simple lookup layer to service any requesting app, the same way that any program can make an "http" request, and the content goes back to the requesting program, not always, say, Internet Explorer. I am hoping to click a "zkn:" in Atom and see the result in Atom, and then VSCode and see it in VSCode. The handler does not call a specific app and script it to run a command such as "File > Open," but rather it returns the content in some agnostic way that the app is expecting (such as the HTML payload of an HTTP request).
That might not turn out to be an essential difference from what you are explaining, but it is different from the example code. This is the part I am wondering about, whether it presents a problem or not.
Now I see what you were looking for. Well, for this to work every program that should be able to open URLs with the zettel:// protocol needs to implement its own handler for it. Only programs that do not implement this handler would then delegate to the operating system. The problem is, of course, that no agreed-upon protocol for Zettel exists, mine is just my homemade solution.
@rhubarb said:
Now I see what you were looking for. Well, for this to work every program that should be able to open URLs with the zettel:// protocol needs to implement its own handler for it. Only programs that do not implement this handler would then delegate to the operating system. The problem is, of course, that no agreed-upon protocol for Zettel exists, mine is just my homemade solution.
I don't know... I can paste a Scrivener link into any application, and they certainly have not implemented the x-scrivener: protocol.
But just now I'm realizing, these do always open in Scrivener, so really that protocol is a message directed at one app, like @ctietze 's script. So I see your point. Maybe what I was envisioning is not possible.
Take the load off of your favorite editor by writing the search logic into a small, dedicated script/app that takes the zettel ID and efficiently returns a file path. Then you only have to script the editor to pass this ID to the lookup app and open the resulting file.
Multiple editors can use the same script, and when you want to change its behavior, you have only one place to change. You can invest some real effort in its logic, since there's only one. You can have a few powerful settings like directories to fall back on, patterns to exclude... and it won't be subject to the whims and gaps or inefficiencies of your editors' scripting languages.
Even if your editor can barely kick off a script but cannot seamlessly receive back a response, you can write a short glue script for that one editor: the editor calls the glue script with the ID, the glue script gets the file path from the lookup app, and then the glue script explicitly calls the editor (hard-coded) with an Open-File command, like the prior example in this thread.
For even worse situations, the glue script can open a little dialog box with a place to paste the ID.
Just FYI, implementing on Windows is pretty easy itself. You have to write some Registry Keys (4, to be exact), and those point to a program/script that will get the full URI passed into it as the parameter to do whatever else you want (so if you open a zettel://20200526142352 link, that will be the string passed to the app as the first parameter).
I have details on what all those need to be, for anyone interested.
Comments
Very interesting! I am on a Mac but I never got into AppleScript. I would want to add a little bit of logic to allow file names starting with the ID and falling back to content search, but I see how your script demonstrates the essential concept.
The big value I see in using this "protocol" approach is that it liberates us from hacking individual editors. If ANY editor can issue a file request for zkn:ID, then we can handle the logic in the protocol handler to control EVERY editor's behavior!
Still, the unclear part to me is, once my editor has opened a zettel through its zkn: link, what happens when I modify that buffer in the editor? How does it know where to Save the buffer? If someone figures that out, then all we need is implementation.
Thanks for linking to that AppleScript post, @ctietze .
The point is that the protocol handler – e.g., Christian's Apple Script – is calling the editor in a way that the editor knows where the file is located. For The Archive just by delegating to the protocol of The Archive, for Sublime Text (a former use case of mine) by providing the file location (i.e., the path in the file system) to the
subl
executable1. You can then simply save with the editors normal save commands.I implemented my
zettel://
-Handler via AppleScript in a python-script (see this comment in another thread and could easily implement the ID with a complex search-fallback strategy as you describe it. This is probably also possible directly in Apple Script, but I'm not sure whether Apple Script is the best language for doing all kinds of file and string operations.In Christian's Apple Script you could simply replace the line
do shell script "open -a VLC " & quoted form of file_URL
withdo shell script "subl -w " & quoted form of file_URL
. ↩︎I would be very interested in porting my approach to iOS, ideally using Pythonista or Workflow If someone knows how to implement custom url-schemes (not
pythonista://
) on iOS without writing a complete iOS app, please let me know.But doesn't this put the handler in charge of sending every request to the same application (VLC or Sublime)? What I had in mind was a simple lookup layer to service any requesting app, the same way that any program can make an "http" request, and the content goes back to the requesting program, not always, say, Internet Explorer. I am hoping to click a "zkn:" in Atom and see the result in Atom, and then VSCode and see it in VSCode. The handler does not call a specific app and script it to run a command such as "File > Open," but rather it returns the content in some agnostic way that the app is expecting (such as the HTML payload of an HTTP request).
That might not turn out to be an essential difference from what you are explaining, but it is different from the example code. This is the part I am wondering about, whether it presents a problem or not.
Now I see what you were looking for. Well, for this to work every program that should be able to open URLs with the
zettel://
protocol needs to implement its own handler for it. Only programs that do not implement this handler would then delegate to the operating system. The problem is, of course, that no agreed-upon protocol for Zettel exists, mine is just my homemade solution.I don't know... I can paste a Scrivener link into any application, and they certainly have not implemented the x-scrivener: protocol.
But just now I'm realizing, these do always open in Scrivener, so really that protocol is a message directed at one app, like @ctietze 's script. So I see your point. Maybe what I was envisioning is not possible.
With all the dust settled, I found my real point!
Take the load off of your favorite editor by writing the search logic into a small, dedicated script/app that takes the zettel ID and efficiently returns a file path. Then you only have to script the editor to pass this ID to the lookup app and open the resulting file.
Multiple editors can use the same script, and when you want to change its behavior, you have only one place to change. You can invest some real effort in its logic, since there's only one. You can have a few powerful settings like directories to fall back on, patterns to exclude... and it won't be subject to the whims and gaps or inefficiencies of your editors' scripting languages.
Even if your editor can barely kick off a script but cannot seamlessly receive back a response, you can write a short glue script for that one editor: the editor calls the glue script with the ID, the glue script gets the file path from the lookup app, and then the glue script explicitly calls the editor (hard-coded) with an Open-File command, like the prior example in this thread.
For even worse situations, the glue script can open a little dialog box with a place to paste the ID.
Just FYI, implementing on Windows is pretty easy itself. You have to write some Registry Keys (4, to be exact), and those point to a program/script that will get the full URI passed into it as the parameter to do whatever else you want (so if you open a zettel://20200526142352 link, that will be the string passed to the app as the first parameter).
I have details on what all those need to be, for anyone interested.
@mleo2003 Please share! We all have friends on Windows who can use some automation
Author at Zettelkasten.de • https://christiantietze.de/