macosvisual-studio-codexsltemacsuri

Is there a way to open links to local files in Emacs from a browser?


I have notebook of LaTeX-like documents that I render as XML pages—one XML page per LaTeX notebook entry. With the help of a stylesheet, I view the notebook in my browser. My style.xsl adds an edit button to each entry that looks like this in the browser:

<a class="edit-button" href="vscode://file/path/to/file.tex">[edit]</a>

The line in the XSL that creates that button looks like this:

  <xsl:template match="f:source-path">
    <a class="edit-button" href="{concat('vscode://file', .)}">
      <xsl:text>[edit]</xsl:text>
    </a>
  </xsl:template>

This works great. I'd like to swap out VSCode for Emacs. I'd like the link to open a new Emacs instance if there isn't one running, or open the file in the currently open Emacs if there is one open.

I tried swapping vscode for emacs both in the button and the XSL. The issue is my operating system (macOS) and Emacs don't know how to open this kind of link emacs://file/path/to/file.tex. When I click this link in my browser, I get:

This page cannot be opened. The address is invalid.

When I run in the terminal open "vscode://file/path/to/file.tex", VSCode opens the link fine. I've played with changing the command to use other text editors, and VSCode seems to be the only one that works. In the terminal, running open "emacs://file/path/to/file.tex gives me this error message:

No application knows how to open URL emacs://file/path/to/file.tex (Error Domain=NSOSStatusErrorDomain Code=-10814 "kLSApplicationNotFoundErr: E.g. no application claims the file" UserInfo={\_LSLine=1747, \_LSFunction=runEvaluator}).

Edit: I learned a bit more about registering URIs, and I've registered emacs as a scheme handler. Now I can run open "emacs://file/path/to/file.tex, which works as I'd expected (after making a wrapper app that executes emacsclient /path/to/file.tex). However, clicking that link in the browser (Firefox) prompts me to open with Emacs and then does nothing. Copying and pasting the URI and opening it works.


Solution

  • The solution ended up being a bit of a hack. I used Platypus to make a small app out of a script that calls emacsclient on the path part of the URI. The benefit of Platypus is that I was able to register the app with an emacs URI scheme handler. I updated my XSL to generate buttons that link to that URI scheme.