[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lazy load of org-protocol

From: Jim Porter
Subject: Re: Lazy load of org-protocol
Date: Sat, 5 Feb 2022 10:27:27 -0800

On 2/5/2022 3:54 AM, Max Nikulin wrote:
I would prefer to avoid
    (require 'org-protocol)
in emacs init file and to postpone loading till invocation of emacsclient with org-protocol URI.

The problem is a hack in org-protocol. URIs are actually treated as (relative) file names and magic is achieved in an advice for `server-visit-files' function. So the advice must be installed in advance.

My first idea was to avoid such magic and to create autoload function org-protocol-from-argv with body similar to that advice. If it were possible to get arguments from `command-line-args-left' then invocation would look like

   emacsclient --eval '(org-protocol-from-argv)' 'org-protocol:/store-link?url=u1&title=t1'

Unfortunately it is against design of emacs server protocol. If --eval option is given than everything other is considered as independent expressions. At the lower level there is no way to transfer `argv` as a list from client to server process.

I've thought a bit about how to improve this too. One further issue with the current implementation is that when emacsclient invokes the alternate editor (usually to start the "main" emacs instance), org-protocol: links no longer work correctly. That's because only the emacsclient itself (through `server-visit-files') knows what to do with them.

I think the problem really starts in emacsclient's command line handling. You can see this in other situations too. For example, Emacs can be configured as your system's mailto: URL handler. (The file etc/emacsclient-mail.desktop in the Emacs repo does this.) The command to use for a new Emacs instance is simple:

  emacs -f message-mailto %u

However, doing this for emacsclient is harder:

emacsclient --alternate-editor= --create-frame --eval "(message-mailto \\"%u\\")"

There's no problem with "--alternate-editor=" and "--create-frame", but the fact that emacsclient requires evaling the function call that way is: if %u holds a string with quotation marks, this will break, and worse, could even result in arbitrary code being executed. (In practice, this is probably rare, since URLs are generally URL-encoded, and so don't have literal quotes in them.)

As a result, I think a good first step might be to add support for "--funcall" to emacsclient, just like the regular emacs binary. (The "-f" shorthand won't work though, since emacsclient already uses that for "--server-file"). This would simplify the `message-mailto' case above and would also allow org-protocol to do something similar:

  emacsclient --funcall org-protocol-capture %u

Then, so long as `org-protocol-capture' has an autoload, this would Just Work, and org-protocol.el would be lazily loaded. Hopefully, this could also be forwarded onto the alternate editor so that when the user open an org-protocol: URL when Emacs is closed, it still handles the URL correctly.

That said, in the short term, you could try out something like:

  emacsclient --eval "(org-protocol-capture \\"%u\\")"

Of course, that has the quoting issues I mentioned above, but it could be helpful for developing a proof of concept.

- Jim

reply via email to

[Prev in Thread] Current Thread [Next in Thread]