views:

119

answers:

3

Very often, compilations errors are displayed with the file:line syntax.

It would be nice to copy-paste this directly to open the file at the right ligne.

Emacs already has some mode to handle this in buffers (compile-mode, iirc), but I would like to have this available from the shell command line, since I use the standard shell most of the time outside of emacs.

Any idea how to tweak emacs to learn file:line syntax to open file at line line? (obviously, if file:line really exists on disk, it should be opened preferably)

+7  A: 

You can do this using emacsclient. e.g. to open FILE at line 4, column 3:

emacsclient -c +4:3 FILE

Leave off the :3 to simply open the file at line 4.

sanityinc
The "-c" flag says to create a new frame; you don't have to specify that in order for the jumping to line to work.
Damyan
Good point -- that was a matter of personal preference/habit.
sanityinc
+1  A: 

I have the following in my .emacs, but I haven't found it as useful as I thought it would be.

;; Open files and goto lines like we see from g++ etc. i.e. file:line#
;; (to-do "make `find-file-line-number' work for emacsclient as well")
;; (to-do "make `find-file-line-number' check if the file exists")
(defadvice find-file (around find-file-line-number
                             (filename &optional wildcards)
                             activate)
  "Turn files like file.cpp:14 into file.cpp and going to the 14-th line."
  (save-match-data
    (let* ((matched (string-match "^\\(.*\\):\\([0-9]+\\):?$" filename))
           (line-number (and matched
                             (match-string 2 filename)
                             (string-to-number (match-string 2 filename))))
           (filename (if matched (match-string 1 filename) filename)))
      ad-do-it
      (when line-number
        ;; goto-line is for interactive use
        (goto-char (point-min))
        (forward-line (1- line-number))))))
Ivan Andrus
nice! any idea how to hook that in the default open function?
elmarco
I'm not sure what you mean. find-file _is_ the default open function. What does C-h C-k C-x C-f show?
Ivan Andrus
+1  A: 

You talk about pasting to open a file (I assume you mean at a find file prompt inside of emacs) and also doing something from the command line. If you want to copy & paste then you need to do something like what Ivan showed with the defadvice. If you want something from the command line you can do the following. I've adapted this from something I did a year ago with an emacs:// URI handler (for use from within Firefox):

Put this in 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)))
          (while (string-match "\\(%20\\)" filename)
            (setq filename (replace-match " " nil t filename 1)))
          (with-current-buffer (find-file filename)
            (goto-line (string-to-number linenum))))
      (beep)
      (message "Unable to parse the URI <%s>"  uri))))

and then create a shell script in your path (I called mine 'emacsat'):

#!/bin/bash
emacsclient --no-wait -e "(emacs-uri-handler \"emacs://$1/${2:-1}\")"

A DOS batch script would look similar, but I don't know how to do default values (though I'm pretty sure you can do it).

See How to configure firefox to run emacsclientw on certain links? for further instructions if you want to integrate with Firefox, too.

Joe Casadonte
I can get some idea from that yes, although it's relying on the shell a bit too much (I could probably write a script to handle the file:no syntax as well, that's an idea)
elmarco