议程视图和日历中下一个/上个月的自定义功能

时间:2013-07-16 18:02:32

标签: emacs org-mode

我正在寻找一种在议程视图和日历中选择nextprevious个月的方法。我已经编写了一个概念/原型函数(如下所示),但它不计算nextprevious个月,我还需要每个月重写一次该函数。

org-agenda-month-view的日期格式与calendar-other-month的日期格式不同。下面是一些与我想要完成的事情相关的功能 - 例如,日历已经具有按月向前或向后移动的能力。

我认为可能需要的功能是识别正在查看的月份,然后在点击nextprevious按钮时加上或减去一个月(以正确的格式)。

(defun lawlist-org-agenda-view-mode-dispatch ()
  "Select the month in agenda view."
  (interactive)
  (message "View: [7] JUL | [8] AUG | [9] SEP | [o]CT | [n]OV | [d]EC ")
  (let ((a (read-char-exclusive)))
    (case a
      (?7
        (org-agenda nil "a")
        (org-agenda-month-view 201307)
        (calendar)
        (calendar-other-month 7 2013)
        (lawlist-org-agenda-view-mode-dispatch))
      (?8
        (org-agenda nil "a")
        (org-agenda-month-view 201308)
        (calendar)
        (calendar-other-month 8 2013)
        (lawlist-org-agenda-view-mode-dispatch))
      (?9
        (org-agenda nil "a")
        (org-agenda-month-view 201309)
        (calendar)
        (calendar-other-month 9 2013)
        (lawlist-org-agenda-view-mode-dispatch))
      (?o
        (org-agenda nil "a")
        (org-agenda-month-view 201310)
        (calendar)
        (calendar-other-month 10 2013)
        (lawlist-org-agenda-view-mode-dispatch))
      (?n
        (org-agenda nil "a")
        (org-agenda-month-view 201311)
        (calendar)
        (calendar-other-month 11 2013)
        (lawlist-org-agenda-view-mode-dispatch))
      (?d
        (org-agenda nil "a")
        (org-agenda-month-view 201312)
        (calendar)
        (calendar-other-month 12 2013)
        (lawlist-org-agenda-view-mode-dispatch))
      (?q (message "Abort"))
      (otherwise (error "Either press \"q\" to quit, or select another option." )))))

以下是我从cal-move.elcalendar.el中提取的一些相关功能:

(defun calendar-other-month (month year &optional event)
  "Display a three-month calendar centered around MONTH and YEAR.
EVENT is an event like `last-nonmenu-event'."
  (interactive (let ((event (list last-nonmenu-event)))
                 (append (calendar-read-date 'noday) event)))
  (save-selected-window
    (and event
         (setq event (event-start event))
         (select-window (posn-window event)))
    (unless (and (= month displayed-month)
                 (= year displayed-year))
      (let ((old-date (calendar-cursor-to-date))
            (today (calendar-current-date)))
        (calendar-generate-window month year)
        (calendar-cursor-to-visible-date
         (cond
          ((calendar-date-is-visible-p old-date) old-date)
          ((calendar-date-is-visible-p today) today)
          (t (list month 1 year))))))))

;;;###cal-autoload
(defun calendar-forward-month (arg)
  "Move the cursor forward ARG months.
Movement is backward if ARG is negative."
  (interactive "p")
  (calendar-cursor-to-nearest-date)
  (let* ((cursor-date (calendar-cursor-to-date t))
         (month (calendar-extract-month cursor-date))
         (day (calendar-extract-day cursor-date))
         (year (calendar-extract-year cursor-date))
         (last (progn
                 (calendar-increment-month month year arg)
                 (calendar-last-day-of-month month year)))
         (day (min last day))
         ;; Put the new month on the screen, if needed, and go to the new date.
         (new-cursor-date (list month day year)))
    (if (not (calendar-date-is-visible-p new-cursor-date))
        (calendar-other-month month year))
    (calendar-cursor-to-visible-date new-cursor-date))
  (run-hooks 'calendar-move-hook))

;;;###cal-autoload
(defun calendar-backward-month (arg)
  "Move the cursor backward by ARG months.
Movement is forward if ARG is negative."
  (interactive "p")
  (calendar-forward-month (- arg)))

;;;###cal-autoload
(defun calendar-forward-year (arg)
  "Move the cursor forward by ARG years.
Movement is backward if ARG is negative."
  (interactive "p")
  (calendar-forward-month (* 12 arg)))

;;;###cal-autoload
(defun calendar-backward-year (arg)
  "Move the cursor backward ARG years.
Movement is forward is ARG is negative."
  (interactive "p")
  (calendar-forward-month (* -12 arg)))

;;;###cal-autoload
(defun calendar-scroll-left (&optional arg event)
  "Scroll the displayed calendar left by ARG months.
If ARG is negative the calendar is scrolled right.  Maintains the relative
position of the cursor with respect to the calendar as well as possible.
EVENT is an event like `last-nonmenu-event'."
  (interactive (list (prefix-numeric-value current-prefix-arg)
                     last-nonmenu-event))
  (unless arg (setq arg 1))
  (save-selected-window
    ;; Nil if called from menu-bar.
    (if (setq event (event-start event)) (select-window (posn-window event)))
    (calendar-cursor-to-nearest-date)
    (unless (zerop arg)
      (let ((old-date (calendar-cursor-to-date))
            (today (calendar-current-date))
            (month displayed-month)
            (year displayed-year))
        (calendar-increment-month month year arg)
        (calendar-generate-window month year)
        (calendar-cursor-to-visible-date
         (cond
          ((calendar-date-is-visible-p old-date) old-date)
          ((calendar-date-is-visible-p today) today)
          (t (list month 1 year))))))
    (run-hooks 'calendar-move-hook)))

(define-obsolete-function-alias
  'scroll-calendar-left 'calendar-scroll-left "23.1")

;;;###cal-autoload
(defun calendar-scroll-right (&optional arg event)
  "Scroll the displayed calendar window right by ARG months.
If ARG is negative the calendar is scrolled left.  Maintains the relative
position of the cursor with respect to the calendar as well as possible.
EVENT is an event like `last-nonmenu-event'."
  (interactive (list (prefix-numeric-value current-prefix-arg)
                     last-nonmenu-event))
  (calendar-scroll-left (- (or arg 1)) event))

(define-obsolete-function-alias
  'scroll-calendar-right 'calendar-scroll-right "23.1")

1 个答案:

答案 0 :(得分:1)

这是我的看法:

(defvar lawlist-month)

(defun lawlist-org-agenda-view-mode-dispatch ()
  "Select the month in agenda view."
  (interactive)
  (message "View: [1-9] [o]CT [n]OV [d]EC, j(next), k(prev).")
  (let* ((a (read-char-exclusive))
         (month (case a
                  (?o 10)
                  (?n 11)
                  (?d 12)
                  (?j (or (and lawlist-month (mod (1+ lawlist-month) 12)) 1))
                  (?k (or (and lawlist-month (mod (1- lawlist-month) 12)) 1))
                  (t (and (> a ?0) (<= a ?9) (- a ?0))))))
    (if (setq lawlist-month month)
        (let ((year (nth 5 (decode-time (current-time)))))
           (org-agenda nil "a")
           (org-agenda-month-view
            (read (format "%d%02d" year month)))
           (calendar)
           (calendar-other-month month year)
           (lawlist-org-agenda-view-mode-dispatch))
      (message "Aborted"))))

它仍然缺少一些功能,如保存窗口配置和 在中止恢复。

UPD

可以在此gist中找到更新的代码。 除了当前,我已经添加了其他年份,支持j / k,以及多年来的h / l。