Add brain-switch library to keep track of mind
Signed-off-by: Sameer Rahmani <lxsameer@gnu.org>
This commit is contained in:
parent
ed26a25ca1
commit
3188b3c451
|
@ -0,0 +1,175 @@
|
|||
;;; brain-switch --- Brain switch library to keep the state of mind
|
||||
;;
|
||||
;; Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
|
||||
;;
|
||||
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||
;; URL: https://gitlab.com/FG42/FG42
|
||||
;; Keywords: webkit
|
||||
;; Version: 0.1.0
|
||||
;; Package-Requires: ()
|
||||
;;
|
||||
;; This program is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
;;
|
||||
;;; Acknoledgement:
|
||||
;; This library is heavily inspired by Kite mini library. Kudos Tung Dao
|
||||
;; for his great work.
|
||||
;;
|
||||
;;; Commentary:
|
||||
;; Personally I switch between many many tasks constantly during a week.
|
||||
;; It's really hard to deal with the context switch and some times I forget
|
||||
;; about what I was doing on a project or why the other task was blocked.
|
||||
;; This library helps me which keeping my state of mind when I'm leaving a
|
||||
;; Task for another one.
|
||||
;;
|
||||
;; This library simply creates a database of the WORK you do and keeps track
|
||||
;; of some NOTES related to each WORK. You can review the notes on each WORK
|
||||
;; when ever you like via `fg42/brain-notes-for' function. You can switch to
|
||||
;; other state of mind with `fg42/brain-switch' which takes a note for your
|
||||
;; current WORK and switches to a new state by showing you what ever note
|
||||
;; you took on the same WORK previously.
|
||||
;;; Code:
|
||||
(require 'seq)
|
||||
(require 'fg42/utils)
|
||||
|
||||
(defvar fg42/brain-state-file "~/.brain.state"
|
||||
"The path to the brain state db.")
|
||||
|
||||
(defvar fg42/brain-state-date-format "%Y-%m-%d %T")
|
||||
|
||||
|
||||
(defun fg42/brain-state-create (current-work entries logs)
|
||||
"Create a new state out of the given ENTRIES and LOGS.
|
||||
CURRENT-WORK is the key that is considered to be the current work."
|
||||
(list 'entry-map entries 'logs logs 'current current-work))
|
||||
|
||||
|
||||
(defun fg42/-brain-entry-map (state)
|
||||
"Return the map of entries of the given STATE."
|
||||
(plist-get state 'entry-map))
|
||||
|
||||
|
||||
(defun fg42/-brain-logs (state)
|
||||
"Return the list of entries of the given STATE."
|
||||
(plist-get state 'logs))
|
||||
|
||||
|
||||
(defun fg42/-brain-current (state)
|
||||
"Return the current work of the given STATE."
|
||||
(plist-get state 'current))
|
||||
|
||||
|
||||
(defun fg42/load-brain-state ()
|
||||
"Load the brain state from the state file."
|
||||
(if (file-exists-p fg42/brain-state-file)
|
||||
(file->lisp fg42/brain-state-file)
|
||||
(list)))
|
||||
|
||||
|
||||
(defun fg42/save-brain-state (state)
|
||||
"Override the state on the brain state file by the given STATE."
|
||||
(lisp->file fg42/brain-state-file state))
|
||||
|
||||
|
||||
(defun fg42/add-brain-entry (state work entry)
|
||||
"Add the given ENTRY under the key WORK in the given STATE."
|
||||
(let ((entries (assoc work (fg42/-brain-entry-map state)))
|
||||
(log (list (format-time-string fg42/brain-state-date-format) work)))
|
||||
(fg42/brain-state-create
|
||||
(fg42/-brain-current state)
|
||||
(cons (list work (cons entry (cadr entries)))
|
||||
(fg42/-brain-entry-map state))
|
||||
(cons log (fg42/-brain-logs state)))))
|
||||
|
||||
|
||||
(defun fg42/brain-keys (state)
|
||||
"Return all the entry-map keys of the given STATE."
|
||||
(seq-reduce (lambda (acc x)
|
||||
(let ((v (car x)))
|
||||
|
||||
(if (member v acc)
|
||||
acc
|
||||
(cons v acc))))
|
||||
(fg42/-brain-entry-map state)
|
||||
'()))
|
||||
|
||||
|
||||
(defun fg42/brain-notes-for (state work)
|
||||
"Create a buffer with all the nosts of the given WORK in STATE."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state)))
|
||||
(list state
|
||||
(completing-read "Work: " (fg42/brain-keys state)))))
|
||||
(let ((buf (get-buffer-create (format "*%s-notes*" work)))
|
||||
(entries (cadr (assoc (intern work) (fg42/-brain-entry-map state)))))
|
||||
(set-buffer buf)
|
||||
(erase-buffer)
|
||||
(mapcar (lambda (entry)
|
||||
(insert (format "[%s]: %s\n"
|
||||
(propertize (car entry) 'face 'font-lock-builtin-face)
|
||||
(propertize (cadr entry) 'face 'bold))))
|
||||
entries)
|
||||
(switch-to-buffer buf)))
|
||||
|
||||
|
||||
(defun fg42/brain-notes-for-current-work (state)
|
||||
"Create a buffer with all the nosts of the current work in STATE."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state)))
|
||||
(list state)))
|
||||
(fg42/brain-notes-for state (fg42/-brain-current state)))
|
||||
|
||||
|
||||
(defun fg42/brain-add-notes-for (state work note)
|
||||
"Add a note for the given WORK in STATE."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state)))
|
||||
(list state
|
||||
(completing-read "Work: " (fg42/brain-keys state))
|
||||
(read-string "Note: "))))
|
||||
(fg42/save-brain-state
|
||||
(fg42/add-brain-entry state
|
||||
work
|
||||
(list (format-time-string fg42/brain-state-date-format)
|
||||
note))))
|
||||
|
||||
|
||||
(defun fg42/brain-switch (state src-work note dst-work)
|
||||
"Switch the brain focus from SRC-WORK to DST-WORK on the given STATE.
|
||||
NOTE is the message that has to be saved for the SRC-WORK."
|
||||
(interactive
|
||||
(let* ((state (fg42/load-brain-state))
|
||||
(current (fg42/-brain-current state)))
|
||||
(list
|
||||
state
|
||||
(or current (read-string "What were you working on: "))
|
||||
(read-string
|
||||
(format "Note for the current work%s: "
|
||||
(if current (format "(%s)" current) "")))
|
||||
(completing-read "Switch brain to: "
|
||||
(fg42/brain-keys state)))))
|
||||
|
||||
(fg42/save-brain-state
|
||||
(plist-put
|
||||
(fg42/add-brain-entry state
|
||||
src-work
|
||||
(list (format-time-string fg42/brain-state-date-format)
|
||||
note))
|
||||
'current
|
||||
(intern dst-work)))
|
||||
;; We don't use the latest state for the target work
|
||||
(fg42/brain-notes-for state dst-work))
|
||||
|
||||
|
||||
(provide 'fg42/brain-switch)
|
||||
;;; brain-switch.el ends here
|
|
@ -72,5 +72,38 @@ with is the buffer."
|
|||
`nil)
|
||||
|
||||
|
||||
(defmacro -> (x &optional form &rest more)
|
||||
"Thread the expr through the forms FORM and rest of form in MORE.
|
||||
Insert X as the second item in the first form, making a list of
|
||||
it if it is not a list already. If there are more forms, insert
|
||||
the first form as the second item in second form, etc."
|
||||
(declare (debug (form &rest [&or symbolp (sexp &rest form)])))
|
||||
(cond
|
||||
((null form) x)
|
||||
((null more) (if (listp form)
|
||||
`(,(car form) ,x ,@(cdr form))
|
||||
(list form x)))
|
||||
(:else `(-> (-> ,x ,form) ,@more))))
|
||||
|
||||
|
||||
(defun read-file (path)
|
||||
"Return the content of the file at the given PATH as string."
|
||||
(when (file-exists-p path)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents path)
|
||||
(buffer-string))))
|
||||
|
||||
|
||||
(defun file->lisp (path)
|
||||
"Read the content of the file at PATH and return the Lisp in it."
|
||||
(read (or (read-file path) "()")))
|
||||
|
||||
|
||||
(defun lisp->file (path expr)
|
||||
"Write the given EXPR to the given file at PATH."
|
||||
(with-temp-file path
|
||||
(print expr (current-buffer))))
|
||||
|
||||
|
||||
(provide 'fg42/utils)
|
||||
;;; utils.el ends here
|
||||
|
|
Loading…
Reference in New Issue