summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2020-03-15 15:17:53 +0000
committerYann Herklotz <git@yannherklotz.com>2020-03-15 15:17:53 +0000
commit437aaf1a29b8469a27b44754376bc78b3b61d77c (patch)
treec89a60b8281701ba0391256165de75e6fb00b547
parent45f0bd1c6a7463ec893172b7f725a93be3ffdd1c (diff)
downloadorg-zettelkasten-437aaf1a29b8469a27b44754376bc78b3b61d77c.tar.gz
org-zettelkasten-437aaf1a29b8469a27b44754376bc78b3b61d77c.zip
Add backlink to parent
-rw-r--r--zettelkasten.el115
1 files changed, 74 insertions, 41 deletions
diff --git a/zettelkasten.el b/zettelkasten.el
index dde92e1..c3d62f3 100644
--- a/zettelkasten.el
+++ b/zettelkasten.el
@@ -21,82 +21,115 @@ After that, changing the prefix key requires manipulating keymaps."
:type 'string
:group 'zettelkasten)
-(defcustom zettelkasten-file-format "%y%W%u%%03d.org"
+(defcustom zettelkasten-file-format "%y%W%u%%02d"
"Format for new zettelkasten files.
For supported options, please consult `format-time-string'."
:type 'string
:group 'zettelkasten)
-(defcustom zettelkasten-top-level "index.org"
- "Top level zettelkasten file that starts the DAG hierarchy."
+(defcustom zettelkasten-link-format "[[./%2$s.%3$s][%1$s]]"
+ "Zettelkasten link format."
:type 'string
:group 'zettelkasten)
-(defun zettelkasten-make-filename (filename)
- "Make a filename using the default directory and the FILENAME passed to it."
- (expand-file-name (concat zettelkasten-directory "/" filename)))
+(defcustom zettelkasten-extension "org"
+ "Default extension for notes."
+ :type 'string
+ :group 'zettelkasten)
+
+(defun zettelkasten-make-filename (note)
+ "Make a filename using the default directory and the NOTE passed to it."
+ (expand-file-name (concat zettelkasten-directory "/" note "." zettelkasten-extension)))
(defun zettelkasten-filename-to-id (filename)
"Convert FILENAME to id."
- (progn (string-match "\\(.*\\)\\.org\\'" filename)
- (match-string 1 filename)))
+ (string-match (format "\\(.*\\)\\.%s\\'" zettelkasten-extension) filename)
+ (match-string 1 filename))
(defun zettelkasten-list-notes-by-id ()
"Return all the ids that are currently available."
(mapcar #'zettelkasten-filename-to-id
(directory-files
- (expand-file-name zettelkasten-directory) nil "\\.org$" t)))
+ (expand-file-name zettelkasten-directory) nil
+ (format "\\.%s$" zettelkasten-extension) t)))
(defun zettelkasten-list-notes ()
"Return all the ids and titles of notes in the `zettelkasten-directory'."
- (progn (shell-command (concat "grep -i \"#+TITLE:\" " zettelkasten-directory "/*"))
- (setq match-list nil)
- (with-current-buffer "*Shell Command Output*"
- (progn
- (set-buffer "*Shell Command Output*")
- (setq morelines t)
- (goto-char 1)
- (while morelines
- (setq current-string (buffer-substring-no-properties (line-beginning-position) (line-end-position)))
- (when (string-match "\\([0-9]*\\)\\.org:#\\+TITLE: \\(.*\\)" current-string)
- (setq matched-string (concat (match-string 1 current-string) " - " (match-string 2 current-string)))
- (setq match-list (append match-list (list matched-string))))
- (setq morelines (= 0 (forward-line 1))))))
- (kill-buffer "*Shell Command Output*")
- match-list))
-
-(defun zettelkasten-find-new-note-name (file iteration)
- "Iterate on ITERATION until a usable file based on FILE is found."
+ (shell-command (concat "grep -i \"#+TITLE:\" " zettelkasten-directory "/*"))
+ (setq match-list nil)
+ (with-current-buffer "*Shell Command Output*"
+ (set-buffer "*Shell Command Output*")
+ (setq morelines t)
+ (goto-char 1)
+ (while morelines
+ (setq current-string (buffer-substring-no-properties (line-beginning-position) (line-end-position)))
+ (when (string-match
+ (format "\\([0-9]*\\)\\.%s:#\\+TITLE: \\(.*\\)" zettelkasten-extension)
+ current-string)
+ (setq matched-string (concat (match-string 1 current-string) " - " (match-string 2 current-string)))
+ (setq match-list (append match-list (list matched-string))))
+ (setq morelines (= 0 (forward-line 1)))))
+ (kill-buffer "*Shell Command Output*")
+ match-list)
+
+(defun zettelkasten-find-new-note-name (note iteration)
+ "Iterate on ITERATION until a usable file based on NOTE is found."
(let ((expanded-name
(zettelkasten-make-filename
- (format file iteration))))
+ (format note iteration))))
(if (file-exists-p expanded-name)
- (zettelkasten-find-new-note-name file (+ iteration 1))
- expanded-name)))
+ (zettelkasten-find-new-note-name note (+ iteration 1))
+ (format note iteration))))
(defun zettelkasten-generate-note-name ()
"Create the new note name."
(zettelkasten-find-new-note-name
(format-time-string zettelkasten-file-format) 0))
-(defun zettelkasten-create-new-note (title)
- "Create a new zettelkasten note using the TITLE it is passed."
- (interactive "MNote title: ")
- (progn (find-file (zettelkasten-generate-note-name))
- (insert (concat "#+TITLE: " title
- (format-time-string "\n#+DATE: %c\n#+TAGS:\n\n")))
- (save-buffer)))
+(defun zettelkasten-get-id (note)
+ "Return the id for a NOTE."
+ (string-match "\\([0-9]*\\)" note)
+ (match-string 1 note))
+
+(defun zettelkasten-format-link (note)
+ "Format a link to a NOTE."
+ (format zettelkasten-link-format note (zettelkasten-get-id note) zettelkasten-extension))
+
+(defun zettelkasten-add-link-to-parent (note parent)
+ "Add a link to NOTE from PARENT."
+ (with-temp-file (zettelkasten-make-filename parent)
+ (insert-file-contents-literally (zettelkasten-make-filename parent))
+ (goto-char (point-max))
+ (insert (concat "\n" (zettelkasten-format-link note)))))
+
+(defun zettelkasten-create-new-note-non-interactive (title parent)
+ "Create a new note based on the TITLE and it's PARENT note.
+
+If PARENT is nil, it will not add a link from a parent."
+ (let ((note (zettelkasten-generate-note-name)))
+ (zettelkasten-add-link-to-parent note (zettelkasten-get-id parent))
+ (find-file (zettelkasten-make-filename note))
+ (insert (concat "#+TITLE: " title
+ (format-time-string "\n#+DATE: %c\n#+TAGS:\n\n")))
+ (save-buffer)))
+
+(defun zettelkasten-create-new-note (prefix)
+ "Create a new zettelkasten.
+
+If PREFIX is used, does not create a parent."
+ (interactive "P")
+ (let ((title (read-string "Note title: "))
+ (parent (unless prefix (completing-read "Parent note: "
+ (zettelkasten-list-notes) nil 'match))))
+ (zettelkasten-create-new-note-non-interactive title parent)))
(defun zettelkasten-insert-link (note)
"Insert a link to another NOTE in the current note."
(interactive
(list (completing-read "Notes: "
(zettelkasten-list-notes) nil 'match)))
- (let ((note-id
- (progn (string-match "\\([0-9]*\\)" note)
- (match-string 1 note))))
- (insert (concat "[[./" note-id ".org][" note "]]"))))
+ (insert (zettelkasten-format-link note)))
(defvar zettelkasten-mode-map
(let ((map (make-sparse-keymap)))