Почему Emacs жалуется на год-переменную void в моем файле.emacs?
Я пытаюсь реализовать солнечные термины в моем .emacs
так что мои "праздники" будут отображать время, когда солнечная долгота пересекает каждый кратный 15 градусов. Вот соответствующий фрагмент.
(defun next-solar-term-date (d)
(solar-date-next-longitude d 15))
(defconst solar-term-names
["moderate cold" "severe cold" "spring commerces"
"rain water" "insects awaken" "vernal equinox"
"Ching Ming" "corn rain" "summer commerces"
"corn forms" "corn on ear" "summer solstice"
"minor heat" "great heat" "autumn commerces"
"end of heat" "white dew" "autumnal equinox"
"cold dew" "frost" "winter commerces"
"light snow" "heavy snow" "winter solstice"])
(setq solar-terms-holidays
(let* ((k 0) (mylist nil))
(dotimes (k 4);k=season
(let* ((j 0))
(dotimes (j 5);no equinoxes/solstices --- use solar for them
(let* ((i (+ j (* 6 k)))
(month (+ 1 (/ i 2)))
(astronextdate (next-solar-term-date
(calendar-astro-from-absolute
(+ (* 15 i)
(calendar-absolute-from-gregorian
(list 1 1 displayed-year))))))
(s (aref solar-term-names i))
(absnextdate (calendar-absolute-from-astro
astronextdate))
(gregnextdate (calendar-gregorian-from-absolute
(floor absnextdate)))
(compt (* 24 (- absnextdate (floor absnextdate))))
(str (concat s " "
(solar-time-string
compt (if (dst-in-effect absnextdate)
calendar-daylight-time-zone-name
calendar-standard-time-zone-name))))
(d (extract-calendar-day gregnextdate)))
(setq mylist (append mylist
(list
(list 'holiday-fixed month d str))))))))
mylist))
Однако emacs (версия 23.2-r2 в Gentoo) жалуется на то, что отображаемый год является переменной-пустотой при запуске, и попытка сгенерировать календарь с помощью Mx calendar RET также не помогает. Есть идеи, как я могу это исправить? (Конечно, не с указанием отображаемого года в моем .emacs
так как это определенно испортит все остальное...)
2 ответа
Расчет должен быть отложен до displayed-year
доступен, что может быть достигнуто путем замены последнего выражения в вашей вставке на эти два:
(defun solar-term (i month)
(let* ((astronextdate (next-solar-term-date
(calendar-astro-from-absolute
(+ (* 15 i)
(calendar-absolute-from-gregorian
(list 1 1 displayed-year))))))
(s (aref solar-term-names i))
(absnextdate (calendar-absolute-from-astro
astronextdate))
(gregnextdate (calendar-gregorian-from-absolute
(floor absnextdate)))
(compt (* 24 (- absnextdate (floor absnextdate))))
(str (concat s " "
(solar-time-string
compt (if (dst-in-effect absnextdate)
calendar-daylight-time-zone-name
calendar-standard-time-zone-name))))
(d (extract-calendar-day gregnextdate)))
(holiday-fixed month d str)))
(setq solar-terms-holidays
(let* ((mylist nil))
(dotimes (k 4) ;k=season
(dotimes (j 5) ;no equinoxes/solstices --- use solar for them
(let* ((i (+ j (* 6 k)))
(month (+ 1 (/ i 2))))
(push `(solar-term ,i ,month) mylist))))
mylist))
Потому что вы не связали символ displayed-year
к стоимости. Проверьте последнюю строку в let*
привязка для astronextdate
:
(list 1 1 displayed-year))))))
Этот символ не привязан ни к какому значению, поэтому вы получаете ошибку переменной void. Переменная определяется в calendar
библиотека, которая имеет документацию:
;; A note on free variables:
;; The calendar passes around a few dynamically bound variables, which
;; unfortunately have rather common names. They are meant to be
;; available for external functions, so the names can't be changed.
;; displayed-month, displayed-year: bound in calendar-generate, the
;; central month of the 3 month calendar window
Итак, похоже, вам просто нужно добавить:
(require 'calendar)
заставить Emacs загрузить пакет, который определяет переменную перед этим.
Тем не менее, это будет определено, но еще не связано. Вы должны изменить свой код, чтобы не принимать статически связанные solar-terms-holidays
, но должен превратить его в функцию, которая вычисляет их по требованию, потому что displayed-year
привязан только когда календарь на самом деле работает...
Итак, одно из возможных решений заключается в следующем: setq
чтобы убедиться, что переменные связаны так, как вы ожидаете, будут:
(save-window-excursion
(calendar)
(setq solar-terms-holidays
....)
(calendar-exit))