2010-11-29 94 views
2

我試圖在我的.emacs中實施節氣,所以我的「假期」將顯示太陽經度與15度的每個倍數交叉的時間。這裏是相關的snipplet。爲什麼Emacs會在我的.emacs文件中抱怨無效顯示年份?

(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日曆RET日曆也沒有幫助。任何想法如何我可以解決這個問題? (當然不是在我的.emacs中定義顯示年份,因爲這肯定會把所有其他東西都搞砸了......)

+0

在運行此功能之前,您是否需要日曆並加載它? – 2010-11-29 18:26:02

回答

1

需要推遲計算直至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)) 
3

因爲您還沒有將符號displayed-year限制爲某個值。看看在let*最後一行爲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)) 
+1

你必須做的不僅僅是'(需要'日曆)`,你必須真正運行'日曆'功能。 – 2010-11-29 18:33:29

+0

@GarethRees Yah,我在添加,因爲你正在輸入你的評論。 :)我們都在同一時間編輯了這個問題。猜猜我們是同步的。 – 2010-11-29 18:41:53

相關問題