emacs - 为什么 Emacs 在我的 .emacs 文件中提示 void-variable displayed-year ?

标签 emacs elisp dot-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(Gentoo 上的版本 23.2-r2)提示启动时显示的年份是一个 void 变量,并且尝试使用 M-x calendar RET 生成日历并没有帮助任何一个。知道我该如何解决这个问题吗? (当然不是在我的 .emacs 中定义显示年份,因为这肯定会搞砸其他一切......)

最佳答案

因为您尚未将符号displayed-year绑定(bind)到一个值。查看 astronextdatelet* 绑定(bind)中的最后一行:

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

该符号未绑定(bind)到任何值,因此您会收到 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 加载预先定义变量的包。

也就是说,它将被定义,但尚未绑定(bind)。您应该更改代码,不要假定静态绑定(bind)的 solar-terms-holidays,而应将其转换为按需计算这些值的函数,因为 displayed-year 是仅在日历实际运行时绑定(bind)...

因此,一种可能的解决方案是执行以下操作,按如下方式包装 setq 以确保变量按照您期望的方式进行绑定(bind):

(save-window-excursion
  (calendar)
  (setq solar-terms-holidays
        ....)
  (calendar-exit))

关于emacs - 为什么 Emacs 在我的 .emacs 文件中提示 void-variable displayed-year ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4306694/

相关文章:

emacs - 打开 emacs 并水平分割

emacs - 退出 Emacs 时自动停止进程

python - 在 IPython 模式下更改 Emacs “send code to interpreter” C-c C-r 命令

emacs:搜索文件名的一部分

emacs - 在 diff 模式下自动启用空白模式

Emacs 在启动时无法识别 .emacs.d 文件夹

python - 如何使用 python 模式在 Emacs 中缩进代码?

Emacs:将标记区域内的每个由 2 位数字组成的数字加 1

arrays - 移位/取消移位缓冲区中数组的元素

Emacs:如何消除自动完成弹出窗口中的空白模式?