Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuco1 committed Apr 16, 2017
0 parents commit 22aec31
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Cask
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(source melpa)
(source org)

(package "org-timeline" "0.1.0" "Add graphical view of agenda to agenda buffer")

(depends-on "dash" "2.13.0")
(depends-on "org-plus-contrib")
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# org-timeline

Add graphical view of agenda to agenda buffer.

# Installation

After you install this package from MELPA Stable, add the following line to your org configuration:

``` emacs-lisp
(add-hook 'org-agenda-finalize-hook 'org-timeline-insert-timeline :append)
```

# How it works

This package adds a graphical view of the agenda after the last agenda line. By default the display starts at 5 AM today and goes up to 4 AM next day (this covers 24 hours).

Scheduled tasks or tasks with time ranges are rendered in the display with `RoyalBlue` color. Clocked entires are displayed in `Grey`. The background of timeslots which are in the past is highlighted with `#555555` color.

You can use custom color for a task by adding the property `TIMELINE_FACE` with either a string which is a color name or a list which specifies the face properties or a symbol which is taken to be a face name.

# TODO

- [ ] Add faces instead of colors
- [ ] Make "midnight"/change-of-day configurable (currently 5 AM)
112 changes: 112 additions & 0 deletions org-timeline.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
;;; org-timeline.el --- Add graphical view of agenda to agenda buffer. -*- lexical-binding: t -*-

;; Copyright (C) 2017 Matúš Goljer

;; Author: Matúš Goljer <[email protected]>
;; Maintainer: Matúš Goljer <[email protected]>
;; Version: 0.1.0
;; Created: 16th April 2017
;; Package-requires: ((dash "2.13.0"))
;; Keywords: calendar

;; 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/>.

;;; Commentary:

;;; Code:

(require 'dash)

(require 'org-agenda)

(defmacro org-timeline-with-each-line (&rest body)
"Execute BODY on each line in buffer."
(declare (indent 0)
(debug (body)))
`(save-excursion
(goto-char (point-min))
,@body
(while (= (forward-line) 0)
,@body)))

(defun org-timeline--generate-timeline ()
(let* ((start-offset 300)
(current-offset (/ (- (+ (* 60 (string-to-number (format-time-string "%H")))
(string-to-number (format-time-string "%M")))
start-offset) 10))
(slotline (copy-sequence "| | | | | | | | | | | | | | | | | | | | | | | | |"))
(slotline (progn
(when (< 0 current-offset)
(put-text-property 0 current-offset 'font-lock-face '(:background "#555555") slotline))
slotline))
(timeline (concat "|05:00|06:00|07:00|08:00|09:00|10:00|11:00|12:00|13:00|14:00|15:00|16:00|17:00|18:00|19:00|20:00|21:00|22:00|23:00|00:00|01:00|02:00|03:00|04:00|"
"\n"
slotline))
(tasks nil))
(org-timeline-with-each-line
(-when-let* ((time-of-day (org-get-at-bol 'time-of-day))
(duration (org-get-at-bol 'duration)))
(when (< duration 0)
(cl-incf duration 1440))
(let* ((hour (/ time-of-day 100))
(minute (mod time-of-day 100))
(beg (+ (* hour 60) minute))
(end (+ beg duration))
(face (--if-let (org-entry-get (org-get-at-bol 'org-marker) "TIMELINE_FACE")
(let ((read-face (car (read-from-string it))))
(if (stringp read-face)
(list :background read-face)
read-face))
(cond
((save-excursion
(forward-char 26)
(looking-at "Clocked:"))
'(:background "Grey"))
(t '(:background "RoyalBlue"))))))
(when (>= beg start-offset)
(push (list beg end face) tasks)))))
(setq tasks (nreverse tasks))
(cl-labels ((get-start-pos (current-line beg) (+ 1 (* current-line (1+ (length slotline))) (/ (- beg start-offset) 10)))
(get-end-pos (current-line end) (+ 1 (* current-line (1+ (length slotline))) (/ (- end start-offset) 10))))
(let ((current-line 1))
(with-temp-buffer
(insert timeline)
(-each tasks
(-lambda ((beg end face))
(while (get-text-property (get-start-pos current-line beg) 'occupied)
(cl-incf current-line)
(when (> (get-start-pos current-line beg) (point-max))
(save-excursion
(goto-char (point-max))
(insert "\n" slotline))))
(let ((start-pos (get-start-pos current-line beg))
(end-pos (get-end-pos current-line end)))
(put-text-property start-pos end-pos 'font-lock-face face)
(put-text-property start-pos end-pos 'occupied t))
(setq current-line 1)))
(buffer-string))))))

(defun org-timeline-insert-timeline ()
(goto-char (point-min))
(while (eq (get-text-property (line-beginning-position) 'org-agenda-type) 'agenda)
(forward-line))
(forward-line)
(let ((inhibit-read-only t))
(insert (org-timeline--generate-timeline))
(insert (propertize (concat "\n" (make-string (/ (window-width) 2) ?─)) 'face 'org-time-grid) "\n"))
;; enable `font-lock-mode' in agenda view to display the "chart"
(font-lock-mode))

(provide 'org-timeline)
;;; org-timeline.el ends here

0 comments on commit 22aec31

Please sign in to comment.