emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/calibre 47ae488aed 07/10: Drop EIEIO in favor of custom


From: ELPA Syncer
Subject: [elpa] externals/calibre 47ae488aed 07/10: Drop EIEIO in favor of custom editing solution
Date: Thu, 18 May 2023 12:57:32 -0400 (EDT)

branch: externals/calibre
commit 47ae488aed0ae84ecd0b20650e115abe262b9dae
Author: Kjartan Óli Ágústsson <kjartanoli@disroot.org>
Commit: Kjartan Óli Ágústsson <kjartanoli@disroot.org>

    Drop EIEIO in favor of custom editing solution
    
    * calibre-book.el: Don't require eieio.
    (calibre-book): Define using cl-defstruct.
    (calibre-book--slot): Delete since cl-defstruct provides this
    automatically.
    * calibre-cli.el (calibre-cli--make-book): Use the cl-defstruct
    provided make-calibre-book.
    * calibre-core.el (calibre-book--print-info, calibre-book--file): Drop
    the use of EIEIO macro with-slots.
    (calibre-core--get-titles, calibre-core--get-authors,
    calibre-core--get-tags, calibre-core--get-formats,
    calibre-core--get-series, calibre-core--get-publishers): Add an
    ignored optional argument to be valid FUN arguments to
    completion-table-dynamic.
    (calibre-authors-completion-table,
    calibre-publishers-completion-table, calibre-series-completion-table,
    calibre-tags-completion-table): Create completion tables.
    * calibre-db.el (calibre-db--make-book): Use the cl-defstruct provided 
make-calibre-book.
    * calibre-edit.el: Don't require eieio-custom.
    Require wid-edit and calibre-widgets.
    (calibre-edit--book, calibre-edit--title, calibre-edit--authors,
    calibre-edit--publisher, calibre-edit--series, calibre-edit--tags):
    Declare variables.
    (calibre-edit-apply):
    (calibre-edit-abort):
    (calibre-edit-reset):
    (calibre-edit-confirm):
    (calibre-edit-mode-map, calibre-edit-field-keymap): Define keymaps for
    editing books.
    (calibre-edit-mode): Define a mode for editing books.
    (calibre-edit-book):
    (eieio-done-customizing): Remove
    (calibre-edit--create-buffer): Add function to set up editing buffer.
    (calibre-edit--different-fields): Adjust to the cl-lib struct API.
    * calibre-widgets.el (calibre-author, calibre-publisher,
    calibre-series, calibre-tag, calibre-date): Add widgets.
---
 calibre-book.el    | 107 ++++++++++++------------------
 calibre-cli.el     |  26 ++++----
 calibre-core.el    |  55 ++++++++++------
 calibre-db.el      |  20 +++---
 calibre-edit.el    | 189 +++++++++++++++++++++++++++++++++++++++++++++++++----
 calibre-widgets.el |  73 +++++++++++++++++++++
 6 files changed, 346 insertions(+), 124 deletions(-)

diff --git a/calibre-book.el b/calibre-book.el
index c83885fbba..d72fa0a388 100644
--- a/calibre-book.el
+++ b/calibre-book.el
@@ -25,75 +25,50 @@
 ;; representations of books
 
 ;;; Code:
