The Org Mode feature was a big reason in my recent re-kindling of my Emacs love affair. Make sure the latest packages are installed:
(packages-install '( org
org-plus-contrib
org-bullets
ox-reveal
org-journal
plantuml-mode
))
I really think that org-mode should be my default for most things, including regular text files:
(add-to-list 'auto-mode-alist '("\\.txt\\'" . org-mode))
Initialization of Org Mode by hooking it into YASnippets, which should allow me to easily add templates to my files.
(add-hook 'org-mode-hook 'turn-on-auto-fill)
(add-hook 'org-mode-hook
'(lambda ()
(yas-minor-mode-on)))
Didn’t realize that org-journal essentially does what I have been doing by hand. With a little customization, I don’t have to change anything else:
(setq org-journal-dir "~/journal/")
(require 'org-journal nil t)
All my journal entries will be formatted using org-mode:
(add-to-list 'auto-mode-alist '(".*/[0-9]*$" . org-mode))
The date format is essentially, the top of the file.
(setq org-journal-date-format "#+TITLE: Journal Entry- %Y-%b-%d (%A)")
The time format is the heading for each section. I will set it to a blank since I really don’t care about the time I add a section.
(setq org-journal-time-format "")
A function to easily load today (and yesterday’s) journal entry.
(defun get-journal-file-today ()
"Return filename for today's journal entry."
(let ((daily-name (format-time-string "%Y%m%d")))
(expand-file-name (concat org-journal-dir daily-name))))
(defun journal-file-today ()
"Create and load a journal file based on today's date."
(interactive)
(find-file (get-journal-file-today)))
(global-set-key (kbd "C-c f j") 'journal-file-today)
Since I sometimes (not often) forget to create a journal entry, and need to re-write history.
(defun get-journal-file-yesterday ()
"Return filename for yesterday's journal entry."
(let ((daily-name (format-time-string "%Y%m%d" (time-subtract (current-time) (days-to-time 1)))))
(expand-file-name (concat org-journal-dir daily-name))))
(defun journal-file-yesterday ()
"Creates and load a file based on yesterday's date."
(interactive)
(find-file (get-journal-file-yesterday)))
(global-set-key (kbd "C-c f y") 'journal-file-yesterday)
Seems like I need to have the inserted template match the file’s name, not necessarily today’s date:
(defun journal-file-insert ()
"Insert's the journal heading based on the file's name."
(interactive)
(when (string-match "\\(20[0-9][0-9]\\)\\([0-9][0-9]\\)\\([0-9][0-9]\\)" (buffer-name))
(let ((year (string-to-number (match-string 1 (buffer-name))))
(month (string-to-number (match-string 2 (buffer-name))))
(day (string-to-number (match-string 3 (buffer-name))))
(datim nil))
(setq datim (encode-time 0 0 0 day month year))
(insert (format-time-string org-journal-date-format datim))
(insert "\n\n")))) ; Start with a blank separating line
Nice to automatically insert this header if the journal entry file is empty…yeah, we’re talking auto-insert:
(add-to-list 'auto-insert-alist '(".*/[0-9]*$" . journal-file-insert))
I really would really like to read what I did last year “at this time”, and by that, I mean, 365 days ago, plus or minus a few to get to the same day of the week.
(defun journal-last-year-file ()
"Returns the string corresponding to the journal entry that
happened 'last year' at this same time (meaning on the same day
of the week)."
(let* ((last-year-seconds (- (float-time) (* 365 24 60 60)))
(last-year (seconds-to-time last-year-seconds))
(last-year-dow (nth 6 (decode-time last-year)))
(this-year-dow (nth 6 (decode-time)))
(difference (if (> this-year-dow last-year-dow)
(- this-year-dow last-year-dow)
(- last-year-dow this-year-dow)))
(target-date-seconds (+ last-year-seconds (* difference 24 60 60)))
(target-date (seconds-to-time target-date-seconds)))
(format-time-string "%Y%m%d" target-date)))
(defun journal-last-year ()
"Loads last year's journal entry, which is not necessary the
same day of the month, but will be the same day of the week."
(interactive)
(let ((journal-file (concat org-journal-dir (journal-last-year-file))))
(find-file journal-file)))
(global-set-key (kbd "C-c f L") 'journal-last-year)
I’ve notice that while I really like taking notes in a meeting, I don’t always like the multiple windows I have opened, so I created this function that I can easily call to eliminate distractions during a meeting.
(defun meeting-notes ()
"Call this after creating an org-mode heading for where the notes for the meeting
should be. After calling this function, call 'meeting-done' to reset the environment."
(interactive)
(outline-mark-subtree) ;; Select org-mode section
(narrow-to-region (region-beginning) (region-end)) ;; Only show that region
(deactivate-mark)
(delete-other-windows) ;; Get rid of other windows
(text-scale-set 2) ;; Text is now readable by others
(fringe-mode 0)
(when (require 'olivetti nil t)
(olivetti-mode 1)
(olivetti-set-width 110)
(olivetti-toggle-hide-modeline))
(message "When finished taking your notes, run meeting-done."))
Of course, I need an ‘undo’ feature when the meeting is over…
(defun meeting-done ()
"Attempt to 'undo' the effects of taking meeting notes."
(interactive)
(widen) ;; Opposite of narrow-to-region
(text-scale-set 0) ;; Reset the font size increase
(fringe-mode 1)
(when (require 'olivetti nil t)
(olivetti-toggle-hide-modeline)
(olivetti-mode 0))
(winner-undo)) ;; Put the windows back in place
Before we load org-mode
proper, we need to set the following
syntax high-lighting parameters. These are used to help bring out
the source code during literate programming mode.
This information came from these instructions, however, they tend to conflict with the color-theme, so we’ll turn them off for now.
(defface org-block-begin-line
'((t (:underline "#A7A6AA" :foreground "#008ED1" :background "#EAEAFF")))
"Face used for the line delimiting the begin of source blocks.")
(defface org-block-background
'((t (:background "#FFFFEA")))
"Face used for the source block background.")
(defface org-block-end-line
'((t (:overline "#A7A6AA" :foreground "#008ED1" :background "#EAEAFF")))
"Face used for the line delimiting the end of source blocks.")
The standard package manager (and most recent versions of Emacs)
include org-mode
, however, I want the latest version that has
specific features for literate programming.
Org-mode is installed in the global directory.
(require 'org)
(require 'ob-tangle)
The org-mode
has some useful keybindings that are helpful no
matter what mode you are using currently.
(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c b") 'org-iswitchb)
(global-set-key (kbd "C-M-|") 'indent-rigidly)
The following keybind ideas came from Emacs24 Starter Kit.
(add-hook 'org-mode-hook
(lambda ()
(local-set-key "\M-\C-n" 'outline-next-visible-heading)
(local-set-key "\M-\C-p" 'outline-previous-visible-heading)
(local-set-key "\M-\C-u" 'outline-up-heading)
;; table
(local-set-key "\M-\C-w" 'org-table-copy-region)
(local-set-key "\M-\C-y" 'org-table-paste-rectangle)
(local-set-key "\M-\C-l" 'org-table-sort-lines)
;; display images
(local-set-key "\M-I" 'org-toggle-iimage-in-org)))
A couple of short-cut keys to make it easier to edit text.
(defun org-text-bold () "Wraps the region with asterisks."
(interactive)
(surround-text "*"))
(defun org-text-italics () "Wraps the region with slashes."
(interactive)
(surround-text "/"))
(defun org-text-code () "Wraps the region with equal signs."
(interactive)
(surround-text "="))
Now we can associate some keystrokes to the org-mode:
(add-hook 'org-mode-hook
(lambda ()
(local-set-key (kbd "A-b") 'org-text-bold)
(local-set-key (kbd "s-b") 'org-text-bold) ;; For Linux
(local-set-key (kbd "A-i") 'org-text-italics)
(local-set-key (kbd "s-i") 'org-text-italics)
(local-set-key (kbd "A-=") 'org-text-code)
(local-set-key (kbd "s-=") 'org-text-code)))
If point is at the beginning of a headline or code block in
org-mode, single keys do fun things. See org-speed-command-help
for details (or hit the ? key at a headline).
(setq org-use-speed-commands t)
I keep all my org-mode
files in a few directories, and I would
like them automatically searched when I generate agendas.
(setq org-agenda-files '("~/Dropbox/org/personal"
"~/Dropbox/org/technical"
"~/Dropbox/org/project"))
Let’s say you were in the middle of something, but would like to take a quick note, but without affecting the file you are working on. This is called a “capture”, and is bound to the following key:
(global-set-key (kbd "C-c c") 'org-capture)
This will bring up a list of note capturing templates. I actually override this in my system-specific “local” configuration file.
(defun ha/first-header ()
(goto-char (point-min))
(search-forward-regexp "^\* ")
(beginning-of-line 1)
(point))
;; General notes go into this file:
(setq org-default-notes-file "~/personal/@SUMMARY.org")
(setq org-default-tasks-file "~/personal/tasks.org")
(setq org-capture-templates
'(("n" "Thought or Note" entry
(file org-default-notes-file)
"* %?\n\n %i\n\n See: %a" :empty-lines 1)
("j" "Journal Note" entry
(file (get-journal-file-today))
"* %?\n\n %i\n\n From: %a" :empty-lines 1)
("t" "Task Entry" entry
(file+function org-default-tasks-file ha/first-header)
"* %?\n\n %i\n\n From: %a" :empty-lines 1)
("w" "Website Announcement" entry
(file+function "~/website/index.org" ha/first-header)
"* %?
:PROPERTIES:
:PUBDATE: %t
:END:
#+HTML: <div class=\"date\">%<%e %b %Y></div>
%i
[[%F][Read more...]" :empty-lines 1)))
After you have selected the template, you type in your note and hit
C-c C-c
to store it in the file listed above.
Just remember, at some point to hit C-c C-w
to refile that note
in the appropriate place.
Using org-trello to sync particular org-mode files with trello.com
(defun ha/org-trello-sync ()
(interactive)
(when (require 'org-trello nil t)
(org-trello-mode 1)
(org-trello/sync-buffer t)))
(global-set-key (kbd "S-<f1>") 'ha/org-trello-sync)
Seems some change now requires a direct load of HTML:
(require 'ox-html)
To make the org-mode
export defaults closer to my liking
(without having to put specific #+PROPERTY commands), I get rid of
the postamble, and then configure the default fonts.
(setq org-html-postamble nil)
(setq org-export-with-section-numbers nil)
(setq org-export-with-toc nil)
(setq org-html-head-extra "
<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,700' rel='stylesheet' type='text/css'>
<style type='text/css'>
body {
font-family: 'Source Sans Pro', sans-serif;
}
pre, code {
font-family: 'Source Code Pro', monospace;
}
</style>")
After reading this article, I decided to expand how I narrow/widen
buffer sections in org-mode. This is specific to org-mode, as I
often like to see the surrounding code using fancy-narrow
as
explained in my Expand Region section.
(defun org-narrow-or-widen-dwim (p)
"If the buffer is narrowed, it widens. Otherwise, it narrows intelligently.
Intelligently means: region, org-src-block, org-subtree, or defun,
whichever applies first.
Narrowing to org-src-block actually calls `org-edit-src-code'.
With prefix P, don't widen, just narrow even if buffer is already
narrowed."
(interactive "P")
(declare (interactive-only))
(cond ((and (buffer-narrowed-p) (not p)) (widen))
((region-active-p)
(narrow-to-region (region-beginning) (region-end)))
((derived-mode-p 'org-mode)
(cond ((ignore-errors (org-edit-src-code))
(delete-other-windows))
((org-at-block-p)
(org-narrow-to-block))
(t (org-narrow-to-subtree))))
(t (narrow-to-defun))))
(global-set-key (kbd "C-x n o") 'org-narrow-or-widen-dwim)
According to the narrow-widen article, we can have C-x C-s
get
out of editing org-mode source code blocks:
(eval-after-load 'org-src
'(define-key org-src-mode-map
"\C-x\C-s" #'org-edit-src-exit))
I alternated between the browser-based presentation tool, reveal.js and staying in Emacs with org-tree-slide.
Generate presentations from my org-mode files using org-reveal. Just download and make the results available to the HTML output:
(when (require 'ox-reveal nil t)
(setq org-reveal-root (concat "file://" (getenv "HOME") "/Public/js/reveal.js"))
(setq org-reveal-postamble "Howard Abrams"))
A quick way to display an org-mode file is using org-tree-slide.
The only downside is the default key-binding for moving to the next
section is C->
… hardly easy to find during a presentation.
- org-tree-slide-move-next-tree (C->)
- org-tree-slide-move-previous-tree (C-<)
- org-tree-slide-content (C-x s c)
Perhaps we can create a function that sets everything at once:
(deftheme ha/org-tree-slide-theme "Sub-theme to hide org code blocks")
(defun ha/present-it ()
(interactive)
(when (require 'demo-it nil t)
(demo-it-presentation (buffer-file-name))
(org-tree-slide-simple-profile)
(define-key org-mode-map (kbd "<f1>") 'org-tree-slide-move-next-tree)
(define-key org-mode-map (kbd "S-<f1>") 'org-tree-slide-move-previous-tree))
(when (require 'olivetti nil t)
(olivetti-mode 1)
(olivetti-set-width 110))
(setq ha/present-it-restoration '(
(face-foreground 'org-block-begin-line nil 'default)
))
(let ((fgc (face-background 'org-block-begin-line nil 'default)))
(setq-default line-spacing 12)
(custom-theme-set-faces 'ha/org-tree-slide-theme
`(org-block-begin-line ((t (:foreground ,fgc :height 0.5 :line-height 1 :invisible t))))
`(org-block-end-line ((t (:foreground ,fgc :height 0.2 :line-height 1 :invisible t))))))
(fringe-mode '(0 . 0)))
And we need an “undo” for this weird presentation:
(defun ha/present-stop ()
(interactive)
(demo-it-end)
(setq-default line-spacing 2)
(when (require 'olivetti nil t)
(olivetti-mode nil))
(let ((fgc (car ha/present-it-restoration)))
(custom-theme-set-faces 'ha/org-tree-slide-theme
`(org-block-begin-line ((t (:foreground ,fgc :height 1.0 :line-height 1.0 :invisible nil))))
`(org-block-end-line ((t (:foreground ,fgc :height 1.0 :line-height 1.0 :invisible nil))))))
(olivetti-mode 0))
Displaying the headers using various bullets are nice for my presentations.
(when (require 'org-bullets nil t)
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))
Here is my approach for quickly making the initial asterisks for listing items and whatnot, appear as Unicode bullets (without actually affecting the text file or the behavior).
(font-lock-add-keywords 'org-mode
'(("^ +\\([-*]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
I use Dropbox with MobileOrg in order to read my notes on my iPad.
The “global” location of my Org files on my local system:
(setq org-directory "~/Dropbox/org/personal")
Set the name of the file where new notes will be stored
(setq org-mobile-inbox-for-pull "~/Dropbox/org/flagged.org")
Set to <your Dropbox root directory>/MobileOrg.
(setq org-mobile-directory "~/Dropbox/Apps/MobileOrg")
To get this going, we just need to: M-x org-mobile-push
The trick to literate programming is in the Babel project, which allows org-mode to not only interpret source code blocks, but evaluate them and tangle them out to a file.
(org-babel-do-load-languages
'org-babel-load-languages
'((sh . t)
(js . t)
(emacs-lisp . t)
(perl . t)
(scala . t)
(clojure . t)
(python . t)
(ruby . t)
(dot . t)
(css . t)
(plantuml . t)))
Make the code pretty:
(setq org-src-fontify-natively t)
I want CoffeeScript to be supported in org-mode, but I need to do it myself at the moment.
(when (locate-library "ob-coffee")
(require 'ob-coffee))
It seems to automatically recognize the language used in a source
block, but if not, call org-babel-lob-ingest
to add all the
languages from the code block into the list that Babel supports.
Keystroke: C-c C-v i
.
I’m normally fine with having my code automatically evaluated.
(setq org-confirm-babel-evaluate nil)
; (setq org-src-fontify-natively t)
(setq org-src-tab-acts-natively t)
(define-key personal-global-map (kbd "S-f") 'org-src-fontify-buffer)
(define-key personal-global-map (kbd "f") 'org-src-fontify-block)
Normally, fontifying the individual code blocks makes it impossible to work with, so instead of turning it on at the global level for all blocks, I created a couple of keystrokes to selectively colorize one block at a time.
Need to provide the init-org-mode
so that I can require this
package.
(provide 'init-org-mode)
Before you can build this on a new system, make sure that you put
the cursor over any of these properties, and hit: C-c C-c