2020-07-03 17:34:41 +01:00
|
|
|
;;; 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)))
|
2020-07-09 11:45:53 +01:00
|
|
|
(log (list :add (format-time-string fg42/brain-state-date-format) work)))
|
2020-07-03 17:34:41 +01:00
|
|
|
(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)
|
|
|
|
'()))
|
|
|
|
|
|
|
|
|
2020-07-09 11:45:53 +01:00
|
|
|
(defun fg42/brain-delete-work (state work)
|
|
|
|
"Remove the give WORK from the given STATE."
|
|
|
|
(interactive
|
|
|
|
(let ((state (fg42/load-brain-state)))
|
|
|
|
(list state
|
|
|
|
(completing-read "Work: " (fg42/brain-keys state)))))
|
|
|
|
(fg42/save-brain-state
|
|
|
|
(fg42/brain-state-create
|
|
|
|
nil
|
|
|
|
(seq-filter (lambda (x) (equal (car x) work))
|
|
|
|
(fg42/-brain-entry-map state))
|
|
|
|
(cons (list :delete
|
|
|
|
(format-time-string fg42/brain-state-date-format)
|
|
|
|
work)
|
|
|
|
(fg42/-brain-logs state)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-07-03 17:34:41 +01:00
|
|
|
(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
|
2020-07-12 12:26:07 +01:00
|
|
|
(completing-read "Work: " (fg42/brain-keys state)))))
|
2020-07-03 17:34:41 +01:00
|
|
|
(let ((buf (get-buffer-create (format "*%s-notes*" work)))
|
2020-07-12 12:26:07 +01:00
|
|
|
(entries (cadr (assoc work (fg42/-brain-entry-map state)))))
|
2020-07-03 17:34:41 +01:00
|
|
|
(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))
|
2020-07-09 11:45:53 +01:00
|
|
|
(keys (fg42/brain-keys state))
|
2020-07-03 17:34:41 +01:00
|
|
|
(current (fg42/-brain-current state)))
|
|
|
|
(list
|
|
|
|
state
|
2020-07-09 11:45:53 +01:00
|
|
|
(completing-read "What were you working on: " keys nil 'confirm)
|
2020-07-03 17:34:41 +01:00
|
|
|
(read-string
|
2020-07-09 11:45:53 +01:00
|
|
|
"Note for the current work: ")
|
|
|
|
|
2020-07-03 17:34:41 +01:00
|
|
|
(completing-read "Switch brain to: "
|
2020-07-09 11:45:53 +01:00
|
|
|
keys))))
|
2020-07-03 17:34:41 +01:00
|
|
|
|
|
|
|
(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
|