-(require 'eieio)
 (require 'parse-time)
 
-
-(defclass calibre-book ()
-  ((id :initarg :id
-       :type number
-       :documentation "The ID of the book in the Calibre database.")
-   (title :initarg :title
-          :type string
-          :documentation "The title of the book."
-          :custom string)
-   (authors :initarg :authors
-            :type list
-            :documentation "The authors of the book."
-            :custom (repeat (string :tag "Author")))
-   (publisher :initarg :publisher
-               :type (or string null)
-               :documentation "The publisher of the book."
-               :custom (choice (const nil) string))
-   (series :initarg :series
-           :initform nil
-           :type (or string null)
-           :documentation "The series the book is a part of."
-           :custom (choice (const nil) string))
-   (series-index :initarg :series-index
-                 :initform 1
-                 :type real
-                 :documentation "The book's position within its series."
-                 :custom number)
-   (formats :initarg :formats
-            :type list)
-   (timestamp :initarg :timestamp
-              :type list)
-   (pubdate :initarg :pubdate
-            :type list)
-   (last-modified :initarg :last-modified
-                  :type list)
-   (tags :initarg :tags
-         :initform '()
-         :type list
-         :documentation "Tags associated with the book."
-         :custom (repeat (string :tag "Tag")))
-   (path :initarg :path
+(cl-defstruct calibre-book
+  (id nil
+      :read-only t
+      :type integer
+      :documentation "The ID of the book in the Calibre database.")
+  (title nil
          :type string
-         :documentation "The book's position within the library")
-   (file-name :initarg :file-name
-              :type string
-              :documentation "The book's filename, sans extension.")))
-
-(defmacro calibre-book--slot (slot &optional internal)
-  "Create a function to access SLOT of a `calibre-book'.
-If INTERNAL is non nil the function name will follow the convention
-for private functions."
-  `(defun ,(intern (format "calibre-book-%s%s" (if internal "-" "") slot)) 
(book)
-     ,(format "Access the %s slot of a `calibre-book'." slot)
-     (slot-value book ',slot)))
-
-(calibre-book--slot id)
-(calibre-book--slot title)
-(calibre-book--slot authors)
-(calibre-book--slot publisher)
-(calibre-book--slot series)
-(calibre-book--slot series-index)
-(calibre-book--slot tags)
-(calibre-book--slot formats)
-(calibre-book--slot path t)
-(calibre-book--slot file-name)
-(calibre-book--slot pubdate)
+         :documentation "The title of the book.")
+  (authors nil
+           :type list
+           :documentation "The authors of the book.")
+  (publisher nil
+             :type (or string null)
+             :documentation "The publisher of the book.")
+  (series nil
+          :type (or string null)
+          :documentation "The series the book is a part of.")
+  (series-index 1
+                :type number
+                :documentation "The book's position within its series.")
+  (formats nil
+           :read-only t
+           :type list
+           :documentation "The formats the book is available in.")
+  (timestamp nil
+             :read-only t
+             :type list)
+  (pubdate nil
+           :type list
+           :documentation "The book's publication date.")
+  (last-modified nil
+                 :type list
+                 :documentation "The last time the book was modified.")
+  (tags nil
+        :type list
+        :documentation "Tags associated with the book.")
+  (path nil
+        :type string
+        :documentation "The book's position within the library")
+  (file-name nil
+             :type string
+             :documentation "The book's filename, sans extension."))
 
 (defcustom calibre-format-preferences '(pdf epub)
   "The preference order of file formats."
diff --git a/calibre-cli.el b/calibre-cli.el
index 345407c648..554fd2756a 100644
--- a/calibre-cli.el
+++ b/calibre-cli.el
@@ -48,19 +48,19 @@
 (defun calibre-cli--make-book (json)
   "Make a `calibre-book' from JSON."
   (let-alist json
-    (calibre-book :id .id
-                  :title .title
-                  :authors (calibre-cli--parse-authors .authors)
-                  :publisher .publisher
-                  :series .series
-                  :series-index .series_index
-                  :timestamp (calibre-cli--parse-timestamp .timestamp)
-                  :pubdate (calibre-cli--parse-timestamp .pubdate)
-                  :last-modified (calibre-cli--parse-timestamp .last_modified)
-                  :tags .tags
-                  :formats (calibre-cli--parse-formats .formats)
-                  :path (calibre-cli--parse-path .formats)
-                  :file-name (calibre-cli--parse-file-name .formats))))
+    (make-calibre-book :id .id
+                       :title .title
+                       :authors (calibre-cli--parse-authors .authors)
+                       :publisher .publisher
+                       :series .series
+                       :series-index .series_index
+                       :timestamp (calibre-cli--parse-timestamp .timestamp)
+                       :pubdate (calibre-cli--parse-timestamp .pubdate)
+                       :last-modified (calibre-cli--parse-timestamp 
.last_modified)
+                       :tags .tags
+                       :formats (calibre-cli--parse-formats .formats)
+                       :path (calibre-cli--parse-path .formats)
+                       :file-name (calibre-cli--parse-file-name .formats))))
 
 (defun calibre-cli--parse-authors (authors)
   "Parse AUTHORS a string, into a list of authors.
diff --git a/calibre-core.el b/calibre-core.el
index ff29f73641..52565ddd58 100644
--- a/calibre-core.el
+++ b/calibre-core.el
@@ -177,24 +177,25 @@ with values determined by `calibre-library-columns'."
   "Return list suitable as a value of `tabulated-list-entries'.
 BOOK is a `calibre-book'."
   (list book
-        (with-slots (id title authors publisher series series-index tags 
formats pubdate) book
-          (vconcat (mapcar (lambda (x)
-                             (let ((column (car x)))
-                               (cl-case column
-                                 (id (int-to-string id))
-                                 (title title)
-                                 (authors (string-join authors ", "))
-                                 (publisher (if (not publisher) "" publisher))
-                                 (series (if (not series) "" series))
-                                 (series-index (if series (format "%.1f" 
series-index) ""))
-                                 (tags (string-join tags ", "))
-                                 (formats (string-join (mapcar (lambda (f) 
(upcase (symbol-name f))) formats) ", "))
-                                 (pubdate (format-time-string 
calibre-library-time-format pubdate)))))
-                           calibre-library-columns)))))
+        (vconcat (mapcar (lambda (x)
+                           (let ((column (car x)))
+                             (cl-case column
+                               (id (int-to-string (calibre-book-id book)))
+                               (title (calibre-book-title book))
+                               (authors (string-join (calibre-book-authors 
book) ", "))
+                               (publisher (let ((publisher 
(calibre-book-publisher book)))
+                                            (if (not publisher) "" publisher)))
+                               (series (let ((series (calibre-book-series 
book))) (if (not series) "" series)))
+                               (series-index (if (calibre-book-series book) 
(format "%.1f" (calibre-book-series-index book)) ""))
+                               (tags (string-join (calibre-book-tags book) ", 
"))
+                               (formats (string-join (mapcar (lambda (f) 
(upcase (symbol-name f))) (calibre-book-formats book)) ", "))
+                               (pubdate (format-time-string 
calibre-library-time-format (calibre-book-pubdate book))))))
+                         calibre-library-columns))))
 
 (defun calibre-book--file (book format)
   "Return the path to BOOK in FORMAT."
-  (with-slots (path file-name) book
+  (let ((path (calibre-book-path book))
+        (file-name (calibre-book-file-name book)))
     (file-name-concat (calibre--library)
                       path
                       (format "%s.%s" file-name format))))
@@ -246,30 +247,42 @@ FILTERS should be a list of vectors, for the exact 
contents see
                                         books)
                     books))))
 
-(defun calibre-core--get-titles ()
+;; The ignored optional argument makes these functions valid arguments
+;; to completion-table-dynamic.
+(defun calibre-core--get-titles (&optional _)
   "Return a list of the titles in the active library."
   (calibre-core--interface get-titles))
 
-(defun calibre-core--get-authors ()
+(defun calibre-core--get-authors (&optional _)
   "Return a list of the authors in the active library."
   (calibre-core--interface get-authors))
 
-(defun calibre-core--get-tags ()
+(defun calibre-core--get-tags (&optional _)
   "Return a list of the tags in the active library."
   (calibre-core--interface get-tags))
 
-(defun calibre-core--get-formats ()
+(defun calibre-core--get-formats (&optional _)
   "Return a list of the file formats stored in the active library."
   (calibre-core--interface get-formats))
 
-(defun calibre-core--get-series ()
+(defun calibre-core--get-series (&optional _)
   "Return a list of the series in the active library."
   (calibre-core--interface get-series))
 
-(defun calibre-core--get-publishers ()
+(defun calibre-core--get-publishers (&optional _)
   "Return a list of the publishers in the active library."
   (calibre-core--interface get-publishers))
 
+;; Completion tables
+(defvar calibre-authors-completion-table
+  (completion-table-dynamic #'calibre-core--get-authors))
+(defvar calibre-publishers-completion-table
+  (completion-table-dynamic #'calibre-core--get-publishers))
+(defvar calibre-series-completion-table
+  (completion-table-dynamic #'calibre-core--get-series))
+(defvar calibre-tags-completion-table
+  (completion-table-dynamic #'calibre-core--get-tags))
+
 
 ;; These functions should be in calibre-cli.el, but they require
 ;; calibre--books because the calibredb interface does not expose the
diff --git a/calibre-db.el b/calibre-db.el
index d5b76c720d..43d27be43a 100644
--- a/calibre-db.el
+++ b/calibre-db.el
@@ -38,19 +38,19 @@ TIMESTAMP is a string of the form YYYY-MM-DD 
HH:MM:SS.xxxxxx+00:00."
 ENTRY is a list of the form:
 \(ID TITLE SERIES SERIES-INDEX TIMESTAMP PUBDATE LAST-MODIFIED)."
   (seq-let [id title series series-index timestamp pubdate last-modified path] 
entry
-    (calibre-book :id id
-                  :title title
-                  :authors (calibre-db--get-book-authors id)
-                  :publisher (calibre-db--get-book-publisher id)
-                  :series series
-                  :series-index series-index
-                  :tags (calibre-db--get-book-tags id)
-                  :formats (calibre-db--get-book-formats id)
-                  :path path
-                  :file-name (calibre-db--get-book-file-name id))))
+    (make-calibre-book :id id
+                       :title title
+                       :authors (calibre-db--get-book-authors id)
+                       :publisher (calibre-db--get-book-publisher id)
+                       :series series
+                       :series-index series-index
                        :timestamp (calibre-db--parse-timestamp timestamp)
                        :pubdate (calibre-db--parse-timestamp pubdate)
                        :last-modified (calibre-db--parse-timestamp 
last-modified)
+                       :tags (calibre-db--get-book-tags id)
+                       :formats (calibre-db--get-book-formats id)
+                       :path path
+                       :file-name (calibre-db--get-book-file-name id))))
 
 (defun calibre-db--get-book-authors (id)
   "Return a list of authors for the book identified by ID."
diff --git a/calibre-edit.el b/calibre-edit.el
index 4c2664664d..b22e4b7623 100644
--- a/calibre-edit.el
+++ b/calibre-edit.el
@@ -18,7 +18,8 @@
 ;; along with calibre.el.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Code:
-(require 'eieio-custom)
+(require 'wid-edit)
+(require 'calibre-widgets)
 (require 'calibre-core)
 (require 'calibre-util)
 (require 'calibre-exec)
@@ -26,19 +27,179 @@
 (defvar calibre-edit--edited-books nil
   "A list containing the original copies of edited books.")
 
+;; Declare these variables to prevent free variable warnings
+(defvar-local calibre-edit--book nil
+  "The book being edited in the current buffer.")
+(defvar-local calibre-edit--title nil
+  "The title widget in the current buffer.")
+(defvar-local calibre-edit--authors nil
+  "The authors widget in the current buffer.")
+(defvar-local calibre-edit--publisher nil
+  "The publisher widget in the current buffer.")
+(defvar-local calibre-edit--series nil
+  "The series widget in the current buffer.")
+(defvar-local calibre-edit--tags nil
+  "The tags widget in the current buffer.")
+
+(defun calibre-edit-apply (&rest _)
+  "Apply any edits to the book in the current buffer."
+  (interactive)
+  (setf (calibre-book-title calibre-edit--book) (widget-value 
calibre-edit--title)
+        (calibre-book-authors calibre-edit--book) (widget-value 
calibre-edit--authors)
+        (calibre-book-publisher calibre-edit--book) (widget-value 
calibre-edit--publisher)
+        (calibre-book-series calibre-edit--book) (if (consp (widget-value 
calibre-edit--series))
+                                                     (car (widget-value 
calibre-edit--series))
+                                                   nil)
+        (calibre-book-series-index calibre-edit--book) (if (consp 
(widget-value calibre-edit--series))
+                                                           (cdr (widget-value 
calibre-edit--series))
+                                                         1)
+        (calibre-book-tags calibre-edit--book) (widget-value 
calibre-edit--tags))
+    (calibre-library--refresh)
+    (let ((book calibre-edit--book))
+      (with-current-buffer (get-buffer calibre-library-buffer)
+        (calibre-library--find-book book)
+        (tabulated-list-put-tag (char-to-string calibre-mod-marker)))))
+
+(defun calibre-edit-abort (&rest _)
+  "Abort any changes made in the current buffer."
+  (interactive)
+  (let ((book calibre-edit--book))
+    (unless (calibre-edit--different-fields book (calibre-edit--find-original 
book))
+      (setf calibre-edit--edited-books (seq-remove (lambda (b)
+                                                     (= (calibre-book-id b)
+                                                        (calibre-book-id 
book)))
+                                                   
calibre-edit--edited-books))))
+  (quit-window t))
+
+(defun calibre-edit-reset (&rest _)
+  "Undo any changes made during this editing session."
+  (interactive)
+  (calibre-edit-book calibre-edit--book))
+
+(defun calibre-edit-confirm (&rest _)
+  "Apply any changes and exit."
+  (interactive)
+  (calibre-edit-apply)
+  (quit-window t))
+
+(defvar-keymap calibre-edit-mode-map
+  :doc "Keymap for `calibre-edit-mode'."
+  :parent widget-keymap
+  "C-c C-c" #'calibre-edit-confirm
+  "C-c C-a" #'calibre-edit-apply
+  "C-c C-r" #'calibre-edit-reset
+  "C-c C-k" #'calibre-edit-abort)
+
+(defvar-keymap calibre-edit-field-keymap
+  :doc "Keymap used inside editable fields in calibre edit buffers."
+  :parent widget-field-keymap
+  "C-c C-c" #'calibre-edit-confirm
+  "C-c C-a" #'calibre-edit-apply
+  "C-c C-r" #'calibre-edit-reset
+  "C-c C-k" #'calibre-edit-abort)
+
+(define-derived-mode calibre-edit-mode nil "Calibre Edit"
+  :group 'calibre
+  (widget-put (get 'editable-field 'widget-type) :keymap 
calibre-edit-field-keymap))
+
 (defun calibre-edit-book (book)
   "Edit the metadata of BOOK."
   (interactive (list (tabulated-list-get-id)) calibre-library-mode)
   (unless (calibre-util-find-book book calibre-edit--edited-books)
-    (push (clone book) calibre-edit--edited-books))
-  (eieio-customize-object book))
-
-(cl-defmethod eieio-done-customizing ((book calibre-book))
-  "Finalise the editing of BOOK."
-  (calibre-library--refresh)
-  (with-current-buffer (get-buffer calibre-library-buffer)
-    (calibre-library--find-book book)
-    (tabulated-list-put-tag (char-to-string calibre-mod-marker))))
+    (push (copy-calibre-book book) calibre-edit--edited-books))
+  (let ((buffer (calibre-edit--create-buffer book)))
+    (pop-to-buffer buffer)))
+
+(defun calibre-edit--create-buffer (book)
+  "Create a buffer for editing BOOK.
+Returns a buffer for editing BOOK, creating it if necessary."
+  (let ((buffer (get-buffer-create (format "*%s - Metadata*" 
(calibre-book-title book)))))
+    (with-current-buffer buffer
+      (kill-all-local-variables)
+      (let ((inhibit-read-only t))
+        (erase-buffer))
+      (remove-overlays)
+      (calibre-edit-mode)
+      (setf calibre-edit--book book)
+      (setq-local
+       header-line-format
+       (substitute-command-keys
+        "\\<calibre-edit-mode-map>Finish `\\[calibre-edit-confirm]', Apply 
`\\[calibre-edit-apply]', Reset `\\[calibre-edit-reset]', Cancel 
`\\[calibre-edit-abort]'"))
+      (setf calibre-edit--title
+            (widget-create 'string
+                           :value (calibre-book-title book)
+                           :tag "Title"
+                           :doc "The title of the book."
+                           :format "%t: %v%d"))
+      (widget-insert "\n")
+      (setf calibre-edit--authors
+            (widget-create 'repeat
+                           :value (calibre-book-authors book)
+                           :tag "Authors"
+                           :doc "The authors of the book."
+                           :format "%t:\n%v%i\n%d"
+                           'calibre-author))
+      (widget-insert "\n")
+      (setf calibre-edit--publisher
+            (widget-create 'choice
+                           :value (calibre-book-publisher book)
+                           :tag "Publisher"
+                           :doc "The publisher of the book."
+                           :format "%[%t%]%v%d"
+                           '(const :tag ": None" :menu-tag "None" nil)
+                           '(calibre-publisher :tag "" :menu-tag "Publisher")))
+      (widget-insert "\n")
+      (setf calibre-edit--series
+            (widget-create 'choice
+                           :value (if (calibre-book-series book)
+                                      (cons (calibre-book-series book)
+                                            (calibre-book-series-index book))
+                                    nil)
+                           :tag "Series"
+                           :format "%[%t%]%v%d"
+                           '(const :tag ": None" :menu-tag "None" nil)
+                           `(cons :tag ""
+                                  :menu-tag "Series"
+                                  (calibre-series :tag "Name"
+                                                  :doc "The series the book is 
part of."
+                                                  :format "%t:  %v%d")
+                                  (number :tag "Index"
+                                          :doc "The book's position within its 
series"
+                                          :format "%t: %v%d"
+                                          :value ,(calibre-book-series-index 
book)))))
+      (widget-insert "\n")
+      (setf calibre-edit--tags
+            (widget-create 'repeat
+                           :value (calibre-book-tags book)
+                           :tag "Tags"
+                           :doc "Tags associated with the book."
+                           :format "%t:\n%v%i\n%d"
+                           'calibre-tag))
+      (widget-insert "\n")
+      (widget-create 'push-button
+                     :tag "Confirm"
+                     :help-echo "Apply any changes and exit."
+                     :notify (lambda (&rest _)
+                               (calibre-edit-confirm)
+                               (kill-buffer)))
+      (widget-insert "   ")
+      (widget-create 'push-button
+                     :tag "Apply"
+                     :help-echo "Apply any changes."
+                     :notify #'calibre-edit-apply)
+      (widget-insert "   ")
+      (widget-create 'push-button
+                     :tag "Reset"
+                     :help-echo "Undo any changes."
+                     :notify #'calibre-edit-reset)
+      (widget-insert "   ")
+      (widget-create 'push-button
+                     :tag "Cancel"
+                     :help-echo "Abort all changes."
+                     :notify #'calibre-edit-abort)
+      (widget-setup)
+      (goto-char (point-min)))
+    buffer))
 
 (defun calibre-edit-revert (book)
   "Undo any edits performed to BOOK in this session."
@@ -58,10 +219,10 @@
 (defun calibre-edit--different-fields (a b)
   "Return a list of slot names whose values differ in A and B."
   (let (diff)
-    (dolist (descriptor (eieio-class-slots 'calibre-book))
-      (let* ((slot-name (eieio-slot-descriptor-name descriptor))
-             (a (slot-value a slot-name))
-             (b (slot-value b slot-name)))
+    (dolist (descriptor (cdr (cl-struct-slot-info 'calibre-book)))
+      (let* ((slot-name (car descriptor))
+             (a (cl-struct-slot-value 'calibre-book slot-name a))
+             (b (cl-struct-slot-value 'calibre-book slot-name b)))
         (unless (equal a b)
           (push slot-name diff))))
     diff))
diff --git a/calibre-widgets.el b/calibre-widgets.el
new file mode 100644
index 0000000000..641755b6dc
--- /dev/null
+++ b/calibre-widgets.el
@@ -0,0 +1,73 @@
+;;; calibre-widgets.el --- Widgets for editing book metadata.  -*- 
lexical-binding: t; -*-
+;; Copyright (C) 2023  Kjartan Óli Águstsson
+
+;; This program 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 program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; This file contains widgets for use in editing book metadata.
+
+;;; Code:
+(require 'calibre-core)
+
+(define-widget 'calibre-author 'string
+  "A author widget.
+It reads an Author's name from an editable text field."
+  :completions calibre-authors-completion-table
+  :format "%{%t%}: %v"
+  :tag "Author")
+
+(define-widget 'calibre-publisher 'string
+  "A publisher widget.
+It reads a Publisher's name from an editable text field."
+  :completions calibre-publishers-completion-table
+  :tag ""
+  :format "%{%t%}: %v")
+
+(define-widget 'calibre-series 'string
+  "A series widget.
+It reads a series's name from an editable text field."
+  :completions calibre-series-completion-table
+  :tag "Series"
+  :format "%{%t%}: %v")
+
+(define-widget 'calibre-tag 'string
+  "A tag widget.
+It reads a tag from an editable text field."
+  :completions calibre-tags-completion-table
+  :tag "Tag"
+  :format "%t %v")
+
+(define-widget 'calibre-series 'cons
+  nil
+  'calibre-series-name
+  '(number))
+
+(define-widget 'calibre-date 'vector
+  "A date widget.
+It reads a year, month, and day."
+  :value-to-internal (lambda (_widget value)
+                       (message "%s" value)
+                       (format-time-string "%F" value))
+  :value-to-external (lambda (_widget value)
+                       (message "to-ext: %s" value)
+                       (seq-let (year month day) value
+                         (parse-iso8601-time-string (format 
"%s-%s-%sT00:00:00" year month day))))
+  :convert-widget (lambda (widget)
+                    (widget-put widget :args '(vector (integer :tag "Year" 
:format "%t:  %v")
+                                                      (integer :tag "Month" 
:format "%t: %v")
+                                                      (integer :tag "Day" 
:format "%t:   %v")))
+                    widget))
+
+(provide 'calibre-widgets)
+;;; calibre-widgets.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]