2

There's the open-in-editor extension on sourcegraph, which

Adds a button at the top of files in both Sourcegraph app and code hosts like GitHub (when the Sourcegraph browser extension is installed) that will open the current file in your editor of choice.

It supports vscode, sublime, and idea out of box, but other editors needs to be manually configured. I'd like to open files in my emacs. How?

1 Answer 1

1

The relevant settings on sourcegraph is as below:

{
  "extensions": {
    "sourcegraph/open-in-editor": true
  },
  "openineditor.editor": "custom",
  "openineditor.customUrlPattern": "emacs://open?file=%file&line=%line&column=%col"
}

The custom URL pattern supports three placeholders. Obviously, %line and %column expands to line number and column numbers.

%file expands to a local file path which should be an absolute path of a file on your local file system to be opened.

Suppose, there's a file foo/bar.txt in the repository baz/xyz (username/repository-name), the 'relative' path to the file is xyz/foo/bar.txt (with username stripped out). Then, there's another configuration option not shown above, openineditor.basePath, which is an absolute path which is the local directory that contains all copies of your local repositories. It's appended to the 'relative' path and becomes the full path of the file to be opened.


Next, you need to create a custom x-scheme handler, which would accept the emacs scheme.

Based on palswim's answer to the question of creating custom x-scheme handler, I've made the following scripts that registers and handles such an emacs x-scheme.


First create a desktop file:

[Desktop Entry]
Type=Application
Name=Emacs Scheme Handler
Exec=emacs-scheme-handler.py %u
StartupNotify=false
MimeType=x-scheme-handler/emacs;

In my case I put it in ~/.local/share/applications/emacs-scheme-handler.desktop.


Then create the companion Python script:

#!/usr/bin/env python3
import sys
from urllib.parse import urlparse, parse_qs
from subprocess import Popen

query = parse_qs(urlparse(sys.argv[1]).query)
filename, line, column = [query[k][0] for k in ("file", "line", "column")]
command = f"emacslient -c -a=emacs +{line}:{column} {filename}"
Popen(
    [
        "/usr/bin/env",
        "emacsclient",
        "-c",
        '-a="/usr/bin/env emacs',
        f"+{line}:{column}",
        filename,
    ],
    stdin=None,
    stdout=None,
    stderr=None,
    close_fds=True,
)

It would spawn a new process which works the same as the following shell command:

/usr/bin/env emacsclient -c -a="/usr/bin/env emacs" +${line}:${column} ${filename}
#                         |  |                              |
#                         |  |                              + Go to the line and column position
#                         |  |
#                         |  + If no emacs server is running, starts a new emacs instance
#                         |
#                         + Open the file in a new frame

You can use and share the above scripts as you like. I declare that these are in public domain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.