From edcdcbaf89685f2f33439a381220f2173658d8ac Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 17:28:03 -0700 Subject: [PATCH 01/45] Add assertion and signal user-error in zk-desktop-make-buttons Provides more feedback to the user if they call `zk-desktop-make-buttons` directly and from the wrong buffer. --- zk-desktop.el | 134 +++++++++++++++++++++++++------------------------- 1 file changed, 68 insertions(+), 66 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 25cead7..48226d9 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -227,74 +227,76 @@ To quickly change this setting, call `zk-desktop-add-toggle'." (defun zk-desktop-make-buttons () "Re-make buttons in ZK-Desktop." (interactive) - (when (and (string-match-p zk-desktop-basename (buffer-name)) - (file-in-directory-p default-directory zk-desktop-directory)) - (let ((inhibit-read-only t)) - (save-excursion - ;; replace titles + (unless (and (string-match-p zk-desktop-basename (buffer-name)) + (file-in-directory-p default-directory zk-desktop-directory)) + (user-error "Can only make buttons in Zk desktop file; %s isn't" + (buffer-name))) + (let ((inhibit-read-only t)) + (save-excursion + ;; replace titles + (goto-char (point-min)) + (let* ((zk-alist (zk--alist)) + (ids (zk--id-list))) + (while (re-search-forward zk-id-regexp nil t) + (let* ((beg (line-beginning-position)) + (end (line-end-position)) + (id (progn + (save-match-data + (beginning-of-line) + (when (re-search-forward "\\[\\[" end t) + (replace-match "")) + (when (re-search-forward "]]" end t) + (replace-match ""))) + (match-string-no-properties 1))) + (title (buffer-substring-no-properties beg (match-beginning 0))) + (new-title (when (member id ids) + (concat zk-desktop-prefix + (zk--parse-id 'title id zk-alist) " ")))) + (beginning-of-line) + (if new-title + (unless (string= title new-title) + (progn + (search-forward title end) + (replace-match new-title))) + (progn + (search-forward title end) + (replace-match (propertize title 'face 'error)))) + (end-of-line))) + ;; make buttons (goto-char (point-min)) - (let* ((zk-alist (zk--alist)) - (ids (zk--id-list))) - (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (progn - (save-match-data - (beginning-of-line) - (when (re-search-forward "\\[\\[" end t) - (replace-match "")) - (when (re-search-forward "]]" end t) - (replace-match ""))) - (match-string-no-properties 1))) - (title (buffer-substring-no-properties beg (match-beginning 0))) - (new-title (when (member id ids) - (concat zk-desktop-prefix - (zk--parse-id 'title id zk-alist) " ")))) - (beginning-of-line) - (if new-title - (unless (string= title new-title) - (progn - (search-forward title end) - (replace-match new-title))) + (while (re-search-forward zk-id-regexp nil t) + (let* ((beg (line-beginning-position)) + (end (line-end-position)) + (id (match-string-no-properties 1))) + (if (member id ids) (progn - (search-forward title end) - (replace-match (propertize title 'face 'error)))) - (end-of-line))) - ;; make buttons - (goto-char (point-min)) - (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (match-string-no-properties 1))) - (if (member id ids) - (progn - (make-text-button beg end - 'type 'zk-desktop - 'help-echo zk-desktop-help-echo-function) - (when zk-desktop-invisible-ids - (beginning-of-line) - ;; find zk-links and plain zk-ids - (if (re-search-forward (zk-link-regexp) (line-end-position) t) - (replace-match - (propertize (match-string 0) 'invisible t) nil t) - (progn - (re-search-forward id) - (replace-match - (propertize id - 'read-only t - 'front-sticky t - 'rear-nonsticky t)) - ;; enable invisibility in org-mode - (overlay-put - (make-overlay (match-beginning 0) (match-end 0)) - 'invisible t)))) - (add-text-properties beg (+ beg 1) - '(front-sticky nil))) - (end-of-line) - (overlay-put (make-overlay (point) (point)) - 'before-string - (propertize" <- ID NOT FOUND" 'font-lock-face 'error)))) - (end-of-line))))))) + (make-text-button beg end + 'type 'zk-desktop + 'help-echo zk-desktop-help-echo-function) + (when zk-desktop-invisible-ids + (beginning-of-line) + ;; find zk-links and plain zk-ids + (if (re-search-forward (zk-link-regexp) (line-end-position) t) + (replace-match + (propertize (match-string 0) 'invisible t) nil t) + (progn + (re-search-forward id) + (replace-match + (propertize id + 'read-only t + 'front-sticky t + 'rear-nonsticky t)) + ;; enable invisibility in org-mode + (overlay-put + (make-overlay (match-beginning 0) (match-end 0)) + 'invisible t)))) + (add-text-properties beg (+ beg 1) + '(front-sticky nil))) + (end-of-line) + (overlay-put (make-overlay (point) (point)) + 'before-string + (propertize" <- ID NOT FOUND" 'font-lock-face 'error)))) + (end-of-line)))))) ;;; Utilities From 3df7809bdf12f0dd6f8104a7f045fcc091fa51c5 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 17:31:25 -0700 Subject: [PATCH 02/45] Pull out zk-alist and ids to a higher let* form Preserves horizontal space by eliminating one level of indentation. --- zk-desktop.el | 124 +++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 48226d9..a041c73 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -231,72 +231,72 @@ To quickly change this setting, call `zk-desktop-add-toggle'." (file-in-directory-p default-directory zk-desktop-directory)) (user-error "Can only make buttons in Zk desktop file; %s isn't" (buffer-name))) - (let ((inhibit-read-only t)) + (let* ((inhibit-read-only t) + (zk-alist (zk--alist)) + (ids (zk--id-list nil zk-alist))) (save-excursion ;; replace titles (goto-char (point-min)) - (let* ((zk-alist (zk--alist)) - (ids (zk--id-list))) - (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (progn - (save-match-data - (beginning-of-line) - (when (re-search-forward "\\[\\[" end t) - (replace-match "")) - (when (re-search-forward "]]" end t) - (replace-match ""))) - (match-string-no-properties 1))) - (title (buffer-substring-no-properties beg (match-beginning 0))) - (new-title (when (member id ids) - (concat zk-desktop-prefix - (zk--parse-id 'title id zk-alist) " ")))) - (beginning-of-line) - (if new-title - (unless (string= title new-title) - (progn - (search-forward title end) - (replace-match new-title))) - (progn - (search-forward title end) - (replace-match (propertize title 'face 'error)))) - (end-of-line))) - ;; make buttons - (goto-char (point-min)) - (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (match-string-no-properties 1))) - (if (member id ids) + (while (re-search-forward zk-id-regexp nil t) + (let* ((beg (line-beginning-position)) + (end (line-end-position)) + (id (progn + (save-match-data + (beginning-of-line) + (when (re-search-forward "\\[\\[" end t) + (replace-match "")) + (when (re-search-forward "]]" end t) + (replace-match ""))) + (match-string-no-properties 1))) + (title (buffer-substring-no-properties beg (match-beginning 0))) + (new-title (when (member id ids) + (concat zk-desktop-prefix + (zk--parse-id 'title id zk-alist) " ")))) + (beginning-of-line) + (if new-title + (unless (string= title new-title) (progn - (make-text-button beg end - 'type 'zk-desktop - 'help-echo zk-desktop-help-echo-function) - (when zk-desktop-invisible-ids - (beginning-of-line) - ;; find zk-links and plain zk-ids - (if (re-search-forward (zk-link-regexp) (line-end-position) t) - (replace-match - (propertize (match-string 0) 'invisible t) nil t) - (progn - (re-search-forward id) - (replace-match - (propertize id - 'read-only t - 'front-sticky t - 'rear-nonsticky t)) - ;; enable invisibility in org-mode - (overlay-put - (make-overlay (match-beginning 0) (match-end 0)) - 'invisible t)))) - (add-text-properties beg (+ beg 1) - '(front-sticky nil))) - (end-of-line) - (overlay-put (make-overlay (point) (point)) - 'before-string - (propertize" <- ID NOT FOUND" 'font-lock-face 'error)))) - (end-of-line)))))) + (search-forward title end) + (replace-match new-title))) + (progn + (search-forward title end) + (replace-match (propertize title 'face 'error)))) + (end-of-line))) + ;; make buttons + (goto-char (point-min)) + (while (re-search-forward zk-id-regexp nil t) + (let* ((beg (line-beginning-position)) + (end (line-end-position)) + (id (match-string-no-properties 1))) + (if (member id ids) + (progn + (make-text-button beg end + 'type 'zk-desktop + 'help-echo zk-desktop-help-echo-function) + (when zk-desktop-invisible-ids + (beginning-of-line) + ;; find zk-links and plain zk-ids + (if (re-search-forward (zk-link-regexp) (line-end-position) t) + (replace-match + (propertize (match-string 0) 'invisible t) nil t) + (progn + (re-search-forward id) + (replace-match + (propertize id + 'read-only t + 'front-sticky t + 'rear-nonsticky t)) + ;; enable invisibility in org-mode + (overlay-put + (make-overlay (match-beginning 0) (match-end 0)) + 'invisible t)))) + (add-text-properties beg (+ beg 1) + '(front-sticky nil))) + (end-of-line) + (overlay-put (make-overlay (point) (point)) + 'before-string + (propertize" <- ID NOT FOUND" 'font-lock-face 'error)))) + (end-of-line))))) ;;; Utilities From 40ad94134793ac5cdbb79378b5d40098f9e8701d Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 18:03:55 -0700 Subject: [PATCH 03/45] Extract zk-desktop--normalize-titles from zk-desktop-make-buttons Makes `zk-desktop-make-buttons` less imposing and self-documents. --- zk-desktop.el | 58 ++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index a041c73..67b411b 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -223,6 +223,37 @@ To quickly change this setting, call `zk-desktop-add-toggle'." 'face 'zk-desktop-button 'cursor-face 'highlight)) +(defun zk-desktop--normalize-titles (buffer id-list zk-alist) + "Normalize titles in a BUFFER based on ID-LIST and ZK-ALIST. +This is a helper function used by `zk-desktop-make-buttons'." + (with-current-buffer buffer + (goto-char (point-min)) + (while (re-search-forward zk-id-regexp nil t) + (let* ((beg (line-beginning-position)) + (end (line-end-position)) + (id (progn + (save-match-data + (beginning-of-line) + (when (re-search-forward "\\[\\[" end t) + (replace-match "")) + (when (re-search-forward "]]" end t) + (replace-match ""))) + (match-string-no-properties 1))) + (title (buffer-substring-no-properties beg (match-beginning 0))) + (new-title (when (member id id-list) + (concat zk-desktop-prefix + (zk--parse-id 'title id zk-alist) " ")))) + (beginning-of-line) + (if new-title + (unless (string= title new-title) + (progn + (search-forward title end) + (replace-match new-title))) + (progn + (search-forward title end) + (replace-match (propertize title 'face 'error)))) + (end-of-line))))) + ;;;###autoload (defun zk-desktop-make-buttons () "Re-make buttons in ZK-Desktop." @@ -236,32 +267,7 @@ To quickly change this setting, call `zk-desktop-add-toggle'." (ids (zk--id-list nil zk-alist))) (save-excursion ;; replace titles - (goto-char (point-min)) - (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (progn - (save-match-data - (beginning-of-line) - (when (re-search-forward "\\[\\[" end t) - (replace-match "")) - (when (re-search-forward "]]" end t) - (replace-match ""))) - (match-string-no-properties 1))) - (title (buffer-substring-no-properties beg (match-beginning 0))) - (new-title (when (member id ids) - (concat zk-desktop-prefix - (zk--parse-id 'title id zk-alist) " ")))) - (beginning-of-line) - (if new-title - (unless (string= title new-title) - (progn - (search-forward title end) - (replace-match new-title))) - (progn - (search-forward title end) - (replace-match (propertize title 'face 'error)))) - (end-of-line))) + (zk-desktop--normalize-titles (current-buffer) ids zk-alist) ;; make buttons (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) From c983f94ea85e2596b7369eb20191c7245ef5aaeb Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 18:05:46 -0700 Subject: [PATCH 04/45] Restructure zk-desktop--normalize-titles The function is easier to read and with fewer searches and replacements, there is less potential for errors to crop up. --- zk-desktop.el | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 67b411b..bdda849 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -229,29 +229,20 @@ This is a helper function used by `zk-desktop-make-buttons'." (with-current-buffer buffer (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (progn - (save-match-data - (beginning-of-line) - (when (re-search-forward "\\[\\[" end t) - (replace-match "")) - (when (re-search-forward "]]" end t) - (replace-match ""))) - (match-string-no-properties 1))) + (let* ((beg (line-beginning-position)) + (end (line-end-position)) + (id (match-string-no-properties 0)) (title (buffer-substring-no-properties beg (match-beginning 0))) (new-title (when (member id id-list) (concat zk-desktop-prefix (zk--parse-id 'title id zk-alist) " ")))) - (beginning-of-line) - (if new-title - (unless (string= title new-title) - (progn - (search-forward title end) - (replace-match new-title))) - (progn - (search-forward title end) - (replace-match (propertize title 'face 'error)))) + (delete-region beg end) + (insert (zk--format "%t %i" ; FIXME: Hardcoded + id + (if (null new-title) + (propertize title 'face 'error) + ;; If there is NEW-TITLE, just use that + new-title))) (end-of-line))))) ;;;###autoload From 47e09aa9903d034ac266dc7e8733c1db92346c23 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 18:10:07 -0700 Subject: [PATCH 05/45] Introduce zk-desktop-format rather than relying on zk-index-format --- zk-desktop.el | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index bdda849..5cb48d9 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -56,6 +56,11 @@ The names of all ZK-Desktops should begin with this string." "String to prepend to note names in ZK-Desktop." :type 'string) +(defcustom zk-desktop-format "%t %i" + "Format string for notes in ZK-Desktop. +See `zk-format-function' and `zk-format-id-and-title'." + :type 'string) + (defcustom zk-desktop-invisible-ids t "If non-nil, IDs will not be visible in the index." :type 'boolean) @@ -237,7 +242,7 @@ This is a helper function used by `zk-desktop-make-buttons'." (concat zk-desktop-prefix (zk--parse-id 'title id zk-alist) " ")))) (delete-region beg end) - (insert (zk--format "%t %i" ; FIXME: Hardcoded + (insert (zk--format zk-desktop-format id (if (null new-title) (propertize title 'face 'error) @@ -340,7 +345,7 @@ on zk-id at point." buffer (items (cond - (arg (zk--formatted-string arg zk-index-format)) + (arg (zk--formatted-string arg zk-desktop-format)) ((eq major-mode 'zk-index-mode) (if (use-region-p) (buffer-substring From 2762e80581f74c8bf5a17f9e711fe68eb7abd9cb Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 18:20:50 -0700 Subject: [PATCH 06/45] Fix reference to wrong group in zk-id-regexp (see PR #66) --- zk-desktop.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 5cb48d9..ac4bef7 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -262,14 +262,13 @@ This is a helper function used by `zk-desktop-make-buttons'." (zk-alist (zk--alist)) (ids (zk--id-list nil zk-alist))) (save-excursion - ;; replace titles (zk-desktop--normalize-titles (current-buffer) ids zk-alist) ;; make buttons (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) (let* ((beg (line-beginning-position)) (end (line-end-position)) - (id (match-string-no-properties 1))) + (id (match-string-no-properties 0))) (if (member id ids) (progn (make-text-button beg end From 20974559b8cda37952cd730ddc198492ed318c6c Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 18:22:00 -0700 Subject: [PATCH 07/45] Extract zk-desktop--make-button from zk-desktop-make-buttons This makes the code more modular and easier to maintain. --- zk-desktop.el | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index ac4bef7..1f7622a 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -250,6 +250,30 @@ This is a helper function used by `zk-desktop-make-buttons'." new-title))) (end-of-line))))) +(defun zk-desktop--make-button (id beg end) + "Make a ZK-Desktop button between BEG and END for ID." + (make-text-button beg end + 'type 'zk-desktop + 'help-echo zk-desktop-help-echo-function) + (when zk-desktop-invisible-ids + (beginning-of-line) + ;; find zk-links and plain zk-ids + (if (re-search-forward (zk-link-regexp) (line-end-position) t) + (replace-match + (propertize (match-string 0) 'invisible t) nil t) + (progn + (re-search-forward id) + (replace-match + (propertize id + 'read-only t + 'front-sticky t + 'rear-nonsticky t)) + ;; enable invisibility in org-mode + (overlay-put + (make-overlay (match-beginning 0) (match-end 0)) + 'invisible t)))) + (add-text-properties beg (+ beg 1) '(front-sticky nil))) + ;;;###autoload (defun zk-desktop-make-buttons () "Re-make buttons in ZK-Desktop." @@ -263,36 +287,13 @@ This is a helper function used by `zk-desktop-make-buttons'." (ids (zk--id-list nil zk-alist))) (save-excursion (zk-desktop--normalize-titles (current-buffer) ids zk-alist) - ;; make buttons (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) (let* ((beg (line-beginning-position)) (end (line-end-position)) (id (match-string-no-properties 0))) (if (member id ids) - (progn - (make-text-button beg end - 'type 'zk-desktop - 'help-echo zk-desktop-help-echo-function) - (when zk-desktop-invisible-ids - (beginning-of-line) - ;; find zk-links and plain zk-ids - (if (re-search-forward (zk-link-regexp) (line-end-position) t) - (replace-match - (propertize (match-string 0) 'invisible t) nil t) - (progn - (re-search-forward id) - (replace-match - (propertize id - 'read-only t - 'front-sticky t - 'rear-nonsticky t)) - ;; enable invisibility in org-mode - (overlay-put - (make-overlay (match-beginning 0) (match-end 0)) - 'invisible t)))) - (add-text-properties beg (+ beg 1) - '(front-sticky nil))) + (zk-desktop--make-button id beg end) (end-of-line) (overlay-put (make-overlay (point) (point)) 'before-string From 3305591fea60d786ca2dec209684e3fabe6909ec Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 19:00:39 -0700 Subject: [PATCH 08/45] Refactor zk-desktop--make-button: simplify structure, add comments --- zk-desktop.el | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 1f7622a..201f065 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -255,24 +255,22 @@ This is a helper function used by `zk-desktop-make-buttons'." (make-text-button beg end 'type 'zk-desktop 'help-echo zk-desktop-help-echo-function) - (when zk-desktop-invisible-ids + (if (not zk-desktop-invisible-ids) + ;; I.e. can add text in front of the button + (add-text-properties beg (+ beg 1) '(front-sticky nil)) + ;; Make both zk-links and plain zk-ids invisible (beginning-of-line) - ;; find zk-links and plain zk-ids - (if (re-search-forward (zk-link-regexp) (line-end-position) t) - (replace-match - (propertize (match-string 0) 'invisible t) nil t) - (progn - (re-search-forward id) - (replace-match - (propertize id - 'read-only t - 'front-sticky t - 'rear-nonsticky t)) - ;; enable invisibility in org-mode - (overlay-put - (make-overlay (match-beginning 0) (match-end 0)) - 'invisible t)))) - (add-text-properties beg (+ beg 1) '(front-sticky nil))) + (cond ((re-search-forward (zk-link-regexp) (line-end-position) t) + (replace-match (propertize (match-string 0) 'invisible t) nil t) + ;; Org-mode requires more drastic measures + (overlay-put (make-overlay (match-beginning 0) (match-end 0)) + 'invisible t)) + ((re-search-forward id) + ;; I.e. can add text in the rear of invis. IDs, but not in the front + (replace-match (propertize id + 'read-only t + 'front-sticky t + 'rear-nonsticky t)))))) ;;;###autoload (defun zk-desktop-make-buttons () From 7d164f3add5b658d5ee2659db6e27eaf1b859566 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 19:07:39 -0700 Subject: [PATCH 09/45] Rename zk-desktop-format custom variable to zk-desktop-button-format The name, along with the updated docstring, clarifies what this actually means. --- zk-desktop.el | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 201f065..93f1b3c 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -56,9 +56,14 @@ The names of all ZK-Desktops should begin with this string." "String to prepend to note names in ZK-Desktop." :type 'string) -(defcustom zk-desktop-format "%t %i" +(defcustom zk-desktop-button-format "%t %i" "Format string for notes in ZK-Desktop. -See `zk-format-function' and `zk-format-id-and-title'." +This is the format for the buttons in ZK-Desktop buffer; use +`zk-desktop-prefix' to add arbitary text that should not be +part of the button itself. + +See `zk-format-function' and `zk-format-id-and-title' for +valid control strings." :type 'string) (defcustom zk-desktop-invisible-ids t @@ -242,7 +247,7 @@ This is a helper function used by `zk-desktop-make-buttons'." (concat zk-desktop-prefix (zk--parse-id 'title id zk-alist) " ")))) (delete-region beg end) - (insert (zk--format zk-desktop-format + (insert (zk--format zk-desktop-button-format id (if (null new-title) (propertize title 'face 'error) @@ -343,7 +348,7 @@ on zk-id at point." buffer (items (cond - (arg (zk--formatted-string arg zk-desktop-format)) + (arg (zk--formatted-string arg zk-desktop-button-format)) ((eq major-mode 'zk-index-mode) (if (use-region-p) (buffer-substring From dc2fd1059685614de88dcfd17e542406f1c7bb88 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 19:08:42 -0700 Subject: [PATCH 10/45] Clarify what BEG and END mean for zk-desktop--make-button --- zk-desktop.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zk-desktop.el b/zk-desktop.el index 93f1b3c..ad07a39 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -256,7 +256,10 @@ This is a helper function used by `zk-desktop-make-buttons'." (end-of-line))))) (defun zk-desktop--make-button (id beg end) - "Make a ZK-Desktop button between BEG and END for ID." + "Make text between BEG and END into a ZK-Desktop button for zk ID. +BEG and END should be the bounds of the button itself, which +will inherit `zk-desktop-button' face and all text +properties defined for `zk-desktop-button' type." (make-text-button beg end 'type 'zk-desktop 'help-echo zk-desktop-help-echo-function) From cf64c4355feb6658facbb78caf457e67e0cb6f44 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 19:11:18 -0700 Subject: [PATCH 11/45] Change BEG and END in zk-desktop-make-buttons with direct references This clarifies what are the actual bounds for the button being made. --- zk-desktop.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index ad07a39..2cfac28 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -295,11 +295,11 @@ properties defined for `zk-desktop-button' type." (zk-desktop--normalize-titles (current-buffer) ids zk-alist) (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (match-string-no-properties 0))) + (let* ((id (match-string-no-properties 0))) (if (member id ids) - (zk-desktop--make-button id beg end) + (zk-desktop--make-button id + (line-beginning-position) + (line-end-position)) (end-of-line) (overlay-put (make-overlay (point) (point)) 'before-string From 43886f859251165cdc01499e42d9462331861664 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 19:46:44 -0700 Subject: [PATCH 12/45] Replace zk-desktop--normalize-titles with zk-desktop--normalize-line --- zk-desktop.el | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 2cfac28..6f193d6 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -233,27 +233,27 @@ To quickly change this setting, call `zk-desktop-add-toggle'." 'face 'zk-desktop-button 'cursor-face 'highlight)) -(defun zk-desktop--normalize-titles (buffer id-list zk-alist) - "Normalize titles in a BUFFER based on ID-LIST and ZK-ALIST. -This is a helper function used by `zk-desktop-make-buttons'." - (with-current-buffer buffer - (goto-char (point-min)) - (while (re-search-forward zk-id-regexp nil t) - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (match-string-no-properties 0)) - (title (buffer-substring-no-properties beg (match-beginning 0))) - (new-title (when (member id id-list) - (concat zk-desktop-prefix - (zk--parse-id 'title id zk-alist) " ")))) - (delete-region beg end) - (insert (zk--format zk-desktop-button-format - id - (if (null new-title) - (propertize title 'face 'error) - ;; If there is NEW-TITLE, just use that - new-title))) - (end-of-line))))) +(defun zk-desktop--normalize-line (id known-ids zk-alist) + "Normalize the current line in ZK-Desktop buffer containing ID. +KNOWN-IDS and ZK-ALIST are passed for efficiency. + +This is a helper function used by `zk-desktop-make-buttons' +and should not be called directly." + (let* ((beg (line-beginning-position)) + (end (line-end-position)) + (id (match-string-no-properties 0)) + (title (buffer-substring-no-properties beg (match-beginning 0))) + (new-title (when (member id known-ids) + (concat zk-desktop-prefix + (zk--parse-id 'title id zk-alist) " ")))) + (delete-region beg end) + (insert (zk--format zk-desktop-button-format + id + (if (null new-title) + (propertize title 'face 'error) + ;; If there is NEW-TITLE, just use that + new-title))) + (end-of-line))) (defun zk-desktop--make-button (id beg end) "Make text between BEG and END into a ZK-Desktop button for zk ID. @@ -292,14 +292,12 @@ properties defined for `zk-desktop-button' type." (zk-alist (zk--alist)) (ids (zk--id-list nil zk-alist))) (save-excursion - (zk-desktop--normalize-titles (current-buffer) ids zk-alist) (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) (let* ((id (match-string-no-properties 0))) + (zk-desktop--normalize-line id ids zk-alist) (if (member id ids) - (zk-desktop--make-button id - (line-beginning-position) - (line-end-position)) + (zk-desktop--make-button id ids zk-alist) (end-of-line) (overlay-put (make-overlay (point) (point)) 'before-string From 3e3c0d8aa55299bdaa5f653cca868eaa4b94b555 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 20:03:22 -0700 Subject: [PATCH 13/45] Rewrite zk-desktop--normalize-line to return button bounds --- zk-desktop.el | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 6f193d6..42eebb9 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -235,25 +235,30 @@ To quickly change this setting, call `zk-desktop-add-toggle'." (defun zk-desktop--normalize-line (id known-ids zk-alist) "Normalize the current line in ZK-Desktop buffer containing ID. -KNOWN-IDS and ZK-ALIST are passed for efficiency. +KNOWN-IDS and ZK-ALIST are passed for efficiency. Return a +tuple of bounds (BEG . END) of the actual zk-desktop-button +according to `zk-desktop-button-format'. This is a helper function used by `zk-desktop-make-buttons' and should not be called directly." - (let* ((beg (line-beginning-position)) - (end (line-end-position)) - (id (match-string-no-properties 0)) - (title (buffer-substring-no-properties beg (match-beginning 0))) + (let* ((lbeg (line-beginning-position)) + (lend (line-end-position)) + (id (match-string-no-properties 0)) + (title (buffer-substring-no-properties lbeg (match-beginning 0))) (new-title (when (member id known-ids) (concat zk-desktop-prefix - (zk--parse-id 'title id zk-alist) " ")))) - (delete-region beg end) - (insert (zk--format zk-desktop-button-format - id - (if (null new-title) - (propertize title 'face 'error) - ;; If there is NEW-TITLE, just use that - new-title))) - (end-of-line))) + (zk--parse-id 'title id zk-alist) " "))) + bounds) + (delete-region lbeg lend) + (cons (point) + (progn + (insert (zk--format zk-desktop-button-format + id + (if (null new-title) + (propertize title 'face 'error) + ;; If there is NEW-TITLE, just use that + new-title))) + (point))))) (defun zk-desktop--make-button (id beg end) "Make text between BEG and END into a ZK-Desktop button for zk ID. @@ -294,10 +299,10 @@ properties defined for `zk-desktop-button' type." (save-excursion (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) - (let* ((id (match-string-no-properties 0))) - (zk-desktop--normalize-line id ids zk-alist) + (let* ((id (match-string-no-properties 0)) + (bounds (zk-desktop--normalize-line id ids zk-alist))) (if (member id ids) - (zk-desktop--make-button id ids zk-alist) + (zk-desktop--make-button id (car bounds) (cdr bounds)) (end-of-line) (overlay-put (make-overlay (point) (point)) 'before-string From 701436d5018640dd2cfb9b259bb8026b926b999c Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 21:12:32 -0700 Subject: [PATCH 14/45] Rewrite zk-desktop--normalize-line to accept different arguments --- zk-desktop.el | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 42eebb9..e5c0b30 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -233,31 +233,23 @@ To quickly change this setting, call `zk-desktop-add-toggle'." 'face 'zk-desktop-button 'cursor-face 'highlight)) -(defun zk-desktop--normalize-line (id known-ids zk-alist) - "Normalize the current line in ZK-Desktop buffer containing ID. -KNOWN-IDS and ZK-ALIST are passed for efficiency. Return a -tuple of bounds (BEG . END) of the actual zk-desktop-button -according to `zk-desktop-button-format'. +(defun zk-desktop--normalize-line (id title missing) + "Prepare the current line in ZK-Desktop buffer for a button. +ID is the zk-ID; TITLE is either existing text in the buffer +or ID's current title; MISSING, if non-nil, means the ID is +not found in the current `zk-directory'. + +Return a tuple of bounds (BEG . END) for the actual +zk-desktop-button according to `zk-desktop-button-format'. This is a helper function used by `zk-desktop-make-buttons' and should not be called directly." (let* ((lbeg (line-beginning-position)) - (lend (line-end-position)) - (id (match-string-no-properties 0)) - (title (buffer-substring-no-properties lbeg (match-beginning 0))) - (new-title (when (member id known-ids) - (concat zk-desktop-prefix - (zk--parse-id 'title id zk-alist) " "))) - bounds) + (lend (line-end-position))) (delete-region lbeg lend) (cons (point) (progn - (insert (zk--format zk-desktop-button-format - id - (if (null new-title) - (propertize title 'face 'error) - ;; If there is NEW-TITLE, just use that - new-title))) + (insert (zk--format zk-desktop-button-format id title)) (point))))) (defun zk-desktop--make-button (id beg end) @@ -299,9 +291,12 @@ properties defined for `zk-desktop-button' type." (save-excursion (goto-char (point-min)) (while (re-search-forward zk-id-regexp nil t) - (let* ((id (match-string-no-properties 0)) - (bounds (zk-desktop--normalize-line id ids zk-alist))) - (if (member id ids) + (let* ((id (match-string-no-properties 0)) + (title (buffer-substring-no-properties + (line-beginning-position) (match-beginning 0))) + (missing (not (member id ids))) + (bounds (zk-desktop--normalize-line id title missing))) + (if (not missing) (zk-desktop--make-button id (car bounds) (cdr bounds)) (end-of-line) (overlay-put (make-overlay (point) (point)) From 168fa86ef18e6c73af7d6d60b86769d2e324d0db Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 21:20:08 -0700 Subject: [PATCH 15/45] Add zk-desktop-line-regexp --- zk-desktop.el | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/zk-desktop.el b/zk-desktop.el index e5c0b30..6596412 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -66,6 +66,17 @@ See `zk-format-function' and `zk-format-id-and-title' for valid control strings." :type 'string) +(defun zk-desktop-line-regexp () + "Return the regexp for the relevant ZK-DESKTOP lines. +The value is computed from `zk-desktop-prefix', +`zk-desktop-button-format', and `zk-id-regexp'. + +Group 1 is the zk-ID. +Group 2 is the title." + (zk--format (regexp-quote (concat zk-desktop-prefix zk-desktop-button-format)) + (concat "\\(?1:" zk-id-regexp "\\)") + (concat "\\(?2:" ".*" "\\)"))) ; FIXME: `zk-title-regexp' + (defcustom zk-desktop-invisible-ids t "If non-nil, IDs will not be visible in the index." :type 'boolean) From 7016422ef22495834e4767f8e3bf9c48af0a4b27 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 22:08:31 -0700 Subject: [PATCH 16/45] Propagate the use of zk-dekstop-button-regexp for button creation --- zk-desktop.el | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 6596412..92371a3 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -276,17 +276,20 @@ properties defined for `zk-desktop-button' type." (add-text-properties beg (+ beg 1) '(front-sticky nil)) ;; Make both zk-links and plain zk-ids invisible (beginning-of-line) - (cond ((re-search-forward (zk-link-regexp) (line-end-position) t) - (replace-match (propertize (match-string 0) 'invisible t) nil t) + (cond ((re-search-forward (zk-desktop-line-regexp) (line-end-position) t) + (replace-match (propertize (match-string 1) 'invisible t) nil t) ;; Org-mode requires more drastic measures - (overlay-put (make-overlay (match-beginning 0) (match-end 0)) + (overlay-put (make-overlay (match-beginning 1) (match-end 1)) 'invisible t)) - ((re-search-forward id) + ((re-search-forward id) ; misformatted line? ;; I.e. can add text in the rear of invis. IDs, but not in the front (replace-match (propertize id 'read-only t 'front-sticky t - 'rear-nonsticky t)))))) + 'rear-nonsticky t))) + (t + ;; Not our line; skip + )))) ;;;###autoload (defun zk-desktop-make-buttons () @@ -301,10 +304,9 @@ properties defined for `zk-desktop-button' type." (ids (zk--id-list nil zk-alist))) (save-excursion (goto-char (point-min)) - (while (re-search-forward zk-id-regexp nil t) - (let* ((id (match-string-no-properties 0)) - (title (buffer-substring-no-properties - (line-beginning-position) (match-beginning 0))) + (while (re-search-forward (zk-desktop-line-regexp) nil t) + (let* ((id (match-string-no-properties 1)) + (title (match-string-no-properties 2)) (missing (not (member id ids))) (bounds (zk-desktop--normalize-line id title missing))) (if (not missing) From c781fe17e9d0de4e7c61650f3d5d3bfe238b9965 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 22:43:04 -0700 Subject: [PATCH 17/45] Rename zk-desktop--normalize-line to zk-desktop--update-line --- zk-desktop.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 92371a3..8a705ad 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -244,7 +244,7 @@ To quickly change this setting, call `zk-desktop-add-toggle'." 'face 'zk-desktop-button 'cursor-face 'highlight)) -(defun zk-desktop--normalize-line (id title missing) +(defun zk-desktop--update-line (id title missing) "Prepare the current line in ZK-Desktop buffer for a button. ID is the zk-ID; TITLE is either existing text in the buffer or ID's current title; MISSING, if non-nil, means the ID is @@ -308,7 +308,7 @@ properties defined for `zk-desktop-button' type." (let* ((id (match-string-no-properties 1)) (title (match-string-no-properties 2)) (missing (not (member id ids))) - (bounds (zk-desktop--normalize-line id title missing))) + (bounds (zk-desktop--update-line id title missing))) (if (not missing) (zk-desktop--make-button id (car bounds) (cdr bounds)) (end-of-line) From 58a6f667efe6931ce839d3a1bde83b06c733d70e Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 22:53:12 -0700 Subject: [PATCH 18/45] Change zk-desktop-line-regexp to capture third group --- zk-desktop.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 8a705ad..bea6379 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -72,8 +72,12 @@ The value is computed from `zk-desktop-prefix', `zk-desktop-button-format', and `zk-id-regexp'. Group 1 is the zk-ID. -Group 2 is the title." - (zk--format (regexp-quote (concat zk-desktop-prefix zk-desktop-button-format)) +Group 2 is the title. +Group 3 is the entire button (sans `zk-desktop-prefix')." + (zk--format (concat "\\(?3:" + (regexp-quote zk-desktop-prefix) + (regexp-quote zk-desktop-button-format) + "\\)") (concat "\\(?1:" zk-id-regexp "\\)") (concat "\\(?2:" ".*" "\\)"))) ; FIXME: `zk-title-regexp' From 32ed50adc831b3150e7e214de93b40f26ad8d381 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 23:05:11 -0700 Subject: [PATCH 19/45] Rewrite zk-desktop--make-button to take match-data argument instead --- zk-desktop.el | 60 +++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index bea6379..0df3eff 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -267,33 +267,37 @@ and should not be called directly." (insert (zk--format zk-desktop-button-format id title)) (point))))) -(defun zk-desktop--make-button (id beg end) - "Make text between BEG and END into a ZK-Desktop button for zk ID. -BEG and END should be the bounds of the button itself, which -will inherit `zk-desktop-button' face and all text -properties defined for `zk-desktop-button' type." - (make-text-button beg end - 'type 'zk-desktop - 'help-echo zk-desktop-help-echo-function) - (if (not zk-desktop-invisible-ids) - ;; I.e. can add text in front of the button - (add-text-properties beg (+ beg 1) '(front-sticky nil)) - ;; Make both zk-links and plain zk-ids invisible - (beginning-of-line) - (cond ((re-search-forward (zk-desktop-line-regexp) (line-end-position) t) - (replace-match (propertize (match-string 1) 'invisible t) nil t) - ;; Org-mode requires more drastic measures - (overlay-put (make-overlay (match-beginning 1) (match-end 1)) - 'invisible t)) - ((re-search-forward id) ; misformatted line? - ;; I.e. can add text in the rear of invis. IDs, but not in the front - (replace-match (propertize id - 'read-only t - 'front-sticky t - 'rear-nonsticky t))) - (t - ;; Not our line; skip - )))) +(defun zk-desktop--make-button (match-data) + "Make a ZK-Desktop button based on MATCH-DATA. +The match data should have captured sub-expresions 1-3 +\(see `zk-desktop-line-regexp'). BEG and END should be the +bounds of the button itself, which will inherit +`zk-desktop-button' face and all text properties defined for +`zk-desktop-button' button type." + (save-match-data + (set-match-data match-data) + (make-text-button (match-beginning 3) (match-end 3) + 'type 'zk-desktop + 'help-echo zk-desktop-help-echo-function) + (if (not zk-desktop-invisible-ids) + ;; I.e. can add text in front of the button + (add-text-properties beg (+ beg 1) '(front-sticky nil)) + ;; Make both zk-links and plain zk-ids invisible + (beginning-of-line) + (cond ((re-search-forward (zk-desktop-line-regexp) (line-end-position) t) + (replace-match (propertize (match-string 1) 'invisible t) nil t) + ;; Org-mode requires more drastic measures + (overlay-put (make-overlay (match-beginning 1) (match-end 1)) + 'invisible t)) + ((re-search-forward id) ; misformatted line? + ;; I.e. can add text in the rear of invis. IDs, but not in the front + (replace-match (propertize id + 'read-only t + 'front-sticky t + 'rear-nonsticky t))) + (t + ;; Not our line; skip + ))))) ;;;###autoload (defun zk-desktop-make-buttons () @@ -314,7 +318,7 @@ properties defined for `zk-desktop-button' type." (missing (not (member id ids))) (bounds (zk-desktop--update-line id title missing))) (if (not missing) - (zk-desktop--make-button id (car bounds) (cdr bounds)) + (zk-desktop--make-button (match-data)) (end-of-line) (overlay-put (make-overlay (point) (point)) 'before-string From c3a9130817d08b77f3f63b036812e137fdee52a2 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 23:17:35 -0700 Subject: [PATCH 20/45] Rewrite zk-desktop--update-line not to bother with bounds --- zk-desktop.el | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 0df3eff..90eb91b 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -254,18 +254,10 @@ ID is the zk-ID; TITLE is either existing text in the buffer or ID's current title; MISSING, if non-nil, means the ID is not found in the current `zk-directory'. -Return a tuple of bounds (BEG . END) for the actual -zk-desktop-button according to `zk-desktop-button-format'. - This is a helper function used by `zk-desktop-make-buttons' and should not be called directly." - (let* ((lbeg (line-beginning-position)) - (lend (line-end-position))) - (delete-region lbeg lend) - (cons (point) - (progn - (insert (zk--format zk-desktop-button-format id title)) - (point))))) + (delete-region (line-beginning-position) (line-end-position)) + (insert (zk--format zk-desktop-button-format id title))) (defun zk-desktop--make-button (match-data) "Make a ZK-Desktop button based on MATCH-DATA. @@ -315,8 +307,8 @@ bounds of the button itself, which will inherit (while (re-search-forward (zk-desktop-line-regexp) nil t) (let* ((id (match-string-no-properties 1)) (title (match-string-no-properties 2)) - (missing (not (member id ids))) - (bounds (zk-desktop--update-line id title missing))) + (missing (not (member id ids)))) + (zk-desktop--update-line id title missing) (if (not missing) (zk-desktop--make-button (match-data)) (end-of-line) From 472580bc6b5e4d54bae7f6dec3f75c96312855b3 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 23:26:23 -0700 Subject: [PATCH 21/45] Inline zk-desktop--update-line back into zk-desktop-make-buttons --- zk-desktop.el | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 90eb91b..2d99bca 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -248,17 +248,6 @@ To quickly change this setting, call `zk-desktop-add-toggle'." 'face 'zk-desktop-button 'cursor-face 'highlight)) -(defun zk-desktop--update-line (id title missing) - "Prepare the current line in ZK-Desktop buffer for a button. -ID is the zk-ID; TITLE is either existing text in the buffer -or ID's current title; MISSING, if non-nil, means the ID is -not found in the current `zk-directory'. - -This is a helper function used by `zk-desktop-make-buttons' -and should not be called directly." - (delete-region (line-beginning-position) (line-end-position)) - (insert (zk--format zk-desktop-button-format id title))) - (defun zk-desktop--make-button (match-data) "Make a ZK-Desktop button based on MATCH-DATA. The match data should have captured sub-expresions 1-3 @@ -308,7 +297,8 @@ bounds of the button itself, which will inherit (let* ((id (match-string-no-properties 1)) (title (match-string-no-properties 2)) (missing (not (member id ids)))) - (zk-desktop--update-line id title missing) + (delete-region (line-beginning-position) (line-end-position)) + (insert (zk--format zk-desktop-button-format id title)) (if (not missing) (zk-desktop--make-button (match-data)) (end-of-line) From f340ab36b1aa4bab8ca6adf4160ff9660ff60dc5 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 23:33:43 -0700 Subject: [PATCH 22/45] Don't clear line; replace matched section of zk-desktop-line-regexp --- zk-desktop.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 2d99bca..8c61cde 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -297,8 +297,8 @@ bounds of the button itself, which will inherit (let* ((id (match-string-no-properties 1)) (title (match-string-no-properties 2)) (missing (not (member id ids)))) - (delete-region (line-beginning-position) (line-end-position)) - (insert (zk--format zk-desktop-button-format id title)) + (replace-match (zk--format zk-desktop-button-format id title) + nil t nil 0) (if (not missing) (zk-desktop--make-button (match-data)) (end-of-line) From 532e0dabce96036adab35a7a26e3b3f4a3084d2d Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 16 Jul 2023 23:49:07 -0700 Subject: [PATCH 23/45] Fix zk-desktop-line-regexp group 3; use in zk-desktop-make-buttons --- zk-desktop.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 8c61cde..e3f402f 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -74,8 +74,8 @@ The value is computed from `zk-desktop-prefix', Group 1 is the zk-ID. Group 2 is the title. Group 3 is the entire button (sans `zk-desktop-prefix')." - (zk--format (concat "\\(?3:" - (regexp-quote zk-desktop-prefix) + (zk--format (concat (regexp-quote zk-desktop-prefix) + "\\(?3:" (regexp-quote zk-desktop-button-format) "\\)") (concat "\\(?1:" zk-id-regexp "\\)") @@ -298,7 +298,7 @@ bounds of the button itself, which will inherit (title (match-string-no-properties 2)) (missing (not (member id ids)))) (replace-match (zk--format zk-desktop-button-format id title) - nil t nil 0) + nil t nil 3) (if (not missing) (zk-desktop--make-button (match-data)) (end-of-line) From b39e4cc43edcc7d7c7680573182c0cb01ae00c6f Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Mon, 17 Jul 2023 00:22:30 -0700 Subject: [PATCH 24/45] Fix unexpected match-data replacement by zk--format --- zk-desktop.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zk-desktop.el b/zk-desktop.el index e3f402f..d63215c 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -297,7 +297,8 @@ bounds of the button itself, which will inherit (let* ((id (match-string-no-properties 1)) (title (match-string-no-properties 2)) (missing (not (member id ids)))) - (replace-match (zk--format zk-desktop-button-format id title) + (replace-match (save-match-data + (zk--format zk-desktop-button-format id title)) nil t nil 3) (if (not missing) (zk-desktop--make-button (match-data)) From 51c3d857454757ede97175a622d9e33f87c036d1 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Mon, 17 Jul 2023 00:24:11 -0700 Subject: [PATCH 25/45] Restructure zk-desktop--make-button for clarity; update docstring --- zk-desktop.el | 59 +++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index d63215c..7bdd2b7 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -249,36 +249,39 @@ To quickly change this setting, call `zk-desktop-add-toggle'." 'cursor-face 'highlight)) (defun zk-desktop--make-button (match-data) - "Make a ZK-Desktop button based on MATCH-DATA. -The match data should have captured sub-expresions 1-3 -\(see `zk-desktop-line-regexp'). BEG and END should be the -bounds of the button itself, which will inherit -`zk-desktop-button' face and all text properties defined for -`zk-desktop-button' button type." + "Make a ZK-Desktop button on the current line. +The MATCH-DATA should have captured groups 1-3 (see +`zk-desktop-line-regexp'). Group 3 becomes the button +itself, which will inherit `zk-desktop-button' face and all +text properties defined for `zk-desktop-button' button +type." (save-match-data (set-match-data match-data) - (make-text-button (match-beginning 3) (match-end 3) - 'type 'zk-desktop - 'help-echo zk-desktop-help-echo-function) - (if (not zk-desktop-invisible-ids) - ;; I.e. can add text in front of the button - (add-text-properties beg (+ beg 1) '(front-sticky nil)) - ;; Make both zk-links and plain zk-ids invisible - (beginning-of-line) - (cond ((re-search-forward (zk-desktop-line-regexp) (line-end-position) t) - (replace-match (propertize (match-string 1) 'invisible t) nil t) - ;; Org-mode requires more drastic measures - (overlay-put (make-overlay (match-beginning 1) (match-end 1)) - 'invisible t)) - ((re-search-forward id) ; misformatted line? - ;; I.e. can add text in the rear of invis. IDs, but not in the front - (replace-match (propertize id - 'read-only t - 'front-sticky t - 'rear-nonsticky t))) - (t - ;; Not our line; skip - ))))) + (let ((beg (match-beginning 3)) + (end (match-end 3))) + (make-text-button beg end + 'type 'zk-desktop + 'help-echo zk-desktop-help-echo-function) + (if (not zk-desktop-invisible-ids) + ;; I.e. can add text in front of the button + (add-text-properties beg (1+ beg) '(front-sticky nil)) + ;; Make whole zk-links invisible, not just zk-ids + (beginning-of-line) + (cond ((re-search-forward (zk-link-regexp) (line-end-position) t) + (replace-match + (propertize (match-string-no-properties 0) 'invisible t) nil t) + ;; Org-mode requires more drastic measures + (overlay-put (make-overlay (match-beginning 0) (match-end 0)) + 'invisible t)) + ((re-search-forward id) + ;; I.e. can add text in the rear of invis. IDs, but not in the front + (replace-match (propertize id + 'read-only t + 'front-sticky t + 'rear-nonsticky t))) + (t + ;; Not our line; skip + )))))) ;;;###autoload (defun zk-desktop-make-buttons () From b359c92f084cb9a5f03fdc416c085e53e271b4bf Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Mon, 17 Jul 2023 00:46:45 -0700 Subject: [PATCH 26/45] Fix leftover overlays messing up ZK-Desktop buffer There were two issue: 1. With `zk-desktop-invisible-ids` set to T, we make the IDs invisible with text properties and overlays; setting `..-invisible-ids` to NIL and re-doing `zk-desktop-make-buttons` not only does not reveal invisible IDs, but makes the titles invisible too. 2. The overlay " <- ID NOT FOUND" stays in the buffer, so that repeated calls to `zk-desktop-make-buttons` results in more and more of these overlays being added to each line with a missing ID. --- zk-desktop.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zk-desktop.el b/zk-desktop.el index 7bdd2b7..61e54e1 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -294,6 +294,8 @@ type." (let* ((inhibit-read-only t) (zk-alist (zk--alist)) (ids (zk--id-list nil zk-alist))) + ;; Clear any residual overlays + (mapc #'delete-overlay (overlays-in (point-min) (point-max))) (save-excursion (goto-char (point-min)) (while (re-search-forward (zk-desktop-line-regexp) nil t) From 294af42e985de647def1547fe066e8c71c60a91f Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Fri, 21 Jul 2023 21:51:47 -0700 Subject: [PATCH 27/45] Extract zk-desktop--gather-items from zk-desktop-send-to-desktop Working to make `zk-desktop-send-to-desktop` more modular and simpler to maintain. --- zk-desktop.el | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 61e54e1..8c23b50 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -345,6 +345,29 @@ type." ;;; Commands +(defun zk-desktop--gather-items (arg) + "Normalize ARG into a list of files." + (cond + (arg (zk--formatted-string arg zk-desktop-button-format)) + ((eq major-mode 'zk-index-mode) + ;; TODO: This just copies the region into desktop file; need to + ;; reformat first, but it would be easier if + ;; `zk-index--current-id-list' could work with region. + (if (use-region-p) + (buffer-substring + (save-excursion + (goto-char (region-beginning)) + (line-beginning-position)) + (save-excursion + (goto-char (region-end)) + (line-end-position))) + (buffer-substring + (line-beginning-position) + (line-end-position)))) + ((zk-file-p) + (car (zk--formatter buffer-file-name zk-desktop-button-format))) + (t (user-error "No item to send to desktop")))) + ;;;###autoload (defun zk-desktop-send-to-desktop (&optional arg) "Send notes from ZK-Index to ZK-Desktop. @@ -355,28 +378,8 @@ on zk-id at point." (unless zk-desktop-directory (error "Please set `zk-desktop-directory' first")) (let ((inhibit-read-only t) - buffer - (items - (cond - (arg (zk--formatted-string arg zk-desktop-button-format)) - ((eq major-mode 'zk-index-mode) - (if (use-region-p) - (buffer-substring - (save-excursion - (goto-char (region-beginning)) - (line-beginning-position)) - (save-excursion - (goto-char (region-end)) - (line-end-position))) - (buffer-substring - (line-beginning-position) - (line-end-position)))) - ((zk-file-p) - (car - (funcall - zk-index-format-function - (list buffer-file-name)))) - (t (user-error "No item to send to desktop"))))) + (items (zk-desktop--gather-items arg)) + buffer) (if (and zk-desktop-current (buffer-live-p (get-buffer zk-desktop-current))) (setq buffer zk-desktop-current) From 72fe3f013a77eba890cb388153fa0687ffe4d435 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Fri, 21 Jul 2023 23:01:29 -0700 Subject: [PATCH 28/45] Fix: zk-desktop-select uses zk-desktop-basename as initial-input Despite `completing-read`'s docstring, this is a good case where INITIAL-INPUT ought to be used, since zk-desktop-basename is by no means a default value; it's just the beginning of any desktop file name. --- zk-desktop.el | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 8c23b50..9430afb 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -209,14 +209,12 @@ To quickly change this setting, call `zk-desktop-add-toggle'." (let* ((last-command last-command) (desktop (completing-read "Select or Create ZK-Desktop: " - (directory-files - zk-desktop-directory - nil - (concat - zk-desktop-basename - ".*")) - nil nil nil nil - (concat zk-desktop-basename " "))) + (directory-files zk-desktop-directory + nil + (concat + zk-desktop-basename + ".*")) + nil nil zk-desktop-basename nil)) (file (concat zk-desktop-directory "/" desktop))) (if (file-exists-p (expand-file-name file)) (setq zk-desktop-current From 640d1e1f491e63364414d69bc297da9478dae0ef Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Fri, 21 Jul 2023 23:04:45 -0700 Subject: [PATCH 29/45] Refactor: Update docstring for zk-desktop-select; simplify code --- zk-desktop.el | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 9430afb..c3e14c3 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -202,7 +202,9 @@ To quickly change this setting, call `zk-desktop-add-toggle'." ;;;###autoload (defun zk-desktop-select () - "Select a ZK-Desktop to work with." + "Select a ZK-Desktop to work with. +Return the buffer object visiting the selected or created +desktop." (interactive) (unless zk-desktop-directory (error "Please set `zk-desktop-directory' first")) @@ -216,12 +218,10 @@ To quickly change this setting, call `zk-desktop-add-toggle'." ".*")) nil nil zk-desktop-basename nil)) (file (concat zk-desktop-directory "/" desktop))) - (if (file-exists-p (expand-file-name file)) - (setq zk-desktop-current - (find-file-noselect file)) - (progn - (generate-new-buffer desktop) - (setq zk-desktop-current desktop))) + (setq zk-desktop-current + (if (file-exists-p (expand-file-name file)) + (find-file-noselect file) + (generate-new-buffer desktop))) (with-current-buffer zk-desktop-current (setq require-final-newline 'visit-save) (unless (bound-and-true-p truncate-lines) From 54a5a08a5b19da2c64e559692588dda0c87eeaaa Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Fri, 21 Jul 2023 23:06:11 -0700 Subject: [PATCH 30/45] Fix: Remove artifact and simplify code in zk-desktop-send-to-desktop Either `zk-desktop-current` is already a live buffer or `zk-desktop-select` creates one, there should be no case where we'd need to `generate-new-buffer`. Especially since it expects a name of a new buffer rather than whatever `buffer` variable ends up being. --- zk-desktop.el | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index c3e14c3..541af1f 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -377,13 +377,9 @@ on zk-id at point." (error "Please set `zk-desktop-directory' first")) (let ((inhibit-read-only t) (items (zk-desktop--gather-items arg)) - buffer) - (if (and zk-desktop-current - (buffer-live-p (get-buffer zk-desktop-current))) - (setq buffer zk-desktop-current) - (setq buffer (zk-desktop-select))) - (unless (get-buffer buffer) - (generate-new-buffer buffer)) + (buffer (if (buffer-live-p zk-desktop-current) + zk-desktop-current + (zk-desktop-select)))) (with-current-buffer buffer (setq require-final-newline 'visit-save) (pcase zk-desktop-add-pos From 9585cdb23b73b538cbcaf2bdff277937ccb9231b Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sat, 29 Jul 2023 17:24:58 -0700 Subject: [PATCH 31/45] Feat: Add 'type overlay property; add zk-desktop--clear to clear Adding the 'type property to overlays makes it possible to later selectively remove "our" overlays, which is what `zk-desktop--clear' does. --- zk-desktop.el | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 541af1f..61a3c1e 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -269,8 +269,9 @@ type." (replace-match (propertize (match-string-no-properties 0) 'invisible t) nil t) ;; Org-mode requires more drastic measures - (overlay-put (make-overlay (match-beginning 0) (match-end 0)) - 'invisible t)) + (let ((overlay (make-overlay (match-beginning 0) (match-end 0)))) + (overlay-put overlay 'invisible t) + (overlay-put overlay 'type 'zk-desktop))) ((re-search-forward id) ;; I.e. can add text in the rear of invis. IDs, but not in the front (replace-match (propertize id @@ -281,6 +282,15 @@ type." ;; Not our line; skip )))))) +(defun zk-desktop--clear () + "Clear special text properties added by `zk-desktop-make-buttons'. +This removes buttons, overlays, and text properties from the +entire buffer." + (save-excursion + (let ((inhibit-read-only t)) + (remove-overlays (point-min) (point-max) 'type 'zk-desktop) + (set-text-properties (point-min) (point-max) '())))) + ;;;###autoload (defun zk-desktop-make-buttons () "Re-make buttons in ZK-Desktop." @@ -292,8 +302,7 @@ type." (let* ((inhibit-read-only t) (zk-alist (zk--alist)) (ids (zk--id-list nil zk-alist))) - ;; Clear any residual overlays - (mapc #'delete-overlay (overlays-in (point-min) (point-max))) + (zk-desktop--clear) (save-excursion (goto-char (point-min)) (while (re-search-forward (zk-desktop-line-regexp) nil t) @@ -306,9 +315,11 @@ type." (if (not missing) (zk-desktop--make-button (match-data)) (end-of-line) - (overlay-put (make-overlay (point) (point)) - 'before-string - (propertize" <- ID NOT FOUND" 'font-lock-face 'error)))) + (let ((overlay (make-overlay (point) (point)))) + (overlay-put overlay 'type 'zk-desktop) + (overlay-put overlay + 'before-string + (propertize" <- ID NOT FOUND" 'font-lock-face 'error))))) (end-of-line))))) ;;; Utilities From a661768f43666a20869e39ee1cfd60d78fd8ec17 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 30 Jul 2023 00:13:55 -0700 Subject: [PATCH 32/45] Feat: Add SUFFIX argument to zk-desktop-send-to-desktop While `zk-desktop-prefix` is a static value, being able to pass a string for every item sent to the desktop allows for things like time-stamps or even brief comments. --- zk-desktop.el | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 61a3c1e..41193ce 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -378,11 +378,12 @@ entire buffer." (t (user-error "No item to send to desktop")))) ;;;###autoload -(defun zk-desktop-send-to-desktop (&optional arg) +(defun zk-desktop-send-to-desktop (&optional arg suffix) "Send notes from ZK-Index to ZK-Desktop. -In ZK-Index, works on note at point or notes in active region. -Also works on files or group of files in minibuffer, as ARG, and -on zk-id at point." +In ZK-Index, works on note at point or notes in active +region. Also works on files or group of files in minibuffer, +as ARG, and on zk-id at point. With non-nil SUFFIX, insert +it after each item." (interactive) (unless zk-desktop-directory (error "Please set `zk-desktop-directory' first")) @@ -403,7 +404,10 @@ on zk-id at point." ('prepend (progn (goto-char (point-min)))) ('at-point (goto-char (point)))) - (insert items "\n") + (mapc (lambda (i) + (insert (concat zk-desktop-prefix + i (or suffix "") "\n"))) + items) (beginning-of-line) (unless (bound-and-true-p truncate-lines) (toggle-truncate-lines)) From 0dff373985fb99486e3a0eb4e8bf8ca346b5a256 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 30 Jul 2023 00:15:47 -0700 Subject: [PATCH 33/45] Feat: Made zk-desktop-mode into a properly toggling minor mode This allows the user an option to treat Zk-Desktop file as a regular text file (in other words, without buttons, read-only text properties, or overlays). Someone who uses org-mode could, for example, just set it up that the Zk-Desktop files are annotated org-mode documents, with each item as a heading or a list item by setting `zk-desktop-prefix` to `"** "` or `"- "`, respectively. --- zk-desktop.el | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 41193ce..896c15e 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -121,11 +121,10 @@ To quickly change this setting, call `zk-desktop-add-toggle'." '((t :inherit default)) "Face used for buttons in `zk-desktop-mode'.") - ;;; Declarations -(defvar zk-desktop-current nil) - +(defvar zk-desktop-current nil + "Buffer object of the current Zk-Desktop.") ;;; Embark Integration @@ -155,13 +154,16 @@ To quickly change this setting, call `zk-desktop-add-toggle'." (define-minor-mode zk-desktop-mode "Minor mode for `zk-desktop'." + :lighter " Zk-Desktop" :init-value nil :keymap zk-desktop-map - (zk-desktop-make-buttons) - (when-let ((mode zk-desktop-major-mode)) - (funcall mode)) - ;;(setq truncate-lines t) - (setq-local zk-desktop-mode t)) + (cond (zk-desktop-mode ; enabled + (zk-desktop-make-buttons) + (when-let ((major-mode zk-desktop-major-mode)) + (funcall major-mode)) + (setq zk-desktop-mode t)) + (t ; disabled + (zk-desktop--clear)))) (eval-and-compile (defvar zk-desktop-button-map @@ -579,7 +581,6 @@ With prefix-argument, raise ZK-Desktop in other frame." (yank) (zk-desktop-make-buttons))) - (provide 'zk-desktop) ;;; zk-desktop.el ends here From 51e1ec9656da2c7ec5fd37c2a7984b960f336817 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sat, 5 Aug 2023 17:31:24 -0700 Subject: [PATCH 34/45] Feat: Add zk-desktop-make-buttons variable to manage button making --- zk-desktop.el | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 896c15e..555c48f 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -66,6 +66,10 @@ See `zk-format-function' and `zk-format-id-and-title' for valid control strings." :type 'string) +;; TODO: Combine with `zk-desktop-invisible-ids' +(defcustom zk-desktop-make-buttons t + "If non-nil, Zk-Desktop will make buttons.") + (defun zk-desktop-line-regexp () "Return the regexp for the relevant ZK-DESKTOP lines. The value is computed from `zk-desktop-prefix', @@ -158,7 +162,8 @@ To quickly change this setting, call `zk-desktop-add-toggle'." :init-value nil :keymap zk-desktop-map (cond (zk-desktop-mode ; enabled - (zk-desktop-make-buttons) + (when zk-desktop-make-buttons + (zk-desktop-make-buttons)) (when-let ((major-mode zk-desktop-major-mode)) (funcall major-mode)) (setq zk-desktop-mode t)) @@ -413,7 +418,8 @@ it after each item." (beginning-of-line) (unless (bound-and-true-p truncate-lines) (toggle-truncate-lines)) - (zk-desktop-mode)) + (when zk-desktop-make-buttons + (zk-desktop-make-buttons))) (if (eq major-mode 'zk-index-mode) (message "Sent to %s - press D to switch" buffer) (message "Sent to %s" buffer)))) @@ -458,7 +464,7 @@ With prefix-argument, raise ZK-Desktop in other frame." (forward-line 1) (transpose-lines 1) (forward-line -1) - (when zk-desktop-invisible-ids + (when (or zk-desktop-make-buttons zk-desktop-invisible-ids) (zk-desktop-make-buttons)))) (defun zk-desktop-move-line-up () @@ -467,7 +473,7 @@ With prefix-argument, raise ZK-Desktop in other frame." (let ((inhibit-read-only t)) (transpose-lines 1) (forward-line -2) - (when zk-desktop-invisible-ids + (when (or zk-desktop-make-buttons zk-desktop-invisible-ids) (zk-desktop-make-buttons)))) (defun zk-desktop-delete-region-maybe () @@ -579,7 +585,8 @@ With prefix-argument, raise ZK-Desktop in other frame." (interactive) (let ((inhibit-read-only t)) (yank) - (zk-desktop-make-buttons))) + (when zk-desktop-make-buttons + (zk-desktop-make-buttons)))) (provide 'zk-desktop) From 0f2f1d79f991dfaaae1af07632d8fd2bba0defb9 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sat, 5 Aug 2023 17:42:47 -0700 Subject: [PATCH 35/45] Feat: Fold zk-desktop-invisible-ids into zk-desktop-make-buttons --- zk-desktop.el | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 555c48f..dc83142 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -66,9 +66,16 @@ See `zk-format-function' and `zk-format-id-and-title' for valid control strings." :type 'string) -;; TODO: Combine with `zk-desktop-invisible-ids' (defcustom zk-desktop-make-buttons t - "If non-nil, Zk-Desktop will make buttons.") + "If non-nil, Zk-Desktop will make buttons. +Possible values are t (make normal buttons), 'invisible +\(make buttons with invisible IDs), or nil (don't make any +buttons)." + :type '(choice (const :tag "Yes" t) + (const :tag "Yes, with invisible IDs" invisible) + (const :tag "No" nil))) + +(make-obsolete-variable 'zk-desktop-invisible-ids 'zk-desktop-make-buttons "0.6") (defun zk-desktop-line-regexp () "Return the regexp for the relevant ZK-DESKTOP lines. @@ -85,10 +92,6 @@ Group 3 is the entire button (sans `zk-desktop-prefix')." (concat "\\(?1:" zk-id-regexp "\\)") (concat "\\(?2:" ".*" "\\)"))) ; FIXME: `zk-title-regexp' -(defcustom zk-desktop-invisible-ids t - "If non-nil, IDs will not be visible in the index." - :type 'boolean) - (defcustom zk-desktop-major-mode nil "Name of major-mode for ZK-Desktop buffers. The value should be a symbol that is a major mode command. @@ -267,7 +270,7 @@ type." (make-text-button beg end 'type 'zk-desktop 'help-echo zk-desktop-help-echo-function) - (if (not zk-desktop-invisible-ids) + (if (not (eq 'invisible zk-desktop-make-buttons)) ;; I.e. can add text in front of the button (add-text-properties beg (1+ beg) '(front-sticky nil)) ;; Make whole zk-links invisible, not just zk-ids @@ -464,7 +467,7 @@ With prefix-argument, raise ZK-Desktop in other frame." (forward-line 1) (transpose-lines 1) (forward-line -1) - (when (or zk-desktop-make-buttons zk-desktop-invisible-ids) + (when zk-desktop-make-buttons (zk-desktop-make-buttons)))) (defun zk-desktop-move-line-up () @@ -473,7 +476,7 @@ With prefix-argument, raise ZK-Desktop in other frame." (let ((inhibit-read-only t)) (transpose-lines 1) (forward-line -2) - (when (or zk-desktop-make-buttons zk-desktop-invisible-ids) + (when zk-desktop-make-buttons (zk-desktop-make-buttons)))) (defun zk-desktop-delete-region-maybe () From f912ac938e1d4f4a2a5289fd50725c9733714ab2 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 20 Aug 2023 12:55:57 -0700 Subject: [PATCH 36/45] Feat: Extend zk-index--current-id-list to work on region This is primarily useful for `zk-desktop--gather-items`, but might come in handy elsewhere too. --- zk-index.el | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/zk-index.el b/zk-index.el index fa324da..c005233 100644 --- a/zk-index.el +++ b/zk-index.el @@ -463,17 +463,26 @@ with query term STRING." (setq zk-index-query-mode-line nil zk-index-query-terms nil)) -(defun zk-index--current-id-list (buf-name) - "Return list of IDs for index in BUF-NAME, as filepaths." - (let (ids) - (with-current-buffer (or buf-name - zk-index-buffer-name) +(defun zk-index--current-id-list (buf-name &optional beg end) + "Return list of IDs for index in BUF-NAME. +If region is active, only return the IDs within the lines +between BEG and END." + (with-current-buffer buf-name + (let ((beg (if (not beg) + (point-min) + (goto-char beg) + (line-beginning-position))) + (end (if (not end) + (point-max) + (goto-char end) + (line-end-position))) + ids) (save-excursion - (goto-char (point-min)) + (goto-char beg) (save-match-data - (while (re-search-forward zk-id-regexp nil t) - (push (match-string-no-properties 0) ids))) - ids)))) + (while (re-search-forward zk-id-regexp end t) + (push (match-string-no-properties 0) ids)))) + ids))) ;;; Index Sort Functions From eba09cd575d2e5881ce7077703d50dc986d0579c Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 20 Aug 2023 12:57:56 -0700 Subject: [PATCH 37/45] Feat/Fix: zk-desktop--gather-items gathers IDs from Zk-Index region This requires extending `zk-index--current-id-list` to return IDs within the active region, but makes it possible to produce consistently-formatted Zk-Desktop file rather than relying on the customizable format of Zk-Index. --- zk-desktop.el | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index dc83142..6faeccc 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -366,26 +366,19 @@ entire buffer." (defun zk-desktop--gather-items (arg) "Normalize ARG into a list of files." - (cond - (arg (zk--formatted-string arg zk-desktop-button-format)) - ((eq major-mode 'zk-index-mode) - ;; TODO: This just copies the region into desktop file; need to - ;; reformat first, but it would be easier if - ;; `zk-index--current-id-list' could work with region. - (if (use-region-p) - (buffer-substring - (save-excursion - (goto-char (region-beginning)) - (line-beginning-position)) - (save-excursion - (goto-char (region-end)) - (line-end-position))) - (buffer-substring - (line-beginning-position) - (line-end-position)))) - ((zk-file-p) - (car (zk--formatter buffer-file-name zk-desktop-button-format))) - (t (user-error "No item to send to desktop")))) + (cond ((stringp arg) + (zk--formatter arg zk-desktop-button-format)) + ((eq major-mode 'zk-index-mode) + (if (use-region-p) + (zk-index--current-id-list (current-buffer) + (region-beginning) + (region-end)) + (zk-index--current-id-list (current-buffer) + (line-beginning-position) + (line-end-position)))) + ((zk-file-p) + (zk--formatter buffer-file-name zk-desktop-button-format)) + (t (user-error "No item to send to desktop")))) ;;;###autoload (defun zk-desktop-send-to-desktop (&optional arg suffix) From a70d869fae42b6f1cfa988600dd082e58c9f2457 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 20 Aug 2023 13:34:40 -0700 Subject: [PATCH 38/45] Feat: Rename zk-desktop-prefix and zk-desktop-button-format Renaming these to `zk-desktop-entry-prefix` and `zk-desktop-entry-format` distinguishes them from actual Emacs buttons that may or may not be created according to `zk-desktop-make-buttons`. --- zk-desktop.el | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 6faeccc..7c55107 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -52,15 +52,17 @@ The names of all ZK-Desktops should begin with this string." :type 'string) -(defcustom zk-desktop-prefix "" - "String to prepend to note names in ZK-Desktop." +(defcustom zk-desktop-entry-prefix "" + "String to prepend to entries in Zk-Desktop." :type 'string) -(defcustom zk-desktop-button-format "%t %i" - "Format string for notes in ZK-Desktop. -This is the format for the buttons in ZK-Desktop buffer; use -`zk-desktop-prefix' to add arbitary text that should not be -part of the button itself. +(defcustom zk-desktop-entry-format "%t %i" + "Format string for entries in ZK-Desktop. +This is the part of each line in ZK-Desktop buffer that +become buttons (see `zk-desktop-make-buttons'); use +`zk-desktop-entry-prefix' to add arbitary text at the +beginning of each line, and which would not be part of the +buttons themselves. See `zk-format-function' and `zk-format-id-and-title' for valid control strings." @@ -78,16 +80,16 @@ buttons)." (make-obsolete-variable 'zk-desktop-invisible-ids 'zk-desktop-make-buttons "0.6") (defun zk-desktop-line-regexp () - "Return the regexp for the relevant ZK-DESKTOP lines. -The value is computed from `zk-desktop-prefix', -`zk-desktop-button-format', and `zk-id-regexp'. + "Return the regexp for the relevant Zk-Desktop lines. +The value is computed from `zk-desktop-entry-prefix', +`zk-desktop-entry-format', and `zk-id-regexp'. Group 1 is the zk-ID. -Group 2 is the title. -Group 3 is the entire button (sans `zk-desktop-prefix')." - (zk--format (concat (regexp-quote zk-desktop-prefix) +Group 2 is the note title. +Group 3 is the entire entry." + (zk--format (concat (regexp-quote zk-desktop-entry-prefix) "\\(?3:" - (regexp-quote zk-desktop-button-format) + (regexp-quote zk-desktop-entry-format) "\\)") (concat "\\(?1:" zk-id-regexp "\\)") (concat "\\(?2:" ".*" "\\)"))) ; FIXME: `zk-title-regexp' @@ -320,7 +322,7 @@ entire buffer." (title (match-string-no-properties 2)) (missing (not (member id ids)))) (replace-match (save-match-data - (zk--format zk-desktop-button-format id title)) + (zk--format zk-desktop-entry-format id title)) nil t nil 3) (if (not missing) (zk-desktop--make-button (match-data)) @@ -357,7 +359,7 @@ entire buffer." (with-selected-window win (goto-char pos) (let* ((beg (+ (line-beginning-position) - (length zk-desktop-prefix))) + (length zk-desktop-entry-prefix))) (end (line-end-position)) (title (buffer-substring beg end))) (format "%s" title))))) @@ -367,7 +369,7 @@ entire buffer." (defun zk-desktop--gather-items (arg) "Normalize ARG into a list of files." (cond ((stringp arg) - (zk--formatter arg zk-desktop-button-format)) + (zk--formatter arg zk-desktop-entry-format)) ((eq major-mode 'zk-index-mode) (if (use-region-p) (zk-index--current-id-list (current-buffer) @@ -377,7 +379,7 @@ entire buffer." (line-beginning-position) (line-end-position)))) ((zk-file-p) - (zk--formatter buffer-file-name zk-desktop-button-format)) + (zk--formatter buffer-file-name zk-desktop-entry-format)) (t (user-error "No item to send to desktop")))) ;;;###autoload @@ -408,7 +410,7 @@ it after each item." (goto-char (point-min)))) ('at-point (goto-char (point)))) (mapc (lambda (i) - (insert (concat zk-desktop-prefix + (insert (concat zk-desktop-entry-prefix i (or suffix "") "\n"))) items) (beginning-of-line) From 177d918e88fcf23f10e1f2f8b004dde3bf60d073 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 20 Aug 2023 14:01:35 -0700 Subject: [PATCH 39/45] Feat: Add zk-desktop-entry-suffix The suffix argument to `zk-desktop-send-to-desktop` allows adding arbitrary text, such as the current time, for example, to each individual entry. In the future, the `-suffix` and `-prefix` variables can accept functions as well as strings to make that easier. --- zk-desktop.el | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 7c55107..465707a 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -56,13 +56,17 @@ The names of all ZK-Desktops should begin with this string." "String to prepend to entries in Zk-Desktop." :type 'string) +(defcustom zk-desktop-entry-suffix "" + "String to append to entries in Zk-Desktop." + :type 'string) + (defcustom zk-desktop-entry-format "%t %i" "Format string for entries in ZK-Desktop. This is the part of each line in ZK-Desktop buffer that become buttons (see `zk-desktop-make-buttons'); use -`zk-desktop-entry-prefix' to add arbitary text at the -beginning of each line, and which would not be part of the -buttons themselves. +`zk-desktop-entry-prefix' and `zk-desktop-entry-suffix' to +add arbitary text around the entry, and which would not be +part of the buttons themselves. See `zk-format-function' and `zk-format-id-and-title' for valid control strings." @@ -82,17 +86,19 @@ buttons)." (defun zk-desktop-line-regexp () "Return the regexp for the relevant Zk-Desktop lines. The value is computed from `zk-desktop-entry-prefix', -`zk-desktop-entry-format', and `zk-id-regexp'. +`zk-desktop-entry-suffix', `zk-desktop-entry-format', and +`zk-id-regexp'. -Group 1 is the zk-ID. +Group 1 is the note zk-ID. Group 2 is the note title. Group 3 is the entire entry." (zk--format (concat (regexp-quote zk-desktop-entry-prefix) "\\(?3:" (regexp-quote zk-desktop-entry-format) - "\\)") + "\\)" + (regexp-quote zk-desktop-entry-suffix)) (concat "\\(?1:" zk-id-regexp "\\)") - (concat "\\(?2:" ".*" "\\)"))) ; FIXME: `zk-title-regexp' + (concat "\\(?2:" ".*" "\\)"))) ; FIXME: `zk-title-regexp' (PR #68) (defcustom zk-desktop-major-mode nil "Name of major-mode for ZK-Desktop buffers. @@ -360,8 +366,9 @@ entire buffer." (goto-char pos) (let* ((beg (+ (line-beginning-position) (length zk-desktop-entry-prefix))) - (end (line-end-position)) - (title (buffer-substring beg end))) + (end (- (line-end-position) + (length zk-desktop-entry-suffix))) + (title (buffer-substring-no-properties beg end))) (format "%s" title))))) ;;; Commands @@ -409,9 +416,11 @@ it after each item." ('prepend (progn (goto-char (point-min)))) ('at-point (goto-char (point)))) - (mapc (lambda (i) + (mapc (lambda (item) (insert (concat zk-desktop-entry-prefix - i (or suffix "") "\n"))) + item + (or suffix zk-desktop-entry-suffix) + "\n"))) items) (beginning-of-line) (unless (bound-and-true-p truncate-lines) From e797c46dc24a0a75a9a0cc80156dcfc72f842a2d Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 20 Aug 2023 14:13:35 -0700 Subject: [PATCH 40/45] Doc: Rename ARG; rewrite docstring in zk-desktop-send-to-desktop --- zk-desktop.el | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 465707a..1b204b0 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -390,31 +390,33 @@ entire buffer." (t (user-error "No item to send to desktop")))) ;;;###autoload -(defun zk-desktop-send-to-desktop (&optional arg suffix) - "Send notes from ZK-Index to ZK-Desktop. +(defun zk-desktop-send-to-desktop (&optional items suffix) + "Add ITEMS to the current ZK-Desktop. In ZK-Index, works on note at point or notes in active region. Also works on files or group of files in minibuffer, -as ARG, and on zk-id at point. With non-nil SUFFIX, insert -it after each item." +passed as ITEMS, and on Zk-ID at point. With non-nil SUFFIX, +insert it after each entry. New entries are inserted +according to `zk-desktop-add-pos'. + +See `zk-desktop-entry-format', `zk-desktop-entry-prefix', +and `zk-desktop-entry-suffix' for the format of each line." (interactive) (unless zk-desktop-directory (error "Please set `zk-desktop-directory' first")) (let ((inhibit-read-only t) - (items (zk-desktop--gather-items arg)) + (items (zk-desktop--gather-items items)) (buffer (if (buffer-live-p zk-desktop-current) zk-desktop-current (zk-desktop-select)))) (with-current-buffer buffer (setq require-final-newline 'visit-save) (pcase zk-desktop-add-pos - ('append (progn - (goto-char (point-max)) - (beginning-of-line) - (when (looking-at-p ".") - (end-of-line) - (newline)))) - ('prepend (progn - (goto-char (point-min)))) + ('append (goto-char (point-max)) + (beginning-of-line) + (when (looking-at-p ".") + (end-of-line) + (newline))) + ('prepend (goto-char (point-min))) ('at-point (goto-char (point)))) (mapc (lambda (item) (insert (concat zk-desktop-entry-prefix From 44032c6149de928ba56d9b724e712c2c41517fea Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 20 Aug 2023 15:13:37 -0700 Subject: [PATCH 41/45] Feat: Add zk-desktop-mark-missing and zk-desktop-missing-button This allows customizing how missing IDs are handled. --- zk-desktop.el | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 1b204b0..1e2bc43 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -83,6 +83,16 @@ buttons)." (make-obsolete-variable 'zk-desktop-invisible-ids 'zk-desktop-make-buttons "0.6") +(defcustom zk-desktop-mark-missing "<- ID NOT FOUND" + "If non-nil, Zk-Desktop will mark missing IDs. +Possible values are a string for the text of an overlay to +add at the end of lines with missing IDs, non-nil to merely +display their buttons with `zk-desktop-missing-button' face, +or nil to eschew checking for missing IDs at all." + :type '(choice (string :tag "Add overlay text" "<- ID NOT FOUND") + (const :tag "Propertize missing" t) + (const :tag "Do not mark" nil))) + (defun zk-desktop-line-regexp () "Return the regexp for the relevant Zk-Desktop lines. The value is computed from `zk-desktop-entry-prefix', @@ -136,6 +146,10 @@ To quickly change this setting, call `zk-desktop-add-toggle'." '((t :inherit default)) "Face used for buttons in `zk-desktop-mode'.") +(defface zk-desktop-missing-button + '((t :inherit error)) + "Face used for buttons in `zk-desktop-mode' with missing IDs.") + ;;; Declarations (defvar zk-desktop-current nil @@ -333,11 +347,13 @@ entire buffer." (if (not missing) (zk-desktop--make-button (match-data)) (end-of-line) - (let ((overlay (make-overlay (point) (point)))) - (overlay-put overlay 'type 'zk-desktop) - (overlay-put overlay - 'before-string - (propertize" <- ID NOT FOUND" 'font-lock-face 'error))))) + (when (stringp zk-desktop-mark-missing) + (let ((overlay (make-overlay (point) (point)))) + (overlay-put overlay 'type 'zk-desktop) + (overlay-put overlay + 'before-string + (propertize zk-desktop-mark-missing + 'font-lock-face 'error)))))) (end-of-line))))) ;;; Utilities From 0eb0926f4a547371867655807b63e12badf94383 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Sun, 20 Aug 2023 18:16:37 -0700 Subject: [PATCH 42/45] Feat: Rewrite zk-desktop--make-button and zk-desktop-make-buttons Previously, `zk-desktop--make-button` relied on match-data from `zk-desktop-make-buttons`, which meant that it couldn't be called from other functions. While rewriting, also made a series of improvements: - `zk-desktop-make-buttons` only gathers list of IDs if `zk-desktop-mark-missing` is non-nil. - When zk-desktop-mark-missing is non-nil, but not a string, set the button face to `zk-desktop-missing-button`. - Add `button-data` text button property that contains the ID and TITLE for the zk-desktop entry. --- zk-desktop.el | 118 +++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 1e2bc43..4e37645 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -273,46 +273,50 @@ desktop." 'read-only t 'front-sticky t 'rear-sticky t + 'button-data nil ; filled by `zk-desktop--make-button' 'keymap zk-desktop-button-map 'action 'zk-desktop-button-action 'face 'zk-desktop-button 'cursor-face 'highlight)) -(defun zk-desktop--make-button (match-data) - "Make a ZK-Desktop button on the current line. -The MATCH-DATA should have captured groups 1-3 (see -`zk-desktop-line-regexp'). Group 3 becomes the button -itself, which will inherit `zk-desktop-button' face and all -text properties defined for `zk-desktop-button' button -type." +(defun zk-desktop--make-button () + "Try to make a ZK-Desktop button after point. +Return nil if there are no more buttons to be made in the +buffer. Otherwise, move point after the button created and +return a tuple of button boundaries." (save-match-data - (set-match-data match-data) - (let ((beg (match-beginning 3)) - (end (match-end 3))) - (make-text-button beg end + (when-let* ((beg (point)) + (_ (re-search-forward (zk-desktop-line-regexp) nil t)) + (id (match-string-no-properties 1)) + (id-beg (match-beginning 1)) + (id-end (match-end 1)) + (title (match-string-no-properties 2)) + (button-beg (match-beginning 3)) + (button-end (match-end 3))) + (replace-match (save-match-data + (zk--format zk-desktop-entry-format id title)) + nil t nil 3) + (if (not (eq 'invisible zk-desktop-make-buttons)) + ;; I.e. can add text in front of the button? + (add-text-properties button-beg (1+ button-beg) '(front-sticky nil)) + ;; Make entire link invisible, not just the ID + (goto-char beg) + (when (re-search-forward (zk-link-regexp) (line-end-position) t) + (setq id-beg (match-beginning 0) + id-end (match-end 0))) + ;; I.e. can add text in the rear of invisible IDs, but not in the front? + (add-text-properties id-beg id-end '(invisible t rear-nonsticky t)) + ;; Org-mode requires more drastic measures + (when (eq zk-desktop-major-mode 'org-mode) + (let ((overlay (make-overlay (match-beginning 0) (match-end 0)))) + (overlay-put overlay 'invisible t) + (overlay-put overlay 'type 'zk-desktop)))) + (make-text-button button-beg button-end 'type 'zk-desktop + 'button-data (list id title nil) ; matches `zk--alist' 'help-echo zk-desktop-help-echo-function) - (if (not (eq 'invisible zk-desktop-make-buttons)) - ;; I.e. can add text in front of the button - (add-text-properties beg (1+ beg) '(front-sticky nil)) - ;; Make whole zk-links invisible, not just zk-ids - (beginning-of-line) - (cond ((re-search-forward (zk-link-regexp) (line-end-position) t) - (replace-match - (propertize (match-string-no-properties 0) 'invisible t) nil t) - ;; Org-mode requires more drastic measures - (let ((overlay (make-overlay (match-beginning 0) (match-end 0)))) - (overlay-put overlay 'invisible t) - (overlay-put overlay 'type 'zk-desktop))) - ((re-search-forward id) - ;; I.e. can add text in the rear of invis. IDs, but not in the front - (replace-match (propertize id - 'read-only t - 'front-sticky t - 'rear-nonsticky t))) - (t - ;; Not our line; skip - )))))) + (goto-char button-end) + (cons button-beg button-end)))) (defun zk-desktop--clear () "Clear special text properties added by `zk-desktop-make-buttons'. @@ -325,36 +329,40 @@ entire buffer." ;;;###autoload (defun zk-desktop-make-buttons () - "Re-make buttons in ZK-Desktop." + "Re-make buttons in ZK-Desktop. +If `zk-desktop-make-buttons' is nil, just clear any existing +buttons and overlays." (interactive) (unless (and (string-match-p zk-desktop-basename (buffer-name)) (file-in-directory-p default-directory zk-desktop-directory)) (user-error "Can only make buttons in Zk desktop file; %s isn't" (buffer-name))) (let* ((inhibit-read-only t) - (zk-alist (zk--alist)) - (ids (zk--id-list nil zk-alist))) + (ids (if zk-desktop-mark-missing + (zk--id-list nil (zk--alist)) + nil)) + button-bounds) (zk-desktop--clear) - (save-excursion - (goto-char (point-min)) - (while (re-search-forward (zk-desktop-line-regexp) nil t) - (let* ((id (match-string-no-properties 1)) - (title (match-string-no-properties 2)) - (missing (not (member id ids)))) - (replace-match (save-match-data - (zk--format zk-desktop-entry-format id title)) - nil t nil 3) - (if (not missing) - (zk-desktop--make-button (match-data)) - (end-of-line) - (when (stringp zk-desktop-mark-missing) - (let ((overlay (make-overlay (point) (point)))) - (overlay-put overlay 'type 'zk-desktop) - (overlay-put overlay - 'before-string - (propertize zk-desktop-mark-missing - 'font-lock-face 'error)))))) - (end-of-line))))) + (when zk-desktop-make-buttons + (save-excursion + (goto-char (point-min)) + (while (setq button-bounds (zk-desktop--make-button)) + (let* ((button-data (get-text-property (car button-bounds) 'button-data)) + (button-id (car button-data))) + (cond ((and (stringp zk-desktop-mark-missing) + (not (member button-id ids))) + (let ((overlay (make-overlay (line-end-position) (line-end-position)))) + (overlay-put overlay 'type 'zk-desktop) + (overlay-put overlay 'before-string + (propertize zk-desktop-mark-missing + 'font-lock-face 'zk-desktop-missing-button)))) + ((and zk-desktop-mark-missing + (not (member button-id ids))) + (add-text-properties (car button-bounds) (cdr button-bounds) + '(face zk-desktop-missing-button))) + (t + ;; do nothing + )))))))) ;;; Utilities From 9e1d5f6d9bd307725cce52963159a33b6897b885 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Fri, 15 Sep 2023 21:48:22 -0700 Subject: [PATCH 43/45] Fix: zk-desktop-send-to-desktop does not remake all buttons If the desktop file is long, this is quite a significant performance boost for each call to `zk-desktop-send-to-desktop`. --- zk-desktop.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zk-desktop.el b/zk-desktop.el index 4e37645..4eeef6f 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -452,7 +452,7 @@ and `zk-desktop-entry-suffix' for the format of each line." (unless (bound-and-true-p truncate-lines) (toggle-truncate-lines)) (when zk-desktop-make-buttons - (zk-desktop-make-buttons))) + (zk-desktop--make-button))) (if (eq major-mode 'zk-index-mode) (message "Sent to %s - press D to switch" buffer) (message "Sent to %s" buffer)))) From 1c32bdd9655c86cdd5d32b77aefe5411d4d2ea1f Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Fri, 15 Sep 2023 22:57:56 -0700 Subject: [PATCH 44/45] Fix zk-index--current-id-list returning in wrong order; docstring --- zk-index.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zk-index.el b/zk-index.el index c005233..f60bf5f 100644 --- a/zk-index.el +++ b/zk-index.el @@ -465,8 +465,8 @@ with query term STRING." (defun zk-index--current-id-list (buf-name &optional beg end) "Return list of IDs for index in BUF-NAME. -If region is active, only return the IDs within the lines -between BEG and END." +If BEG and END are given, only return the IDs in the lines +between those positions, inclusive." (with-current-buffer buf-name (let ((beg (if (not beg) (point-min) @@ -482,7 +482,7 @@ between BEG and END." (save-match-data (while (re-search-forward zk-id-regexp end t) (push (match-string-no-properties 0) ids)))) - ids))) + (nreverse ids)))) ;;; Index Sort Functions From d3b74dd10a3b129969d16982fff25f24860aac31 Mon Sep 17 00:00:00 2001 From: Richard Boyechko Date: Fri, 15 Sep 2023 23:08:28 -0700 Subject: [PATCH 45/45] Fix zk-desktop--gather-items not formatting IDs from zk-index --- zk-desktop.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/zk-desktop.el b/zk-desktop.el index 4eeef6f..9baddaa 100644 --- a/zk-desktop.el +++ b/zk-desktop.el @@ -402,13 +402,14 @@ buttons and overlays." (cond ((stringp arg) (zk--formatter arg zk-desktop-entry-format)) ((eq major-mode 'zk-index-mode) - (if (use-region-p) - (zk-index--current-id-list (current-buffer) - (region-beginning) - (region-end)) - (zk-index--current-id-list (current-buffer) - (line-beginning-position) - (line-end-position)))) + (let ((ids (if (use-region-p) + (zk-index--current-id-list (current-buffer) + (region-beginning) + (region-end)) + (zk-index--current-id-list (current-buffer) + (line-beginning-position) + (line-end-position))))) + (zk--formatter ids zk-desktop-entry-format))) ((zk-file-p) (zk--formatter buffer-file-name zk-desktop-entry-format)) (t (user-error "No item to send to desktop"))))