繁体   English   中英

为什么Emacs会在我的.emacs文件中抱怨void变量显示年份?

[英]Why does Emacs complain about void-variable displayed-year in my .emacs file?

我正在尝试在.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(Gentoo上的版本23.2-r2)抱怨显示年份在启动时是一个空变量,尝试使用Mx日历RET生成日历也无济于事。 知道我该如何解决吗? (当然不能在我的.emacs定义显示年份,因为这肯定会.emacs其他所有内容...)

因为您尚未将符号displayed-year绑定到一个值。 astronextdatelet*绑定中的最后一行以获取astronextdate

                                      (list 1 1 displayed-year))))))

该符号没有任何值,因此您会得到一个空变量错误。 变量在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))

需要将计算推迟到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))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM