Emacs align-regexp on =, но не ==

Я работаю в Haskell и часто нахожу код, похожий на следующий:

func i j | i == j = i
         | otherwise = j

Я хочу выровнять по символу '=' с помощью align-regexp, но не имеет ноу-хау elisp. Я пробовал просто делать "=" без кавычек, но это вставляет символ нежелательного пробела перед каждым "=". Я нашел предлагаемое решение здесь, но, похоже, я ничего не могу сделать, чтобы что-либо сделать.

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

Ответ 1

C-u M-x align-regexp RET \(\s-*\) = RET 1 RET 0 RET n

(n.b. там есть пробел после '=', но это не очень очевидно.)

То есть...

Используйте префиксный аргумент, чтобы сообщить align-regexp задать вам больше параметров, чем по умолчанию.

Подробнее см. C-h f align-regexp и C-h v align-rules-list, но вкратце:

\(\s-*\) - это "группа" по умолчанию для удаления/расширения. Мы добавим наш шаблон к концу этого: '='. (Обратите внимание, что \s- представляет собой синтаксис Emacs regexp для пробелов.)

1 просто относится к заключенной в скобки группе 1 (как указано выше). Это значение по умолчанию.

0 для интервала между двумя частями линии. По умолчанию это 1, и именно поэтому вы попали в дополнительное пространство.

n, чтобы не выровнять последующие совпадения шаблонов после первого в каждой строке.

edit: На самом деле, Q & A, с которым вы связаны, почти идентичен, и отлично работает для меня в Emacs 23.2.1, так что это дубликат, но для продолжения и ответа на вопрос, связанный с ключом:

Вы можете связать эту (или любую) последовательность с помощью макросов клавиатуры. Здесь конечный результат, который вы, вероятно, можете добавить в свой файл инициализации, хотя я рекомендую вам пройти процесс самостоятельно. Используйте ключ, который вам нужен вместо C-c a для ключа. C-c (letter) и F5-F9 зарезервированы для конечных пользователей, которые свяжутся по своему усмотрению, поэтому один из них будет безопасным от скремблирования с помощью клавиатуры режима.

(global-set-key (kbd "C-c a") (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([21 134217848 97 108 105 103 110 45 114 101 103 101 120 112 return 32 61 32 return return backspace 48 return 110] 0 "%d")) arg)))

Я сделал это:

  • выбор текста.
  • F3, чтобы начать запись.
  • выполняя align-regexp, как указано выше (будьте осторожны, чтобы набирать все дословно, а не использовать историю минибуферов или yanking). 1
  • F4, чтобы остановить запись.
  • C-x C-k n align-single-equals RET, чтобы дать макросу имя
  • M-x insert-kbd-macro RET align-single-equals RET, чтобы получить lisp.
  • Обертка выражения (lambda) с помощью (global-set-key), чтобы связать его. (Хотя вы также можете использовать код (fset 'align-single-equals ...) как предусмотрено, а затем привязать ключ к этому символу.

1 Если вы ошиблись при записи сложного макроса, не раздражайтесь; Emacs предоставляет действительно хороший редактор макросов, который вы можете использовать для устранения любых ошибок после завершения записи (просто введите C-x C-k e), поэтому вам не нужно быть идеальным.

edit 2: Может также добавить пример функции в соответствии с комментариями.

(defun my-align-single-equals ()
  "Align on a single equals sign (with a space either side)."
  (interactive)
  (align-regexp
   (region-beginning) (region-end)
   "\\(\\s-*\\) = " 1 0 nil))

(global-set-key (kbd "C-c a") 'my-align-single-equals)