about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-09-15T19·05+0100
committertazjin <mail@tazj.in>2020-09-17T10·51+0000
commitb1a84f001943a20855b38ec0f54d328c99cee17b (patch)
tree418a1d1d7a79dbe5de99eabff1dac38e40ae8577
parent40aeba62814a8f28454ee23c6687b5e6dd53aecd (diff)
feat(notable): Add note listing functionality r/1798
Adds a very simple initial display of all notes in chronologically
descending order.

Currently this is a read-only view with no available actions.

Change-Id: I6d47363909f1a9ab8d1d18a1c44966883aa758ad
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1983
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
-rw-r--r--tools/emacs-pkgs/notable/default.nix3
-rw-r--r--tools/emacs-pkgs/notable/notable.el60
2 files changed, 61 insertions, 2 deletions
diff --git a/tools/emacs-pkgs/notable/default.nix b/tools/emacs-pkgs/notable/default.nix
index 74cdddf6ab..94af474dad 100644
--- a/tools/emacs-pkgs/notable/default.nix
+++ b/tools/emacs-pkgs/notable/default.nix
@@ -1,4 +1,4 @@
-{ pkgs, ... }:
+{ depot, pkgs, ... }:
 
 pkgs.emacsPackages.trivialBuild rec {
   pname = "notable";
@@ -6,5 +6,6 @@ pkgs.emacsPackages.trivialBuild rec {
   src = ./notable.el;
   packageRequires = with pkgs.emacsPackages; [
     dash f ht s
+    depot.tools.emacs-pkgs.dottime
   ];
 }
diff --git a/tools/emacs-pkgs/notable/notable.el b/tools/emacs-pkgs/notable/notable.el
index d3866bb809..4669579ad7 100644
--- a/tools/emacs-pkgs/notable/notable.el
+++ b/tools/emacs-pkgs/notable/notable.el
@@ -21,6 +21,7 @@
 
 (require 'cl-lib)
 (require 'dash)
+(require 'dottime)
 (require 'f)
 (require 'ht)
 (require 'rx)
@@ -93,12 +94,16 @@
       (setq notable--next-note (+ 1 id))
       id)))
 
+(defun notable--note-path (id)
+  (check-type id integer)
+  (f-join notable-note-dir (format "note-%d.json" id)))
+
 (defun notable--add-note (content)
   "Add a note with CONTENT to the note store."
   (let* ((id (notable--next-id))
          (note (notable--make-note :time (time-convert nil 'integer)
                                    :content content))
-         (path (f-join notable-note-dir (format "note-%d.json" id))))
+         (path (notable--note-path id)))
     (when (f-exists? path) (error "Note file '%s' already exists!" path))
     (f-write-text (notable--serialize-note note) 'utf-8 path)
     (message "Saved note %d" id)))
@@ -111,6 +116,44 @@
            do (push (string-to-number (match-string 1 file)) res)
            finally return res))
 
+(defun notable--get-note (id)
+  (let ((path (notable--note-path id)))
+    (unless (f-exists? path)
+      (error "No note with ID %s in note storage!" id))
+    (notable--deserialize-note (f-read-text path 'utf-8))))
+
+;; Note list buffer implementation
+
+(define-derived-mode notable-list-mode fundamental-mode "notable"
+  "Major mode displaying the Notable note list."
+  ;; TODO(tazjin): `imenu' functions?
+
+  (set (make-local-variable 'scroll-preserve-screen-position) t)
+  (setq truncate-lines t)
+  (setq buffer-read-only t)
+  (setq buffer-undo-list t)
+  (hl-line-mode t))
+
+(defun notable--render-note (id note)
+  (check-type id integer)
+  (check-type note notable--note)
+
+  (let ((first-line (car (s-lines "foo")))
+        (date (dottime-format (seconds-to-time
+                               (notable--note-time note)))))
+    (insert (propertize (s-concat date "  " first-line)
+                        'notable-note-id id))
+    (insert "\n")))
+
+(defun notable--render-notes (notes)
+  "Retrieve each note in NOTES by ID and insert its contents into
+the list buffer.
+
+For larger notes only the first line is displayed."
+  (-each notes
+    (lambda (id)
+      (notable--render-note id (notable--get-note id)))))
+
 ;; User-facing functions
 
 (defun notable-take-note (content)
@@ -120,4 +163,19 @@ in Notable."
   (check-type content string)
   (notable--add-note content))
 
+(defun notable-list-notes ()
+  "Open a buffer listing all active notes."
+  (interactive)
+
+  (let ((buffer (get-buffer-create "*notable*"))
+        (notes (notable--list-note-ids))
+        (inhibit-read-only t))
+    (with-current-buffer buffer
+      (notable-list-mode)
+      (erase-buffer)
+      (setq header-line-format "Notable notes"))
+    (switch-to-buffer buffer)
+    (goto-char (point-min))
+    (notable--render-notes notes)))
+
 (provide 'notable)