Emacs выровнять-выровнять на =, но не == - PullRequest
15 голосов
/ 11 января 2011

Я работаю в Haskell и часто сталкиваюсь с кодом, подобным следующему:

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

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

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

1 Ответ

18 голосов
/ 11 января 2011

Cu Mx align-regexp RET \(\s-*\) = RET 1 RET 0 RET n

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

Что сказать ...

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

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

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

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

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

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

edit: На самом деле, вопросы и ответы, с которыми вы связаны, почти идентичны, и отлично работают для меня в 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)))

Я сделал это:

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

1 Если вы ошиблись при записи сложного макроса, не волнуйтесь & mdash; 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)
...