Как сделать файл .emacs идемпотентным?

Независимо от того, сколько раз я перезагружаю свой .emacs файл,

M-x загрузочный файл RET ~ / .emacs RET

Я хочу, чтобы результаты были такими же, как и в первый раз. Я хочу, чтобы мой файл .emacs был idempotent .

Мотивация

Я знаю, что могу хирургически оценить область (C-c C-r), defun (C-M-x) или последний sexp (C-x C-e). Я часто использую такой более тонкий подход, когда вношу небольшие изменения. Однако при переработке .emacs файла я иногда хочу окончательно проверить результаты изменения, перезагружая .emacs файл целиком. Каждый раз перезапускать emacs быстро устаревает, особенно при выполнении основных .emacs хозяйственных операций.

Конкретные шаги

Какие конкретные шаги я должен предпринять, чтобы обновить мой .emacs файл, чтобы заменить неидемпотентные операции идемпотентными?

Например,

  1. Найдите «-hook» и замените прямое добавление хуков вызовами add-hook, которые не будут повторно добавлять функцию в ловушку, если она уже есть.
  2. Замените переключение любых флагов прямой установкой или сбросом. Остерегайтесь, в частности, ??.
  3. ...

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


person kjhughes    schedule 02.08.2014    source источник
comment
В elisp невозможно быть полностью идемпотентным. Если только вы не отслеживали каждое определение и не знали, что отвязать. Особенно, если вы используете много сторонних пакетов. Вы находитесь на правильном пути со своим списком, но в идеале вам нужно будет выгрузить все свои пакеты перед повторной оценкой. Я нашел способ красиво разработать свой .emacs - написать его таким образом, чтобы перезапуск emacs не был проблемой, если ваше время запуска мало, а затем выполнение разработки в одном экземпляре emacs и перезапуск несколько раз для проверки вашего init в другом случае - не большая проблема.   -  person Jordon Biondo    schedule 03.08.2014
comment
Что вы могли бы сделать, это запустить -Q и сохранить все в основном obarry в файле, затем написать функцию, которая отвяжет все, кроме того, что находится в -Q obarray, и восстановит все нормальные значения из вашего магазина.   -  person Jordon Biondo    schedule 03.08.2014


Ответы (3)


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

  1. Используйте именованные функции для add-hook и привязки клавиш вместо анонимных функций. В частности, для add-hook это позволяет заменить существующую ссылку.

  2. Осторожное использование defvar, по умолчанию тело оценивается только в том случае, если переменная не определена. C-M-x на defvar будет повторно оценивать тело, но eval-buffer не будет, если переменная уже инициализирована.

  3. Осторожное использование (quote function) вместо function для ссылки на именованную функцию вместо значения функции. См. Анонимные функции для более подробного обсуждения этого вопроса.

  4. Помните, что require будет загружать соответствующую библиотеку только при первом запуске, она не будет повторно оценивать при повторных вызовах, как это делает load. Автозагрузка также использует требование для загрузки соответствующей библиотеки.

  5. Предпочитайте add-to-list вместо cons, чтобы добавить элемент только в том случае, если он не существует.

  6. Для активации более старого режима не забудьте использовать (mode-name-mode t) для активации вместо функции переключения. То же самое для turn-on- функций второстепенного режима вместо переключения режима.

  7. Защитные блоки, которые имеют побочные эффекты при повторном выполнении. В частности, для режима сервера (unless (server-running-p) (server-start)) и подобных средств защиты для установки пакетов.

  8. Будьте осторожны с побочными эффектами в eval-after-load обработчиках или в пользовательских режимах. Помните, что обработчики режима по умолчанию запускаются при первом включении режима и в каждом последующем буфере, но не будут повторно запускаться в существующих буферах при изменении функции обработки. eval-after-load реже ошибается, это все еще важно помнить при оценке.

  9. Связанный с # 2, makunbound может быть полезен, если цепочку переменных, зависящих друг от друга, необходимо переоценить, поскольку это заставит defvar всегда выполняться при оценке файла.

Запуск eval-buffer в файле инициализации должен быть максимально идемпотентным, но важно помнить, что emacs lisp любит побочные эффекты и состояние. Хотя в некоторой степени это можно улучшить, повторное преобразование init никогда не вернет emacs в то состояние, в котором он был при первом запуске.

person dgtized    schedule 02.08.2014

Ограничьтесь вещами, которые, как вы знаете, идемпотентны:

  • defun.
  • установите q на константу.
  • добавить в список с константой.
  • add-hook, но желательно добавить символ, а не лямбда-выражение.
  • включение / выключение второстепенного режима.
  • обертывание некоторых из вышеперечисленных условий.

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

person Stefan    schedule 02.08.2014

В дополнение к тому, что говорили другие, загрузите (например, require) библиотеки, включая сторонние библиотеки, загрузка которых идемпотентна.

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

person Drew    schedule 03.08.2014