使用"filename:line"语法打开一个文件

elm*_*rco 49 emacs bash

通常,编译错误会随file:line语法一起显示.

将它直接复制粘贴以打开右侧的文件会很不错.

Emacs已经有一些模式可以在缓冲区(compile-mode,iirc)中处理这个问题,但我想从shell命令行中获取它,因为我在emacs之外的大部分时间都使用标准shell.

知道如何调整emacs来学习在线file:line打开的语法吗?(显然,如果真的存在于磁盘上,最好应该打开)filelinefile:line

san*_*inc 42

您可以使用emacsclient执行此操作.例如,在新框架的第4行,第3列打开FILE:

emacsclient +4:3 FILE
Run Code Online (Sandbox Code Playgroud)

不要:3在第4行打开文件.

  • "-c"标志表示创建一个新帧; 你不必指定为了跳转到行工作. (5认同)
  • 虽然这是一个有趣的事实,但当您从错误消息中剪切和粘贴文件名时,Ivan 的解决方案功能更强大,就像原始问题所说 (2认同)

Iva*_*rus 16

我有以下内容.emacs,但我发现它没有像我想象的那样有用.

;; 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))))))
Run Code Online (Sandbox Code Playgroud)

  • "defadvice"修改了下一个名称的定义(在本例中为find-file,默认的open函数).所以这个(defadvice find-file ...)实际上确实修改了find-file来表现这种方式. (2认同)

jac*_*cob 9

这是我的目标.调用原始的find-file-at-point

(defun find-file-at-point-with-line()
  "if file has an attached line num goto that line, ie boom.rb:12"
  (interactive)
  (setq line-num 0)
  (save-excursion
    (search-forward-regexp "[^ ]:" (point-max) t)
    (if (looking-at "[0-9]+")
         (setq line-num (string-to-number (buffer-substring (match-beginning 0) (match-end 0))))))
  (find-file-at-point)
  (if (not (equal line-num 0))
      (goto-line line-num)))
Run Code Online (Sandbox Code Playgroud)


小智 9

我建议在emacs配置中添加以下代码:

(defadvice server-visit-files (before parse-numbers-in-lines (files proc &optional nowait) activate)
  "looks for filenames like file:line or file:line:position and reparses name in such manner that position in file"
  (ad-set-arg 0
              (mapcar (lambda (fn)
                        (let ((name (car fn)))
                          (if (string-match "^\\(.*?\\):\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?$" name)
                              (cons
                               (match-string 1 name)
                               (cons (string-to-number (match-string 2 name))
                                     (string-to-number (or (match-string 3 name) "")))
                               )
                            fn))) files))
  )
Run Code Online (Sandbox Code Playgroud)

到现在为止,您可以从命令行打开带有行号的文件,如下所示:

emacsclient filename:linenumber:position
Run Code Online (Sandbox Code Playgroud)

PS我希望我的回答不会太迟.

  • 一个有用的答案永远不会太晚. (2认同)

ecm*_*aut 8

另一个版本的Ivan Andrus'很好的查找文件建议,可以同时执行行+可选列号,如您在node和coffeescript错误中看到的那样:

;; Open files and go places like we see from error messages, i e: path:line:col
;; (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
                             (path &optional wildcards)
                             activate)
  "Turn files like file.js:14:10 into file.js and going to line 14, col 10."
  (save-match-data
    (let* ((match (string-match "^\\(.*?\\):\\([0-9]+\\):?\\([0-9]*\\)$" path))
           (line-no (and match
                         (match-string 2 path)
                         (string-to-number (match-string 2 path))))
           (col-no (and match
                        (match-string 3 path)
                        (string-to-number (match-string 3 path))))
           (path (if match (match-string 1 path) path)))
      ad-do-it
      (when line-no
        ;; goto-line is for interactive use
        (goto-char (point-min))
        (forward-line (1- line-no))
        (when (> col-no 0)
          (forward-char (1- col-no)))))))
Run Code Online (Sandbox Code Playgroud)


Håk*_*and 8

您可以使用bash脚本:

#! /bin/bash
file=$(awk '{sub(/:[0-9]*$/,"")}1' <<< "$1")
line=$(awk '{sub(/^.*:/,"")}1' <<< "$1")
emacs --no-splash "+$line" "$file" &
Run Code Online (Sandbox Code Playgroud)

如果您调用此脚本openline并收到错误消息,例如

Error: file.cpp:1046
Run Code Online (Sandbox Code Playgroud)

你可以做

openline file.cpp:1046
Run Code Online (Sandbox Code Playgroud)

打开file.cppEmacs的行1046 ..


Eve*_*pes 5

Emacs 25不再使用defadvice参考

所以这是更新为新语法的版本:

(defun find-file--line-number (orig-fun filename &optional wildcards)
  "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)))
      (apply orig-fun (list filename wildcards))
      (when line-number
        ;; goto-line is for interactive use
        (goto-char (point-min))
        (forward-line (1- line-number))))))

(advice-add 'find-file :around #'find-file--line-number)
Run Code Online (Sandbox Code Playgroud)

This works if you call open file from inside emacs (C-x C-f), but not works anymore from command line, it seems that emacs 25 is not using find-file when you call it from command line and I don't know how to debug this kind of thing.