如何使用elisp让用户从日历中选择日期?

时间:2014-12-27 12:11:48

标签: date calendar elisp

学习在elisp中编写交互式函数:

如果使用前缀调用,请打开日历并获取用户选择的日期。

我尝试做这样的事情:

(calendar)
(org-get-date-from-calendar)

它立即返回,而不是让用户选择日期。

2 个答案:

答案 0 :(得分:3)

正如您所见,问题是在调用(calendar)之后,您的代码会继续,并且不会等待日历窗口中的任何交互。在用户选择日期之前,您需要阻止emacs command loop继续。

设置自己的密钥是实现此目的的一种方法。例如,如果您查看org-read-date-minibuffer-local-map variable中的org-mode source code,您可以看到org-mode在日历模式下基本上接管了密钥以允许用户在org-mode等待的情况下导航日历结果。研究这个键图和org-eval-in-calendar function可能会给你一些关于如何实现你想要的想法。

等待结果的另一种方法是通过recursive-edit。下面的代码输入日历,并通过调用(recursive-edit)等待用户通过q键退出日历,该密钥通常会调用calendar-exit。代码临时将建议应用于该函数,以便在调用calendar-exit之前(通过funcall)将局部变量设置为日历中选择的日期,然后退出递归编辑:

(let* (date
       (adv '(lambda (fn &rest args)
               (setq date (calendar-cursor-to-date))
               (funcall fn args)
               (exit-recursive-edit))))
  (advice-add 'calendar-exit :around adv)
  (calendar)
  (message "Select the desired date, then type `q' to exit.")
  (recursive-edit)
  (advice-remove 'calendar-exit adv)
  date)
但是,使用建议可能是一种脆弱的方法。它可能会以意想不到的方式改变函数语义 - 而see this page则会出现其他潜在问题 - 此外,对于异常退出,可能存在潜在的其他问题。你最好使用像org-mode中使用的键映射方法。

答案 1 :(得分:2)

我试过

(org-read-date)

这对我有用