Last active
August 27, 2023 01:42
-
-
Save ivan/c280d6eb402b83058542ddecae4cd9f6 to your computer and use it in GitHub Desktop.
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
; 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) |
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/