elisp, добавьте регулярное выражение для обнаружения ошибок

Я начинаю с 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)

to:

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

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

Я решил, что нужно добавить регулярное выражение в режим подтверждения. Режим подтверждения определяется следующим образом:

(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 *.


person Gauthier    schedule 19.03.2010    source источник


Ответы (1)


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

person Ivan Andrus    schedule 19.03.2010
comment
Спасибо за помощь в определении списка. Однако я все еще не уверен, как передать его команде компиляции. Выходные данные в настоящее время, похоже, заботятся о ack-regexp-alist, хотя я (setq compilation-error-regexp-alist (append compilation-error-regexp-alist ack-regexp-alist)) - person Gauthier; 20.03.2010
comment
У меня это работает, когда я запускаю ack вручную с M-x compile (хотя регулярное выражение файла работает не совсем правильно). Единственное, что вам нужно сделать, это убедиться, что ack-regexp-alist обновляется. Многократная оценка defvar не изменит значение после того, как оно было установлено. C-h v ack-regexp-alist RET покажет вам текущее значение ack-regexp-alist. Аналогично для compilation-error-regexp-alist. - person Ivan Andrus; 21.03.2010
comment
Еще раз спасибо. Я все еще не понимаю, я отредактировал свой вопрос, чтобы показать, где я застрял после вашего предложения. - person Gauthier; 22.03.2010
comment
Еще раз спасибо. Я пытаюсь выполнить полную проверку. Результат выглядит очень красиво. Однако есть два досадных недостатка: 1. В буфере вывода вы должны нажать Enter на самом искомом термине, чтобы перейти к коду. Нажатие Enter в любом другом месте строки не работает. 2. искомый термин не заменяется автоматически словом под курсором. Это заставляет меня пока придерживаться ack.el. Я попробую ваше решение и дам вам знать. - person Gauthier; 29.03.2010
comment
И еще один серьезный недостаток с полным подтверждением: выполнение нового поиска убивает ваш старый буфер результатов! - person Gauthier; 29.03.2010
comment
Справедливо. Я не знаю, как решить первую. Я обнаружил (после долгого разочарования), что изменение порядка регулярных выражений, похоже, работает. Я обновил свое решение. - person Ivan Andrus; 30.03.2010
comment
Привет, спасибо за обновление. Это действительно работает лучше! Строки ошибок теперь являются ссылками. Но все же я не могу перейти к файлу. Мне предлагается указать имя файла, который нужно открыть, хотя я ожидаю, что это произойдет автоматически. Find this error in (default): - вот что я получаю. Может быть, имя файла regexp не работает в windows? Я не король регулярных выражений, пойду посмотрю, смогу ли я лучше понять, что вы написали. - person Gauthier; 02.04.2010
comment
Я заменил ваш "^\\S +$" на "[a-zA-Z]:/.+$", и он заработал! Спасибо большое за вашу помощь! - person Gauthier; 02.04.2010