Skip to content

Instantly share code, notes, and snippets.

@ivan
Last active August 27, 2023 01:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivan/c280d6eb402b83058542ddecae4cd9f6 to your computer and use it in GitHub Desktop.
Save ivan/c280d6eb402b83058542ddecae4cd9f6 to your computer and use it in GitHub Desktop.
Emacs + org-mode configuration
; Load files as UTF-8 including quotes.org which has problems without this
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
; Make emacs start much faster on Windows by disabling support for git and other VCSes
(setq vc-handled-backends ())
; 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 . maximized))
(add-to-list 'initial-frame-alist '(fullscreen . maximized))
; 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, amex, ido-yes-or-no
(require 'ido-completing-read+)
(ido-ubiquitous-mode t)
(require 'amx)
(amx-mode 1) ; this rebinds M-x
(require 'ido-yes-or-no)
(ido-yes-or-no-mode 1)
; Enable htmlize
(require 'htmlize)
; Access the TODO menu in fewer keystrokes
(global-set-key (kbd "C-t") 'org-todo)
(global-set-key (kbd "C-e") 'org-set-tags-command)
(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") 'amx-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)
; https://emacs.stackexchange.com/questions/13485/something-like-delete-frame-but-that-would-also-delete-the-last-frame-like-al
(defun delete-frame-or-kill-emacs ()
"Delete the selected frame. If the last one, kill Emacs."
(interactive)
(condition-case nil (delete-frame) (error (kill-emacs))))
(global-set-key [M-f4] 'delete-frame-or-kill-emacs)
; 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 " ↴↴↴")
; Use PragmataPro Mono for ↴ to make it narrower.
; Use :weight 'normal to fix the "missing glyph" breakage after every :tag: (rendered bold) in org-mode
; Also, for some reason it is still rendered bold when fixed??
(set-fontset-font t '(#x21b4 . #x21b4) (font-spec :family "PragmataPro Mono" :weight 'normal))
(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)
; If a bullet is messing up the line height, see https://unicode-search.net/unicode-namesearch.pl?term=CIRCLE for a replacement
;(setq org-bullets-bullet-list '("●" "○"))
(setq org-bullets-bullet-list '("○"))
(require 'org-indent)
(add-hook 'text-mode-hook
(lambda ()
; Treat _ character as part of the word when double-clicking
(modify-syntax-entry ?_ "w")
)
)
(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))
; Treat _ character as part of the word when double-clicking
(modify-syntax-entry ?_ "w")
)
)
;;; 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)))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(default ((t (:background "#111111"))))
'(fixed-pitch ((t (:family "PragmataPro Mono"))))
'(link ((t (:foreground "#66AAEE"))))
'(org-agenda-done ((t (:foreground "#666666"))))
'(org-ellipsis ((t (:foreground "#666666"))))
'(org-headline-done ((t (:foreground "#666666"))))
'(org-hide ((t (:foreground "#1E1E1E"))))
'(outline-1 ((t (:foreground "#AAAAAA"))))
'(outline-2 ((t (:foreground "#AAAAAA"))))
'(outline-3 ((t (:foreground "#AAAAAA"))))
'(outline-4 ((t (:foreground "#AAAAAA"))))
'(outline-5 ((t (:foreground "#AAAAAA"))))
'(outline-6 ((t (:foreground "#AAAAAA"))))
'(outline-7 ((t (:foreground "#AAAAAA"))))
'(outline-8 ((t (:foreground "#AAAAAA"))))
'(region ((t (:background "#004EAD")))))
; 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.15)
; no extra height between lines
(setq-default line-spacing nil))
(redraw-display))
(setq-default line-spacing 0.15)
(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