Skip to content
This repository has been archived by the owner on Sep 18, 2020. It is now read-only.

Commit

Permalink
Add support for refiling & aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
l3kn committed Apr 18, 2020
1 parent 2f561df commit 3a1a1a4
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 10 deletions.
123 changes: 113 additions & 10 deletions org-zk-core.el
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
;;; Configuration
;;; Customization

(defcustom org-zk-alias-keyword "ZK_ALIAS"
"Keyword for file title aliases")

(defvar org-zk-gtd-states
'("active"
Expand Down Expand Up @@ -172,6 +175,12 @@ then call ACTION with the collection that was selected."
:title
(or (alist-get "TITLE" org-keywords nil nil #'string=)
(file-relative-name filename (plist-get collection :path)))
:aliases
(mapcar
#'cdr
(remove-if-not
(lambda (kv) (string= (car kv) org-zk-alias-keyword))
org-keywords))
:collection (org-zk-collection-for-file filename)
:headlines (org-zk--cache-headlines el)))))

Expand Down Expand Up @@ -227,15 +236,36 @@ if not, return its filename."
(if collection
(cons
(format "%s (%s)" title (plist-get collection :name))
filename)
(cons title filename))
(cons (format "%s" title) filename))))))

(defun org-zk-files-with-titles-and-aliases ()
"Return an alist of entries (title-with-collection . filename).
Also treats file aliases as titles."
(org-el-cache-flatmap
org-zk-cache
(lambda (filename entry)
(let* ((collection (plist-get entry :collection))
(col-name (plist-get collection :name))
(titles (cons (plist-get entry :title)
(plist-get entry :aliases))))
(if collection
(mapcar
(lambda (title)
(cons
(format "%s (%s)" title col-name)
(cons title filename)))
titles)
(mapcar
(lambda (title) (cons (format "%s" title) (cons title filename)))
titles))))))

(defvar org-zk-ivy-histoy nil)

(defun org-zk-select-file (action)
(ivy-read
"File: "
(org-zk-files-with-titles)
(org-zk-files-with-titles-and-aliases)
:history 'org-zk-ivy-history
:action action))

Expand All @@ -246,7 +276,7 @@ if not, return its filename."
(lambda (selection)
(if (stringp selection)
(org-zk-new-file selection)
(find-file (cdr selection))))))
(find-file (cddr selection))))))

;;; Linking Files

Expand Down Expand Up @@ -277,9 +307,9 @@ creates a file with that title in collection of the current file."
title)))
(insert (org-zk-make-link
(file-relative-name
(cdr selection)
(cddr selection)
(file-name-directory (org-zk-buffer-file-name)))
(org-zk-file-title (cdr selection))))))))
(cadr selection)))))))

;;;; Finding Linked Files

Expand Down Expand Up @@ -487,7 +517,7 @@ buffer"
buffer."
(interactive)
(org-zk-select-file
(lambda (selection) (org-zk--file-to-headline (cdr selection)))))
(lambda (selection) (org-zk--file-to-headline (cddr selection)))))

;;; (Changing) File Keywords

Expand Down Expand Up @@ -518,6 +548,79 @@ buffer."
"Read a keyword."
(ivy-completing-read "Keyword: " (org-zk-keywords-used)))

(defun org-zk-add-alias (alias)
(interactive (list (read-string "Alias: ")))
(org-zk-keywords-add org-zk-alias-keyword alias))

;;; Refile

(defun org-zk-refile--position (file regexp)
"Find point of the first match of REGEXP in FILE.
Used to generate target positions for refiling to headlines."
(org-zk-in-file file
(save-excursion
(goto-char (point-min))
(and (re-search-forward regexp)
(point-at-bol)))))

;; `org-refile' is quite complicated, the best way to implement a
;; refile function seems to be generating a rfloc to pass to that
;; function.
;;
;; Refile Locations are lists of four elements:
;;
;; 1. The name used for showing them in `completing-read'
;; 2. The file to refile to
;; 3. nil or a regex matching the target heading
;; 4. point at target heading
;;
(defun org-zk-refile (&optional arg)
(interactive "P")
(org-zk-select-file
(lambda (file-selection)
(org-zk-refile--select-heading
(cddr file-selection)
(lambda (hl-selection)
(if (cdr hl-selection)
(let ((hl-regexp
(format org-complex-heading-regexp-format
(regexp-quote (cdr hl-selection)))))
(org-refile arg nil
(list
nil
(cddr file-selection)
hl-regexp
(org-zk-refile--position
(cddr file-selection)
hl-regexp))))
(org-refile
arg nil
(list nil (cddr file-selection) nil nil))))))))


;; Use cached headlines and add an option to refile as a new top-level
;; heading (value: nil)
(defun org-zk-refile--select-heading (file action)
"Call ACTION with a heading of FILE as refile target."
(let ((headlines
(cl-remove-if-not
(lambda (hl)
(<= (plist-get hl :level) org-zk-refile-maxlevel))
(plist-get
(org-el-cache-get org-zk-cache file)
:headlines))))
(if (null headlines)
(funcall action (cons nil nil))
(ivy-read
"File: "
(cons
(cons "<As top-level heading>" nil)
(mapcar
(lambda (hl) (cons (plist-get hl :title)
(plist-get hl :title)))
headlines))
:action action))))

;;; Agenda Hacks

(defun org-zk--has-todos (entry)
Expand Down Expand Up @@ -567,13 +670,13 @@ buffer."
buffer."
(interactive)
(org-zk-select-file
(lambda (selection) (org-zk--file-to-headline (cdr selection)))))
(lambda (selection) (org-zk--file-to-headline (cddr selection)))))

(defun org-zk-delete-file (file)
"Delete FILE, removing all links to it."
(let ((file (expand-file-name file)))
(dolist (entry (org-zk-files-linking-to file))
(org-zk-in-file (plist-get entry :file)
(dolist (other-file (org-zk-files-linking-to file))
(org-zk-in-file other-file
(org-zk-delete-link file)
(save-buffer)
(kill-buffer))))
Expand Down
5 changes: 5 additions & 0 deletions org-zk-hydra.el
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(require 'hydra)
(require 'org-zk-core)
(require 'org-zk-keywords)

(defhydra org-zk-hydra (:columns 4)
Expand All @@ -11,7 +12,11 @@
("o" org-zk-open-file "Open File")
("R" org-zk-rename "Rename")
("k" org-zk-add-keyword "Add Keyword")
("a" org-zk-add-alias "Add Alias")
("w" org-zk-refile "Refile")
("K" org-zk-edit-keywords "Add Keyword")
("G" org-zk-graphviz-show "Show Graph")
("j" org-zk-journal-today "Journal" :exit t)
;; I'm using C-b as a hotkey for the hydra
;; double-tapping b opens a file
("b" org-zk-open-file "Open File")
Expand Down

0 comments on commit 3a1a1a4

Please sign in to comment.