通常,编译错误会以file:line
语法显示。
将它直接复制粘贴以打开右侧的文件会很不错。
Emacs已经有一些模式可以在缓冲区(compile-mode,iirc)中处理这个问题,但是我想从shell命令行中获取它,因为我在emacs之外的大部分时间都使用标准shell。 / p>
知道如何调整emacs以了解file:line
语法,以便在file
行打开line
吗? (显然,如果file:line
确实存在于磁盘上,则应该优先打开它)
答案 0 :(得分:42)
您可以使用emacsclient执行此操作。例如在第4行第3列打开FILE:
emacsclient +4:3 FILE
取消:3
只需在第4行打开文件。
答案 1 :(得分:15)
我的.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))))))
答案 2 :(得分: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)))
答案 3 :(得分:8)
您可以使用bash脚本:
#! /bin/bash
file=$(awk '{sub(/:[0-9]*$/,"")}1' <<< "$1")
line=$(awk '{sub(/^.*:/,"")}1' <<< "$1")
emacs --no-splash "+$line" "$file" &
如果您为openline
调用此脚本,则会收到错误消息,例如
Error: file.cpp:1046
你可以做到
openline file.cpp:1046
在第1046行打开file.cpp
中的Emacs
..
答案 4 :(得分:8)
我建议在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))
)
到现在为止,您可以直接从命令行打开带有行号的文件,如下所示:
emacsclient filename:linenumber:position
P.S。我希望我的回答不会太迟。
答案 5 :(得分:7)
另一个版本的Ivan Andrus'很好的查找文件建议,可以同时执行行+可选列号,正如您在节点和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)))))))
答案 6 :(得分:5)
Emacs 25不再使用defadvice
。 Refs
所以这里是更新为新语法的版本:
(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)
如果你从emacs(Cx Cf)内部调用打开文件,但是从命令行不再工作,这是有效的,当你从命令行调用它时,似乎emacs 25没有使用find-file
而且我没有&# 39;我知道如何调试这种事情。
答案 7 :(得分:3)
您谈到粘贴打开文件(我假设您的意思是在emacs内的查找文件提示符下)并且还从命令行执行某些操作。如果你想复制&amp;粘贴,然后你需要做一些像伊万与defadvice显示的东西。如果您需要命令行中的某些内容,则可以执行以下操作。我从一年前使用emacs:// URI处理程序(在Firefox中使用)中做了一些改编:
将它放在您的.emacs文件中:
(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))))
然后在你的路径中创建一个shell脚本(我称之为'emacsat'):
#!/bin/bash
emacsclient --no-wait -e "(emacs-uri-handler \"emacs://$1/${2:-1}\")"
DOS批处理脚本看起来很相似,但我不知道如何做默认值(虽然我很确定你可以这样做)。
如果您想要与Firefox集成,请参阅How to configure firefox to run emacsclientw on certain links?以获取更多说明。
答案 8 :(得分:1)
我稍微重写了find-file-at-point
函数。
如果行号匹配,则该文件将在另一个窗口中打开,并且courser将被放置在该行中。如果没有行号匹配,请执行ffap通常执行的操作...
;; find file at point, jump to line no.
;; ====================================
(require 'ffap)
(defun find-file-at-point-with-line (&optional filename)
"Opens file at point and moves point to line specified next to file name."
(interactive)
(let* ((filename (or filename (ffap-prompter)))
(line-number
(and (or (looking-at ".* line \\(\[0-9\]+\\)")
(looking-at ".*:\\(\[0-9\]+\\):"))
(string-to-number (match-string-no-properties 1)))))
(message "%s --> %s" filename line-number)
(cond ((ffap-url-p filename)
(let (current-prefix-arg)
(funcall ffap-url-fetcher filename)))
((and line-number
(file-exists-p filename))
(progn (find-file-other-window filename)
(goto-line line-number)))
((and ffap-pass-wildcards-to-dired
ffap-dired-wildcards
(string-match ffap-dired-wildcards filename))
(funcall ffap-directory-finder filename))
((and ffap-dired-wildcards
(string-match ffap-dired-wildcards filename)
find-file-wildcards
;; Check if it's find-file that supports wildcards arg
(memq ffap-file-finder '(find-file find-alternate-file)))
(funcall ffap-file-finder (expand-file-name filename) t))
((or (not ffap-newfile-prompt)
(file-exists-p filename)
(y-or-n-p "File does not exist, create buffer? "))
(funcall ffap-file-finder
;; expand-file-name fixes "~/~/.emacs" bug sent by CHUCKR.
(expand-file-name filename)))
;; User does not want to find a non-existent file:
((signal 'file-error (list "Opening file buffer"
"no such file or directory"
filename))))))
如果你有旧版本的ffap(2008),你应该更新你的emacs或申请 另一个小补丁...
--- Emacs/lisp/ffap.el
+++ Emacs/lisp/ffap.el
@@ -1170,7 +1170,7 @@ which may actually result in an url rather than a filename."
;; remote, you probably already have a connection.
((and (not abs) (ffap-file-exists-string name)))
;; Try stripping off line numbers; good for compilation/grep output.
- ((and (not abs) (string-match ":[0-9]" name)
+ ((and (string-match ":[0-9]" name)
(ffap-file-exists-string (substring name 0 (match-beginning 0)))))
;; Try stripping off prominent (non-root - #) shell prompts
答案 9 :(得分:1)
要返回42的代码,添加了列号支持,并清理了存在列号的情况,并寻求行号。
;; find file at point, jump to line no.
;; ====================================
(require 'ffap)
(defun find-file-at-point-with-line (&optional filename)
"Opens file at point and moves point to line specified next to file name."
(interactive)
(let* ((filename (or filename (if current-prefix-arg (ffap-prompter) (ffap-guesser))))
(line-number
(and (or (looking-at ".* line \\(\[0-9\]+\\)")
(looking-at "[^:]*:\\(\[0-9\]+\\)"))
(string-to-number (match-string-no-properties 1))))
(column-number
(or
(and (looking-at "[^:]*:\[0-9\]+:\\(\[0-9\]+\\)")
(string-to-number (match-string-no-properties 1)))
(let 'column-number 0))))
(message "%s --> %s:%s" filename line-number column-number)
(cond ((ffap-url-p filename)
(let (current-prefix-arg)
(funcall ffap-url-fetcher filename)))
((and line-number
(file-exists-p filename))
(progn (find-file-other-window filename)
;; goto-line is for interactive use
(goto-char (point-min))
(forward-line (1- line-number))
(forward-char column-number)))
((and ffap-pass-wildcards-to-dired
ffap-dired-wildcards
(string-match ffap-dired-wildcards filename))
(funcall ffap-directory-finder filename))
((and ffap-dired-wildcards
(string-match ffap-dired-wildcards filename)
find-file-wildcards
;; Check if it's find-file that supports wildcards arg
(memq ffap-file-finder '(find-file find-alternate-file)))
(funcall ffap-file-finder (expand-file-name filename) t))
((or (not ffap-newfile-prompt)
(file-exists-p filename)
(y-or-n-p "File does not exist, create buffer? "))
(funcall ffap-file-finder
;; expand-file-name fixes "~/~/.emacs" bug sent by CHUCKR.
(expand-file-name filename)))
;; User does not want to find a non-existent file:
((signal 'file-error (list "Opening file buffer"
"no such file or directory"
filename))))))
答案 10 :(得分:1)
如果将zsh函数放入.zshrc
文件中,则可以使用zsh函数。
由于我通常在zsh中运行我的代码,这就是我看到错误的地方。感谢@sanityinc的emacs部分。只是认为这应该在google上。
emn () {
blah=$1
filen=(${(s.:.)blah})
/Applications/Emacs.app/Contents/MacOS/Emacs +$filen[2] $filen[1] &
}
像emn /long/stack/error.rb:123
答案 11 :(得分:1)
我修改了ivan-andrus package org.wso2.carbon.um.ws.service;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.9-b130926.1035
* Generated source version: 2.2
*
*/
@WebServiceClient(name = "RemoteUserStoreManagerService", targetNamespace = "http://service.ws.um.carbon.wso2.org", wsdlLocation = "https://svn.wso2.org/repos/wso2/people/asela/user-mgt/jaxws/RemoteUserStoreManagerService.wsdl")
public class RemoteUserStoreManagerService
extends Service
{
private final static URL REMOTEUSERSTOREMANAGERSERVICE_WSDL_LOCATION;
private final static WebServiceException REMOTEUSERSTOREMANAGERSERVICE_EXCEPTION;
private final static QName REMOTEUSERSTOREMANAGERSERVICE_QNAME = new QName("http://service.ws.um.carbon.wso2.org", "RemoteUserStoreManagerService");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("https://svn.wso2.org/repos/wso2/people/asela/user-mgt/jaxws/RemoteUserStoreManagerService.wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
REMOTEUSERSTOREMANAGERSERVICE_WSDL_LOCATION = url;
REMOTEUSERSTOREMANAGERSERVICE_EXCEPTION = e;
}
public RemoteUserStoreManagerService() {
super(__getWsdlLocation(), REMOTEUSERSTOREMANAGERSERVICE_QNAME);
}
public RemoteUserStoreManagerService(WebServiceFeature... features) {
super(__getWsdlLocation(), REMOTEUSERSTOREMANAGERSERVICE_QNAME, features);
}
public RemoteUserStoreManagerService(URL wsdlLocation) {
super(wsdlLocation, REMOTEUSERSTOREMANAGERSERVICE_QNAME);
}
public RemoteUserStoreManagerService(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, REMOTEUSERSTOREMANAGERSERVICE_QNAME, features);
}
public RemoteUserStoreManagerService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public RemoteUserStoreManagerService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
/**
*
* @return
* returns RemoteUserStoreManagerServicePortType
*/
@WebEndpoint(name = "RemoteUserStoreManagerServiceHttpSoap11Endpoint")
public RemoteUserStoreManagerServicePortType getRemoteUserStoreManagerServiceHttpSoap11Endpoint() {
return super.getPort(new QName("http://service.ws.um.carbon.wso2.org", "RemoteUserStoreManagerServiceHttpsSoap11Endpoint"), RemoteUserStoreManagerServicePortType.class);
}
/**
*
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* @return
* returns RemoteUserStoreManagerServicePortType
*/
@WebEndpoint(name = "RemoteUserStoreManagerServiceHttpSoap11Endpoint")
public RemoteUserStoreManagerServicePortType getRemoteUserStoreManagerServiceHttpSoap11Endpoint(WebServiceFeature... features) {
return super.getPort(new QName("http://service.ws.um.carbon.wso2.org", "RemoteUserStoreManagerServiceHttpSoap11Endpoint"), RemoteUserStoreManagerServicePortType.class, features);
}
private static URL __getWsdlLocation() {
if (REMOTEUSERSTOREMANAGERSERVICE_EXCEPTION!= null) {
throw REMOTEUSERSTOREMANAGERSERVICE_EXCEPTION;
}
return REMOTEUSERSTOREMANAGERSERVICE_WSDL_LOCATION;
}
}
,因此它适用于emacsclient:
defadvice
答案 12 :(得分:0)
我经常使用它,我是用命令行 1 实现的:
;;;; Open files and goto lines like we see from g++ etc. i.e. file:line#
(defun command-line-1--line-number (orig-fun args)
(setq new-args ())
(dolist (f args)
(setq new-args
(append new-args
(if (string-match "^\\(.*\\):\\([0-9]+\\):?$" f)
(list (concat "+" (match-string 2 f))
(match-string 1 f))
(list f)))))
(apply orig-fun (list new-args)))
(advice-add 'command-line-1 :around #'command-line-1--line-number)