Skip to content

Instantly share code, notes, and snippets.

@ivan
Last active December 2, 2020 10:19
Embed
What would you like to do?
Emacs + org-mode configuration
; 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)
@ivan
Copy link
Author

ivan commented Oct 18, 2017

Linked to from https://ludios.org/links/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment