Откройте файл в строке с синтаксисом «filename: line» - PullRequest
49 голосов
/ 29 июня 2010

Очень часто ошибки компиляции отображаются с синтаксисом file:line.

Было бы неплохо скопировать и вставить это напрямую, чтобы открыть файл в правой строке.

В Emacs уже есть какой-то режим для обработки этого в буферах (режим компиляции, iirc), но я бы хотел, чтобы это было доступно из командной строки оболочки, поскольку большую часть времени я использую стандартную оболочку вне emacs.

Есть идеи, как настроить emacs для изучения file:line синтаксиса для открытия file в строке line? (очевидно, если file:line действительно существует на диске, его лучше открыть)

Ответы [ 12 ]

42 голосов
/ 29 июня 2010

Вы можете сделать это, используя emacsclient.например, чтобы открыть ФАЙЛ в строке 4, столбце 3 в новом кадре:

emacsclient +4:3 FILE

Оставьте :3, чтобы просто открыть файл в строке 4.

15 голосов
/ 29 июня 2010

В моем .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))))))
9 голосов
/ 24 августа 2012

А вот и я.Вызывает исходный файл поиска в точке

(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)))
8 голосов
/ 25 мая 2014

Я предлагаю добавить следующий код в вашу конфигурацию 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

PSНадеюсь, я еще не опоздал с ответом.

8 голосов
/ 04 декабря 2013

Вы можете использовать скрипт 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

, чтобы открыть file.cpp в Emacs в строке 1046 ..

7 голосов
/ 03 августа 2013

Другая версия приятного совета Ивана Андруса по поиску файлов, в котором указана строка и необязательный номер столбца, как вы видите в сообщениях об ошибках узлов и кодов:

;; 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)))))))
5 голосов
/ 18 сентября 2017

Emacs 25 больше не использует defadvice. * 1003 работы *.

Итак, вот версия, обновленная до нового синтаксиса:

(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, когда вы вызываете его из командной строки, и я не знаю как отлаживать подобные вещи.

3 голосов
/ 29 июня 2010

Вы говорите о вставке, чтобы открыть файл (я предполагаю, что вы имеете в виду в приглашении найти файл внутри emacs), а также что-то делаете из командной строки.Если вы хотите скопировать и вставить, вам нужно сделать что-то вроде того, что Иван показал с помощью defadvice.Если вы хотите что-то из командной строки, вы можете сделать следующее.Я адаптировал это из того, что сделал год назад, с помощью обработчика URI emacs: // (для использования из 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))))

и затем создайте сценарий оболочки на вашем пути (я назвал мой 'emacsat'):

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

Пакетный сценарий DOS будет выглядеть аналогично, но я не знаю, как сделать значения по умолчанию (хотя яя уверен, что вы можете это сделать).

См. Как настроить firefox для запуска emacsclientw по определенным ссылкам? для получения дополнительных инструкций, если вы хотите интегрировать и с Firefox.

1 голос
/ 14 февраля 2017

Я изменил ivan-andrus defadvice, чтобы он работал с emacsclient:

(defadvice find-file-noselect (around find-file-noselect-at-line
                                      (filename &optional nowarn rawfile 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))
           (buffer-name ad-do-it))
      (when line-number
        (with-current-buffer buffer-name
          (goto-char (point-min))
          (forward-line (1- line-number)))))))
1 голос
/ 13 октября 2013

Вот функция zsh, которая работает, если вы поместите ее в файл .zshrc.

Поскольку я обычно запускаю свой код на 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...