2019-03-29 08:46:29 -04:00
|
|
|
;;; gnus-icalendar.el --- reply to iCalendar meeting requests -*- lexical-binding:t -*-
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2020-01-01 00:19:43 +00:00
|
|
|
;; Copyright (C) 2013-2020 Free Software Foundation, Inc.
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
;; Author: Jan Tatarik <Jan.Tatarik@gmail.com>
|
|
|
|
;; Keywords: mail, icalendar, org
|
|
|
|
|
2020-08-27 02:42:36 +02:00
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
2013-08-01 22:58:40 +00:00
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
2020-08-27 02:42:36 +02:00
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
2013-08-01 22:58:40 +00:00
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
2020-08-27 02:42:36 +02:00
|
|
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
;; To install:
|
|
|
|
;; (require 'gnus-icalendar)
|
|
|
|
;; (gnus-icalendar-setup)
|
|
|
|
|
|
|
|
;; to enable optional iCalendar->Org sync functionality
|
|
|
|
;; NOTE: both the capture file and the headline(s) inside must already exist
|
|
|
|
;; (setq gnus-icalendar-org-capture-file "~/org/notes.org")
|
|
|
|
;; (setq gnus-icalendar-org-capture-headline '("Calendar"))
|
|
|
|
;; (gnus-icalendar-org-setup)
|
|
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
(require 'icalendar)
|
|
|
|
(require 'eieio)
|
2013-09-17 23:49:48 +00:00
|
|
|
(require 'gmm-utils)
|
2013-08-01 22:58:40 +00:00
|
|
|
(require 'mm-decode)
|
|
|
|
(require 'gnus-sum)
|
2014-04-20 22:35:24 +00:00
|
|
|
(require 'gnus-art)
|
2013-08-01 22:58:40 +00:00
|
|
|
|
gnus: replace cl with cl-lib
* lisp/gnus/gnus-agent.el, lisp/gnus/gnus-art.el:
* lisp/gnus/gnus-async.el, lisp/gnus/gnus-cache.el:
* lisp/gnus/gnus-demon.el, lisp/gnus/gnus-group.el:
* lisp/gnus/gnus-icalendar.el, lisp/gnus/gnus-logic.el:
* lisp/gnus/gnus-msg.el, lisp/gnus/gnus-picon.el:
* lisp/gnus/gnus-registry.el, lisp/gnus/gnus-salt.el:
* lisp/gnus/gnus-score.el, lisp/gnus/gnus-spec.el:
* lisp/gnus/gnus-srvr.el, lisp/gnus/gnus-start.el:
* lisp/gnus/gnus-sum.el, lisp/gnus/gnus-topic.el:
* lisp/gnus/gnus-util.el, lisp/gnus/gnus-uu.el, lisp/gnus/gnus-win.el:
* lisp/gnus/mail-source.el, lisp/gnus/mm-decode.el:
* lisp/gnus/mm-encode.el, lisp/gnus/mm-url.el, lisp/gnus/mm-view.el:
* lisp/gnus/mml-smime.el, lisp/gnus/mml.el, lisp/gnus/mml2015.el:
* lisp/gnus/nnbabyl.el, lisp/gnus/nndoc.el, lisp/gnus/nneething.el:
* lisp/gnus/nnheader.el, lisp/gnus/nnimap.el, lisp/gnus/nnmail.el:
* lisp/gnus/nnmaildir.el, lisp/gnus/nnoo.el, lisp/gnus/nnrss.el:
* lisp/gnus/nnspool.el, lisp/gnus/nntp.el, lisp/gnus/nnvirtual.el:
* lisp/gnus/nnweb.el, lisp/gnus/spam.el: Replace cl with cl-lib.
* lisp/gnus/canlock.el, lisp/gnus/gnus-bcklg.el:
* lisp/gnus/gnus-cite.el, lisp/gnus/gnus-cloud.el:
* lisp/gnus/gnus-draft.el, lisp/gnus/gnus-dup.el:
* lisp/gnus/gnus-fun.el, lisp/gnus/gnus-html.el:
* lisp/gnus/gnus-int.el, lisp/gnus/gnus-kill.el, lisp/gnus/gnus-ml.el:
* lisp/gnus/gnus-mlspl.el, lisp/gnus/gnus-range.el:
* lisp/gnus/gnus-undo.el, lisp/gnus/gnus-vm.el:
* lisp/gnus/mm-partial.el, lisp/gnus/mm-uu.el, lisp/gnus/mml1991.el:
* lisp/gnus/nnagent.el, lisp/gnus/nndiary.el, lisp/gnus/nndir.el:
* lisp/gnus/nndraft.el, lisp/gnus/nnfolder.el, lisp/gnus/nngateway.el:
* lisp/gnus/nnmairix.el, lisp/gnus/nnmbox.el, lisp/gnus/nnmh.el:
* lisp/gnus/nnml.el, lisp/gnus/score-mode.el, lisp/gnus/smiley.el:
No need for cl.
2018-03-23 16:13:09 -04:00
|
|
|
(eval-when-compile (require 'cl-lib))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defun gnus-icalendar-find-if (pred seq)
|
|
|
|
(catch 'found
|
|
|
|
(while seq
|
|
|
|
(when (funcall pred (car seq))
|
|
|
|
(throw 'found (car seq)))
|
|
|
|
(pop seq))))
|
|
|
|
|
|
|
|
;;;
|
|
|
|
;;; ical-event
|
|
|
|
;;;
|
|
|
|
|
|
|
|
(defclass gnus-icalendar-event ()
|
|
|
|
((organizer :initarg :organizer
|
|
|
|
:accessor gnus-icalendar-event:organizer
|
|
|
|
:initform ""
|
|
|
|
:type (or null string))
|
|
|
|
(summary :initarg :summary
|
|
|
|
:accessor gnus-icalendar-event:summary
|
|
|
|
:initform ""
|
|
|
|
:type (or null string))
|
|
|
|
(description :initarg :description
|
|
|
|
:accessor gnus-icalendar-event:description
|
|
|
|
:initform ""
|
|
|
|
:type (or null string))
|
|
|
|
(location :initarg :location
|
|
|
|
:accessor gnus-icalendar-event:location
|
|
|
|
:initform ""
|
|
|
|
:type (or null string))
|
2013-11-12 22:16:09 +00:00
|
|
|
(start-time :initarg :start-time
|
|
|
|
:accessor gnus-icalendar-event:start-time
|
2013-08-01 22:58:40 +00:00
|
|
|
:initform ""
|
2013-11-12 22:16:09 +00:00
|
|
|
:type (or null t))
|
|
|
|
(end-time :initarg :end-time
|
|
|
|
:accessor gnus-icalendar-event:end-time
|
2013-08-01 22:58:40 +00:00
|
|
|
:initform ""
|
2013-11-12 22:16:09 +00:00
|
|
|
:type (or null t))
|
2013-08-01 22:58:40 +00:00
|
|
|
(recur :initarg :recur
|
|
|
|
:accessor gnus-icalendar-event:recur
|
|
|
|
:initform ""
|
|
|
|
:type (or null string))
|
|
|
|
(uid :initarg :uid
|
|
|
|
:accessor gnus-icalendar-event:uid
|
|
|
|
:type string)
|
|
|
|
(method :initarg :method
|
|
|
|
:accessor gnus-icalendar-event:method
|
|
|
|
:initform "PUBLISH"
|
|
|
|
:type (or null string))
|
|
|
|
(rsvp :initarg :rsvp
|
|
|
|
:accessor gnus-icalendar-event:rsvp
|
|
|
|
:initform nil
|
2013-11-15 00:07:54 +00:00
|
|
|
:type (or null boolean))
|
2013-11-28 23:33:52 +00:00
|
|
|
(participation-type :initarg :participation-type
|
|
|
|
:accessor gnus-icalendar-event:participation-type
|
|
|
|
:initform 'non-participant
|
|
|
|
:type (or null t))
|
2013-11-15 00:07:54 +00:00
|
|
|
(req-participants :initarg :req-participants
|
|
|
|
:accessor gnus-icalendar-event:req-participants
|
|
|
|
:initform nil
|
|
|
|
:type (or null t))
|
|
|
|
(opt-participants :initarg :opt-participants
|
|
|
|
:accessor gnus-icalendar-event:opt-participants
|
|
|
|
:initform nil
|
|
|
|
:type (or null t)))
|
2013-08-01 22:58:40 +00:00
|
|
|
"generic iCalendar Event class")
|
|
|
|
|
|
|
|
(defclass gnus-icalendar-event-request (gnus-icalendar-event)
|
|
|
|
nil
|
|
|
|
"iCalendar class for REQUEST events")
|
|
|
|
|
|
|
|
(defclass gnus-icalendar-event-cancel (gnus-icalendar-event)
|
|
|
|
nil
|
|
|
|
"iCalendar class for CANCEL events")
|
|
|
|
|
|
|
|
(defclass gnus-icalendar-event-reply (gnus-icalendar-event)
|
|
|
|
nil
|
|
|
|
"iCalendar class for REPLY events")
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:recurring-p ((event gnus-icalendar-event))
|
2013-08-01 22:58:40 +00:00
|
|
|
"Return t if EVENT is recurring."
|
|
|
|
(not (null (gnus-icalendar-event:recur event))))
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:recurring-freq ((event gnus-icalendar-event))
|
2013-08-01 22:58:40 +00:00
|
|
|
"Return recurring frequency of EVENT."
|
|
|
|
(let ((rrule (gnus-icalendar-event:recur event)))
|
|
|
|
(string-match "FREQ=\\([[:alpha:]]+\\)" rrule)
|
|
|
|
(match-string 1 rrule)))
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:recurring-interval ((event gnus-icalendar-event))
|
2013-08-01 22:58:40 +00:00
|
|
|
"Return recurring interval of EVENT."
|
|
|
|
(let ((rrule (gnus-icalendar-event:recur event))
|
2020-09-28 13:08:32 +02:00
|
|
|
(default-interval "1"))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2020-09-28 13:08:32 +02:00
|
|
|
(if (string-match "INTERVAL=\\([[:digit:]]+\\)" rrule)
|
|
|
|
(match-string 1 rrule)
|
|
|
|
default-interval)))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2020-08-22 15:39:17 +02:00
|
|
|
(cl-defmethod gnus-icalendar-event:recurring-days ((event gnus-icalendar-event))
|
|
|
|
"Return, when available, the week day numbers on which the EVENT recurs."
|
|
|
|
(let ((rrule (gnus-icalendar-event:recur event))
|
|
|
|
(weekday-map '(("SU" . 0)
|
|
|
|
("MO" . 1)
|
|
|
|
("TU" . 2)
|
|
|
|
("WE" . 3)
|
|
|
|
("TH" . 4)
|
|
|
|
("FR" . 5)
|
|
|
|
("SA" . 6))))
|
2020-08-25 16:36:15 +02:00
|
|
|
(when (and rrule (string-match "BYDAY=\\([^;]+\\)" rrule))
|
2020-08-22 15:39:17 +02:00
|
|
|
(let ((bydays (split-string (match-string 1 rrule) ",")))
|
|
|
|
(seq-map
|
|
|
|
(lambda (x) (cdr (assoc x weekday-map)))
|
|
|
|
(seq-filter (lambda (x) (string-match "^[A-Z]\\{2\\}$" x)) bydays))))))
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:start ((event gnus-icalendar-event))
|
2013-11-12 22:16:09 +00:00
|
|
|
(format-time-string "%Y-%m-%d %H:%M" (gnus-icalendar-event:start-time event)))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2014-10-16 22:12:03 +00:00
|
|
|
(defun gnus-icalendar-event--decode-datefield (event field zone-map)
|
|
|
|
(let* ((dtdate (icalendar--get-event-property event field))
|
|
|
|
(dtdate-zone (icalendar--find-time-zone
|
|
|
|
(icalendar--get-event-property-attributes
|
|
|
|
event field) zone-map))
|
|
|
|
(dtdate-dec (icalendar--decode-isodatetime dtdate nil dtdate-zone)))
|
Simplify use of encode-time
Most uses of (apply #'encode-time foo) can now be replaced
with (encode-time foo). Make similar simplifications.
* lisp/calendar/time-date.el (date-to-time):
* lisp/calendar/timeclock.el (timeclock-when-to-leave)
(timeclock-day-base, timeclock-generate-report):
* lisp/emacs-lisp/timer.el (timer-set-idle-time):
* lisp/eshell/esh-util.el (eshell-parse-ange-ls):
* lisp/gnus/gnus-art.el (article-make-date-line):
* lisp/gnus/gnus-delay.el (gnus-delay-article)
(gnus-delay-send-queue):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event--decode-datefield):
* lisp/gnus/gnus-logic.el (gnus-advanced-date):
* lisp/gnus/message.el (message-make-expires-date):
* lisp/gnus/nndiary.el (nndiary-compute-reminders):
* lisp/mail/ietf-drums.el (ietf-drums-parse-date):
* lisp/net/tramp-adb.el (tramp-adb-ls-output-time-less-p):
* lisp/org/org-agenda.el (org-agenda-get-timestamps)
(org-agenda-get-progress, org-agenda-show-clocking-issues):
* lisp/org/org-capture.el (org-capture-set-target-location):
* lisp/org/org-clock.el (org-clock-get-sum-start, org-clock-sum)
(org-clocktable-steps):
* lisp/org/org-colview.el (org-colview-construct-allowed-dates)
* lisp/org/org-macro.el (org-macro--vc-modified-time):
* lisp/org/org-table.el (org-table-eval-formula):
* lisp/org/org.el (org-current-time, org-store-link)
(org-time-today, org-read-date, org-read-date-display)
(org-display-custom-time, org-time-string-to-time)
(org-timestamp-change, org-timestamp--to-internal-time):
* lisp/url/url-dav.el (url-dav-process-date-property):
* lisp/vc/vc-cvs.el (vc-cvs-annotate-current-time)
(vc-cvs-parse-entry):
Simplify use of encode-time.
* lisp/org/org-clock.el (org-clock-get-clocked-time):
(org-clock-resolve, org-resolve-clocks, org_clock_out)
(org-clock-update-time-maybe):
Avoid some rounding problems with encode-time and float-time.
* lisp/org/org-clock.el (org-clock-in, org-clock-update-time-maybe):
* lisp/org/org-colview.el (org-columns--age-to-minutes):
* lisp/org/org.el (org-get-scheduled-time, org-get-deadline-time)
(org-add-planning-info, org-2ft, org-time-string-to-absolute)
(org-closest-date):
Use org-time-string-to-time instead of doing it by hand with
encode-time.
* lisp/org/org.el (org-current-time): Simplify rounding.
(org-read-date): Avoid extra trip through encode-time.
2019-02-10 20:25:22 -08:00
|
|
|
(encode-time dtdate-dec)))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defun gnus-icalendar-event--find-attendee (ical name-or-email)
|
|
|
|
(let* ((event (car (icalendar--all-events ical)))
|
|
|
|
(event-props (caddr event)))
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels ((attendee-name (att) (plist-get (cadr att) 'CN))
|
|
|
|
(attendee-email
|
|
|
|
(att)
|
|
|
|
(replace-regexp-in-string "^.*MAILTO:" "" (caddr att)))
|
|
|
|
(attendee-prop-matches-p
|
|
|
|
(prop)
|
|
|
|
(and (eq (car prop) 'ATTENDEE)
|
|
|
|
(or (member (attendee-name prop) name-or-email)
|
|
|
|
(let ((att-email (attendee-email prop)))
|
|
|
|
(gnus-icalendar-find-if
|
2020-10-10 22:32:41 +02:00
|
|
|
(lambda (str-or-fun)
|
|
|
|
(if (functionp str-or-fun)
|
|
|
|
(funcall str-or-fun att-email)
|
|
|
|
(string-match str-or-fun att-email)))
|
2016-02-13 16:40:17 +11:00
|
|
|
name-or-email))))))
|
2013-08-01 22:58:40 +00:00
|
|
|
(gnus-icalendar-find-if #'attendee-prop-matches-p event-props))))
|
|
|
|
|
2013-11-15 00:07:54 +00:00
|
|
|
(defun gnus-icalendar-event--get-attendee-names (ical)
|
|
|
|
(let* ((event (car (icalendar--all-events ical)))
|
2017-11-25 18:42:55 -08:00
|
|
|
(attendee-props (seq-filter
|
2013-11-15 00:07:54 +00:00
|
|
|
(lambda (p) (eq (car p) 'ATTENDEE))
|
|
|
|
(caddr event))))
|
|
|
|
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((attendee-role (prop) (plist-get (cadr prop) 'ROLE))
|
|
|
|
(attendee-name
|
|
|
|
(prop)
|
|
|
|
(or (plist-get (cadr prop) 'CN)
|
|
|
|
(replace-regexp-in-string "^.*MAILTO:" "" (caddr prop))))
|
|
|
|
(attendees-by-type (type)
|
2017-11-25 18:42:55 -08:00
|
|
|
(seq-filter
|
2016-02-13 16:40:17 +11:00
|
|
|
(lambda (p) (string= (attendee-role p) type))
|
|
|
|
attendee-props))
|
|
|
|
(attendee-names-by-type
|
|
|
|
(type)
|
|
|
|
(mapcar #'attendee-name (attendees-by-type type))))
|
2013-11-15 00:07:54 +00:00
|
|
|
(list
|
|
|
|
(attendee-names-by-type "REQ-PARTICIPANT")
|
|
|
|
(attendee-names-by-type "OPT-PARTICIPANT")))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defun gnus-icalendar-event-from-ical (ical &optional attendee-name-or-email)
|
|
|
|
(let* ((event (car (icalendar--all-events ical)))
|
|
|
|
(organizer (replace-regexp-in-string
|
|
|
|
"^.*MAILTO:" ""
|
|
|
|
(or (icalendar--get-event-property event 'ORGANIZER) "")))
|
|
|
|
(prop-map '((summary . SUMMARY)
|
|
|
|
(description . DESCRIPTION)
|
|
|
|
(location . LOCATION)
|
|
|
|
(recur . RRULE)
|
|
|
|
(uid . UID)))
|
|
|
|
(method (caddr (assoc 'METHOD (caddr (car (nreverse ical))))))
|
|
|
|
(attendee (when attendee-name-or-email
|
|
|
|
(gnus-icalendar-event--find-attendee ical attendee-name-or-email)))
|
2013-11-15 00:07:54 +00:00
|
|
|
(attendee-names (gnus-icalendar-event--get-attendee-names ical))
|
2013-11-28 23:33:52 +00:00
|
|
|
(role (plist-get (cadr attendee) 'ROLE))
|
|
|
|
(participation-type (pcase role
|
|
|
|
("REQ-PARTICIPANT" 'required)
|
|
|
|
("OPT-PARTICIPANT" 'optional)
|
|
|
|
(_ 'non-participant)))
|
2014-10-16 22:12:03 +00:00
|
|
|
(zone-map (icalendar--convert-all-timezones ical))
|
2013-08-01 22:58:40 +00:00
|
|
|
(args (list :method method
|
|
|
|
:organizer organizer
|
2014-10-16 22:12:03 +00:00
|
|
|
:start-time (gnus-icalendar-event--decode-datefield event 'DTSTART zone-map)
|
|
|
|
:end-time (gnus-icalendar-event--decode-datefield event 'DTEND zone-map)
|
2013-11-28 23:33:52 +00:00
|
|
|
:rsvp (string= (plist-get (cadr attendee) 'RSVP) "TRUE")
|
|
|
|
:participation-type participation-type
|
|
|
|
:req-participants (car attendee-names)
|
2013-11-15 00:07:54 +00:00
|
|
|
:opt-participants (cadr attendee-names)))
|
2013-08-06 22:09:27 +00:00
|
|
|
(event-class (cond
|
|
|
|
((string= method "REQUEST") 'gnus-icalendar-event-request)
|
|
|
|
((string= method "CANCEL") 'gnus-icalendar-event-cancel)
|
|
|
|
((string= method "REPLY") 'gnus-icalendar-event-reply)
|
|
|
|
(t 'gnus-icalendar-event))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((map-property
|
|
|
|
(prop)
|
|
|
|
(let ((value (icalendar--get-event-property event prop)))
|
|
|
|
(when value
|
|
|
|
;; ugly, but cannot get
|
|
|
|
;;replace-regexp-in-string work with "\\" as
|
|
|
|
;;REP, plus we should also handle "\\;"
|
|
|
|
(replace-regexp-in-string
|
|
|
|
"\\\\," ","
|
|
|
|
(replace-regexp-in-string
|
|
|
|
"\\\\n" "\n" (substring-no-properties value))))))
|
|
|
|
(accumulate-args
|
|
|
|
(mapping)
|
gnus: replace cl with cl-lib
* lisp/gnus/gnus-agent.el, lisp/gnus/gnus-art.el:
* lisp/gnus/gnus-async.el, lisp/gnus/gnus-cache.el:
* lisp/gnus/gnus-demon.el, lisp/gnus/gnus-group.el:
* lisp/gnus/gnus-icalendar.el, lisp/gnus/gnus-logic.el:
* lisp/gnus/gnus-msg.el, lisp/gnus/gnus-picon.el:
* lisp/gnus/gnus-registry.el, lisp/gnus/gnus-salt.el:
* lisp/gnus/gnus-score.el, lisp/gnus/gnus-spec.el:
* lisp/gnus/gnus-srvr.el, lisp/gnus/gnus-start.el:
* lisp/gnus/gnus-sum.el, lisp/gnus/gnus-topic.el:
* lisp/gnus/gnus-util.el, lisp/gnus/gnus-uu.el, lisp/gnus/gnus-win.el:
* lisp/gnus/mail-source.el, lisp/gnus/mm-decode.el:
* lisp/gnus/mm-encode.el, lisp/gnus/mm-url.el, lisp/gnus/mm-view.el:
* lisp/gnus/mml-smime.el, lisp/gnus/mml.el, lisp/gnus/mml2015.el:
* lisp/gnus/nnbabyl.el, lisp/gnus/nndoc.el, lisp/gnus/nneething.el:
* lisp/gnus/nnheader.el, lisp/gnus/nnimap.el, lisp/gnus/nnmail.el:
* lisp/gnus/nnmaildir.el, lisp/gnus/nnoo.el, lisp/gnus/nnrss.el:
* lisp/gnus/nnspool.el, lisp/gnus/nntp.el, lisp/gnus/nnvirtual.el:
* lisp/gnus/nnweb.el, lisp/gnus/spam.el: Replace cl with cl-lib.
* lisp/gnus/canlock.el, lisp/gnus/gnus-bcklg.el:
* lisp/gnus/gnus-cite.el, lisp/gnus/gnus-cloud.el:
* lisp/gnus/gnus-draft.el, lisp/gnus/gnus-dup.el:
* lisp/gnus/gnus-fun.el, lisp/gnus/gnus-html.el:
* lisp/gnus/gnus-int.el, lisp/gnus/gnus-kill.el, lisp/gnus/gnus-ml.el:
* lisp/gnus/gnus-mlspl.el, lisp/gnus/gnus-range.el:
* lisp/gnus/gnus-undo.el, lisp/gnus/gnus-vm.el:
* lisp/gnus/mm-partial.el, lisp/gnus/mm-uu.el, lisp/gnus/mml1991.el:
* lisp/gnus/nnagent.el, lisp/gnus/nndiary.el, lisp/gnus/nndir.el:
* lisp/gnus/nndraft.el, lisp/gnus/nnfolder.el, lisp/gnus/nngateway.el:
* lisp/gnus/nnmairix.el, lisp/gnus/nnmbox.el, lisp/gnus/nnmh.el:
* lisp/gnus/nnml.el, lisp/gnus/score-mode.el, lisp/gnus/smiley.el:
No need for cl.
2018-03-23 16:13:09 -04:00
|
|
|
(cl-destructuring-bind (slot . ical-property) mapping
|
2016-02-13 16:40:17 +11:00
|
|
|
(setq args (append (list
|
|
|
|
(intern (concat ":" (symbol-name slot)))
|
|
|
|
(map-property ical-property))
|
|
|
|
args)))))
|
2013-08-01 22:58:40 +00:00
|
|
|
(mapc #'accumulate-args prop-map)
|
2020-10-16 10:16:31 +02:00
|
|
|
(apply
|
|
|
|
#'make-instance
|
|
|
|
event-class
|
|
|
|
(cl-loop for slot in (eieio-class-slots event-class)
|
|
|
|
for keyword = (intern
|
|
|
|
(format ":%s" (eieio-slot-descriptor-name slot)))
|
2020-10-16 10:46:14 +02:00
|
|
|
when (plist-member args keyword)
|
2020-10-16 10:16:31 +02:00
|
|
|
append (list keyword (plist-get args keyword)))))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defun gnus-icalendar-event-from-buffer (buf &optional attendee-name-or-email)
|
|
|
|
"Parse RFC5545 iCalendar in buffer BUF and return an event object.
|
|
|
|
|
|
|
|
Return a gnus-icalendar-event object representing the first event
|
lisp/*.el: Fix typos and other trivial doc fixes
* lisp/allout-widgets.el (allout-widgets-auto-activation)
(allout-current-decorated-p):
* lisp/auth-source.el (auth-source-protocols):
* lisp/autorevert.el (auto-revert-set-timer):
* lisp/battery.el (battery-mode-line-limit):
* lisp/calc/calcalg3.el (math-map-binop):
* lisp/calendar/cal-dst.el (calendar-dst-find-startend):
* lisp/calendar/cal-mayan.el (calendar-mayan-long-count-to-absolute):
* lisp/calendar/calendar.el (calendar-date-echo-text)
(calendar-generate-month, calendar-string-spread)
(calendar-cursor-to-date, calendar-read, calendar-read-date)
(calendar-mark-visible-date, calendar-dayname-on-or-before):
* lisp/calendar/diary-lib.el (diary-ordinal-suffix):
* lisp/cedet/ede/autoconf-edit.el (autoconf-new-program)
(autoconf-find-last-macro, autoconf-parameter-strip):
* lisp/cedet/ede/config.el (ede-target-with-config-build):
* lisp/cedet/ede/linux.el (ede-linux--detect-architecture)
(ede-linux--get-architecture):
* lisp/cedet/semantic/complete.el (semantic-collector-calculate-cache)
(semantic-displayer-abstract, semantic-displayer-point-position):
* lisp/cedet/semantic/format.el (semantic-format-face-alist)
(semantic-format-tag-short-doc):
* lisp/cedet/semantic/fw.el (semantic-find-file-noselect):
* lisp/cedet/semantic/idle.el (semantic-idle-scheduler-work-idle-time)
(semantic-idle-breadcrumbs-display-function)
(semantic-idle-breadcrumbs-format-tag-list-function):
* lisp/cedet/semantic/lex.el (semantic-lex-map-types)
(define-lex, define-lex-block-type-analyzer):
* lisp/cedet/semantic/senator.el (senator-search-default-tag-filter):
* lisp/cedet/semantic/symref.el (semantic-symref-result)
(semantic-symref-hit-to-tag-via-db):
* lisp/cedet/semantic/symref.el (semantic-symref-tool-baseclass):
* lisp/cedet/semantic/tag.el (semantic-tag-new-variable)
(semantic-tag-new-include, semantic-tag-new-package)
(semantic-tag-set-faux, semantic-create-tag-proxy)
(semantic-tag-function-parent)
(semantic-tag-components-with-overlays):
* lisp/cedet/srecode/cpp.el (srecode-cpp-namespaces)
(srecode-semantic-handle-:c, srecode-semantic-apply-tag-to-dict):
* lisp/cedet/srecode/dictionary.el (srecode-create-dictionary)
(srecode-dictionary-add-entries, srecode-dictionary-lookup-name)
(srecode-create-dictionaries-from-tags):
* lisp/cmuscheme.el (scheme-compile-region):
* lisp/color.el (color-lab-to-lch):
* lisp/doc-view.el (doc-view-image-width)
(doc-view-set-up-single-converter):
* lisp/dynamic-setting.el (font-setting-change-default-font)
(dynamic-setting-handle-config-changed-event):
* lisp/elec-pair.el (electric-pair-text-pairs)
(electric-pair-skip-whitespace-function)
(electric-pair-string-bound-function):
* lisp/emacs-lisp/avl-tree.el (avl-tree--del-balance)
(avl-tree-member, avl-tree-mapcar, avl-tree-iter):
* lisp/emacs-lisp/bytecomp.el (byte-compile-generate-call-tree):
* lisp/emacs-lisp/checkdoc.el (checkdoc-autofix-flag)
(checkdoc-spellcheck-documentation-flag, checkdoc-ispell)
(checkdoc-ispell-current-buffer, checkdoc-ispell-interactive)
(checkdoc-ispell-message-interactive)
(checkdoc-ispell-message-text, checkdoc-ispell-start)
(checkdoc-ispell-continue, checkdoc-ispell-comments)
(checkdoc-ispell-defun):
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method):
* lisp/emacs-lisp/eieio-custom.el (eieio-read-customization-group):
* lisp/emacs-lisp/lisp.el (forward-sexp, up-list):
* lisp/emacs-lisp/package-x.el (package--archive-contents-from-file):
* lisp/emacs-lisp/package.el (package-desc)
(package--make-autoloads-and-stuff, package-hidden-regexps):
* lisp/emacs-lisp/tcover-ses.el (ses-exercise-startup):
* lisp/emacs-lisp/testcover.el (testcover-nohits)
(testcover-1value):
* lisp/epg.el (epg-receive-keys, epg-start-edit-key):
* lisp/erc/erc-backend.el (erc-server-processing-p)
(erc-split-line-length, erc-server-coding-system)
(erc-server-send, erc-message):
* lisp/erc/erc-button.el (erc-button-face, erc-button-alist)
(erc-browse-emacswiki):
* lisp/erc/erc-ezbounce.el (erc-ezbounce, erc-ezb-get-login):
* lisp/erc/erc-fill.el (erc-fill-variable-maximum-indentation):
* lisp/erc/erc-log.el (erc-current-logfile):
* lisp/erc/erc-match.el (erc-log-match-format)
(erc-text-matched-hook):
* lisp/erc/erc-netsplit.el (erc-netsplit, erc-netsplit-debug):
* lisp/erc/erc-networks.el (erc-server-alist)
(erc-networks-alist, erc-current-network):
* lisp/erc/erc-ring.el (erc-input-ring-index):
* lisp/erc/erc-speedbar.el (erc-speedbar)
(erc-speedbar-update-channel):
* lisp/erc/erc-stamp.el (erc-timestamp-only-if-changed-flag):
* lisp/erc/erc-track.el (erc-track-position-in-mode-line)
(erc-track-remove-from-mode-line, erc-modified-channels-update)
(erc-track-last-non-erc-buffer, erc-track-sort-by-importance)
(erc-track-get-active-buffer):
* lisp/erc/erc.el (erc-get-channel-user-list)
(erc-echo-notice-hook, erc-echo-notice-always-hook)
(erc-wash-quit-reason, erc-format-@nick):
* lisp/ffap.el (ffap-latex-mode):
* lisp/files.el (abort-if-file-too-large)
(dir-locals--get-sort-score, buffer-stale--default-function):
* lisp/filesets.el (filesets-tree-max-level, filesets-data)
(filesets-update-pre010505):
* lisp/gnus/gnus-agent.el (gnus-agent-flush-cache):
* lisp/gnus/gnus-art.el (gnus-article-encrypt-protocol)
(gnus-button-prefer-mid-or-mail):
* lisp/gnus/gnus-cus.el (gnus-group-parameters):
* lisp/gnus/gnus-demon.el (gnus-demon-handlers)
(gnus-demon-run-callback):
* lisp/gnus/gnus-dired.el (gnus-dired-print):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-buffer):
* lisp/gnus/gnus-range.el (gnus-range-normalize):
* lisp/gnus/gnus-spec.el (gnus-pad-form):
* lisp/gnus/gnus-srvr.el (gnus-server-agent, gnus-server-cloud)
(gnus-server-opened, gnus-server-closed, gnus-server-denied)
(gnus-server-offline):
* lisp/gnus/gnus-sum.el (gnus-refer-thread-use-nnir)
(gnus-refer-thread-limit-to-thread)
(gnus-summary-limit-include-thread, gnus-summary-refer-thread)
(gnus-summary-find-matching):
* lisp/gnus/gnus-util.el (gnus-rescale-image):
* lisp/gnus/gnus.el (gnus-summary-line-format, gnus-no-server):
* lisp/gnus/mail-source.el (mail-source-incoming-file-prefix):
* lisp/gnus/message.el (message-cite-reply-position)
(message-cite-style-outlook, message-cite-style-thunderbird)
(message-cite-style-gmail, message--send-mail-maybe-partially):
* lisp/gnus/mm-extern.el (mm-inline-external-body):
* lisp/gnus/mm-partial.el (mm-inline-partial):
* lisp/gnus/mml-sec.el (mml-secure-message-sign)
(mml-secure-message-sign-encrypt, mml-secure-message-encrypt):
* lisp/gnus/mml2015.el (mml2015-epg-key-image)
(mml2015-epg-key-image-to-string):
* lisp/gnus/nndiary.el (nndiary-reminders, nndiary-get-new-mail):
* lisp/gnus/nnheader.el (nnheader-directory-files-is-safe):
* lisp/gnus/nnir.el (nnir-search-history)
(nnir-imap-search-other, nnir-artlist-length)
(nnir-artlist-article, nnir-artitem-group, nnir-artitem-number)
(nnir-artitem-rsv, nnir-article-group, nnir-article-number)
(nnir-article-rsv, nnir-article-ids, nnir-categorize)
(nnir-retrieve-headers-override-function)
(nnir-imap-default-search-key, nnir-hyrex-additional-switches)
(gnus-group-make-nnir-group, nnir-run-namazu, nnir-read-parms)
(nnir-read-parm, nnir-read-server-parm, nnir-search-thread):
* lisp/gnus/nnmairix.el (nnmairix-default-group)
(nnmairix-propagate-marks):
* lisp/gnus/smime.el (smime-keys, smime-crl-check)
(smime-verify-buffer, smime-noverify-buffer):
* lisp/gnus/spam-report.el (spam-report-url-ping-mm-url):
* lisp/gnus/spam.el (spam-spamassassin-positive-spam-flag-header)
(spam-spamassassin-spam-status-header, spam-sa-learn-rebuild)
(spam-classifications, spam-check-stat, spam-spamassassin-score):
* lisp/help.el (describe-minor-mode-from-symbol):
* lisp/hippie-exp.el (hippie-expand-ignore-buffers):
* lisp/htmlfontify.el (hfy-optimizations, hfy-face-resolve-face)
(hfy-begin-span):
* lisp/ibuf-ext.el (ibuffer-update-saved-filters-format)
(ibuffer-saved-filters, ibuffer-old-saved-filters-warning)
(ibuffer-filtering-qualifiers, ibuffer-repair-saved-filters)
(eval, ibuffer-unary-operand, file-extension, directory):
* lisp/image-dired.el (image-dired-cmd-pngcrush-options):
* lisp/image-mode.el (image-toggle-display):
* lisp/international/ccl.el (ccl-compile-read-multibyte-character)
(ccl-compile-write-multibyte-character):
* lisp/international/kkc.el (kkc-save-init-file):
* lisp/international/latin1-disp.el (latin1-display):
* lisp/international/ogonek.el (ogonek-name-encoding-alist)
(ogonek-information, ogonek-lookup-encoding)
(ogonek-deprefixify-region):
* lisp/isearch.el (isearch-filter-predicate)
(isearch--momentary-message):
* lisp/jsonrpc.el (jsonrpc-connection-send)
(jsonrpc-process-connection, jsonrpc-shutdown)
(jsonrpc--async-request-1):
* lisp/language/tibet-util.el (tibetan-char-p):
* lisp/mail/feedmail.el (feedmail-queue-use-send-time-for-date)
(feedmail-last-chance-hook, feedmail-before-fcc-hook)
(feedmail-send-it-immediately-wrapper, feedmail-find-eoh):
* lisp/mail/hashcash.el (hashcash-generate-payment)
(hashcash-generate-payment-async, hashcash-insert-payment)
(hashcash-verify-payment):
* lisp/mail/rmail.el (rmail-movemail-variant-in-use)
(rmail-get-attr-value):
* lisp/mail/rmailmm.el (rmail-mime-prefer-html, rmail-mime):
* lisp/mail/rmailsum.el (rmail-summary-show-message):
* lisp/mail/supercite.el (sc-raw-mode-toggle):
* lisp/man.el (Man-start-calling):
* lisp/mh-e/mh-acros.el (mh-do-at-event-location)
(mh-iterate-on-messages-in-region, mh-iterate-on-range):
* lisp/mh-e/mh-alias.el (mh-alias-system-aliases)
(mh-alias-reload, mh-alias-ali)
(mh-alias-canonicalize-suggestion, mh-alias-add-alias-to-file)
(mh-alias-add-alias):
* lisp/mouse.el (mouse-save-then-kill):
* lisp/net/browse-url.el (browse-url-default-macosx-browser):
* lisp/net/eudc.el (eudc-set, eudc-variable-protocol-value)
(eudc-variable-server-value, eudc-update-variable)
(eudc-expand-inline):
* lisp/net/eudcb-bbdb.el (eudc-bbdb-format-record-as-result):
* lisp/net/eudcb-ldap.el (eudc-ldap-get-field-list):
* lisp/net/pop3.el (pop3-list):
* lisp/net/soap-client.el (soap-namespace-put)
(soap-xs-parse-sequence, soap-parse-envelope):
* lisp/net/soap-inspect.el (soap-inspect-xs-complex-type):
* lisp/nxml/rng-xsd.el (rng-xsd-date-to-days):
* lisp/org/ob-C.el (org-babel-prep-session:C)
(org-babel-load-session:C):
* lisp/org/ob-J.el (org-babel-execute:J):
* lisp/org/ob-asymptote.el (org-babel-prep-session:asymptote):
* lisp/org/ob-awk.el (org-babel-execute:awk):
* lisp/org/ob-core.el (org-babel-process-file-name):
* lisp/org/ob-ebnf.el (org-babel-execute:ebnf):
* lisp/org/ob-forth.el (org-babel-execute:forth):
* lisp/org/ob-fortran.el (org-babel-execute:fortran)
(org-babel-prep-session:fortran, org-babel-load-session:fortran):
* lisp/org/ob-groovy.el (org-babel-execute:groovy):
* lisp/org/ob-io.el (org-babel-execute:io):
* lisp/org/ob-js.el (org-babel-execute:js):
* lisp/org/ob-lilypond.el (org-babel-default-header-args:lilypond)
(org-babel-lilypond-compile-post-tangle)
(org-babel-lilypond-display-pdf-post-tangle)
(org-babel-lilypond-tangle)
(org-babel-lilypond-execute-tangled-ly)
(org-babel-lilypond-compile-lilyfile)
(org-babel-lilypond-check-for-compile-error)
(org-babel-lilypond-process-compile-error)
(org-babel-lilypond-mark-error-line)
(org-babel-lilypond-parse-error-line)
(org-babel-lilypond-attempt-to-open-pdf)
(org-babel-lilypond-attempt-to-play-midi)
(org-babel-lilypond-switch-extension)
(org-babel-lilypond-set-header-args):
* lisp/org/ob-lua.el (org-babel-prep-session:lua):
* lisp/org/ob-picolisp.el (org-babel-execute:picolisp):
* lisp/org/ob-processing.el (org-babel-prep-session:processing):
* lisp/org/ob-python.el (org-babel-prep-session:python):
* lisp/org/ob-scheme.el (org-babel-scheme-capture-current-message)
(org-babel-scheme-execute-with-geiser, org-babel-execute:scheme):
* lisp/org/ob-shen.el (org-babel-execute:shen):
* lisp/org/org-agenda.el (org-agenda-entry-types)
(org-agenda-move-date-from-past-immediately-to-today)
(org-agenda-time-grid, org-agenda-sorting-strategy)
(org-agenda-filter-by-category, org-agenda-forward-block):
* lisp/org/org-colview.el (org-columns--overlay-text):
* lisp/org/org-faces.el (org-verbatim, org-cycle-level-faces):
* lisp/org/org-indent.el (org-indent-set-line-properties):
* lisp/org/org-macs.el (org-get-limited-outline-regexp):
* lisp/org/org-mobile.el (org-mobile-files):
* lisp/org/org.el (org-use-fast-todo-selection)
(org-extend-today-until, org-use-property-inheritance)
(org-refresh-effort-properties, org-open-at-point-global)
(org-track-ordered-property-with-tag, org-shiftright):
* lisp/org/ox-html.el (org-html-checkbox-type):
* lisp/org/ox-man.el (org-man-source-highlight)
(org-man-verse-block):
* lisp/org/ox-publish.el (org-publish-sitemap-default):
* lisp/outline.el (outline-head-from-level):
* lisp/progmodes/dcl-mode.el (dcl-back-to-indentation-1)
(dcl-calc-command-indent, dcl-indent-to):
* lisp/progmodes/flymake.el (flymake-make-diagnostic)
(flymake--overlays, flymake-diagnostic-functions)
(flymake-diagnostic-types-alist, flymake--backend-state)
(flymake-is-running, flymake--collect, flymake-mode):
* lisp/progmodes/gdb-mi.el (gdb-threads-list, gdb, gdb-non-stop)
(gdb-buffers, gdb-gud-context-call, gdb-jsonify-buffer):
* lisp/progmodes/grep.el (grep-error-screen-columns):
* lisp/progmodes/gud.el (gud-prev-expr):
* lisp/progmodes/ps-mode.el (ps-mode, ps-mode-target-column)
(ps-run-goto-error):
* lisp/progmodes/python.el (python-eldoc-get-doc)
(python-eldoc-function-timeout-permanent, python-eldoc-function):
* lisp/shadowfile.el (shadow-make-group):
* lisp/speedbar.el (speedbar-obj-do-check):
* lisp/textmodes/flyspell.el (flyspell-auto-correct-previous-hook):
* lisp/textmodes/reftex-cite.el (reftex-bib-or-thebib):
* lisp/textmodes/reftex-index.el (reftex-index-goto-entry)
(reftex-index-kill, reftex-index-undo):
* lisp/textmodes/reftex-parse.el (reftex-context-substring):
* lisp/textmodes/reftex.el (reftex-TeX-master-file):
* lisp/textmodes/rst.el (rst-next-hdr, rst-toc)
(rst-uncomment-region, rst-font-lock-extend-region-internal):
* lisp/thumbs.el (thumbs-mode):
* lisp/vc/ediff-util.el (ediff-restore-diff):
* lisp/vc/pcvs-defs.el (cvs-cvsroot, cvs-force-dir-tag):
* lisp/vc/vc-hg.el (vc-hg--ignore-patterns-valid-p):
* lisp/wid-edit.el (widget-field-value-set, string):
* lisp/x-dnd.el (x-dnd-version-from-flags)
(x-dnd-more-than-3-from-flags): Assorted docfixes.
2019-09-21 00:27:53 +02:00
|
|
|
contained in the invitation. Return nil for calendars without an
|
|
|
|
event entry.
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
ATTENDEE-NAME-OR-EMAIL is a list of strings that will be matched
|
lisp/*.el: Fix typos and other trivial doc fixes
* lisp/allout-widgets.el (allout-widgets-auto-activation)
(allout-current-decorated-p):
* lisp/auth-source.el (auth-source-protocols):
* lisp/autorevert.el (auto-revert-set-timer):
* lisp/battery.el (battery-mode-line-limit):
* lisp/calc/calcalg3.el (math-map-binop):
* lisp/calendar/cal-dst.el (calendar-dst-find-startend):
* lisp/calendar/cal-mayan.el (calendar-mayan-long-count-to-absolute):
* lisp/calendar/calendar.el (calendar-date-echo-text)
(calendar-generate-month, calendar-string-spread)
(calendar-cursor-to-date, calendar-read, calendar-read-date)
(calendar-mark-visible-date, calendar-dayname-on-or-before):
* lisp/calendar/diary-lib.el (diary-ordinal-suffix):
* lisp/cedet/ede/autoconf-edit.el (autoconf-new-program)
(autoconf-find-last-macro, autoconf-parameter-strip):
* lisp/cedet/ede/config.el (ede-target-with-config-build):
* lisp/cedet/ede/linux.el (ede-linux--detect-architecture)
(ede-linux--get-architecture):
* lisp/cedet/semantic/complete.el (semantic-collector-calculate-cache)
(semantic-displayer-abstract, semantic-displayer-point-position):
* lisp/cedet/semantic/format.el (semantic-format-face-alist)
(semantic-format-tag-short-doc):
* lisp/cedet/semantic/fw.el (semantic-find-file-noselect):
* lisp/cedet/semantic/idle.el (semantic-idle-scheduler-work-idle-time)
(semantic-idle-breadcrumbs-display-function)
(semantic-idle-breadcrumbs-format-tag-list-function):
* lisp/cedet/semantic/lex.el (semantic-lex-map-types)
(define-lex, define-lex-block-type-analyzer):
* lisp/cedet/semantic/senator.el (senator-search-default-tag-filter):
* lisp/cedet/semantic/symref.el (semantic-symref-result)
(semantic-symref-hit-to-tag-via-db):
* lisp/cedet/semantic/symref.el (semantic-symref-tool-baseclass):
* lisp/cedet/semantic/tag.el (semantic-tag-new-variable)
(semantic-tag-new-include, semantic-tag-new-package)
(semantic-tag-set-faux, semantic-create-tag-proxy)
(semantic-tag-function-parent)
(semantic-tag-components-with-overlays):
* lisp/cedet/srecode/cpp.el (srecode-cpp-namespaces)
(srecode-semantic-handle-:c, srecode-semantic-apply-tag-to-dict):
* lisp/cedet/srecode/dictionary.el (srecode-create-dictionary)
(srecode-dictionary-add-entries, srecode-dictionary-lookup-name)
(srecode-create-dictionaries-from-tags):
* lisp/cmuscheme.el (scheme-compile-region):
* lisp/color.el (color-lab-to-lch):
* lisp/doc-view.el (doc-view-image-width)
(doc-view-set-up-single-converter):
* lisp/dynamic-setting.el (font-setting-change-default-font)
(dynamic-setting-handle-config-changed-event):
* lisp/elec-pair.el (electric-pair-text-pairs)
(electric-pair-skip-whitespace-function)
(electric-pair-string-bound-function):
* lisp/emacs-lisp/avl-tree.el (avl-tree--del-balance)
(avl-tree-member, avl-tree-mapcar, avl-tree-iter):
* lisp/emacs-lisp/bytecomp.el (byte-compile-generate-call-tree):
* lisp/emacs-lisp/checkdoc.el (checkdoc-autofix-flag)
(checkdoc-spellcheck-documentation-flag, checkdoc-ispell)
(checkdoc-ispell-current-buffer, checkdoc-ispell-interactive)
(checkdoc-ispell-message-interactive)
(checkdoc-ispell-message-text, checkdoc-ispell-start)
(checkdoc-ispell-continue, checkdoc-ispell-comments)
(checkdoc-ispell-defun):
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method):
* lisp/emacs-lisp/eieio-custom.el (eieio-read-customization-group):
* lisp/emacs-lisp/lisp.el (forward-sexp, up-list):
* lisp/emacs-lisp/package-x.el (package--archive-contents-from-file):
* lisp/emacs-lisp/package.el (package-desc)
(package--make-autoloads-and-stuff, package-hidden-regexps):
* lisp/emacs-lisp/tcover-ses.el (ses-exercise-startup):
* lisp/emacs-lisp/testcover.el (testcover-nohits)
(testcover-1value):
* lisp/epg.el (epg-receive-keys, epg-start-edit-key):
* lisp/erc/erc-backend.el (erc-server-processing-p)
(erc-split-line-length, erc-server-coding-system)
(erc-server-send, erc-message):
* lisp/erc/erc-button.el (erc-button-face, erc-button-alist)
(erc-browse-emacswiki):
* lisp/erc/erc-ezbounce.el (erc-ezbounce, erc-ezb-get-login):
* lisp/erc/erc-fill.el (erc-fill-variable-maximum-indentation):
* lisp/erc/erc-log.el (erc-current-logfile):
* lisp/erc/erc-match.el (erc-log-match-format)
(erc-text-matched-hook):
* lisp/erc/erc-netsplit.el (erc-netsplit, erc-netsplit-debug):
* lisp/erc/erc-networks.el (erc-server-alist)
(erc-networks-alist, erc-current-network):
* lisp/erc/erc-ring.el (erc-input-ring-index):
* lisp/erc/erc-speedbar.el (erc-speedbar)
(erc-speedbar-update-channel):
* lisp/erc/erc-stamp.el (erc-timestamp-only-if-changed-flag):
* lisp/erc/erc-track.el (erc-track-position-in-mode-line)
(erc-track-remove-from-mode-line, erc-modified-channels-update)
(erc-track-last-non-erc-buffer, erc-track-sort-by-importance)
(erc-track-get-active-buffer):
* lisp/erc/erc.el (erc-get-channel-user-list)
(erc-echo-notice-hook, erc-echo-notice-always-hook)
(erc-wash-quit-reason, erc-format-@nick):
* lisp/ffap.el (ffap-latex-mode):
* lisp/files.el (abort-if-file-too-large)
(dir-locals--get-sort-score, buffer-stale--default-function):
* lisp/filesets.el (filesets-tree-max-level, filesets-data)
(filesets-update-pre010505):
* lisp/gnus/gnus-agent.el (gnus-agent-flush-cache):
* lisp/gnus/gnus-art.el (gnus-article-encrypt-protocol)
(gnus-button-prefer-mid-or-mail):
* lisp/gnus/gnus-cus.el (gnus-group-parameters):
* lisp/gnus/gnus-demon.el (gnus-demon-handlers)
(gnus-demon-run-callback):
* lisp/gnus/gnus-dired.el (gnus-dired-print):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-buffer):
* lisp/gnus/gnus-range.el (gnus-range-normalize):
* lisp/gnus/gnus-spec.el (gnus-pad-form):
* lisp/gnus/gnus-srvr.el (gnus-server-agent, gnus-server-cloud)
(gnus-server-opened, gnus-server-closed, gnus-server-denied)
(gnus-server-offline):
* lisp/gnus/gnus-sum.el (gnus-refer-thread-use-nnir)
(gnus-refer-thread-limit-to-thread)
(gnus-summary-limit-include-thread, gnus-summary-refer-thread)
(gnus-summary-find-matching):
* lisp/gnus/gnus-util.el (gnus-rescale-image):
* lisp/gnus/gnus.el (gnus-summary-line-format, gnus-no-server):
* lisp/gnus/mail-source.el (mail-source-incoming-file-prefix):
* lisp/gnus/message.el (message-cite-reply-position)
(message-cite-style-outlook, message-cite-style-thunderbird)
(message-cite-style-gmail, message--send-mail-maybe-partially):
* lisp/gnus/mm-extern.el (mm-inline-external-body):
* lisp/gnus/mm-partial.el (mm-inline-partial):
* lisp/gnus/mml-sec.el (mml-secure-message-sign)
(mml-secure-message-sign-encrypt, mml-secure-message-encrypt):
* lisp/gnus/mml2015.el (mml2015-epg-key-image)
(mml2015-epg-key-image-to-string):
* lisp/gnus/nndiary.el (nndiary-reminders, nndiary-get-new-mail):
* lisp/gnus/nnheader.el (nnheader-directory-files-is-safe):
* lisp/gnus/nnir.el (nnir-search-history)
(nnir-imap-search-other, nnir-artlist-length)
(nnir-artlist-article, nnir-artitem-group, nnir-artitem-number)
(nnir-artitem-rsv, nnir-article-group, nnir-article-number)
(nnir-article-rsv, nnir-article-ids, nnir-categorize)
(nnir-retrieve-headers-override-function)
(nnir-imap-default-search-key, nnir-hyrex-additional-switches)
(gnus-group-make-nnir-group, nnir-run-namazu, nnir-read-parms)
(nnir-read-parm, nnir-read-server-parm, nnir-search-thread):
* lisp/gnus/nnmairix.el (nnmairix-default-group)
(nnmairix-propagate-marks):
* lisp/gnus/smime.el (smime-keys, smime-crl-check)
(smime-verify-buffer, smime-noverify-buffer):
* lisp/gnus/spam-report.el (spam-report-url-ping-mm-url):
* lisp/gnus/spam.el (spam-spamassassin-positive-spam-flag-header)
(spam-spamassassin-spam-status-header, spam-sa-learn-rebuild)
(spam-classifications, spam-check-stat, spam-spamassassin-score):
* lisp/help.el (describe-minor-mode-from-symbol):
* lisp/hippie-exp.el (hippie-expand-ignore-buffers):
* lisp/htmlfontify.el (hfy-optimizations, hfy-face-resolve-face)
(hfy-begin-span):
* lisp/ibuf-ext.el (ibuffer-update-saved-filters-format)
(ibuffer-saved-filters, ibuffer-old-saved-filters-warning)
(ibuffer-filtering-qualifiers, ibuffer-repair-saved-filters)
(eval, ibuffer-unary-operand, file-extension, directory):
* lisp/image-dired.el (image-dired-cmd-pngcrush-options):
* lisp/image-mode.el (image-toggle-display):
* lisp/international/ccl.el (ccl-compile-read-multibyte-character)
(ccl-compile-write-multibyte-character):
* lisp/international/kkc.el (kkc-save-init-file):
* lisp/international/latin1-disp.el (latin1-display):
* lisp/international/ogonek.el (ogonek-name-encoding-alist)
(ogonek-information, ogonek-lookup-encoding)
(ogonek-deprefixify-region):
* lisp/isearch.el (isearch-filter-predicate)
(isearch--momentary-message):
* lisp/jsonrpc.el (jsonrpc-connection-send)
(jsonrpc-process-connection, jsonrpc-shutdown)
(jsonrpc--async-request-1):
* lisp/language/tibet-util.el (tibetan-char-p):
* lisp/mail/feedmail.el (feedmail-queue-use-send-time-for-date)
(feedmail-last-chance-hook, feedmail-before-fcc-hook)
(feedmail-send-it-immediately-wrapper, feedmail-find-eoh):
* lisp/mail/hashcash.el (hashcash-generate-payment)
(hashcash-generate-payment-async, hashcash-insert-payment)
(hashcash-verify-payment):
* lisp/mail/rmail.el (rmail-movemail-variant-in-use)
(rmail-get-attr-value):
* lisp/mail/rmailmm.el (rmail-mime-prefer-html, rmail-mime):
* lisp/mail/rmailsum.el (rmail-summary-show-message):
* lisp/mail/supercite.el (sc-raw-mode-toggle):
* lisp/man.el (Man-start-calling):
* lisp/mh-e/mh-acros.el (mh-do-at-event-location)
(mh-iterate-on-messages-in-region, mh-iterate-on-range):
* lisp/mh-e/mh-alias.el (mh-alias-system-aliases)
(mh-alias-reload, mh-alias-ali)
(mh-alias-canonicalize-suggestion, mh-alias-add-alias-to-file)
(mh-alias-add-alias):
* lisp/mouse.el (mouse-save-then-kill):
* lisp/net/browse-url.el (browse-url-default-macosx-browser):
* lisp/net/eudc.el (eudc-set, eudc-variable-protocol-value)
(eudc-variable-server-value, eudc-update-variable)
(eudc-expand-inline):
* lisp/net/eudcb-bbdb.el (eudc-bbdb-format-record-as-result):
* lisp/net/eudcb-ldap.el (eudc-ldap-get-field-list):
* lisp/net/pop3.el (pop3-list):
* lisp/net/soap-client.el (soap-namespace-put)
(soap-xs-parse-sequence, soap-parse-envelope):
* lisp/net/soap-inspect.el (soap-inspect-xs-complex-type):
* lisp/nxml/rng-xsd.el (rng-xsd-date-to-days):
* lisp/org/ob-C.el (org-babel-prep-session:C)
(org-babel-load-session:C):
* lisp/org/ob-J.el (org-babel-execute:J):
* lisp/org/ob-asymptote.el (org-babel-prep-session:asymptote):
* lisp/org/ob-awk.el (org-babel-execute:awk):
* lisp/org/ob-core.el (org-babel-process-file-name):
* lisp/org/ob-ebnf.el (org-babel-execute:ebnf):
* lisp/org/ob-forth.el (org-babel-execute:forth):
* lisp/org/ob-fortran.el (org-babel-execute:fortran)
(org-babel-prep-session:fortran, org-babel-load-session:fortran):
* lisp/org/ob-groovy.el (org-babel-execute:groovy):
* lisp/org/ob-io.el (org-babel-execute:io):
* lisp/org/ob-js.el (org-babel-execute:js):
* lisp/org/ob-lilypond.el (org-babel-default-header-args:lilypond)
(org-babel-lilypond-compile-post-tangle)
(org-babel-lilypond-display-pdf-post-tangle)
(org-babel-lilypond-tangle)
(org-babel-lilypond-execute-tangled-ly)
(org-babel-lilypond-compile-lilyfile)
(org-babel-lilypond-check-for-compile-error)
(org-babel-lilypond-process-compile-error)
(org-babel-lilypond-mark-error-line)
(org-babel-lilypond-parse-error-line)
(org-babel-lilypond-attempt-to-open-pdf)
(org-babel-lilypond-attempt-to-play-midi)
(org-babel-lilypond-switch-extension)
(org-babel-lilypond-set-header-args):
* lisp/org/ob-lua.el (org-babel-prep-session:lua):
* lisp/org/ob-picolisp.el (org-babel-execute:picolisp):
* lisp/org/ob-processing.el (org-babel-prep-session:processing):
* lisp/org/ob-python.el (org-babel-prep-session:python):
* lisp/org/ob-scheme.el (org-babel-scheme-capture-current-message)
(org-babel-scheme-execute-with-geiser, org-babel-execute:scheme):
* lisp/org/ob-shen.el (org-babel-execute:shen):
* lisp/org/org-agenda.el (org-agenda-entry-types)
(org-agenda-move-date-from-past-immediately-to-today)
(org-agenda-time-grid, org-agenda-sorting-strategy)
(org-agenda-filter-by-category, org-agenda-forward-block):
* lisp/org/org-colview.el (org-columns--overlay-text):
* lisp/org/org-faces.el (org-verbatim, org-cycle-level-faces):
* lisp/org/org-indent.el (org-indent-set-line-properties):
* lisp/org/org-macs.el (org-get-limited-outline-regexp):
* lisp/org/org-mobile.el (org-mobile-files):
* lisp/org/org.el (org-use-fast-todo-selection)
(org-extend-today-until, org-use-property-inheritance)
(org-refresh-effort-properties, org-open-at-point-global)
(org-track-ordered-property-with-tag, org-shiftright):
* lisp/org/ox-html.el (org-html-checkbox-type):
* lisp/org/ox-man.el (org-man-source-highlight)
(org-man-verse-block):
* lisp/org/ox-publish.el (org-publish-sitemap-default):
* lisp/outline.el (outline-head-from-level):
* lisp/progmodes/dcl-mode.el (dcl-back-to-indentation-1)
(dcl-calc-command-indent, dcl-indent-to):
* lisp/progmodes/flymake.el (flymake-make-diagnostic)
(flymake--overlays, flymake-diagnostic-functions)
(flymake-diagnostic-types-alist, flymake--backend-state)
(flymake-is-running, flymake--collect, flymake-mode):
* lisp/progmodes/gdb-mi.el (gdb-threads-list, gdb, gdb-non-stop)
(gdb-buffers, gdb-gud-context-call, gdb-jsonify-buffer):
* lisp/progmodes/grep.el (grep-error-screen-columns):
* lisp/progmodes/gud.el (gud-prev-expr):
* lisp/progmodes/ps-mode.el (ps-mode, ps-mode-target-column)
(ps-run-goto-error):
* lisp/progmodes/python.el (python-eldoc-get-doc)
(python-eldoc-function-timeout-permanent, python-eldoc-function):
* lisp/shadowfile.el (shadow-make-group):
* lisp/speedbar.el (speedbar-obj-do-check):
* lisp/textmodes/flyspell.el (flyspell-auto-correct-previous-hook):
* lisp/textmodes/reftex-cite.el (reftex-bib-or-thebib):
* lisp/textmodes/reftex-index.el (reftex-index-goto-entry)
(reftex-index-kill, reftex-index-undo):
* lisp/textmodes/reftex-parse.el (reftex-context-substring):
* lisp/textmodes/reftex.el (reftex-TeX-master-file):
* lisp/textmodes/rst.el (rst-next-hdr, rst-toc)
(rst-uncomment-region, rst-font-lock-extend-region-internal):
* lisp/thumbs.el (thumbs-mode):
* lisp/vc/ediff-util.el (ediff-restore-diff):
* lisp/vc/pcvs-defs.el (cvs-cvsroot, cvs-force-dir-tag):
* lisp/vc/vc-hg.el (vc-hg--ignore-patterns-valid-p):
* lisp/wid-edit.el (widget-field-value-set, string):
* lisp/x-dnd.el (x-dnd-version-from-flags)
(x-dnd-more-than-3-from-flags): Assorted docfixes.
2019-09-21 00:27:53 +02:00
|
|
|
against the event's attendee names and emails. Invitation rsvp
|
2013-08-01 22:58:40 +00:00
|
|
|
status will be retrieved from the first matching attendee record."
|
|
|
|
(let ((ical (with-current-buffer (icalendar--get-unfolded-buffer (get-buffer buf))
|
|
|
|
(goto-char (point-min))
|
|
|
|
(icalendar--read-element nil nil))))
|
|
|
|
|
|
|
|
(when ical
|
|
|
|
(gnus-icalendar-event-from-ical ical attendee-name-or-email))))
|
|
|
|
|
|
|
|
;;;
|
|
|
|
;;; gnus-icalendar-event-reply
|
|
|
|
;;;
|
|
|
|
|
|
|
|
(defun gnus-icalendar-event--build-reply-event-body (ical-request status identities)
|
|
|
|
(let ((summary-status (capitalize (symbol-name status)))
|
|
|
|
(attendee-status (upcase (symbol-name status)))
|
|
|
|
reply-event-lines)
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((update-summary
|
|
|
|
(line)
|
|
|
|
(if (string-match "^[^:]+:" line)
|
|
|
|
(replace-match (format "\\&%s: " summary-status) t nil line)
|
|
|
|
line))
|
|
|
|
(update-dtstamp ()
|
|
|
|
(format-time-string "DTSTAMP:%Y%m%dT%H%M%SZ" nil t))
|
|
|
|
(attendee-matches-identity
|
|
|
|
(line)
|
|
|
|
(gnus-icalendar-find-if (lambda (name) (string-match-p name line))
|
|
|
|
identities))
|
|
|
|
(update-attendee-status
|
|
|
|
(line)
|
|
|
|
(when (and (attendee-matches-identity line)
|
|
|
|
(string-match "\\(PARTSTAT=\\)[^;]+" line))
|
|
|
|
(replace-match (format "\\1%s" attendee-status) t nil line)))
|
|
|
|
(process-event-line
|
|
|
|
(line)
|
|
|
|
(when (string-match "^\\([^;:]+\\)" line)
|
|
|
|
(let* ((key (match-string 0 line))
|
|
|
|
;; NOTE: not all of the below fields are mandatory,
|
|
|
|
;; but they are often present in other clients'
|
|
|
|
;; replies. Can be helpful for debugging, too.
|
|
|
|
(new-line
|
|
|
|
(cond
|
|
|
|
((string= key "ATTENDEE") (update-attendee-status line))
|
|
|
|
((string= key "SUMMARY") (update-summary line))
|
|
|
|
((string= key "DTSTAMP") (update-dtstamp))
|
|
|
|
((member key '("ORGANIZER" "DTSTART" "DTEND"
|
|
|
|
"LOCATION" "DURATION" "SEQUENCE"
|
2019-03-29 08:46:29 -04:00
|
|
|
"RECURRENCE-ID" "UID"))
|
|
|
|
line)
|
2016-02-13 16:40:17 +11:00
|
|
|
(t nil))))
|
|
|
|
(when new-line
|
|
|
|
(push new-line reply-event-lines))))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(mapc #'process-event-line (split-string ical-request "\n"))
|
|
|
|
|
|
|
|
(unless (gnus-icalendar-find-if (lambda (x) (string-match "^ATTENDEE" x))
|
2016-02-13 16:40:17 +11:00
|
|
|
reply-event-lines)
|
2020-08-05 18:01:27 +02:00
|
|
|
(lwarn 'gnus-icalendar :warning
|
|
|
|
"Could not find an event attendee matching given identity"))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(mapconcat #'identity `("BEGIN:VEVENT"
|
|
|
|
,@(nreverse reply-event-lines)
|
|
|
|
"END:VEVENT")
|
|
|
|
"\n"))))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-event-reply-from-buffer (buf status identities)
|
|
|
|
"Build a calendar event reply for request contained in BUF.
|
|
|
|
The reply will have STATUS (`accepted', `tentative' or `declined').
|
|
|
|
The reply will be composed for attendees matching any entry
|
|
|
|
on the IDENTITIES list."
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((extract-block
|
|
|
|
(blockname)
|
|
|
|
(save-excursion
|
|
|
|
(let ((block-start-re (format "^BEGIN:%s" blockname))
|
|
|
|
(block-end-re (format "^END:%s" blockname))
|
|
|
|
start)
|
|
|
|
(when (re-search-forward block-start-re nil t)
|
|
|
|
(setq start (line-beginning-position))
|
|
|
|
(re-search-forward block-end-re)
|
|
|
|
(buffer-substring-no-properties start (line-end-position)))))))
|
2013-08-01 22:58:40 +00:00
|
|
|
(let (zone event)
|
|
|
|
(with-current-buffer (icalendar--get-unfolded-buffer (get-buffer buf))
|
|
|
|
(goto-char (point-min))
|
|
|
|
(setq zone (extract-block "VTIMEZONE")
|
|
|
|
event (extract-block "VEVENT")))
|
|
|
|
|
|
|
|
(when event
|
|
|
|
(let ((contents (list "BEGIN:VCALENDAR"
|
|
|
|
"METHOD:REPLY"
|
|
|
|
"PRODID:Gnus"
|
|
|
|
"VERSION:2.0"
|
|
|
|
zone
|
|
|
|
(gnus-icalendar-event--build-reply-event-body event status identities)
|
|
|
|
"END:VCALENDAR")))
|
|
|
|
|
|
|
|
(mapconcat #'identity (delq nil contents) "\n"))))))
|
|
|
|
|
|
|
|
;;;
|
|
|
|
;;; gnus-icalendar-org
|
2019-03-29 08:46:29 -04:00
|
|
|
;;
|
|
|
|
;; TODO: this is an optional feature, and it's only available with org-mode
|
|
|
|
;; 7+, so will need to properly handle emacsen with no/outdated org-mode
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(require 'org)
|
|
|
|
(require 'org-capture)
|
|
|
|
|
|
|
|
(defgroup gnus-icalendar-org nil
|
|
|
|
"Settings for Calendar Event gnus/org integration."
|
2013-12-27 18:16:05 -08:00
|
|
|
:version "24.4"
|
2013-08-01 22:58:40 +00:00
|
|
|
:group 'gnus-icalendar
|
|
|
|
:prefix "gnus-icalendar-org-")
|
|
|
|
|
|
|
|
(defcustom gnus-icalendar-org-capture-file nil
|
|
|
|
"Target Org file for storing captured calendar events."
|
2019-03-29 08:46:29 -04:00
|
|
|
:type '(choice (const nil) file))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defcustom gnus-icalendar-org-capture-headline nil
|
|
|
|
"Target outline in `gnus-icalendar-org-capture-file' for storing captured events."
|
2019-03-29 08:46:29 -04:00
|
|
|
:type '(repeat string))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defcustom gnus-icalendar-org-template-name "used by gnus-icalendar-org"
|
|
|
|
"Org-mode template name."
|
2019-03-29 08:46:29 -04:00
|
|
|
:type '(string))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defcustom gnus-icalendar-org-template-key "#"
|
|
|
|
"Org-mode template hotkey."
|
2019-03-29 08:46:29 -04:00
|
|
|
:type '(string))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defvar gnus-icalendar-org-enabled-p nil)
|
|
|
|
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:org-repeat ((event gnus-icalendar-event))
|
2013-08-01 22:58:40 +00:00
|
|
|
"Return `org-mode' timestamp repeater string for recurring EVENT.
|
|
|
|
Return nil for non-recurring EVENT."
|
|
|
|
(when (gnus-icalendar-event:recurring-p event)
|
|
|
|
(let* ((freq-map '(("HOURLY" . "h")
|
|
|
|
("DAILY" . "d")
|
|
|
|
("WEEKLY" . "w")
|
|
|
|
("MONTHLY" . "m")
|
|
|
|
("YEARLY" . "y")))
|
|
|
|
(org-freq (cdr (assoc (gnus-icalendar-event:recurring-freq event) freq-map))))
|
|
|
|
|
|
|
|
(when org-freq
|
|
|
|
(format "+%s%s" (gnus-icalendar-event:recurring-interval event) org-freq)))))
|
|
|
|
|
2020-08-22 15:39:17 +02:00
|
|
|
(defun gnus-icalendar--find-day (start-date end-date day)
|
|
|
|
(let ((time-1-day 86400))
|
|
|
|
(if (= (decoded-time-weekday (decode-time start-date))
|
|
|
|
day)
|
|
|
|
(list start-date end-date)
|
|
|
|
(gnus-icalendar--find-day (time-add start-date time-1-day)
|
|
|
|
(time-add end-date time-1-day)
|
|
|
|
day))))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-event--org-timestamp (start end org-repeat)
|
|
|
|
(let* ((start-date (format-time-string "%Y-%m-%d" start))
|
2013-11-12 22:16:09 +00:00
|
|
|
(start-time (format-time-string "%H:%M" start))
|
2013-11-21 22:55:59 +00:00
|
|
|
(start-at-midnight (string= start-time "00:00"))
|
2016-02-26 16:06:43 +10:30
|
|
|
(end-date (format-time-string "%Y-%m-%d" end))
|
2013-11-12 22:16:09 +00:00
|
|
|
(end-time (format-time-string "%H:%M" end))
|
2013-11-21 22:55:59 +00:00
|
|
|
(end-at-midnight (string= end-time "00:00"))
|
2016-02-23 21:17:41 +11:00
|
|
|
(start-end-date-diff
|
2020-08-22 15:39:17 +02:00
|
|
|
(time-to-number-of-days
|
|
|
|
(time-subtract (org-time-string-to-time end-date)
|
|
|
|
(org-time-string-to-time start-date))))
|
2013-11-21 22:55:59 +00:00
|
|
|
(repeat (if org-repeat (concat " " org-repeat) ""))
|
Avoid some double-rounding of Lisp timestamps
Also, simplify some time-related Lisp timestamp code
while we’re in the neighborhood.
* lisp/battery.el (battery-linux-proc-acpi)
(battery-linux-sysfs, battery-upower, battery-bsd-apm):
* lisp/calendar/timeclock.el (timeclock-seconds-to-string)
(timeclock-log, timeclock-last-period)
(timeclock-entry-length, timeclock-entry-list-span)
(timeclock-find-discrep, timeclock-generate-report):
* lisp/cedet/ede/detect.el (ede-detect-qtest):
* lisp/completion.el (cmpl-hours-since-origin):
* lisp/ecomplete.el (ecomplete-decay-1):
* lisp/emacs-lisp/ert.el (ert--results-update-stats-display)
(ert--results-update-stats-display-maybe):
* lisp/emacs-lisp/timer-list.el (list-timers):
* lisp/emacs-lisp/timer.el (timer-until)
(timer-event-handler):
* lisp/erc/erc-backend.el (erc-server-send-ping)
(erc-server-send-queue, erc-handle-parsed-server-response)
(erc-handle-unknown-server-response):
* lisp/erc/erc-track.el (erc-buffer-visible):
* lisp/erc/erc.el (erc-lurker-cleanup, erc-lurker-p)
(erc-cmd-PING, erc-send-current-line):
* lisp/eshell/em-pred.el (eshell-pred-file-time):
* lisp/eshell/em-unix.el (eshell-show-elapsed-time):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event:org-timestamp):
* lisp/gnus/gnus-int.el (gnus-backend-trace):
* lisp/gnus/gnus-sum.el (gnus-user-date):
* lisp/gnus/mail-source.el (mail-source-delete-crash-box):
* lisp/gnus/nnmaildir.el (nnmaildir--scan):
* lisp/ibuf-ext.el (ibuffer-mark-old-buffers):
* lisp/gnus/nnmaildir.el (nnmaildir--scan):
* lisp/mouse.el (mouse--down-1-maybe-follows-link)
(mouse--click-1-maybe-follows-link):
* lisp/mpc.el (mpc--faster-toggle):
* lisp/net/rcirc.el (rcirc-handler-ctcp-KEEPALIVE)
(rcirc-sentinel):
* lisp/net/tramp-cache.el (tramp-get-file-property):
* lisp/net/tramp-sh.el (tramp-sh-handle-file-newer-than-file-p)
(tramp-maybe-open-connection):
* lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection):
* lisp/org/org-clock.el (org-clock-resolve):
(org-resolve-clocks, org-clock-in, org-clock-out, org-clock-sum):
* lisp/org/org-timer.el (org-timer-start)
(org-timer-pause-or-continue, org-timer-seconds):
* lisp/org/org.el (org-evaluate-time-range):
* lisp/org/ox-publish.el (org-publish-cache-ctime-of-src):
* lisp/pixel-scroll.el (pixel-scroll-in-rush-p):
* lisp/play/hanoi.el (hanoi-move-ring):
* lisp/proced.el (proced-format-time):
* lisp/progmodes/cpp.el (cpp-progress-message):
* lisp/progmodes/flymake.el (flymake--handle-report):
* lisp/progmodes/js.el (js--wait-for-matching-output):
* lisp/subr.el (progress-reporter-do-update):
* lisp/term/xterm.el (xterm--read-event-for-query):
* lisp/time.el (display-time-update, emacs-uptime):
* lisp/tooltip.el (tooltip-delay):
* lisp/url/url-cookie.el (url-cookie-parse-file-netscape):
* lisp/url/url-queue.el (url-queue-prune-old-entries):
* lisp/url/url.el (url-retrieve-synchronously):
* lisp/xt-mouse.el (xterm-mouse-event):
Avoid double-rounding of time-related values. Simplify.
* lisp/calendar/icalendar.el (icalendar--decode-isodatetime):
When hoping for the best (unlikely), use a better decoded time.
(icalendar--convert-sexp-to-ical): Avoid unnecessary encode-time.
* lisp/calendar/timeclock.el (timeclock-when-to-leave):
* lisp/cedet/ede/detect.el (ede-detect-qtest):
* lisp/desktop.el (desktop-create-buffer):
* lisp/emacs-lisp/benchmark.el (benchmark-elapse):
* lisp/gnus/gnus-art.el (article-lapsed-string):
* lisp/gnus/gnus-group.el (gnus-group-timestamp-delta):
* lisp/gnus/nnmail.el (nnmail-expired-article-p):
* lisp/gnus/nnmaildir.el (nnmaildir-request-expire-articles):
* lisp/nxml/rng-maint.el (rng-time-function):
* lisp/org/org-clock.el (org-clock-get-clocked-time)
(org-clock-resolve, org-resolve-clocks, org-resolve-clocks-if-idle):
* lisp/org/org-habit.el (org-habit-insert-consistency-graphs):
* lisp/progmodes/vhdl-mode.el (vhdl-update-progress-info)
(vhdl-fix-case-region-1):
Use time-since instead of open-coding most of it.
* lisp/erc/erc-dcc.el (erc-dcc-get-sentinel):
* lisp/erc/erc.el (erc-string-to-emacs-time, erc-time-gt):
Now obsolete. All uses changed.
(erc-time-diff): Accept all Lisp time values.
All uses changed.
* lisp/gnus/gnus-demon.el (gnus-demon-idle-since):
* lisp/gnus/gnus-score.el (gnus-score-headers):
* lisp/gnus/nneething.el (nneething-make-head):
* lisp/gnus/nnheader.el (nnheader-message-maybe):
* lisp/gnus/nnimap.el (nnimap-keepalive):
* lisp/image.el (image-animate-timeout):
* lisp/mail/feedmail.el (feedmail-rfc822-date):
* lisp/net/imap.el (imap-wait-for-tag):
* lisp/net/newst-backend.el (newsticker--image-get):
* lisp/net/rcirc.el (rcirc-handler-317, rcirc-handler-333):
* lisp/obsolete/xesam.el (xesam-refresh-entry):
* lisp/org/org-agenda.el (org-agenda-show-clocking-issues)
(org-agenda-check-clock-gap, org-agenda-to-appt):
* lisp/org/org-capture.el (org-capture-set-target-location):
* lisp/org/org-clock.el (org-clock-resolve-clock)
(org-clocktable-steps):
* lisp/org/org-colview.el (org-columns-edit-value)
(org-columns, org-agenda-columns):
* lisp/org/org-duration.el (org-duration-from-minutes):
* lisp/org/org-element.el (org-element-cache-sync-duration)
(org-element-cache-sync-break)
(org-element--cache-interrupt-p, org-element--cache-sync):
* lisp/org/org-habit.el (org-habit-get-faces)
* lisp/org/org-indent.el (org-indent-add-properties):
* lisp/org/org-table.el (org-table-sum):
* lisp/org/org-timer.el (org-timer-show-remaining-time)
(org-timer-set-timer):
* lisp/org/org.el (org-babel-load-file, org-today)
(org-auto-repeat-maybe, org-2ft, org-time-stamp)
(org-read-date-analyze, org-time-stamp-to-now)
(org-small-year-to-year, org-goto-calendar):
* lisp/org/ox.el (org-export-insert-default-template):
* lisp/ses.el (ses--time-check):
* lisp/type-break.el (type-break-time-warning)
(type-break-statistics, type-break-demo-boring):
* lisp/url/url-cache.el (url-cache-expired)
(url-cache-prune-cache):
* lisp/vc/vc-git.el (vc-git-stash-snapshot):
* lisp/erc/erc-match.el (erc-log-matches-come-back):
Simplify.
2019-02-22 18:32:31 -08:00
|
|
|
(time-1-day 86400))
|
2013-11-21 22:55:59 +00:00
|
|
|
|
|
|
|
;; NOTE: special care is needed with appointments ending at midnight
|
|
|
|
;; (typically all-day events): the end time has to be changed to 23:59 to
|
|
|
|
;; prevent org agenda showing the event on one additional day
|
|
|
|
(cond
|
|
|
|
;; start/end midnight
|
|
|
|
;; A 0:0 - A+1 0:0 -> A
|
|
|
|
;; A 0:0 - A+n 0:0 -> A - A+n-1
|
|
|
|
((and start-at-midnight end-at-midnight) (if (> start-end-date-diff 1)
|
2016-02-26 16:06:43 +10:30
|
|
|
(let ((end-ts (format-time-string "%Y-%m-%d" (time-subtract end time-1-day))))
|
2013-11-21 22:55:59 +00:00
|
|
|
(format "<%s>--<%s>" start-date end-ts))
|
|
|
|
(format "<%s%s>" start-date repeat)))
|
|
|
|
;; end midnight
|
|
|
|
;; A .:. - A+1 0:0 -> A .:.-23:59
|
|
|
|
;; A .:. - A+n 0:0 -> A .:. - A_n-1
|
|
|
|
(end-at-midnight (if (= start-end-date-diff 1)
|
|
|
|
(format "<%s %s-23:59%s>" start-date start-time repeat)
|
2016-02-26 16:06:43 +10:30
|
|
|
(let ((end-ts (format-time-string "%Y-%m-%d" (time-subtract end time-1-day))))
|
2013-11-21 22:55:59 +00:00
|
|
|
(format "<%s %s>--<%s>" start-date start-time end-ts))))
|
|
|
|
;; start midnight
|
|
|
|
;; A 0:0 - A .:. -> A 0:0-.:. (default 1)
|
|
|
|
;; A 0:0 - A+n .:. -> A - A+n .:.
|
|
|
|
((and start-at-midnight
|
gnus: replace cl with cl-lib
* lisp/gnus/gnus-agent.el, lisp/gnus/gnus-art.el:
* lisp/gnus/gnus-async.el, lisp/gnus/gnus-cache.el:
* lisp/gnus/gnus-demon.el, lisp/gnus/gnus-group.el:
* lisp/gnus/gnus-icalendar.el, lisp/gnus/gnus-logic.el:
* lisp/gnus/gnus-msg.el, lisp/gnus/gnus-picon.el:
* lisp/gnus/gnus-registry.el, lisp/gnus/gnus-salt.el:
* lisp/gnus/gnus-score.el, lisp/gnus/gnus-spec.el:
* lisp/gnus/gnus-srvr.el, lisp/gnus/gnus-start.el:
* lisp/gnus/gnus-sum.el, lisp/gnus/gnus-topic.el:
* lisp/gnus/gnus-util.el, lisp/gnus/gnus-uu.el, lisp/gnus/gnus-win.el:
* lisp/gnus/mail-source.el, lisp/gnus/mm-decode.el:
* lisp/gnus/mm-encode.el, lisp/gnus/mm-url.el, lisp/gnus/mm-view.el:
* lisp/gnus/mml-smime.el, lisp/gnus/mml.el, lisp/gnus/mml2015.el:
* lisp/gnus/nnbabyl.el, lisp/gnus/nndoc.el, lisp/gnus/nneething.el:
* lisp/gnus/nnheader.el, lisp/gnus/nnimap.el, lisp/gnus/nnmail.el:
* lisp/gnus/nnmaildir.el, lisp/gnus/nnoo.el, lisp/gnus/nnrss.el:
* lisp/gnus/nnspool.el, lisp/gnus/nntp.el, lisp/gnus/nnvirtual.el:
* lisp/gnus/nnweb.el, lisp/gnus/spam.el: Replace cl with cl-lib.
* lisp/gnus/canlock.el, lisp/gnus/gnus-bcklg.el:
* lisp/gnus/gnus-cite.el, lisp/gnus/gnus-cloud.el:
* lisp/gnus/gnus-draft.el, lisp/gnus/gnus-dup.el:
* lisp/gnus/gnus-fun.el, lisp/gnus/gnus-html.el:
* lisp/gnus/gnus-int.el, lisp/gnus/gnus-kill.el, lisp/gnus/gnus-ml.el:
* lisp/gnus/gnus-mlspl.el, lisp/gnus/gnus-range.el:
* lisp/gnus/gnus-undo.el, lisp/gnus/gnus-vm.el:
* lisp/gnus/mm-partial.el, lisp/gnus/mm-uu.el, lisp/gnus/mml1991.el:
* lisp/gnus/nnagent.el, lisp/gnus/nndiary.el, lisp/gnus/nndir.el:
* lisp/gnus/nndraft.el, lisp/gnus/nnfolder.el, lisp/gnus/nngateway.el:
* lisp/gnus/nnmairix.el, lisp/gnus/nnmbox.el, lisp/gnus/nnmh.el:
* lisp/gnus/nnml.el, lisp/gnus/score-mode.el, lisp/gnus/smiley.el:
No need for cl.
2018-03-23 16:13:09 -04:00
|
|
|
(cl-plusp start-end-date-diff)) (format "<%s>--<%s %s>" start-date end-date end-time))
|
2013-11-21 22:55:59 +00:00
|
|
|
;; default
|
|
|
|
;; A .:. - A .:. -> A .:.-.:.
|
|
|
|
;; A .:. - B .:.
|
|
|
|
((zerop start-end-date-diff) (format "<%s %s-%s%s>" start-date start-time end-time repeat))
|
2020-08-22 15:39:17 +02:00
|
|
|
(t (format "<%s %s>--<%s %s>" start-date start-time end-date end-time))))
|
|
|
|
)
|
|
|
|
|
|
|
|
(cl-defmethod gnus-icalendar-event:org-timestamp ((event gnus-icalendar-event))
|
|
|
|
"Build `org-mode' timestamp from EVENT start/end dates and recurrence info."
|
|
|
|
;; if org-repeat +1d or +1w and byday: generate one timestamp per
|
|
|
|
;; byday, starting at start-date. Change +1d to +7d.
|
|
|
|
(let ((start (gnus-icalendar-event:start-time event))
|
|
|
|
(end (gnus-icalendar-event:end-time event))
|
|
|
|
(org-repeat (gnus-icalendar-event:org-repeat event))
|
|
|
|
(recurring-days (gnus-icalendar-event:recurring-days event)))
|
|
|
|
(if (and (or (string= org-repeat "+1d")
|
|
|
|
(string= org-repeat "+1w"))
|
|
|
|
recurring-days)
|
|
|
|
(let ((repeat "+1w")
|
|
|
|
(dates (seq-sort-by
|
|
|
|
'car
|
|
|
|
'time-less-p
|
|
|
|
(seq-map (lambda (x)
|
|
|
|
(gnus-icalendar--find-day start end x))
|
|
|
|
recurring-days))))
|
|
|
|
(mapconcat (lambda (x)
|
|
|
|
(gnus-icalendar-event--org-timestamp (car x) (cadr x)
|
|
|
|
repeat)) dates "\n"))
|
|
|
|
(gnus-icalendar-event--org-timestamp start end org-repeat))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2013-11-13 22:16:42 +00:00
|
|
|
(defun gnus-icalendar--format-summary-line (summary &optional location)
|
|
|
|
(if location
|
|
|
|
(format "%s (%s)" summary location)
|
|
|
|
(format "%s" summary)))
|
|
|
|
|
2013-11-15 00:07:54 +00:00
|
|
|
|
|
|
|
(defun gnus-icalendar--format-participant-list (participants)
|
|
|
|
(mapconcat #'identity participants ", "))
|
|
|
|
|
2013-08-01 22:58:40 +00:00
|
|
|
;; TODO: make the template customizable
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event->org-entry ((event gnus-icalendar-event) reply-status)
|
2013-08-01 22:58:40 +00:00
|
|
|
"Return string with new `org-mode' entry describing EVENT."
|
|
|
|
(with-temp-buffer
|
|
|
|
(org-mode)
|
|
|
|
(with-slots (organizer summary description location
|
|
|
|
recur uid) event
|
|
|
|
(let* ((reply (if reply-status (capitalize (symbol-name reply-status))
|
|
|
|
"Not replied yet"))
|
|
|
|
(props `(("ICAL_EVENT" . "t")
|
|
|
|
("ID" . ,uid)
|
|
|
|
("ORGANIZER" . ,(gnus-icalendar-event:organizer event))
|
|
|
|
("LOCATION" . ,(gnus-icalendar-event:location event))
|
2013-11-28 23:33:52 +00:00
|
|
|
("PARTICIPATION_TYPE" . ,(symbol-name (gnus-icalendar-event:participation-type event)))
|
2013-11-15 00:07:54 +00:00
|
|
|
("REQ_PARTICIPANTS" . ,(gnus-icalendar--format-participant-list (gnus-icalendar-event:req-participants event)))
|
|
|
|
("OPT_PARTICIPANTS" . ,(gnus-icalendar--format-participant-list (gnus-icalendar-event:opt-participants event)))
|
2013-08-01 22:58:40 +00:00
|
|
|
("RRULE" . ,(gnus-icalendar-event:recur event))
|
|
|
|
("REPLY" . ,reply))))
|
|
|
|
|
2013-11-13 22:16:42 +00:00
|
|
|
(insert (format "* %s\n\n"
|
|
|
|
(gnus-icalendar--format-summary-line summary location)))
|
2013-08-01 22:58:40 +00:00
|
|
|
(mapc (lambda (prop)
|
|
|
|
(org-entry-put (point) (car prop) (cdr prop)))
|
|
|
|
props))
|
|
|
|
|
2019-06-22 13:16:24 +02:00
|
|
|
(save-restriction
|
|
|
|
(narrow-to-region (point) (point))
|
|
|
|
(insert (gnus-icalendar-event:org-timestamp event)
|
|
|
|
"\n\n"
|
2019-10-15 12:00:34 +02:00
|
|
|
(or description "No description"))
|
2019-06-22 13:16:24 +02:00
|
|
|
(indent-region (point-min) (point-max) 2)
|
|
|
|
(fill-region (point-min) (point-max)))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(buffer-string))))
|
|
|
|
|
|
|
|
(defun gnus-icalendar--deactivate-org-timestamp (ts)
|
|
|
|
(replace-regexp-in-string "[<>]"
|
2013-08-06 22:09:27 +00:00
|
|
|
(lambda (m) (cond ((string= m "<") "[")
|
|
|
|
((string= m ">") "]")))
|
2013-08-01 22:58:40 +00:00
|
|
|
ts))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-find-org-event-file (event &optional org-file)
|
|
|
|
"Return the name of the file containing EVENT org entry.
|
|
|
|
Return nil when not found.
|
|
|
|
|
|
|
|
All org agenda files are searched for the EVENT entry. When
|
|
|
|
the optional ORG-FILE argument is specified, only that one file
|
|
|
|
is searched."
|
|
|
|
(let ((uid (gnus-icalendar-event:uid event))
|
|
|
|
(files (or org-file (org-agenda-files t 'ifmode))))
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((find-event-in
|
|
|
|
(file)
|
|
|
|
(org-check-agenda-file file)
|
|
|
|
(with-current-buffer (find-file-noselect file)
|
|
|
|
(let ((event-pos (org-find-entry-with-id uid)))
|
|
|
|
(when (and event-pos
|
|
|
|
(string= (cdr (assoc "ICAL_EVENT"
|
|
|
|
(org-entry-properties event-pos)))
|
|
|
|
"t"))
|
|
|
|
(throw 'found file))))))
|
2013-08-01 22:58:40 +00:00
|
|
|
(gnus-icalendar-find-if #'find-event-in files))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun gnus-icalendar--show-org-event (event &optional org-file)
|
|
|
|
(let ((file (gnus-icalendar-find-org-event-file event org-file)))
|
|
|
|
(when file
|
|
|
|
(switch-to-buffer (find-file file))
|
|
|
|
(goto-char (org-find-entry-with-id (gnus-icalendar-event:uid event)))
|
|
|
|
(org-show-entry))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun gnus-icalendar--update-org-event (event reply-status &optional org-file)
|
|
|
|
(let ((file (gnus-icalendar-find-org-event-file event org-file)))
|
|
|
|
(when file
|
|
|
|
(with-current-buffer (find-file-noselect file)
|
2013-11-15 00:07:54 +00:00
|
|
|
(with-slots (uid summary description organizer location recur
|
2013-11-28 23:33:52 +00:00
|
|
|
participation-type req-participants opt-participants) event
|
2013-08-01 22:58:40 +00:00
|
|
|
(let ((event-pos (org-find-entry-with-id uid)))
|
|
|
|
(when event-pos
|
|
|
|
(goto-char event-pos)
|
|
|
|
|
|
|
|
;; update the headline, keep todo, priority and tags, if any
|
|
|
|
(save-excursion
|
|
|
|
(let* ((priority (org-entry-get (point) "PRIORITY"))
|
|
|
|
(headline (delq nil (list
|
|
|
|
(org-entry-get (point) "TODO")
|
|
|
|
(when priority (format "[#%s]" priority))
|
2013-11-13 22:16:42 +00:00
|
|
|
(gnus-icalendar--format-summary-line summary location)
|
2013-08-01 22:58:40 +00:00
|
|
|
(org-entry-get (point) "TAGS")))))
|
|
|
|
|
|
|
|
(re-search-forward "^\\*+ " (line-end-position))
|
|
|
|
(delete-region (point) (line-end-position))
|
|
|
|
(insert (mapconcat #'identity headline " "))))
|
|
|
|
|
|
|
|
;; update props and description
|
|
|
|
(let ((entry-end (org-entry-end-position))
|
|
|
|
(entry-outline-level (org-outline-level)))
|
|
|
|
|
|
|
|
;; delete body of the entry, leave org drawers intact
|
|
|
|
(save-restriction
|
|
|
|
(org-narrow-to-element)
|
|
|
|
(goto-char entry-end)
|
|
|
|
(re-search-backward "^[\t ]*:END:")
|
|
|
|
(forward-line)
|
|
|
|
(delete-region (point) entry-end))
|
|
|
|
|
|
|
|
;; put new event description in the entry body
|
|
|
|
(when description
|
|
|
|
(save-restriction
|
|
|
|
(narrow-to-region (point) (point))
|
2014-04-20 22:10:33 +00:00
|
|
|
(insert "\n"
|
|
|
|
(gnus-icalendar-event:org-timestamp event)
|
|
|
|
"\n\n"
|
|
|
|
(replace-regexp-in-string "[\n]+$" "\n" description)
|
|
|
|
"\n")
|
2013-08-01 22:58:40 +00:00
|
|
|
(indent-region (point-min) (point-max) (1+ entry-outline-level))
|
|
|
|
(fill-region (point-min) (point-max))))
|
|
|
|
|
|
|
|
;; update entry properties
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((update-org-entry
|
|
|
|
(position property value)
|
|
|
|
(if (or (null value)
|
|
|
|
(string= value ""))
|
|
|
|
(org-entry-delete position property)
|
|
|
|
(org-entry-put position property value))))
|
2014-04-20 22:10:33 +00:00
|
|
|
|
|
|
|
(update-org-entry event-pos "ORGANIZER" organizer)
|
|
|
|
(update-org-entry event-pos "LOCATION" location)
|
2016-02-13 16:40:17 +11:00
|
|
|
(update-org-entry event-pos "PARTICIPATION_TYPE"
|
|
|
|
(symbol-name participation-type))
|
|
|
|
(update-org-entry event-pos "REQ_PARTICIPANTS"
|
|
|
|
(gnus-icalendar--format-participant-list
|
|
|
|
req-participants))
|
|
|
|
(update-org-entry event-pos "OPT_PARTICIPANTS"
|
|
|
|
(gnus-icalendar--format-participant-list
|
|
|
|
opt-participants))
|
2014-04-20 22:10:33 +00:00
|
|
|
(update-org-entry event-pos "RRULE" recur)
|
2016-02-13 16:40:17 +11:00
|
|
|
(update-org-entry
|
|
|
|
event-pos "REPLY"
|
|
|
|
(if reply-status (capitalize (symbol-name reply-status))
|
|
|
|
"Not replied yet")))
|
2013-08-01 22:58:40 +00:00
|
|
|
(save-buffer)))))))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun gnus-icalendar--cancel-org-event (event &optional org-file)
|
|
|
|
(let ((file (gnus-icalendar-find-org-event-file event org-file)))
|
|
|
|
(when file
|
|
|
|
(with-current-buffer (find-file-noselect file)
|
|
|
|
(let ((event-pos (org-find-entry-with-id (gnus-icalendar-event:uid event))))
|
|
|
|
(when event-pos
|
|
|
|
(let ((ts (org-entry-get event-pos "DT")))
|
|
|
|
(when ts
|
|
|
|
(org-entry-put event-pos "DT" (gnus-icalendar--deactivate-org-timestamp ts))
|
|
|
|
(save-buffer)))))))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun gnus-icalendar--get-org-event-reply-status (event &optional org-file)
|
|
|
|
(let ((file (gnus-icalendar-find-org-event-file event org-file)))
|
|
|
|
(when file
|
|
|
|
(save-excursion
|
|
|
|
(with-current-buffer (find-file-noselect file)
|
|
|
|
(let ((event-pos (org-find-entry-with-id (gnus-icalendar-event:uid event))))
|
|
|
|
(org-entry-get event-pos "REPLY")))))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun gnus-icalendar-insinuate-org-templates ()
|
|
|
|
(unless (gnus-icalendar-find-if (lambda (x) (string= (cadr x) gnus-icalendar-org-template-name))
|
|
|
|
org-capture-templates)
|
|
|
|
(setq org-capture-templates
|
|
|
|
(append `((,gnus-icalendar-org-template-key
|
|
|
|
,gnus-icalendar-org-template-name
|
|
|
|
entry
|
|
|
|
(file+olp ,gnus-icalendar-org-capture-file ,@gnus-icalendar-org-capture-headline)
|
|
|
|
"%i"
|
|
|
|
:immediate-finish t))
|
|
|
|
org-capture-templates))
|
|
|
|
|
|
|
|
;; hide the template from interactive template selection list
|
|
|
|
;; (org-capture)
|
|
|
|
;; NOTE: doesn't work when capturing from string
|
|
|
|
;; (when (boundp 'org-capture-templates-contexts)
|
|
|
|
;; (push `(,gnus-icalendar-org-template-key "" ((in-mode . "gnus-article-mode")))
|
|
|
|
;; org-capture-templates-contexts))
|
|
|
|
))
|
|
|
|
|
|
|
|
(defun gnus-icalendar:org-event-save (event reply-status)
|
|
|
|
(with-temp-buffer
|
|
|
|
(org-capture-string (gnus-icalendar-event->org-entry event reply-status)
|
|
|
|
gnus-icalendar-org-template-key)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-show-org-agenda (event)
|
|
|
|
(let* ((time-delta (time-subtract (gnus-icalendar-event:end-time event)
|
|
|
|
(gnus-icalendar-event:start-time event)))
|
New function time-convert
This replaces the awkward reuse of encode-time to both convert
calendrical timestamps to Lisp timestamps, and to convert Lisp
timestamps to other forms. Now, encode-time does just the
former and the new function does just the latter.
The new function builds on a suggestion by Lars Ingebrigtsen in:
https://lists.gnu.org/r/emacs-devel/2019-07/msg00801.html
and refined by Stefan Monnier in:
https://lists.gnu.org/r/emacs-devel/2019-07/msg00803.html
* doc/lispref/os.texi (Time of Day, Time Conversion):
* doc/misc/emacs-mime.texi (time-date):
* etc/NEWS: Update documentation.
* lisp/calendar/cal-dst.el (calendar-next-time-zone-transition):
* lisp/calendar/time-date.el (seconds-to-time, days-to-time):
* lisp/calendar/timeclock.el (timeclock-seconds-to-time):
* lisp/cedet/ede/detect.el (ede-detect-qtest):
* lisp/completion.el (cmpl-hours-since-origin):
* lisp/ecomplete.el (ecomplete-add-item):
* lisp/emacs-lisp/cl-extra.el (cl--random-time):
* lisp/emacs-lisp/timer.el (timer--time-setter)
(timer-next-integral-multiple-of-time):
* lisp/find-lisp.el (find-lisp-format-time):
* lisp/gnus/gnus-diary.el (gnus-user-format-function-d):
* lisp/gnus/gnus-group.el (gnus-group-set-timestamp):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-show-org-agenda):
* lisp/gnus/nnrss.el (nnrss-normalize-date):
* lisp/gnus/nnspool.el (nnspool-request-newgroups):
* lisp/net/ntlm.el (ntlm-compute-timestamp):
* lisp/net/pop3.el (pop3-uidl-dele):
* lisp/obsolete/vc-arch.el (vc-arch-add-tagline):
* lisp/org/org-clock.el (org-clock-get-clocked-time)
(org-clock-resolve, org-resolve-clocks, org-clock-in)
(org-clock-out, org-clock-sum):
* lisp/org/org-id.el (org-id-uuid, org-id-time-to-b36):
* lisp/org/ox-publish.el (org-publish-cache-ctime-of-src):
* lisp/proced.el (proced-format-time):
* lisp/progmodes/cc-cmds.el (c-progress-init)
(c-progress-update):
* lisp/progmodes/cperl-mode.el (cperl-time-fontification):
* lisp/progmodes/flymake.el (flymake--schedule-timer-maybe):
* lisp/progmodes/vhdl-mode.el (vhdl-update-progress-info)
(vhdl-fix-case-region-1):
* lisp/tar-mode.el (tar-octal-time):
* lisp/time.el (emacs-uptime):
* lisp/url/url-auth.el (url-digest-auth-make-cnonce):
* lisp/url/url-util.el (url-lazy-message):
* lisp/vc/vc-cvs.el (vc-cvs-parse-entry):
* lisp/vc/vc-hg.el (vc-hg-state-fast):
* lisp/xt-mouse.el (xterm-mouse-event):
* test/lisp/emacs-lisp/timer-tests.el:
(timer-next-integral-multiple-of-time-2):
Use time-convert, not encode-time.
* lisp/calendar/icalendar.el (icalendar--decode-isodatetime):
Don’t use now-removed FORM argument for encode-time.
It wasn’t crucial anyway.
* lisp/emacs-lisp/byte-opt.el (side-effect-free-fns): Add time-convert.
* lisp/emacs-lisp/elint.el (elint-unknown-builtin-args):
Update encode-time signature to match current arg set.
* lisp/emacs-lisp/timer.el (timer-next-integral-multiple-of-time):
Use timer-convert with t rather than doing it by hand.
* src/timefns.c (time_hz_ticks, time_form_stamp, lisp_time_form_stamp):
Remove; no longer needed.
(decode_lisp_time): Rturn the form instead of having a *PFORM arg.
All uses changed.
(time_arith): Just return TICKS if HZ is 1.
(Fencode_time): Remove argument FORM. All callers changed.
Do not attempt to encode time values; just encode
decoded (calendrical) times.
Unless CURRENT_TIME_LIST, just return VALUE since HZ is 1.
(Ftime_convert): New function, which does the time value
conversion that bleeding-edge encode-time formerly did.
Return TIME if it is easy to see that it is already
of the correct form.
(Fcurrent_time): Mention in doc that the form is planned to change.
* test/src/timefns-tests.el (decode-then-encode-time):
Don’t use (encode-time nil).
2019-08-05 17:38:52 -07:00
|
|
|
(duration-days (1+ (floor (time-convert time-delta 'integer) 86400))))
|
2013-08-01 22:58:40 +00:00
|
|
|
(org-agenda-list nil (gnus-icalendar-event:start event) duration-days)))
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:sync-to-org ((event gnus-icalendar-event-request) reply-status)
|
2013-08-01 22:58:40 +00:00
|
|
|
(if (gnus-icalendar-find-org-event-file event)
|
|
|
|
(gnus-icalendar--update-org-event event reply-status)
|
|
|
|
(gnus-icalendar:org-event-save event reply-status)))
|
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
(cl-defmethod gnus-icalendar-event:sync-to-org ((event gnus-icalendar-event-cancel) _reply-status)
|
2013-08-01 22:58:40 +00:00
|
|
|
(when (gnus-icalendar-find-org-event-file event)
|
|
|
|
(gnus-icalendar--cancel-org-event event)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-org-setup ()
|
|
|
|
(if (and gnus-icalendar-org-capture-file gnus-icalendar-org-capture-headline)
|
|
|
|
(progn
|
|
|
|
(gnus-icalendar-insinuate-org-templates)
|
|
|
|
(setq gnus-icalendar-org-enabled-p t))
|
|
|
|
(message "Cannot enable Calendar->Org: missing capture file, headline")))
|
|
|
|
|
|
|
|
;;;
|
|
|
|
;;; gnus-icalendar
|
|
|
|
;;;
|
|
|
|
|
|
|
|
(defgroup gnus-icalendar nil
|
|
|
|
"Settings for inline display of iCalendar invitations."
|
2013-12-27 18:16:05 -08:00
|
|
|
:version "24.4"
|
2013-08-01 22:58:40 +00:00
|
|
|
:group 'gnus-article
|
|
|
|
:prefix "gnus-icalendar-")
|
|
|
|
|
|
|
|
(defcustom gnus-icalendar-reply-bufname "*CAL*"
|
|
|
|
"Buffer used for building iCalendar invitation reply."
|
2019-03-29 08:46:29 -04:00
|
|
|
:type '(string))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2013-11-21 22:55:59 +00:00
|
|
|
(defcustom gnus-icalendar-additional-identities nil
|
|
|
|
"We need to know your identity to make replies to calendar requests work.
|
|
|
|
|
|
|
|
Gnus will only offer you the Accept/Tentative/Decline buttons for
|
|
|
|
calendar events if any of your identities matches at least one
|
|
|
|
RSVP participant.
|
|
|
|
|
2014-10-06 22:11:44 +00:00
|
|
|
Your identity is guessed automatically from the variables
|
|
|
|
`user-full-name', `user-mail-address',
|
|
|
|
`gnus-ignored-from-addresses' and `message-alternative-emails'.
|
2013-11-21 22:55:59 +00:00
|
|
|
|
|
|
|
If you need even more aliases you can define them here. It really
|
|
|
|
only makes sense to define names or email addresses."
|
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
:type '(repeat string))
|
2013-11-21 22:55:59 +00:00
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
(defvar-local gnus-icalendar-reply-status nil)
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
(defvar-local gnus-icalendar-event nil)
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
(defvar-local gnus-icalendar-handle nil)
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2013-12-18 22:11:40 +00:00
|
|
|
(defun gnus-icalendar-identities ()
|
|
|
|
"Return list of regexp-quoted names and email addresses belonging to the user.
|
|
|
|
|
|
|
|
These will be used to retrieve the RSVP information from ical events."
|
2013-08-01 22:58:40 +00:00
|
|
|
(apply #'append
|
2016-02-08 13:28:37 +11:00
|
|
|
(mapcar
|
|
|
|
(lambda (x) (if (listp x) x (list x)))
|
|
|
|
(list user-full-name (regexp-quote user-mail-address)
|
|
|
|
;; NOTE: these can be lists
|
2020-10-10 22:32:41 +02:00
|
|
|
gnus-ignored-from-addresses ; String or function.
|
|
|
|
message-alternative-emails ; String or function.
|
2016-02-08 13:28:37 +11:00
|
|
|
(mapcar #'regexp-quote gnus-icalendar-additional-identities)))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
;; TODO: make the template customizable
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event->gnus-calendar ((event gnus-icalendar-event) &optional reply-status)
|
2013-08-01 22:58:40 +00:00
|
|
|
"Format an overview of EVENT details."
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((format-header (x)
|
|
|
|
(format "%-12s%s"
|
|
|
|
(propertize (concat (car x) ":") 'face 'bold)
|
|
|
|
(cadr x))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
2013-11-15 00:07:54 +00:00
|
|
|
(with-slots (organizer summary description location recur uid
|
2019-03-29 08:46:29 -04:00
|
|
|
method rsvp participation-type)
|
|
|
|
event
|
2013-08-01 22:58:40 +00:00
|
|
|
(let ((headers `(("Summary" ,summary)
|
2016-02-13 16:40:17 +11:00
|
|
|
("Location" ,(or location ""))
|
|
|
|
("Time" ,(gnus-icalendar-event:org-timestamp event))
|
|
|
|
("Organizer" ,organizer)
|
|
|
|
("Attendance" ,(if (eq participation-type 'non-participant)
|
|
|
|
"You are not listed as an attendee"
|
|
|
|
(capitalize (symbol-name participation-type))))
|
|
|
|
("Method" ,method))))
|
|
|
|
|
|
|
|
(when (and (not (gnus-icalendar-event-reply-p event)) rsvp)
|
|
|
|
(setq headers (append headers
|
|
|
|
`(("Status" ,(or reply-status "Not replied yet"))))))
|
|
|
|
|
|
|
|
(concat
|
|
|
|
(mapconcat #'format-header headers "\n")
|
|
|
|
"\n\n"
|
|
|
|
description)))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defmacro gnus-icalendar-with-decoded-handle (handle &rest body)
|
|
|
|
"Execute BODY in buffer containing the decoded contents of HANDLE."
|
|
|
|
(let ((charset (make-symbol "charset")))
|
|
|
|
`(let ((,charset (cdr (assoc 'charset (mm-handle-type ,handle)))))
|
|
|
|
(with-temp-buffer
|
|
|
|
(mm-insert-part ,handle)
|
2020-08-21 13:31:38 +02:00
|
|
|
(when (and ,charset (string= (downcase ,charset) "utf-8"))
|
2016-02-12 14:39:30 +11:00
|
|
|
(decode-coding-region (point-min) (point-max) 'utf-8))
|
2013-08-01 22:58:40 +00:00
|
|
|
,@body))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun gnus-icalendar-event-from-handle (handle &optional attendee-name-or-email)
|
|
|
|
(gnus-icalendar-with-decoded-handle handle
|
|
|
|
(gnus-icalendar-event-from-buffer (current-buffer) attendee-name-or-email)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-insert-button (text callback data)
|
|
|
|
;; FIXME: the gnus-mime-button-map keymap does not make sense for this kind
|
|
|
|
;; of button.
|
|
|
|
(let ((start (point)))
|
2016-02-13 18:13:03 +11:00
|
|
|
(add-text-properties
|
2013-08-01 22:58:40 +00:00
|
|
|
start
|
|
|
|
(progn
|
|
|
|
(insert "[ " text " ]")
|
|
|
|
(point))
|
|
|
|
`(gnus-callback
|
|
|
|
,callback
|
|
|
|
keymap ,gnus-mime-button-map
|
|
|
|
face ,gnus-article-button-face
|
2019-11-16 05:33:17 +01:00
|
|
|
follow-link t
|
2019-07-30 15:24:55 +02:00
|
|
|
button t
|
|
|
|
gnus-data ,data))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(defun gnus-icalendar-send-buffer-by-mail (buffer-name subject)
|
|
|
|
(let ((message-signature nil))
|
|
|
|
(with-current-buffer gnus-summary-buffer
|
|
|
|
(gnus-summary-reply)
|
|
|
|
(message-goto-body)
|
|
|
|
(mml-insert-multipart "alternative")
|
|
|
|
(mml-insert-empty-tag 'part 'type "text/plain")
|
|
|
|
(mml-attach-buffer buffer-name "text/calendar; method=REPLY; charset=UTF-8")
|
|
|
|
(message-goto-subject)
|
|
|
|
(delete-region (line-beginning-position) (line-end-position))
|
|
|
|
(insert "Subject: " subject)
|
|
|
|
(message-send-and-exit))))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-reply (data)
|
|
|
|
(let* ((handle (car data))
|
|
|
|
(status (cadr data))
|
|
|
|
(event (caddr data))
|
|
|
|
(reply (gnus-icalendar-with-decoded-handle handle
|
|
|
|
(gnus-icalendar-event-reply-from-buffer
|
2013-12-18 22:11:40 +00:00
|
|
|
(current-buffer) status (gnus-icalendar-identities)))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(when reply
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((fold-icalendar-buffer
|
|
|
|
()
|
|
|
|
(goto-char (point-min))
|
|
|
|
(while (re-search-forward "^\\(.\\{72\\}\\)\\(.+\\)$" nil t)
|
|
|
|
(replace-match "\\1\n \\2")
|
|
|
|
(goto-char (line-beginning-position)))))
|
2013-08-01 22:58:40 +00:00
|
|
|
(let ((subject (concat (capitalize (symbol-name status))
|
|
|
|
": " (gnus-icalendar-event:summary event))))
|
|
|
|
|
2020-01-10 13:34:59 -05:00
|
|
|
(with-current-buffer (gnus-get-buffer-create gnus-icalendar-reply-bufname)
|
2013-08-01 22:58:40 +00:00
|
|
|
(delete-region (point-min) (point-max))
|
|
|
|
(insert reply)
|
|
|
|
(fold-icalendar-buffer)
|
|
|
|
(gnus-icalendar-send-buffer-by-mail (buffer-name) subject))
|
|
|
|
|
|
|
|
;; Back in article buffer
|
|
|
|
(setq-local gnus-icalendar-reply-status status)
|
|
|
|
(when gnus-icalendar-org-enabled-p
|
|
|
|
(gnus-icalendar--update-org-event event status)
|
|
|
|
;; refresh article buffer to update the reply status
|
|
|
|
(with-current-buffer gnus-summary-buffer
|
|
|
|
(gnus-summary-show-article))))))))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-sync-event-to-org (event)
|
|
|
|
(gnus-icalendar-event:sync-to-org event gnus-icalendar-reply-status))
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:inline-reply-buttons ((event gnus-icalendar-event) handle)
|
2013-08-01 22:58:40 +00:00
|
|
|
(when (gnus-icalendar-event:rsvp event)
|
|
|
|
`(("Accept" gnus-icalendar-reply (,handle accepted ,event))
|
|
|
|
("Tentative" gnus-icalendar-reply (,handle tentative ,event))
|
|
|
|
("Decline" gnus-icalendar-reply (,handle declined ,event)))))
|
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
(cl-defmethod gnus-icalendar-event:inline-reply-buttons ((_event gnus-icalendar-event-reply) _handle)
|
2013-08-01 22:58:40 +00:00
|
|
|
"No buttons for REPLY events."
|
|
|
|
nil)
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:inline-reply-status ((event gnus-icalendar-event))
|
2013-08-01 22:58:40 +00:00
|
|
|
(or (when gnus-icalendar-org-enabled-p
|
|
|
|
(gnus-icalendar--get-org-event-reply-status event))
|
|
|
|
"Not replied yet"))
|
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
(cl-defmethod gnus-icalendar-event:inline-reply-status ((_event gnus-icalendar-event-reply))
|
2013-08-01 22:58:40 +00:00
|
|
|
"No reply status for REPLY events."
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:inline-org-buttons ((event gnus-icalendar-event))
|
2013-08-01 22:58:40 +00:00
|
|
|
(let* ((org-entry-exists-p (gnus-icalendar-find-org-event-file event))
|
|
|
|
(export-button-text (if org-entry-exists-p "Update Org Entry" "Export to Org")))
|
|
|
|
|
|
|
|
(delq nil (list
|
|
|
|
`("Show Agenda" gnus-icalendar-show-org-agenda ,event)
|
|
|
|
(when (gnus-icalendar-event-request-p event)
|
|
|
|
`(,export-button-text gnus-icalendar-sync-event-to-org ,event))
|
|
|
|
(when org-entry-exists-p
|
|
|
|
`("Show Org Entry" gnus-icalendar--show-org-event ,event))))))
|
|
|
|
|
2013-11-13 22:16:42 +00:00
|
|
|
|
2016-02-12 16:25:13 +11:00
|
|
|
(cl-defmethod gnus-icalendar-event:inline-org-buttons ((event gnus-icalendar-event-cancel))
|
2013-11-13 22:16:42 +00:00
|
|
|
(let ((org-entry-exists-p (gnus-icalendar-find-org-event-file event)))
|
|
|
|
|
|
|
|
(delq nil (list
|
|
|
|
`("Show Agenda" gnus-icalendar-show-org-agenda ,event)
|
|
|
|
(when org-entry-exists-p
|
|
|
|
`("Update Org Entry" gnus-icalendar-sync-event-to-org ,event))
|
|
|
|
(when org-entry-exists-p
|
|
|
|
`("Show Org Entry" gnus-icalendar--show-org-event ,event))))))
|
|
|
|
|
2019-03-29 08:46:29 -04:00
|
|
|
;;;###autoload
|
2013-08-01 22:58:40 +00:00
|
|
|
(defun gnus-icalendar-mm-inline (handle)
|
2013-12-18 22:11:40 +00:00
|
|
|
(let ((event (gnus-icalendar-event-from-handle handle (gnus-icalendar-identities))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(setq gnus-icalendar-reply-status nil)
|
|
|
|
|
|
|
|
(when event
|
2016-02-13 16:40:17 +11:00
|
|
|
(cl-labels
|
|
|
|
((insert-button-group
|
|
|
|
(buttons)
|
|
|
|
(when buttons
|
|
|
|
(mapc (lambda (x)
|
2019-03-29 08:46:29 -04:00
|
|
|
(apply #'gnus-icalendar-insert-button x)
|
2016-02-13 16:40:17 +11:00
|
|
|
(insert " "))
|
|
|
|
buttons)
|
|
|
|
(insert "\n\n"))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(insert-button-group
|
|
|
|
(gnus-icalendar-event:inline-reply-buttons event handle))
|
|
|
|
|
|
|
|
(when gnus-icalendar-org-enabled-p
|
|
|
|
(insert-button-group (gnus-icalendar-event:inline-org-buttons event)))
|
|
|
|
|
|
|
|
(setq gnus-icalendar-event event
|
|
|
|
gnus-icalendar-handle handle)
|
|
|
|
|
|
|
|
(insert (gnus-icalendar-event->gnus-calendar
|
|
|
|
event
|
|
|
|
(gnus-icalendar-event:inline-reply-status event)))))))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-save-part (handle)
|
|
|
|
(let (event)
|
|
|
|
(when (and (equal (car (mm-handle-type handle)) "text/calendar")
|
2013-12-18 22:11:40 +00:00
|
|
|
(setq event (gnus-icalendar-event-from-handle handle (gnus-icalendar-identities))))
|
2013-08-01 22:58:40 +00:00
|
|
|
|
|
|
|
(gnus-icalendar-event:sync-to-org event))))
|
|
|
|
|
|
|
|
|
|
|
|
(defun gnus-icalendar-save-event ()
|
|
|
|
"Save the Calendar event in the text/calendar part under point."
|
|
|
|
(interactive)
|
|
|
|
(gnus-article-check-buffer)
|
|
|
|
(let ((data (get-text-property (point) 'gnus-data)))
|
|
|
|
(when data
|
|
|
|
(gnus-icalendar-save-part data))))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-reply-accept ()
|
|
|
|
"Accept invitation in the current article."
|
|
|
|
(interactive)
|
|
|
|
(with-current-buffer gnus-article-buffer
|
|
|
|
(gnus-icalendar-reply (list gnus-icalendar-handle 'accepted gnus-icalendar-event))
|
|
|
|
(setq-local gnus-icalendar-reply-status 'accepted)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-reply-tentative ()
|
|
|
|
"Send tentative response to invitation in the current article."
|
|
|
|
(interactive)
|
|
|
|
(with-current-buffer gnus-article-buffer
|
|
|
|
(gnus-icalendar-reply (list gnus-icalendar-handle 'tentative gnus-icalendar-event))
|
|
|
|
(setq-local gnus-icalendar-reply-status 'tentative)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-reply-decline ()
|
|
|
|
"Decline invitation in the current article."
|
|
|
|
(interactive)
|
|
|
|
(with-current-buffer gnus-article-buffer
|
|
|
|
(gnus-icalendar-reply (list gnus-icalendar-handle 'declined gnus-icalendar-event))
|
|
|
|
(setq-local gnus-icalendar-reply-status 'declined)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-event-export ()
|
|
|
|
"Export calendar event to `org-mode', or update existing agenda entry."
|
|
|
|
(interactive)
|
|
|
|
(with-current-buffer gnus-article-buffer
|
|
|
|
(gnus-icalendar-sync-event-to-org gnus-icalendar-event))
|
|
|
|
;; refresh article buffer in case the reply had been sent before initial org
|
|
|
|
;; export
|
|
|
|
(with-current-buffer gnus-summary-buffer
|
|
|
|
(gnus-summary-show-article)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-event-show ()
|
|
|
|
"Display `org-mode' agenda entry related to the calendar event."
|
|
|
|
(interactive)
|
|
|
|
(gnus-icalendar--show-org-event
|
|
|
|
(with-current-buffer gnus-article-buffer
|
|
|
|
gnus-icalendar-event)))
|
|
|
|
|
|
|
|
(defun gnus-icalendar-event-check-agenda ()
|
|
|
|
"Display `org-mode' agenda for days between event start and end dates."
|
|
|
|
(interactive)
|
|
|
|
(gnus-icalendar-show-org-agenda
|
|
|
|
(with-current-buffer gnus-article-buffer gnus-icalendar-event)))
|
|
|
|
|
2013-09-11 23:47:07 -07:00
|
|
|
(defvar gnus-mime-action-alist) ; gnus-art
|
|
|
|
|
2013-08-01 22:58:40 +00:00
|
|
|
(defun gnus-icalendar-setup ()
|
2019-03-29 08:46:29 -04:00
|
|
|
;; FIXME: Get rid of this!
|
|
|
|
;; The three add-to-list are now redundant (good), but I think the rest
|
|
|
|
;; is still not automatically setup.
|
2013-08-01 22:58:40 +00:00
|
|
|
(add-to-list 'mm-inlined-types "text/calendar")
|
|
|
|
(add-to-list 'mm-automatic-display "text/calendar")
|
|
|
|
(add-to-list 'mm-inline-media-tests '("text/calendar" gnus-icalendar-mm-inline identity))
|
|
|
|
|
|
|
|
(gnus-define-keys (gnus-summary-calendar-map "i" gnus-summary-mode-map)
|
|
|
|
"a" gnus-icalendar-reply-accept
|
|
|
|
"t" gnus-icalendar-reply-tentative
|
|
|
|
"d" gnus-icalendar-reply-decline
|
|
|
|
"c" gnus-icalendar-event-check-agenda
|
|
|
|
"e" gnus-icalendar-event-export
|
|
|
|
"s" gnus-icalendar-event-show)
|
|
|
|
|
|
|
|
(require 'gnus-art)
|
|
|
|
(add-to-list 'gnus-mime-action-alist
|
2019-03-29 08:46:29 -04:00
|
|
|
(cons "save calendar event" #'gnus-icalendar-save-event)
|
2013-08-01 22:58:40 +00:00
|
|
|
t))
|
|
|
|
|
|
|
|
(provide 'gnus-icalendar)
|
|
|
|
|
|
|
|
;;; gnus-icalendar.el ends here
|