I’m giving Org mode a try. This page will contain my configuration and the small subset of commands that I want to learn.
MY PROJECTS -*- mode: org; -*-
In .emacs
file:
(require 'org)
;; Change M-TAB completion to C-TAB
(define-key org-mode-map (kbd "C-<tab>") 'pcomplete)
(setq org-todo-keywords
'((sequence "TODO" "ONGOING" "CLOCKING" "|" "DONE")))
(global-set-key (kbd "C-c a") 'org-agenda)
(setq org-startup-truncated nil) ;; wrap lines
(setq org-startup-indented 1) ;; heading indentation
(setq org-return-follows-link 1) ;; RET to follow links
(setq org-agenda-start-on-weekday nil) ;; start agenda on current day
(setq calendar-week-start-day 1) ;; but calendar starts on Monday (not Sunday!)
(setq org-catch-invisible-edits nil) ;; block (confusing) invisible edits ("...")
(setq org-enforce-todo-dependencies t) ;; Switch TODO dependencies on
(setq org-agenda-dim-blocked-tasks 'invisible) ;; Hide tasked blocked by dependencies
;; path to org files
(setq org-directory "~/Documents/orgmode")
(setq org-agenda-files (list org-directory))
;; capture
(setq org-default-notes-file (concat org-directory "/notes.org"))
(global-set-key (kbd "C-c c") 'org-capture)
(setq system-time-locale "C") ;; use weekdays in English (even on French Ubuntu)
*bold*
, /italic/
, _underlined_
, +strike-through+
.=verbatim=
, ~code~
.: simple text, e.g. code source
: respecting line breaks
C-c c
C-c a
.C-c C-r
C-tab
.C-c C-n
/C-c C-p
.C-c C-f
/C-c C-b
.C-c C-u
.C-RET
.M-LEFT
/M-RIGHT
.M-S-LEFT
/M-S-RIGHT
.M-UP
/M-DOWN
.S-RIGHT
/S-LEFT
.C-c /
.C-c C-o
.C-c C-l
.C-c C-x p
.C-x n s
/C-x n w
.C-u C-c C-c
C-c .
C-c C-s
.C-c C-d
.S-ARROW
..
.10:00+1
means from 10am to 11am.For example regular meetings
<2020-03-18 Wed 12:30 +1w>
After using this for some time, I agree with Karl Voit that it’s more practical to duplicate the events instead (helps dealing with exceptional changes, taking notes, keeping a trace once the event stops).
C-c C-x c
clone an event/task (specify how many times and the time shift)SPC
.TAB
.RET
.t
.b
/f
j
.I use calfw to get a calendar-like view of the main events/meetings to come.
It’s easily installable through MELPA (see Emacs page), packages calfw
and calfw-org
.
Then in the .emacs
config:
(require 'calfw-org)
(setq cfw:org-agenda-schedule-args '(:timestamp))
M-x cfw:open-org-calendar
to open the calendarr
to refreshTAB
to navigate to items within a day.t
todayC-c C-c
.*** TODO Do this before the deadline
SCHEDULED: <2004-02-22 Sun>
DEADLINE: <2004-02-29 Sun>
C-c C-c
format the table. If on a TBLFM:
line, recompute the formula."| " TAB
make a new row."|-" TAB
make a line separation.M-RIGHT
/M-LEFT
move column.M-UP
/M-DOWN
move row.S-M-RIGHT
/S-M-DOWN
add new column/row.S-M-LEFT
/S-M-UP
remove current column/row.C-c }
show rows/columns labels.C-c ^
sort rows based on the current column.An example with a right-aligned column, a field formula and a column formula.
| <r> | | |
| ColA | ColB | ColC |
|------+------+------|
| tes | 13 | 12 |
| asd | 3 | 2 |
| a | 16 | 15 |
|------+------+------|
| mean | 10.7 | 9.7 |
#+TBLFM: $3=$2-1::@>$2=vmean(@3..@-I);p3
Start a formula in a cell by typing :=FORMULA
and C-c C-c
(=FORMULA
for column formulas).
@>
means the last row
I
to define range relative to the target field, e.g. @-I
=row above.
A plot line could look like: #+PLOT: title:"graph title" ind:1 deps:(2 3) set:"xlabel 'ColA'"
C-c " g
to make a plot (requires gnuplot and gnuplot to be installed)
Can be triggered by C-c C-, s
(potentially surrounding a selected region).
A simple code block:
#+NAME: <name>
#+BEGIN_SRC <language>
<body>
#+END_SRC
See the list of available languages.
To switch on syntax highlighting, add to .emacs
:
(setq org-src-fontify-natively t)
To enable the evaluation of a language, e.g. R:
(require 'ob-R)
(org-babel-do-load-languages
'org-babel-load-languages
'((R . t)))
If it looks like it’s not working, remove all *.elc
files in ~/.emacs.d/elpa/org-plus-contrib-*/
and restart.
C-c C-c
to evaluate a source blockExample of a R block that uses a named org-table as input:
#+tblname: tbl1
| x | y | group |
|-----+----+-------|
| 0 | 47 | A |
| 111 | 50 | A |
| 180 | 56 | A |
| 0 | 46 | B |
| 109 | 58 | B |
| 167 | 60 | B |
#+begin_src R :exports both :results output graphics :var tbl1=tbl1 :file tbl1-r.pdf :width 7 :height 5 :file-ext pdf
library(ggplot2)
ggplot(tbl1, aes(x=x, y=y, colour=group)) + geom_point()
#+end_src
No empty lines between header/scheduled/deadline and property chunk.
* John Doe
:PROPERTIES:
:EMAIL: [[mailto:john.doe@gmail.com][john.doe@gmail.com]]
:BIRTHDAY: 1982-01-14
:END:
#+COLUMNS: %25ITEM %BIRTHDAY
.C-c C-x C-c
.
c
to toggle compact table.g
to refresh.** TODO Go for a run
SCHEDULED: <2019-07-16 Tue .+2d/7d>
:PROPERTIES:
:STYLE: habit
:LAST_REPEAT: [2019-07-14 Sun 14:13]
:END:
- State "DONE" from "WAITING" [2019-07-14 Sun 14:13]
For a view of the habit and how well they are followed, I added to my .emacs
:
(add-to-list 'org-modules 'org-habit)
(require 'org-habit)
;; (setq org-habit-show-all-today t
;; org-habit-show-habits-only-for-today t
;; org-habit-show-done-always-green t
;; org-habit-graph-column 40
;; org-habit-preceding-days 28
;; org-habit-following-days 7)
[[LINK][DESCRIPTION]]
With LINK:
http://jmonlong.github.io/Hippocamplus/
file:path/to/file
file:sometextfile::NNN
file with line number.file:projects.org::*task title
Org file with heading search.doi:XX.XXXX/XXX
Using custom id: [[#my-id]]
will point at the place where a CUSTOM_ID as been set to my-id in a PROPERTIES drawer.
E.g.
:PROPERTIES:
:CUSTOM_ID: my-id
:END:
This also works for file:proj.org::#mu-id
.
To define tags/shortcuts, for example Google Map search using [[gmap:UCSC, Santa Cruz][UCSC]]
, add to .emacs
:
(setq org-link-abbrev-alist
'(("gmap" . "http://maps.google.com/maps?q=%s")))
C-c C-x ;
starts a timer/pomodoro.C-c C-x C-i
starts clocking, or I
in agenda view.C-c C-x C-o
stops clocking (also stops when the task is DONE).C-c C-x C-d
shows a summary of the file.C-c C-x C-r
inserts a report table.To force saving the clock items in a LOGBOOK drawer I added in my ~/.emacs
:
(setq org-clock-into-drawer t)
(setq org-pretty-entities t)
(setq org-clock-in-switch-to-state "CLOCKING")
I either want to know the tasks and events for the day, or just the events for the upcoming week/year.
(setq org-agenda-custom-commands
'(("c" "Today's agenda"
((agenda "" ((org-agenda-span 1)
(org-agenda-block-separator nil)
(org-agenda-skip-function
'(org-agenda-skip-subtree-if 'regexp ":habit:")
)
))
(alltodo ""
((org-agenda-skip-function
(lambda nil
(org-agenda-skip-entry-if (quote scheduled)
(quote deadline))))
(org-agenda-overriding-header "Un-scheduled tasks:")
(org-agenda-block-separator nil)
))
(agenda ""
(
(org-agenda-span 'day)
(org-agenda-block-separator nil)
(org-agenda-format-date "")
(org-agenda-use-time-grid nil)
(org-agenda-skip-function
'(org-agenda-skip-subtree-if 'notregexp ":habit:")
)
(org-agenda-overriding-header "Habits:")
))
)
)
("w" "Week's events"
((agenda "" ((org-agenda-span 7)
(org-agenda-skip-function
'(or (org-agenda-skip-entry-if 'todo '("TODO" "ONGOING" "DONE"))
)
)
(org-agenda-show-all-dates nil)
(org-agenda-overriding-header "Week's events:")
)))
((org-agenda-compact-blocks t))
)
("y" "Year's events (no recurrents)"
((agenda "" ((org-agenda-span 365)
(org-agenda-skip-function
'(or (org-agenda-skip-entry-if 'todo '("TODO" "ONGOING" "DONE"))
(org-agenda-skip-subtree-if 'regexp ":recurrent:")
(org-agenda-skip-subtree-if 'regexp ":birthday:")
)
)
(org-agenda-show-all-dates nil)
(org-agenda-overriding-header "Year's events (no recurrents):")
)))
((org-agenda-compact-blocks t))
)
)
)
I also changed the way tasks are displayed in the agenda view.
Instead of showing the filename where the task resides, I show the first characters of the parent heading.
That way I can use short and generic task names and still understand it in the agenda.
No need to repeat the context in the task name anymore.
I added in my .emacs
:
;; Prefix tasks with parent heading
(defun getlasthead ()
(let ((x (nth 0 (last (org-get-outline-path)))))
(if x
(if (> (string-width x) 12)
(concat "[" (org-format-outline-path (list (substring x 0 12))) "]")
(concat "[" (org-format-outline-path (list x)) "]"))
"")))
(setq org-agenda-prefix-format " %i %-15(getlasthead)%?-12t% s ")
To specify custom French holidays, I first took their definition from french-holidays.el, and added them to a custom-holidays
list.
Then updated the calendar-holidays
list with that list.
In my .emacs
:
(setq custom-holidays
`((holiday-fixed 1 1 "Jour de l'an")
(holiday-fixed 1 6 "Épiphanie")
(holiday-fixed 2 2 "Chandeleur")
(holiday-fixed 2 14 "Saint Valentin")
(holiday-fixed 5 1 "Fête du travail")
(holiday-fixed 5 8 "Commémoration de la capitulation de l'Allemagne en 1945")
(holiday-fixed 6 21 "Fête de la musique")
(holiday-fixed 7 14 "Fête nationale - Prise de la Bastille")
(holiday-fixed 8 15 "Assomption (Religieux)")
(holiday-fixed 11 11 "Armistice de 1918")
(holiday-fixed 11 1 "Toussaint")
(holiday-fixed 11 2 "Commémoration des fidèles défunts")
(holiday-fixed 12 25 "Noël")
(holiday-easter-etc 0 "Pâques")
(holiday-easter-etc 1 "Lundi de Pâques")
(holiday-easter-etc 39 "Ascension")
(holiday-easter-etc 49 "Pentecôte")
(holiday-easter-etc -47 "Mardi gras")
(if (not (equal (calendar-nth-named-day -1 0 5 displayed-year)
(caar (holiday-easter-etc 49))))
(holiday-float 5 0 -1 "Fête des mères")
(holiday-float 6 0 1 "Fête des mères"))
(holiday-float 6 0 3 "Fête des pères"))) ;; troisième dimanche de juin
(setq calendar-holidays (append calendar-holidays custom-holidays))
There is apparently no way to handle time zones easily. It makes it a bit annoying when traveling to a different time zone. This is the best I could find:
m
C-u 3 B h
I defined the custom function linked to the bulk command h in my .emacs
:
(setq org-agenda-bulk-custom-functions
`((?h (lambda () (call-interactively 'org-agenda-date-later-hours)))
,@org-agenda-bulk-custom-functions))
This is easy enough because I really just want to change the times of upcoming meetings, not everything.
I don’t really care if the scheduled tasks I set for myself are not in the proper time zone, they tend to be re-scheduled anyway.
And I travel for a couple of weeks maximum, so it’s quick to launch a week agenda view (C-c a w
) and mark/shift the few upcoming meetings.
For example, when realizing half-way through that I prefer anti-chronological order (better have the latest/in-progress header at the top and not have to scroll down to the bottom).
From the higher-level header: M-x org-sort RET F point RET RET
I use Termux to keep the git repo hosting the files up to date on my Android phone. Their wiki explains how to install packages and setup the app. I did:
## to give termux permissions to access a shared folder
termux-setup-storage
Packages, like git, can be installed with pkg install PKG
.
After setting up the repo once, I wrote a script to sync my local copy with the copy on git:
#!/bin/sh
cd storage/shared/.../REPO
git commit -am "update on phone"
git pull
git push
That works when there are no conflicts that need manual fixing (so, most times).
I then use Orgzly to browser and edit the org files, or check my agenda.
I’ve added new custom “searches” to check events in the coming week/month/year:
e.ge.now ad.7
e.ge.now ad.31
e.ge.now ad.365