From b0f3ee82d3e936c6e09d2fa44dc1f9ec933ac2b6 Mon Sep 17 00:00:00 2001 From: Richard Lawrence Date: Fri, 20 Dec 2024 11:15:42 +0100 Subject: [PATCH 3/3] New major mode icalendar-mode Import icalendar-mode.el from external repo Move font lock setup from ical:define-* macros into constants in icalendar-mode.el Check that face keywords are non-nil, and require icalendar-mode, when adding to icalendar-font-lock-keywords in ical:define-* macros --- lisp/calendar/icalendar-macs.el | 10 +- lisp/calendar/icalendar-mode.el | 609 ++++++++++++++++++++++++++++++ lisp/calendar/icalendar-parser.el | 75 +--- 3 files changed, 614 insertions(+), 80 deletions(-) create mode 100644 lisp/calendar/icalendar-mode.el diff --git a/lisp/calendar/icalendar-macs.el b/lisp/calendar/icalendar-macs.el index 2030efc5e6d..fab78fce866 100644 --- a/lisp/calendar/icalendar-macs.el +++ b/lisp/calendar/icalendar-macs.el @@ -379,9 +379,7 @@ ical:define-param ;; Associate the print name with the type symbol for ;; `ical:parse-params' and `ical:print-param': (when ,param-name - (push (cons ,param-name (quote ,symbolic-name)) ical:param-types)) - ;; TODO: integrate param-name with eldoc in icalendar-mode - ))) + (push (cons ,param-name (quote ,symbolic-name)) ical:param-types))))) ;; Define properties: @@ -797,10 +795,8 @@ ical:define-component ;; Associate the print name with the type symbol for ;; `icalendar-parse-component', `icalendar-print-component' etc.: (when ,component-name - (push (cons ,component-name (quote ,symbolic-name)) ical:component-types)) - - ;; TODO: integrate component-name with eldoc in icalendar-mode - ))) + (push (cons ,component-name (quote ,symbolic-name)) + ical:component-types))))) (provide 'icalendar-macs) ;; Local Variables: diff --git a/lisp/calendar/icalendar-mode.el b/lisp/calendar/icalendar-mode.el new file mode 100644 index 00000000000..0a0d339c89c --- /dev/null +++ b/lisp/calendar/icalendar-mode.el @@ -0,0 +1,609 @@ +;;; icalendar-mode.el --- Major mode for iCalendar format -*- lexical-binding: t; -*- +;;; + +;; Copyright (C) 2024 Richard Lawrence + +;; Author: Richard Lawrence +;; Keywords: calendar + +;; This file is part of GNU Emacs. + +;; This file is free software: you can redistribute it and/or modify +;; 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. + +;; This file is distributed in the hope that it will be useful, +;; 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 +;; along with this file. If not, see . + +;;; Commentary: + +;; This file defines icalendar-mode, a major mode for editing +;; iCalendar data. It defines a syntax table, faces, hooks, and +;; commands for the mode and sets up syntax highlighting via +;; font-lock-mode. Syntax highlighting uses the entries for +;; font-lock-keywords already gathered in icalendar-parser.el, which +;; see. + +;; When activated, icalendar-mode offers to unfold content lines if +;; necessary, and switch to a new buffer containing the unfolded data; +;; see `ical:maybe-switch-to-unfolded-buffer'. This is because the +;; parsing facilities, and thus syntax highlighting, assume that +;; content lines have already been unfolded. When a buffer is saved, +;; icalendar-mode also offers to fold long content if necessary, as +;; required by RFC5545; see `ical:before-save-checks'. + +;;; Code: + +(require 'icalendar-parser) + +;; Faces and font lock: +(defgroup ical:faces + '((ical:property-name custom-face) + (ical:property-value custom-face) + (ical:parameter-name custom-face) + (ical:parameter-value custom-face) + (ical:component-name custom-face) + (ical:keyword custom-face) + (ical:binary-data custom-face) + (ical:date-time-types custom-face) + (ical:numeric-types custom-face) + (ical:recurrence-rule custom-face) + (ical:warning custom-face) + (ical:ignored custom-face)) + "Faces for icalendar-mode.") ; TODO: :group + +(defface ical:property-name + '((default . (:inherit font-lock-keyword-face))) + "Face for iCalendar property names") + +(defface ical:property-value + '((default . (:inherit default))) + "Face for iCalendar property values") + +(defface ical:parameter-name + '((default . (:inherit font-lock-property-name-face))) + "Face for iCalendar parameter names") + +(defface ical:parameter-value + '((default . (:inherit font-lock-property-use-face))) + "Face for iCalendar parameter values") + +(defface ical:component-name + '((default . (:inherit font-lock-constant-face))) + "Face for iCalendar component names") + +(defface ical:keyword + '((default . (:inherit font-lock-keyword-face))) + "Face for other iCalendar keywords") + +(defface ical:binary-data + '((default . (:inherit font-lock-comment-face))) + "Face for iCalendar values that represent binary data") + +(defface ical:date-time-types + '((default . (:inherit font-lock-type-face))) + "Face for iCalendar values that represent dates, date-times, +durations, periods, and UTC offsets") + +(defface ical:numeric-types + '((default . (:inherit ical:property-value-face))) + "Face for iCalendar values that represent integers, floats, and geolocations") + +(defface ical:recurrence-rule + '((default . (:inherit font-lock-type-face))) + "Face for iCalendar recurrence rule values") + +(defface ical:uri + '((default . (:inherit ical:property-value-face :underline t))) + "Face for iCalendar values that are URIs (including URLs and mail addresses)") + +(defface ical:warning + '((default . (:inherit font-lock-warning-face))) + "Face for iCalendar syntax errors") + +(defface ical:ignored + '((default . (:inherit font-lock-comment-face))) + "Face for iCalendar syntax which is parsed but ignored") + +;;; Font lock: +(defconst ical:params-font-lock-keywords + '((ical:match-other-param + (1 'font-lock-comment-face t t) + (2 'font-lock-comment-face t t) + (3 'ical:warning t t)) + (ical:match-value-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-tzid-param + (1 'ical:parameter-name t t) + (2 'ical:parameter-value t t) + (3 'ical:warning t t)) + (ical:match-sent-by-param + (1 'ical:parameter-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-rsvp-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-role-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-reltype-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-related-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-range-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-partstat-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-member-param + (1 'ical:parameter-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-language-param + (1 'ical:parameter-name t t) + (2 'ical:parameter-value t t) + (3 'ical:warning t t)) + (ical:match-fbtype-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-fmttype-param + (1 'ical:parameter-name t t) + (2 'ical:parameter-value t t) + (3 'ical:warning t t)) + (ical:match-encoding-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-dir-param + (1 'ical:parameter-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-delegated-to-param + (1 'ical:parameter-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-delegated-from-param + (1 'ical:parameter-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-cutype-param + (1 'ical:parameter-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-cn-param + (1 'ical:parameter-name t t) + (2 'ical:parameter-value t t) + (3 'ical:warning t t)) + (ical:match-altrep-param + (1 'ical:parameter-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t))) + "Entries for iCalendar property parameters in `font-lock-keywords'.") + +(defconst ical:properties-font-lock-keywords + '((ical:match-request-status-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-other-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-sequence-property + (1 'ical:property-name t t) + (2 'ical:numeric-types t t) + (3 'ical:warning t t)) + (ical:match-last-modified-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-dtstamp-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-created-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-trigger-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-repeat-property + (1 'ical:property-name t t) + (2 'ical:numeric-types t t) + (3 'ical:warning t t)) + (ical:match-action-property + (1 'ical:property-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-rrule-property + (1 'ical:property-name t t) + (2 'ical:recurrence-rule t t) + (3 'ical:warning t t)) + (ical:match-rdate-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-exdate-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-uid-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-url-property + (1 'ical:property-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-related-to-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-recurrence-id-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-organizer-property + (1 'ical:property-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-contact-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-attendee-property + (1 'ical:property-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-tzurl-property + (1 'ical:property-name t t) + (2 'ical:uri t t) + (3 'ical:warning t t)) + (ical:match-tzoffsetto-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-tzoffsetfrom-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-tzname-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-tzid-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-transp-property + (1 'ical:property-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-freebusy-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-duration-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-dtstart-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-due-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-dtend-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-completed-property + (1 'ical:property-name t t) + (2 'ical:date-time-types t t) + (3 'ical:warning t t)) + (ical:match-summary-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-status-property + (1 'ical:property-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-resources-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-priority-property + (1 'ical:property-name t t) + (2 'ical:numeric-types t t) + (3 'ical:warning t t)) + (ical:match-percent-complete-property + (1 'ical:property-name t t) + (2 'ical:numeric-types t t) + (3 'ical:warning t t)) + (ical:match-location-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-geo-property + (1 'ical:property-name t t) + (2 'ical:numeric-types t t) + (3 'ical:warning t t)) + (ical:match-description-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-comment-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-class-property + (1 'ical:property-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t)) + (ical:match-categories-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-attach-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t) + (13 'ical:uri t t) + (14 'ical:binary-data t t)) + (ical:match-version-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-prodid-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-method-property + (1 'ical:property-name t t) + (2 'ical:property-value t t) + (3 'ical:warning t t)) + (ical:match-calscale-property + (1 'ical:property-name t t) + (2 'ical:keyword t t) + (3 'ical:warning t t))) + "Entries for iCalendar properties in `font-lock-keywords'.") + +(defconst ical:ignored-properties-font-lock-keywords + `((,(rx ical:other-property) (1 'ical:ignored keep) + (2 'ical:ignored keep))) + "Entries for iCalendar ignored properties in `font-lock-keywords'.") + +(defconst ical:components-font-lock-keywords + '((ical:match-vcalendar-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-other-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-valarm-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-daylight-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-standard-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-vtimezone-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-vfreebusy-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-vjournal-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-vtodo-component + (1 'ical:keyword t t) + (2 'ical:component-name t t)) + (ical:match-vevent-component + (1 'ical:keyword t t) + (2 'ical:component-name t t))) + "Entries for iCalendar components in `font-lock-keywords'.") + +(defvar ical:font-lock-keywords + (append ical:params-font-lock-keywords + ical:properties-font-lock-keywords + ical:components-font-lock-keywords + ical:ignored-properties-font-lock-keywords) + "Value of `font-lock-keywords' for icalendar-mode.") + + +;; The major mode: + +;;; Mode hook +(defvar ical:mode-hook nil + "Hook run when activating `ical:mode'.") + +(add-to-list 'auto-mode-alist '("\\.ics\\'" . icalendar-mode)) + +;;; Syntax table +(defvar ical:mode-syntax-table + (let ((st (make-syntax-table))) + ;; Characters for which the standard syntax table suffices: + ;; ; (punctuation): separates some property values, and property parameters + ;; " (string): begins and ends string values + ;; : (punctuation): separates property name (and parameters) from property + ;; values + ;; , (punctuation): separates values in a list + ;; CR, LF (whitespace): content line endings + ;; space (whitespace): when at the beginning of a line, continues the + ;; previous line + + ;; Characters which need to be adjusted from the standard syntax table: + ;; = is punctuation, not a symbol constituent: + (modify-syntax-entry ?= ". " st) + ;; / is punctuation, not a symbol constituent: + (modify-syntax-entry ?/ ". " st) + st) + "Syntax table used in `ical:mode'.") + + +;;; Commands + +;; TODO: is there a corresponding list by mimetype for buffers +;; displaying message parts? Thought I saw this somewhere... + +(defun ical:switch-to-unfolded-buffer () + "Switch to viewing the contents of the current buffer in a new +buffer where content lines have been unfolded. + +`Folding' means inserting a line break and a single whitespace +character to continue lines longer than 75 octets; `unfolding' +means removing the extra whitespace inserted by folding. The +iCalendar standard (RFC5545) requires folding lines when +serializing data to iCalendar format, and unfolding before +parsing it. In icalendar-mode, folded lines may not have proper +syntax highlighting; this command allows you to view iCalendar +data with proper syntax highlighting, as the parser sees it. + +If the current buffer is visiting a file, this function will +offer to save the buffer first, and then reload the contents from +the file, performing unfolding with `icalendar-unfold-undecoded-region' +before decoding it. This is the most reliable way to unfold lines. + +If it is not visiting a file, it will unfold the new buffer +with `icalendar-unfold-region'. This can in some cases have +undesirable effects (see its docstring), so the original contents +are preserved unchanged in the current buffer. + +In both cases, after switching to the new buffer, this command +offers to kill the original buffer. + +It is recommended to turn off `auto-fill-mode' when viewing an +unfolded buffer, so that filling does not interfere with syntax +highlighting. This function offers to disable `auto-fill-mode' if +it is enabled in the new buffer; consider using +`visual-line-mode' instead." + (interactive) + (when (and buffer-file-name (buffer-modified-p)) + (when (y-or-n-p (format "Save before reloading from %s?" + (file-name-nondirectory buffer-file-name))) + (save-buffer))) + (let ((old-buffer (current-buffer)) + (mmode major-mode) + (uf-buffer (if buffer-file-name + (ical:unfolded-buffer-from-file buffer-file-name) + (ical:unfolded-buffer-from-buffer (current-buffer))))) + (switch-to-buffer uf-buffer) + ;; restart original major mode, in case the new buffer is + ;; still in fundamental-mode: TODO: is this necessary? + (funcall mmode) + (when (y-or-n-p (format "Unfolded buffer is shown. Kill %s?" + (buffer-name old-buffer))) + (kill-buffer old-buffer)) + (when (and auto-fill-function + (y-or-n-p "Disable auto-fill-mode?")) + (auto-fill-mode -1)))) + +(defun ical:maybe-switch-to-unfolded-buffer () + "Check for folded lines and ask for confirmation before calling +`icalendar-switch-to-unfolded-buffer', which see. + +This function is intended to be run via `icalendar-mode-hook' +when `icalendar-mode' is activated." + (interactive) + (if (ical:contains-folded-lines-p) + (when (y-or-n-p "Buffer contains folded lines; unfold in new buffer?") + (ical:switch-to-unfolded-buffer)) + ;; No need for unfolding, just inform the user: + (message "Buffer does not contain any lines to unfold"))) + +(add-hook 'ical:mode-hook 'ical:maybe-switch-to-unfolded-buffer) + +(defun ical:before-save-checks () + "Offer to change coding system and fold content lines in the +current buffer when saving a buffer in `icalendar-mode'. + +The iCalendar standard requires CR-LF line endings, so if +`buffer-file-coding-system' does not use a coding system which +specifies them, this command offers to switch to a corresponding +coding system which does. + +`Folding' means inserting a line break and a single whitespace +character to continue lines longer than 75 octets. The iCalendar +standard requires folding lines when serializing data to +iCalendar format, so if the buffer contains unfolded lines, this +command asks you whether you want to fold them." + (interactive) + (when (eq major-mode 'ical:mode) + (let* ((cs buffer-file-coding-system) + (suggested-cs (if cs (coding-system-change-eol-conversion cs 'dos) + 'prefer-utf-8-dos))) + (when (and (not (coding-system-equal cs suggested-cs)) + (y-or-n-p + (format "Current coding system %s does not use CR-LF line endings. Change to %s for save?" cs suggested-cs))) + (set-buffer-file-coding-system suggested-cs)) + (when (and (ical:contains-unfolded-lines-p) + (y-or-n-p "Fold content lines before saving?")) + (ical:fold-region (point-min) (point-max)))))) + +(add-hook 'before-save-hook 'ical:before-save-checks) + +;;; Mode definition +(define-derived-mode ical:mode text-mode "iCalendar" + "Major mode for viewing and editing iCalendar (RFC5545) data. + +This mode provides syntax highlighting for iCalendar components, +properties, values, and property parameters, and commands to deal +with folding and unfolding iCalendar content lines. + +`Folding' means inserting whitespace characters to continue long +lines; `unfolding' means removing the extra whitespace inserted +by folding. The iCalendar standard requires folding lines when +serializing data to iCalendar format, and unfolding before +parsing it. + +Thus icalendar-mode's syntax highlighting is designed to work with +unfolded lines. When icalendar-mode is activated, it will offer to +unfold lines; see `icalendar-switch-to-unfolded-buffer'. It will also +offer to fold lines when saving a buffer to a file; see +`icalendar-before-save-checks'. That function also offers to convert the +line endings in the file to CR-LF, as the standard requires." + :group 'icalendar + :syntax-table ical:mode-syntax-table + ;; TODO: Keymap? + ;; TODO: buffer-local variables? + ;; TODO: indent-line-function and indentation variables + ;; TODO: mode-specific menu and context menus + ;; TODO: eldoc integration + ;; TODO: completion of keywords + ;; TODO: hook for folding in change-major-mode-hook? + (progn + (setq font-lock-defaults '(ical:font-lock-keywords nil t)))) + +(provide 'icalendar-mode) + +;; Local Variables: +;; read-symbol-shorthands: (("ical:" . "icalendar-")) +;; End: +;;; icalendar-mode.el ends here diff --git a/lisp/calendar/icalendar-parser.el b/lisp/calendar/icalendar-parser.el index bc9524ff389..08cc4dbd0fb 100644 --- a/lisp/calendar/icalendar-parser.el +++ b/lisp/calendar/icalendar-parser.el @@ -41,12 +41,7 @@ ;; standard as type symbols. These type symbols store all the metadata ;; about the relevant types, and are used for type-based dispatch in the ;; parser and printer functions. In the abstract syntax tree, each node -;; contains a type symbol naming its type. -;; -;; The regular expressions defined by the `ical:define-*' macros are -;; also used to create entries for `font-lock-keywords', which are -;; gathered into several constants along the way, and used to provide -;; syntax highlighting in icalendar-mode.el. A number of other regular +;; contains a type symbol naming its type. A number of other regular ;; expressions which encode basic categories of the grammar are also ;; defined in this file. ;; @@ -1619,9 +1614,6 @@ ical:utc-offset ;;; Section 3.2: Property Parameters -(defconst ical:params-font-lock-keywords nil ;; populated by ical:define-param - "Entries for iCalendar property parameters in `font-lock-keywords'.") - (defconst ical:param-types nil ;; populated by ical:define-param "Alist mapping printed parameter names to type symbols") @@ -1756,7 +1748,6 @@ ical:altrepparam "Alternate text representation (URI)" ical:uri :quoted t - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.1") (ical:define-param ical:cnparam "CN" @@ -1778,7 +1769,6 @@ ical:cutypeparam ;; don't recognize the same way as they would the UNKNOWN ;; value": :unrecognized "UNKNOWN" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.3") (ical:define-param ical:delfromparam "DELEGATED-FROM" @@ -1791,7 +1781,6 @@ ical:delfromparam ical:cal-address :quoted t :list-sep "," - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.4") (ical:define-param ical:deltoparam "DELEGATED-TO" @@ -1804,7 +1793,6 @@ ical:deltoparam ical:cal-address :quoted t :list-sep "," - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.5") (ical:define-param ical:dirparam "DIR" @@ -1816,7 +1804,6 @@ ical:dirparam user which is the value of the property." ical:uri :quoted t - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.6") (ical:define-param ical:encodingparam "ENCODING" @@ -1827,7 +1814,6 @@ ical:encodingparam is \"BINARY\"." (or "8BIT" "BASE64") :default "8BIT" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.7") (rx-define ical:mimetype @@ -1867,7 +1853,6 @@ ical:fbtypeparam ical:x-name ical:iana-token) :default "BUSY" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.9") ;; TODO: see https://www.rfc-editor.org/rfc/rfc5646#section-2.1 @@ -1893,7 +1878,6 @@ ical:memberparam ical:cal-address :quoted t :list-sep "," - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.11") (ical:define-param ical:partstatparam "PARTSTAT" @@ -1925,7 +1909,6 @@ ical:partstatparam ;; they don't recognize the same way as they would the ;; NEEDS-ACTION value." :default "NEEDS-ACTION" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.12") (ical:define-param ical:rangeparam "RANGE" @@ -1936,7 +1919,6 @@ ical:rangeparam legacy applications might also produce \"THISANDPRIOR\"." "THISANDFUTURE" :default "THISANDFUTURE" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.13") (ical:define-param ical:trigrelparam "RELATED" @@ -1948,7 +1930,6 @@ ical:trigrelparam the start of the component; similarly for \"END\"." (or "START" "END") :default "START" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.14") (ical:define-param ical:reltypeparam "RELTYPE" @@ -1968,7 +1949,6 @@ ical:reltypeparam ;; "Applications MUST treat x-name and iana-token values they don't ;; recognize the same way as they would the PARENT value." :default "PARENT" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.15") (ical:define-param ical:roleparam "ROLE" @@ -1991,7 +1971,6 @@ ical:roleparam ;; they don't recognize the same way as they would the ;; REQ-PARTICIPANT value." :default "REQ-PARTICIPANT" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.16") (ical:define-param ical:rsvpparam "RSVP" @@ -2002,7 +1981,6 @@ ical:rsvpparam the Organizer of a VEVENT or VTODO." ical:boolean :default "FALSE" - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.17") (ical:define-param ical:sentbyparam "SENT-BY" @@ -2019,7 +1997,6 @@ ical:sentbyparam ;; have the same print name. ical:cal-address :quoted t - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.18") (ical:define-param ical:tzidparam "TZID" @@ -2107,7 +2084,6 @@ ical:valuetypeparam containing property's value, if it is not of the default value type." ical:printed-value-type - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.2.20") (ical:define-param ical:otherparam nil ; don't add to ical:param-types @@ -2117,9 +2093,7 @@ ical:otherparam parameters with an unknown name (matching rx `icalendar-param-name') whose values must be parsed and preserved but not further interpreted." - ical:param-value - :name-face font-lock-comment-face - :value-face font-lock-comment-face) + ical:param-value) (rx-define ical:other-param-safe ;; we use this rx to skip params when matching properties and @@ -2134,10 +2108,6 @@ ical:other-param-safe ;;; Properties: -(defconst ical:properties-font-lock-keywords - nil ;; populated by ical:define-property - "Entries for iCalendar properties in `font-lock-keywords'.") - (defconst ical:property-types nil ;; populated by ical:define-property "Alist mapping printed property names to type symbols") @@ -2373,7 +2343,6 @@ ical:calscale "GREGORIAN" :default "GREGORIAN" :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.7.1") (ical:define-property ical:method "METHOD" @@ -2440,8 +2409,6 @@ ical:attach ical:encodingparam) :zero-or-more (ical:otherparam)) :other-validator ical:attach-validator - :extra-faces ((13 'ical:uri t t) - (14 'ical:binary-data t t)) :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.1") (defun ical:attach-validator (node) @@ -2504,7 +2471,6 @@ ical:class :default "PUBLIC" :unrecognized "PRIVATE" :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.3") (ical:define-property ical:comment "COMMENT" @@ -2566,7 +2532,6 @@ ical:geo the equator if negative. The longitude value is east of the prime meridian if positive, and west of it if negative." ical:geo-coordinates - :value-face ical:numeric-types :child-spec (:zero-or-more (ical:otherparam)) :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.6") @@ -2595,7 +2560,6 @@ ical:percent-complete enforced here)." ical:integer :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:numeric-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.8") ;; TODO: type for priority values? @@ -2609,7 +2573,6 @@ ical:priority ical:integer :default "0" :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:numeric-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.9") (ical:define-property ical:resources "RESOURCES" @@ -2650,7 +2613,6 @@ ical:status at most once on these components." ical:status-keyword :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.11") (ical:define-property ical:summary "SUMMARY" @@ -2675,7 +2637,6 @@ ical:completed an `icalendar-vtodo' was actually completed. The value must be an `icalendar-date-time' with a UTC time." ical:date-time - :value-face ical:date-time-types :child-spec (:zero-or-more (ical:otherparam)) :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.2.1") @@ -2694,7 +2655,6 @@ ical:dtend :other-types (ical:date) :child-spec (:zero-or-one (ical:valuetypeparam ical:tzidparam) :zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.2.2") (ical:define-property ical:due "DUE" @@ -2712,7 +2672,6 @@ ical:due :other-types (ical:date) :child-spec (:zero-or-one (ical:valuetypeparam ical:tzidparam) :zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.2.3") (ical:define-property ical:dtstart "DTSTART" @@ -2739,7 +2698,6 @@ ical:dtstart :other-types (ical:date) :child-spec (:zero-or-one (ical:valuetypeparam ical:tzidparam) :zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.2.4") (ical:define-property ical:duration "DURATION" @@ -2757,7 +2715,6 @@ ical:duration value, then the duration must be given as a number of weeks or days." ical:dur-value :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.2.5") (ical:define-property ical:freebusy "FREEBUSY" @@ -2771,7 +2728,6 @@ ical:freebusy :list-sep "," :child-spec (:zero-or-one (ical:fbtypeparam) :zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.2.6") (ical:define-property ical:transp "TRANSP" @@ -2786,7 +2742,6 @@ ical:transp "OPAQUE") :default "OPAQUE" :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.2.7") ;;;;; Section 3.8.3: Time Zone Component Properties @@ -2824,7 +2779,6 @@ ical:tzoffsetfrom UTC)." ical:utc-offset :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.3.3") (ical:define-property ical:tzoffsetto "TZOFFSETTO" @@ -2839,7 +2793,6 @@ ical:tzoffsetto the prime meridian (behind UTC)." ical:utc-offset :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.3.4") (ical:define-property ical:tzurl "TZURL" @@ -2849,7 +2802,6 @@ ical:tzurl `icalendar-vtimezone' component are published." ical:uri :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.3.5") ;;;;; Section 3.8.4: Relationship Component Properties @@ -2885,7 +2837,6 @@ ical:attendee ical:dirparam ical:languageparam) :zero-or-more (ical:otherparam)) - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.1") (ical:define-property ical:contact "CONTACT" @@ -2915,7 +2866,6 @@ ical:organizer ical:sentbyparam ical:languageparam) :zero-or-more (ical:otherparam)) - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.3") (ical:define-property ical:recurrence-id "RECURRENCE-ID" @@ -2937,7 +2887,6 @@ ical:recurrence-id ical:tzidparam ical:rangeparam) :zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.4") (ical:define-property ical:related-to "RELATED-TO" @@ -2961,7 +2910,6 @@ ical:url `icalendar-vfreebusy' component." ical:uri :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:uri :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.6") ;; TODO: UID should probably be its own type @@ -2998,7 +2946,6 @@ ical:exdate :list-sep "," :child-spec (:zero-or-one (ical:valuetypeparam ical:tzidparam) :zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.5.1") (ical:define-property ical:rdate "RDATE" @@ -3018,7 +2965,6 @@ ical:rdate :list-sep "," :child-spec (:zero-or-one (ical:valuetypeparam ical:tzidparam) :zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.5.2") (ical:define-property ical:rrule "RRULE" @@ -3033,7 +2979,6 @@ ical:rrule ical:recur ;; TODO: faces for subexpressions? :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:recurrence-rule :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.5.3") ;;;;; Section 3.8.6: Alarm Component Properties @@ -3052,7 +2997,6 @@ ical:action ical:x-name))) :default-type ical:text :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:keyword :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.6.1") (ical:define-property ical:repeat "REPEAT" @@ -3065,7 +3009,6 @@ ical:repeat ical:integer :default 0 :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:numeric-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.6.2") (ical:define-property ical:trigger "TRIGGER" @@ -3087,7 +3030,6 @@ ical:trigger :child-spec (:zero-or-one (ical:valuetypeparam ical:trigrelparam) :zero-or-more (ical:otherparam)) :other-validator ical:trigger-validator - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.6.3") (defun ical:trigger-validator (node) @@ -3130,7 +3072,6 @@ ical:created in UTC time." ical:date-time :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.7.1") (ical:define-property ical:dtstamp "DTSTAMP" @@ -3154,7 +3095,6 @@ ical:dtstamp The value must be in UTC time." ical:date-time :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.7.2") (ical:define-property ical:last-modified "LAST-MODIFIED" @@ -3165,7 +3105,6 @@ ical:last-modified was last modified in the calendar database." ical:date-time :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:date-time-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.7.3") (ical:define-property ical:sequence "SEQUENCE" @@ -3180,7 +3119,6 @@ ical:sequence ical:integer :default 0 :child-spec (:zero-or-more (ical:otherparam)) - :value-face ical:numeric-types :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.7.4") ;;;;; Section 3.8.8: Miscellaneous Component Properties @@ -3204,11 +3142,6 @@ ical:other-property :child-spec (:allow-others t) :link "https://www.rfc-editor.org/rfc/rfc5545#section-3.8.8") -(defconst ical:ignored-properties-font-lock-keywords - `((,(rx ical:other-property) (1 'ical:ignored keep) - (2 'ical:ignored keep))) - "Entries for iCalendar ignored properties in `font-lock-keywords'.") - (defun ical:read-req-status-info (s) "Read a request status value from S. S should have been previously matched against `icalendar-request-status-info'." @@ -3281,10 +3214,6 @@ ical:request-status ;;; Section 3.6: Calendar Components -(defconst ical:components-font-lock-keywords - nil ;; populated by ical:define-component - "Entries for iCalendar components in `font-lock-keywords'.") - (defconst ical:component-types nil ;; populated by ical:define-component "Alist mapping printed component names to type symbols") -- 2.39.5