Newer
Older
cl-todo / cl-todo.lisp
;;;;
;;;; A simple TODO app for the GNOME desktop
;;;; (mainly written to try out GTK+Lisp)
;;;;
;;;; (c) Daniel Vedder 2020
;;;; Licensed under the terms of the MIT license
;;;;

(in-package :cl-todo)

;;TODO change into a list of lists
;;TODO add text field at end of file
(defvar *task-list* NIL)
(defvar *note-text* "")
(defvar *runfile* (uiop:native-namestring "~/.todo"))


(defun launch ()
	(multiple-value-setq
		(*task-list* *note-text*)
		(load-task-file))
	(make-gui)
	(bt:join-thread (gtk-thread)))

(defun load-task-file (&optional (file-name *runfile*))
	"Load a list of (task) strings and the note text from the run file"
	(with-open-file (f file-name :if-does-not-exist nil)
		(when (null f)
			(format t "~&No task file found at ~S" file-name)
			(return-from load-task-file))
		(do* ((line (read-line f nil nil)
				  (read-line f nil nil))
				 (tasks-complete NIL)
				 (tasks NIL) (notes ""))
			((null line) (values tasks notes))
			(if tasks-complete
				(setf notes (concatenate 'string notes line (string #\Newline)))
				(if (equalp line "!=====!")
					(setf tasks-complete T)
					(setf tasks (append tasks (list line))))))))
		
(defun write-task-list (&optional (lst *task-list*) (notes *note-text*) (filename *runfile*))
	"Write the task list to file, one entry per line, and append the notes."
	(let ((f (open filename :direction :output :if-exists :supersede)))
		(dolist (i lst) (format f "~&~A" i))
		(format f "~&!=====!~&~A" notes)
		(close f)))

(defun add-task! (task)
	"Append a task to the task list and save to file"
	(setf *task-list* (append *task-list* (list task)))
	(write-task-list))

(defun remove-task! (task)
	"Remove a task from the list and save to file"
	(setf *task-list*
		(remove-if #'(lambda (s) (equalp s task))
			*task-list* :count 1))
	(write-task-list))