views:

361

answers:

3

I've got a Perl script that groks a bunch of log files looking for "interesting" lines, for some definition of interesting. It generates an HTML file which consists of a table whose columns are a timestamp, a filename/linenum reference and the "interesting" bit. What I'd love to do is have the filename/linenum be an actual link that will bring up that file with the cursor positioned on that line number, in emacs.

emacsclientw will allow such a thing (e.g. emacsclientw +60 foo.log) but I don't know what kind of URL/URI to construct that will let FireFox call out to emacsclientw. The original HTML file will be local, so there's no problem there.

Should I define my own MIME type and hook in that way?

Firefox version is 3.5 and I'm running Windows, in case any of that matters. Thanks!

+6  A: 

Go to about:config page in firefox. Add a new string :

network.protocol-handler.app.emacs

value: path to a script that parse the url without protocol (what's after emacs://) and then call emacsclient with the proper argument.

You can't just put the path of emacsclient because everything after the protocol is passed as one arg to the executable so your +60 foo.log would be a new file named that way.

But you could easily imagine someting like emacs:///path/to/your/file/LINENUM and have a little script that remove the final / and number and call emacsclient with the number and the file :-)

EDIT: I could do that in bash if you want but i don't know how to do that with the windows "shell" or whatever it is called.

EDIT2: I'm wrong on something, the protocol is passed in the arg string to ! Here is a little bash script that i just made for me, BTW thanks for the idea :-D

#!/bin/bash
ARG=${1##emacs://}
LINE=${ARG##*/}
FILE=${ARG%/*}
if wmctrl -l | grep emacs@romuald &>/dev/null; then # if there's already an emacs frame
  ARG="" # then just open the file in the existing emacs frame
else
  ARG="-c" # else create a new frame
fi
emacsclient $ARG -n +$LINE "$FILE"
exit $?

and my network.protocol-handler.app.emacs in my iceweasel (firefox) is /home/p4bl0/bin/ffemacsclient. It works just fine !

And yes, my laptop's name is romuald ^^.

p4bl0
*Just* beat me to it. :-)
Ben Blank
A: 

Might be a great reason to write your first FF plugin ;)

Russell Leggett
no need for a plugin here ;-)
p4bl0
+1  A: 

Thanks for the pointer, p4bl0. Unfortunately, that only works on a real OS; Windows uses a completely different method. See http://kb.mozillazine.org/Register_protocol for more info.

But, you certainly provided me the start I needed, so thank you very, very much!

Here's the solution for Windows:

First you need to set up the registry correctly to handle this new URL type. For that, save the following to a file, edit it to suit your environment, save it and double click on it:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\emacs]
@="URL:Emacs Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\emacs\shell]

[HKEY_CLASSES_ROOT\emacs\shell\open]

[HKEY_CLASSES_ROOT\emacs\shell\open\command]
@="\"c:\\product\\emacs\\bin\\emacsclientw.exe\" --no-wait -e \"(emacs-uri-handler \\\"%1\\\")\""

This is not as robust as p4bl0's shell script, because it does not make sure that Emacs is running first. Then add the following to your .emacs file:

(defun emacs-uri-handler (uri)
  "Handles emacs URIs in the form: emacs:///path/to/file/LINENUM"
  (save-match-data
    (if (string-match "emacs://\\(.*\\)/\\([0-9]+\\)$" uri)
        (let ((filename (match-string 1 uri))
              (linenum (match-string 2 uri)))
          (with-current-buffer (find-file filename)
            (goto-line (string-to-number linenum))))
      (beep)
      (message "Unable to parse the URI <%s>"  uri))))

The above code will not check to make sure the file exists, and the error handling is rudimentary at best. But it works!

Then create an HTML file that has lines like the following:

<a href="emacs://c:/temp/my.log/60">file: c:/temp/my.log, line: 60</a>

and then click on the link.

Post Script:

I recently switched to Linux (Ubuntu 9.10) and here's what I did for that OS:

$ gconftool -s /desktop/gnome/url-handlers/emacs/command '/usr/bin/emacsclient --no-wait -e "(emacs-uri-handler \"%s\")"' --type String
$ gconftool -s /desktop/gnome/url-handlers/emacs/enabled --type Boolean true

Using the same emacs-uri-handler from above.

Joe Casadonte