So the basic thing you need to start working with org-mode is to install org-mode. Emacs > 24.??? already have it bundled and if you're not going to use some cool features like org-drill and stuff, that should be enough.
Basically, org-mode operates with org files. Create one (work.org
for example). Org files' markup is simple -- there are headers
with info. Header format is '*'{1..} TODO-kw Description
. To
create entry just write it. Also C-c RET
does something similar
(I never use it tho). So, stars are indentation -- more indented
headers are 'contained' inside less indented. Philosophically, you
can think that leaves are tasks, while nodes are categories. File
is rose tree. Dunno. You can expand or shrink the header with
TAB
.
Todo-keywords are 'status'es of task. I'm using simple setup that
i find rather convenient. Add to your ~/.emacs
:
(setq org-todo-keywords '((type "TODO" "STARTED" "WAITING" "|" "DONE" "CANCELED")))
That adds default todo-keywords. You can also specify per-file
keywords with file headers (should be placed on the top of
file). Here are my work.org
headers:
#+TODO: TODO STARTED WAITING | DONE CANCELED
#+TODO: BUG PROGRESS UNTESTED | FIXED DROPPED
#+TITLE: Work stuff
Work file is the only place i add another todo-list with
bug-related stuff, but I don't use the second one frequently. Also
in study-related files tasks are 'topic's, they have some text
inside and task's status defines my knowledge of that topic, so i
also have #+TODO: X 0 1 2 | OK
header in those. You can see
analogy now.
Add some custom hightlighting for those task statuses:
(setq org-todo-keyword-faces
'(("TODO" . "red")
("STARTED" . "yellow")
("WAITING" . "purple")
("CANCELED" . (:foreground "blue" :weight bold))
("DONE" . "green")
("BUG" . "red")
("PROGRESS" . "yellow")
("UNTESTED" . "purple")
("DROPPED" . (:foreground "blue" :weight bold))
("FIXED" . "green")))
So you now should have some primitive understanding of how to write org file. Create some tasks now. I believe that the best structure of file you can invent is your optimal, but i'll share my though.
Top headers: Clocking, Serokell, OtherCompanyName. Serokell is divided into: Meta task (for speaking in chat, reading logs, issue making), global category (everything that doesn't relate to projects, like the task to create this manual), rscoin, bitgram, ghost. That's all.
Changing task status is S-<arrow left>
, S-<arrow right>
, but
also Num C-c C-t
is available (DONE keyword is 4th, so 4 C-c C-t
would set DONE status).
You can also use M-S-<arrow up>
and M-S-<arrow down>
to move
task up or down in it's level (I usually arrange tasks in the way
that done/canceled are on the bottom while todo/started are on the
top).
Ok, what's the point? We now have tasks, but what can you do with
them? First of all, let's have a look at agenda. First, press
C-c [
in work file to add it to agenda files. M-x org-agenda
opens agenda window and then you can press a
to view all your
tasks. But there's no tasks, because it's agenda, so it's supposed
to show scheduled tasks. Easy -- C-c C-s
while your cursor is on
tasks opens calendar to choose schedule date, C-c C-d
is the
same for deadline.
The task with schedules and deadlines will look like this:
*** TODO Youtrack tutorial
DEADLINE: <2016-04-17 Sun> SCHEDULED: <2016-04-16 Sat>
https://www.jetbrains.com/youtrack/documentation/
Dates can be altered with S-<arrow up, down, left, right>
. You'll get how it works.
OFC you shouldn't call agenda every time with M-x
. Here are
bindings (I use only the first one, but the second is popular).
(global-set-key (kbd "<f12>") 'org-agenda)
(global-set-key "\C-ca" 'org-agenda)
Now scheduled tasks will show up in agenda, so <f-12> a
would
show what you should do today, what are deadlines, etc. If you're
using evil, you might find helpful:
(add-hook 'org-agenda-mode-hook 'my-org-agenda-mode-hook)
(defun my-org-agenda-mode-hook ()
"Enables hjkl-bindings for agenda-mode."
(define-key org-agenda-mode-map "j" 'org-agenda-next-line)
(define-key org-agenda-mode-map "k" 'org-agenda-previous-line)
(define-key org-agenda-mode-map "l" 'evil-forward-char)
(define-key org-agenda-mode-map "h" 'evil-backward-char))
Agenda is much more than that! There are repeated tasks, habits, estimates, tags, ....
Ok, so now we have tasks which we're aware of because of agenda. Clocking! Tasks can be clocked in and out. Clock in creates a record in tas's subtree, clock out closes a record. Simple. Here's a bunch of settings (don't be afraid...):
; sets some hooks for clock persistence over emacs restart
(org-clock-persistence-insinuate)
; dunno what's that
(setq org-clock-in-resume t)
; moves TODO to STARTED when clocked in
(setq org-clock-in-switch-to-state 'bh/clock-in-to-next)
; Sets drawers
(setq org-drawers (quote ("PROPERTIES" "LOGBOOK")))
; Clock entries are stored in drawer (lots of clock lines fit into
; drawer, it's expanded by tab)
(setq org-clock-into-drawer t)
; Do not show up scheduled or deadline tasks if they're done.
(setq org-agenda-skip-scheduled-if-done t)
(setq org-agenda-skip-deadline-if-done t)
; If you clock out task and it's 0 time, the record is not stored.
(setq org-clock-out-remove-zero-time-clocks t)
; Adds DONE record to the task when it's done.
(setq org-log-done t)
; Clocks task out when done
(setq org-clock-out-when-done t)
; Some persistance settings
(setq org-clock-persist-query-resume nil)
(setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
; Clocking tasks are in clock report
(setq org-clock-report-include-clocking-task t)
; functions for clock-in-to-next
(defun bh/is-project-p ()
"Any task with a todo keyword subtask"
(save-restriction
(widen)
(let ((has-subtask)
(subtree-end (save-excursion (org-end-of-subtree t)))
(is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
(save-excursion
(forward-line 1)
(while (and (not has-subtask)
(< (point) subtree-end)
(re-search-forward "^\*+ " subtree-end t))
(when (member (org-get-todo-state) org-todo-keywords-1)
(setq has-subtask t))))
(and is-a-task has-subtask))))
(defun bh/is-task-p ()
"Any task with a todo keyword and no subtask"
(save-restriction
(widen)
(let ((has-subtask)
(subtree-end (save-excursion (org-end-of-subtree t))) (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1))) (save-excursion
(forward-line 1)
(while (and (not has-subtask)
(< (point) subtree-end)
(re-search-forward "^\*+ " subtree-end t))
(when (member (org-get-todo-state) org-todo-keywords-1)
(setq has-subtask t))))
(and is-a-task (not has-subtask)))))
(defun bh/clock-in-to-next (kw)
"Switch a task from TODO to STARTED when clocking in.
Skips capture tasks, projects, and subprojects.
Switch projects and subprojects from STARTED back to TODO"
(when (not (and (boundp 'org-capture-mode) org-capture-mode))
(cond
((and (member (org-get-todo-state) (list "TODO"))
(bh/is-task-p))
"STARTED")
((and (member (org-get-todo-state) (list "STARTED"))
(bh/is-project-p))
"TODO"))))
Eeeemm, so here it is. It's not necessary to adopt all settings of
course. Press C-c C-x C-i
to clock in, C-c C-x C-o
to clock
out. You can just clock in another task, previous one will clock
out automatically. If you forgot to clock task out and already
doing some other thing, M-x org-resolve-clocks
might be
helpful. Pressing K
and then choosing the number of minutes to
save is the thing.
I have org-resolve-clocks
added to startup hook:
(add-hook 'org-mode-hook 'my-org-mode-hook)
(defun my-org-mode-hook ()
"Hook for org mode."
(local-set-key (kbd "C-c C-x C-k") 'org-resolve-clocks))
Now clock-reports! That's the thing i have my first top-level
header in work.org
for. It contains just this thing:
#+BEGIN: clocktable :maxlevel 5 :scope file :block week tcolumns 3
#+END:
Pressing C-c C-c
on it would create a clock report. Also C-c C-o C-r
generates this stuff. More on clock reports here:
http://orgmode.org/manual/The-clock-table.html
There's also one thing to say about clock report styles. By
default report is indented with \emsp
which is not really
nice. But this link points out the solution: StackExchange
Personally i solve it in this way:
(defun my-org-clocktable-indent-string (level)
(if (= level 1)
""
(let ((str "*"))
(while (> level 2)
(setq level (1- level)
str (concat str " ")))
(concat str " "))))
(advice-add 'org-clocktable-indent-string :override #'my-org-clocktable-indent-string)
That's all I guess. Org has lots of features, I can't just cover them all quickly. Read org manual, google more, ask me.
Peace.
Good.