Compare commits

...

2 Commits

Author SHA1 Message Date
55b2e50a81
wip2 2023-06-22 11:24:33 +10:00
1890d288f6
wip 2023-06-22 11:24:24 +10:00

View File

@ -61,9 +61,9 @@
"Retrieves the ENDPOINT from the current `bookstack-server' asynchronously,
executing CALLBACK with the decoded result."
(unless bookstack-token
(user-error "%s" "`bookstack-token' must be defined"))
(user-error "`bookstack-token' must be defined"))
(unless bookstack-server
(user-error "%s" "`bookstack-server' must be defined"))
(user-error "`bookstack-server' must be defined"))
(let ((url-request-extra-headers
`(("Authorization" . ,(format "Token %s" bookstack-token))
("Content-Type" . "application/json")))
@ -84,25 +84,31 @@ executing CALLBACK with the decoded result."
'utf-8)))
(bookstack--retrieve (format "pages/%d" id) (lambda (_)))))
(defun bookstack--read-page (pages)
"Reads a page from the user with `completing-read', returning its ID.
PAGES should be a sequence of pages (as returned by `bookstack-pages')."
(defun bookstack--read (prompt items)
"Reads an item from the user with `completing-read', returning its ID. ITEMS
should be a data sequence of items returned from a listing endpoint such as
`bookstack-pages'."
(let* ((opts (seq-reduce
(lambda (acc page)
(push `(,(alist-get 'name page) . ,(alist-get 'id page)) acc))
pages
(lambda (acc item)
(push `(,(alist-get 'name item) . ,(alist-get 'id item)) acc))
items
nil))
(page-name (progn
(switch-to-minibuffer)
(completing-read "Page: " opts))))
(completing-read prompt opts))))
(cdr (assoc page-name opts))))
(defun bookstack--read-book (books) (bookstack--read "Book: " books))
(defun bookstack--read-chapter (chapters) (bookstack--read "Chapter: " chapters))
(defun bookstack--read-page (pages) (bookstack--read "Page: " pages))
(defun bookstack--edit-page (id)
"Asynchronously loads a page by ID for editing into a new buffer."
(bookstack-page
id
(lambda (page)
(or page (error "Missing full page '%d'" id))
(unless page
(error "Missing page '%d'" id))
(let-alist page
(let ((buffer (get-buffer-create (format "%s.md" .name)))
;; fix line endings
@ -115,6 +121,18 @@ PAGES should be a sequence of pages (as returned by `bookstack-pages')."
(switch-to-buffer buffer)
(bookstack-mode +1))))))
(defun bookstack-books (callback)
"Retrieve all books from `bookstack-server'."
(bookstack--retrieve
"books"
(lambda (res) (apply callback (list (alist-get 'data res))))))
(defun bookstack-chapters (callback)
"Retrieve all chapters from `bookstack-server'."
(bookstack--retrieve
"chapters"
(lambda (res) (apply callback (list (alist-get 'data res))))))
(defun bookstack-pages (callback)
"Retrieve all pages from `bookstack-server'."
(bookstack--retrieve
@ -134,12 +152,63 @@ PAGES should be a sequence of pages (as returned by `bookstack-pages')."
(bookstack--write-page bookstack--buffer-page-id (buffer-string))
(message "Wrote %s/.../page/%s" bookstack-server slug)))
(defun bookstack--delete-page (id callback &optional force-p)
(bookstack-page
id
(lambda (page)
(let ((page-name (alist-get 'name page)))
(unless (or force-p (y-or-n-p (format "Really delete %S?" page-name)))
(user-error "Aborted"))
(let ((url-request-method "DELETE"))
(bookstack--retrieve
(format "pages/%d" page)
(lambda (_) (apply callback page))))))))
(defun bookstack-delete-page (&optional id force-p)
"Delete PAGE and kill its buffers.
If ID is not specified, defaults to the current buffer's page, if available.
If FORCE-P, delete without confirmation."
(interactive
(list bookstack--buffer-page-id
current-prefix-arg))
(unless (or id bookstack--buffer-page-id)
(user-error "Buffer is not visiting a BookStack page"))
(bookstack-pages
(lambda (pages)
(bookstack--delete-page (bookstack--read-page pages) force-p)
(lambda (page)
(let ((buf (current-buffer)))
(kill-buffer buf)
(message "Deleted %S" page))))))
(defun bookstack-delete-this-page (&optional id force-p)
"Delete PAGE and kill its buffers.
If ID is not specified, defaults to the current buffer's page, if available.
If FORCE-P, delete without confirmation."
(interactive
(list bookstack--buffer-page-id
current-prefix-arg))
(unless (or id bookstack--buffer-page-id)
(user-error "Buffer is not visiting a BookStack page"))
(bookstack-pages
(lambda (pages)
(bookstack--delete-page (bookstack--read-page pages) force-p)
(lambda (page)
(let ((buf (current-buffer)))
(kill-buffer buf)
(message "Deleted %S" page))))))
(define-minor-mode bookstack-mode
"Minor mode for editing remote BookStack buffers."
:init-value nil
:lighter " BookStack"
:keymap (let ((map (make-sparse-keymap)))
(define-key map [remap save-buffer] #'bookstack-save-buffer)
(define-key map [remap delete-file] #'bookstack-delete-page)
map))
;;;###autoload