elisp compile, добавьте регулярное выражение для обнаружения ошибок - PullRequest
0 голосов
/ 19 марта 2010

Я начинаю с emacs, и не очень хорошо знаю elisp. На самом деле почти ничего.

Я хочу использовать ack вместо grep.

Вот инструкции, которым я следовал, чтобы использовать ack из Emacs: http://www.rooijan.za.net/?q=ack_el

Теперь мне не нравится формат вывода, который используется в этом файле el, я хотел бы, чтобы вывод был ack --group.

Итак, я изменился:

(read-string "Ack arguments: " "-i" nil "-i" nil)

до:

(read-string "Ack arguments: " "-i --group" nil "-i --group" nil)

Пока все хорошо. Но это заставило меня потерять способность click-press_enter на строках буфера вывода. В исходном поведении режим компиляции использовался для возможности перехода к выбранной строке.

Я решил, что должен добавить регулярное выражение в ack-mode. Ack-режим определяется так:

(define-compilation-mode ack-mode "Ack"
  "Specialization of compilation-mode for use with ack."
   nil)

и я хочу добавить регулярное выражение [0-9]+:, которое также будет определяться как ошибка, поскольку это то, что включает в себя каждая строка выходного буфера (номер строки).

Я пытался изменить define-compilation-mode выше, чтобы добавить регулярное выражение, но с треском провалился.

Как сделать буфер вывода равным ack, дайте мне щелкнуть по его строкам?

--- РЕДАКТИРОВАТЬ, я пробовал также: ---

(defvar ack-regexp-alist 
    '(("[0-9]+:"
     2 3))
  "Alist that specifies how to match rows in ack output.")

(setq compilation-error-regexp-alist
      (append compilation-error-regexp-alist
          ack-regexp-alist))

Я украл это где-то и попытался приспособиться к моим потребностям. Не повезло.

--- РЕДАКТИРОВАТЬ, результат после предложения Ивана ---

С обновленным ack.el:

(defvar ack-regexp-alist 
  '(("^[0-9]+:" ;; match the line number
     nil        ;; the file is not found on this line, so assume that it's the same as before
     0          ;; The line is the 0'th subexpression (the whole thing)
     )
    ("^[^: ]+$" ;; match a file -- this could be better
     0          ;; The file is the 0'th subexpression
     ))
  "Alist that specifies how to match rows in ack output.")

(setq compilation-error-regexp-alist
      (append compilation-error-regexp-alist
          ack-regexp-alist))


(define-compilation-mode ack-mode "Ack"
  "Specialization of compilation-mode for use with ack."
   nil) 

Затем, проверяя переменную compilation-error-regext-alist, я получаю значение:

(absoft ada aix ant bash borland caml comma edg-1 edg-2 epc ftnchek iar ibm irix java jikes-file jikes-line gnu gcc-include lcc makepp mips-1 mips-2 msft oracle perl rxp sparc-pascal-file sparc-pascal-line sparc-pascal-example sun sun-ada 4bsd gcov-file gcov-header gcov-nomark gcov-called-line gcov-never-called
        ("^[0-9]+:" nil 0)
        ("^[^: ]+$" 0))

Я нахожу формат переменной очень странным, не так ли? Я не знаю elisp (пока), так что, возможно, это правильно.

Все еще нет ссылок или цвета в буфере * ack *.

1 Ответ

2 голосов
/ 19 марта 2010

Существует еще один full-ack пакет на ELPA , который я использовал ранее и обрабатывает --group вывод.

Тем не менее, читая документацию для compilation-error-regexp-alist, вы видите, что она имеет вид:

(REGEXP FILE [LINE COLUMN TYPE HYPERLINK HIGHLIGHT...])

В случае вывода --group вы должны сопоставлять файл и строку отдельно, поэтому я думаю, что вы хотите что-то вроде (не проверено)

(defvar ack-regexp-alist
  '(("^\\S +$" ;; match a file -- this could be better
     0          ;; The file is the 1st subexpression
     )
    ("^[0-9]+:" ;; match the line number
     nil        ;; the file is not found on this line, so assume that it's the same as before
     0          ;; The line is the 0'th subexpression (the whole thing)
     ))
  "Alist that specifies how to match rows in ack output.")

- Обновлено -

Переменная compilation-error-regext-alist представляет собой список символов или элементов, таких как (REGEXP ...). Символы ищутся в compilation-error-regexp-alist-alist, чтобы найти соответствующие элементы. Так что да, это немного странно, но легче увидеть, что включено и выключено, без необходимости смотреть на уродливые регулярные выражения и угадывать, что они делают. Если вы собираетесь распространять это я хотел бы предложить добавить регулярное выражение к compilation-error-regexp-alist-alist, а затем включите ее в compilation-error-regext-alist, но это немного неточное, пока вы не получите его, чтобы работать правильно.

Если присмотреться к ack.el более внимательно, я заметил, что он использует

(let (compile-command
      (compilation-error-regexp-alist grep-regexp-alist)
      ...)
  ...
  )

Другими словами, он локально перезаписывает compilation-error-regexp-alist с помощью grep-regexp-alist, поэтому вместо него вам нужно добавить регулярные выражения. Или еще лучше заменить его на

(let (compile-command
      (compilation-error-regexp-alist ack-regexp-alist)
      ...)
  ...
  )

В конце я все еще рекомендую full-ack , так как имя файла regex не работает правильно. Это кажется более полным (хотя и более сложным), и я был счастлив с ним.

...