Emacs + org-mode configuration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Keep this here to prevent it from getting added back uncommented | |
;(package-initialize) | |
; Recommended by flx, gc every 20MB | |
(setq gc-cons-threshold 20000000) | |
; Disable double-buffering; we don't need it and it seems to make things | |
; slightly laggier. | |
(modify-frame-parameters nil '((inhibit-double-buffering . t))) | |
(setq default-frame-parameters '((inhibit-double-buffering . t))) | |
; Always maximize frame height; very helpful when cycling fonts | |
(add-to-list 'default-frame-alist '(fullscreen . fullheight)) | |
; Disable the toolbar | |
(tool-bar-mode -1) | |
; Disable cursor blinking | |
(blink-cursor-mode -1) | |
; Reopen the files that were open in the previous session | |
(desktop-save-mode 1) | |
; Always save desktop | |
(setq desktop-save t) | |
; Load desktop even if locked (due to e.g. unclean shutdown) | |
(setq desktop-load-locked-desktop t) | |
; Never pop up dialog boxes | |
(setq use-dialog-box nil) | |
; We use version control, so don't create backup or autosave files. | |
(setq make-backup-files nil) | |
(setq auto-save-default nil) | |
; Don't create lockfiles. | |
(setq create-lockfiles nil) | |
; Automatically revert files to the on-disk contents | |
(global-auto-revert-mode 1) | |
; Wrap words rather than characters | |
(setq-default word-wrap t) | |
; Don't truncate lines | |
(setq-default truncate-lines nil) | |
; When reaching the end, scroll by one line instead of half the viewport | |
(setq scroll-step 1) | |
; Make mousewheel scroll three lines at a time | |
(setq mouse-wheel-scroll-amount '(2 ((shift) . 1))) | |
; Don't accelerate scrolling | |
(setq mouse-wheel-progressive-speed nil) | |
; Scroll the window under the mouse cursor | |
(setq mouse-wheel-follow-mouse 't) | |
; Highlight matching parentheses with no delay | |
(setq show-paren-delay 0) | |
(show-paren-mode 1) | |
; Open URLs in Chrome | |
(setq browse-url-browser-function 'browse-url-generic) | |
(setq browse-url-generic-program "google-chrome") | |
; This is C-<return> by default, but we need that for org-mode | |
(setq cua-rectangle-mark-key (kbd "C-S-<return>")) | |
; Don't clear the region after copying | |
(setq cua-keep-region-after-copy t) | |
; Must be done after setq cua-rectangle-mark-key | |
(cua-mode t) | |
; Enable ido | |
(ido-mode t) | |
(ido-everywhere t) | |
; Enable ido-ubiquitous | |
(setq load-path (cons "~/opt/ido-ubiquitous" load-path)) | |
(require 'ido-completing-read+) | |
(ido-ubiquitous-mode t) | |
; Enable smex | |
(setq load-path (cons "~/opt/smex" load-path)) | |
(require 'smex) | |
(setq smex-save-file "~/.cache/emacs/smex-items") | |
(smex-initialize) | |
; Access the TODO menu in fewer keystrokes | |
(global-set-key (kbd "C-t") 'org-todo) | |
(global-set-key (kbd "C-c a") 'org-agenda) | |
(global-set-key (kbd "M-q") 'switch-to-buffer) | |
(global-set-key (kbd "C--") 'text-scale-decrease) | |
(global-set-key (kbd "C-=") 'text-scale-increase) | |
; Note that browse-url-at-point always opens in the browser, unlike C-c C-o org-open-at-point | |
(global-set-key (kbd "C-o") 'browse-url-at-point) | |
(global-set-key (kbd "C-a") 'mark-whole-buffer) | |
(global-set-key (kbd "C-s") 'save-buffer) | |
(global-set-key (kbd "C-w") 'kill-this-buffer) | |
(global-set-key (kbd "C-f") 'isearch-forward) | |
(global-set-key (kbd "C-b") 'isearch-backward) | |
(global-set-key (kbd "<f3>") 'isearch-repeat-forward) | |
(global-set-key (kbd "S-<f3>") 'isearch-repeat-backward) | |
(global-set-key (kbd "<escape>") 'keyboard-escape-quit) | |
(global-set-key (kbd "M-x") 'smex) | |
(global-set-key (kbd "M-X") 'smex-major-mode-commands) ; commands relevant to active major mode | |
(define-key isearch-mode-map (kbd "C-f") 'isearch-repeat-forward) | |
(define-key isearch-mode-map (kbd "C-b") 'isearch-repeat-backward) | |
(define-key isearch-mode-map (kbd "C-v") 'isearch-yank-kill) | |
; Change frame title from [user@host] to filename | |
(setq frame-title-format "%b - Emacs") | |
; For emacsclient | |
(server-start) | |
;;; org-mode | |
; It's way too easy to accidentally open links with mouse-1; you can still | |
; open them with mouse-2 or mouse-3. | |
; | |
; Needs to be set before org-mode is loaded. | |
(setq org-mouse-1-follows-link nil) | |
(setq load-path (cons "~/opt/org-mode/lisp" load-path)) | |
(require 'org) | |
; Also load both .org_archive files with org-mode | |
(add-to-list 'auto-mode-alist '("\\.org_archive$" . org-mode)) | |
; "Make point visible, and do insertion/deletion if it is | |
; adjacent to visible text and the change feels predictable. | |
; Never delete a previously invisible character or add in the | |
; middle or right after an invisible region. Basically, this | |
; allows insertion and backward-delete right before ellipses." | |
(setq org-catch-invisible-edits 'smart) | |
; http://orgmode.org/manual/Clean-view.html | |
(setq org-startup-indented t) | |
(setq org-ellipsis " ↴↴↴") | |
(setq org-todo-keywords | |
; keywords following the "|" are considered complete | |
; | |
; ! = timestamp | |
; @ = note with a timestamp | |
; /! = timestamp even if destination keyword has no logging configured | |
'((sequence "TODO(t!)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELED(c!)"))) | |
; http://orgmode.org/manual/Weekly_002fdaily-agenda.html | |
(setq org-agenda-include-diary t) | |
(setq org-agenda-files | |
'( | |
"~/wiki/tasks.org" | |
"~/wiki/events.org" | |
)) | |
; Using ido for refiling is buggy: https://lists.gnu.org/archive/html/emacs-orgmode/2016-05/msg00665.html | |
; Use ido for refiling | |
;(setq org-completion-use-ido t) | |
; Needed to use ido for refiling | |
;(setq org-outline-path-complete-in-steps nil) | |
; Make org-refile work on files | |
(setq org-refile-use-outline-path 'file) | |
(defun update-all-org-files (ignored) | |
(setq all-org-files (file-expand-wildcards "~/wiki/*.org"))) | |
(update-all-org-files nil) | |
(advice-add 'org-refile-get-targets :before #'update-all-org-files) | |
(setq org-refile-targets | |
'((all-org-files :maxlevel . 1))) | |
; Refile to the top instead of the bottom | |
(setq org-reverse-note-order t) | |
; Shift-down should increase the time/day on an item to match the order in the agenda | |
(setq org-edit-timestamp-down-means-later t) | |
; Operate an all the selected headlines; seems to be buggy: e.g. marking things as DONE writes | |
; a state change only to the last headline. | |
; (setq org-loop-over-headlines-in-active-region t) | |
(defun org-save-all-org-buffers-quietly () | |
(save-some-buffers t (lambda () (derived-mode-p 'org-mode))) | |
(when (featurep 'org-id) (org-id-locations-save))) | |
; Save all modified org buffers frequently, because otherwise it's easy to | |
; accidentally leave things unsaved after refilings or other changes. | |
(run-with-idle-timer 5 5 'org-save-all-org-buffers-quietly) | |
(defun load-org-modules () | |
; Merely loading org-mouse breaks clicking inside a region: clicking | |
; should clear the region; with org-mouse loaded, the region is truncated | |
; to the point. | |
; | |
; Note that we don't need org-mouse for activate-bullets because org-bullets | |
; provide this functionality. | |
;(add-to-list 'org-modules 'org-mouse) | |
) | |
(eval-after-load "org" '(load-org-modules)) | |
;(setq org-mouse-features '(context-menu activate-stars activate-bullets activate-checkboxes)) | |
(setq load-path (cons "~/opt/org-bullets" load-path)) | |
(require 'org-bullets) | |
; Avoid using ✸ because it increases the line height | |
(setq org-bullets-bullet-list '("◉" "○")) | |
(require 'org-indent) | |
(add-hook 'org-mode-hook | |
(lambda () | |
(setq truncate-lines nil) | |
(org-bullets-mode 1) | |
; org-mode binds ctrl-a to org-beginning-of-line, but we don't need it | |
; because we have Home and End. | |
(local-set-key (kbd "C-a") 'mark-whole-buffer) | |
(auto-revert-mode 1) | |
; Fix indentation for non-headline text below headlines when using variable-width fonts | |
; https://emacs.stackexchange.com/questions/26864/variable-pitch-face-breaking-indentation-in-org-mode | |
(set-face-attribute 'org-indent nil :inherit '(org-hide fixed-pitch)) | |
) | |
) | |
;;; notmuch | |
(require 'notmuch) | |
;;; outgoing mail | |
(require 'smtpmail) | |
(setq | |
send-mail-function 'smtpmail-send-it | |
message-send-mail-function 'smtpmail-send-it | |
smtpmail-smtp-server "smtp.gmail.com" | |
smtpmail-smtp-service 587 | |
smtpmail-stream-type 'starttls) | |
; Sends a message with something like | |
; Message-Id: 87h8t8ebpe.fsf@mail.gmail.com | |
; instead of | |
; Message-Id: 87h8t8ebpe.fsf@ra.i-did-not-set--mail-host-address--so-tickle-me | |
(setq mail-host-address "mail.gmail.com") | |
;;; fonts and colors | |
; Needed for the org-headline-done below to work | |
(setq org-fontify-done-headline t) | |
(setq org-todo-keyword-faces | |
'(("CANCELED" :foreground "#686868" :weight bold) | |
("WAIT" :foreground "#B26818" :weight bold) | |
("DONE" :foreground "#686868" :weight bold) | |
("TODO" :foreground "#3F9E1D" :weight bold))) | |
(set-face-attribute 'default nil :font "Sans-9.5") | |
(custom-set-faces | |
'(default ((t (:background "#E8E2D9")))) ; Light gray background | |
'(org-hide ((t (:foreground "#E8E2D9")))) ; Make the invisible asterisks match the background | |
'(region ((t (:background "#FFCC33")))) ; Orange text selection | |
; Make all outline levels black so we don't mentally associate outline depth with anything | |
'(outline-1 ((t (:foreground "#000000")))) | |
'(outline-2 ((t (:foreground "#000000")))) | |
'(outline-3 ((t (:foreground "#000000")))) | |
'(outline-4 ((t (:foreground "#000000")))) | |
'(outline-5 ((t (:foreground "#000000")))) | |
'(outline-6 ((t (:foreground "#000000")))) | |
'(org-ellipsis ((t (:foreground "#888888")))) | |
'(org-headline-done ((t (:foreground "LavenderBlush4")))) ; Gray out DONE items in files | |
'(org-agenda-done ((t (:foreground "LavenderBlush4")))) ; Gray out DONE items in agenda | |
) | |
; Set the fringe colors to match our background and foreground colors | |
(set-face-attribute | |
'fringe nil | |
:foreground (face-foreground 'default) | |
:background (face-background 'default)) | |
;;; interactive functions | |
; http://xahlee.org/emacs/emacs_make_modern.html | |
(defun toggle-line-spacing () | |
"Toggle line spacing between no extra space to extra half line height." | |
(interactive) | |
(if (eq line-spacing nil) | |
; add some height between lines | |
(setq-default line-spacing 0.25) | |
; no extra height between lines | |
(setq-default line-spacing nil)) | |
(redraw-display)) | |
(setq-default line-spacing 0.25) | |
(defun get-font-list () | |
(pcase (system-name) | |
("plato" '("Sans-10.5" "monospace-10.5")) | |
("ra" '("Roboto-9.5" "SF Pro Text-9.5" "monospace-9.5")))) | |
; http://xahlee.blogspot.com/2010/07/how-to-quickly-switch-fonts-in-emacs.html | |
(defun cycle-font (num) | |
"Change font in current frame. | |
Each time this is called, font cycles thru a predefined set of fonts. | |
If NUM is 1, cycle forward. | |
If NUM is -1, cycle backward." | |
(interactive "p") | |
;; this function sets a property “state”. It is a integer. Possible values are any index to the font-list. | |
(let (font-list font-to-use current-state next-state) | |
(setq font-list (get-font-list)) | |
(setq current-state (if (get 'cycle-font 'state) (get 'cycle-font 'state) 0)) | |
(setq next-state (% (+ current-state (length font-list) num) (length font-list))) | |
(setq font-to-use (nth next-state font-list)) | |
(set-frame-parameter nil 'font font-to-use) | |
(redraw-frame (selected-frame)) | |
(message "Current font is: %s" font-to-use) | |
(put 'cycle-font 'state next-state))) | |
(defun cycle-font-forward () | |
"Switch to the next font, in the current frame. | |
See `cycle-font'." | |
(interactive) | |
(cycle-font 1)) | |
(defun cycle-font-backward () | |
"Switch to the previous font, in the current frame. | |
See `cycle-font'." | |
(interactive) | |
(cycle-font -1)) | |
(global-set-key (kbd "C-_") 'cycle-font-backward) | |
(global-set-key (kbd "C-+") 'cycle-font-forward) | |
; Emacs' Ctrl-backspace runs backward-kill-word which deletes too much, so use | |
; this replacement from http://stackoverflow.com/questions/28221079/ctrl-backspace-in-emacs-deletes-too-much | |
; with kill ring tweak from http://stackoverflow.com/a/6133921/3282436 | |
(defun my-kill-back () | |
(interactive) | |
(if (bolp) | |
; Beginnning of line, just delete one character | |
(backward-delete-char 1) | |
(if (string-match "[^[:space:]]" (buffer-substring (point-at-bol) (point))) | |
; There's a word on the line, delete it | |
; delete-region instead of (backward-kill-word 1) to avoid putting word into the kill ring | |
(delete-region (point) (progn (backward-word 1) (point))) | |
; All whitespace, delete it | |
(delete-region (point-at-bol) (point))))) | |
(global-set-key [C-backspace] 'my-kill-back) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Linked to from https://ludios.org/links/