1 #+TITLE: Emacs configuration
5 https://github.com/hrs/dotfiles/blob/master/emacs/.emacs.d/configuration.org
6 https://github.com/daviwil/emacs-from-scratch
8 * Set personal information
10 #+BEGIN_SRC emacs-lisp
11 (setq user-full-name "Ralph Böhme"
12 user-mail-address "slow@samba.org")
17 Setup package management with Melpa, nifty!
19 #+BEGIN_SRC emacs-lisp
22 (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
23 (add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/"))
25 (unless package-archive-contents
26 (package-refresh-contents))
28 (require 'use-package)
29 (setq use-package-always-ensure t)
34 #+BEGIN_SRC emacs-lisp
35 (add-to-list 'load-path "~/.emacs.d/lisp/")
39 #+BEGIN_SRC emacs-lisp
40 (scroll-bar-mode -1) ; Disable visible scrollbar
41 (tool-bar-mode -1) ; Disable the toolbar
42 (tooltip-mode -1) ; Disable tooltips
43 (set-fringe-mode 10) ; Give some breathing room
44 (menu-bar-mode -1) ; Disable the menu bar
47 ** Keyboard mapping and keybindings
49 #+BEGIN_SRC emacs-lisp
50 (setq ns-right-option-modifier 'super)
51 (global-set-key (kbd "C-M-j") 'counsel-switch-buffer)
55 #+begin_src emacs-lisp
58 (setq smblog-src-dir "/git/samba/scratch/foo")
63 (use-package helm :config (require 'helm-config))
64 (global-set-key (kbd "M-x") #'helm-M-x)
65 (global-set-key (kbd "C-x r b") #'helm-filtered-bookmarks)
66 (global-set-key (kbd "C-x C-f") #'helm-find-files)
72 (use-package all-the-icons
74 (use-package powerline
76 :hook (after-init . powerline-default-theme)
78 (powerline-active0 ((t (:inherit mode-line :background "color-255"))))
79 (powerline-active1 ((t (:inherit mode-line :background "color-253" :foreground "black"))))
80 (powerline-active2 ((t (:inherit mode-line :background "color-251" :foreground "black"))))
88 (use-package which-key
90 :diminish which-key-mode
93 (setq which-key-idle-delay 1))
98 ** Autosave buffers when changing buffer
100 #+BEGIN_SRC emacs-lisp
101 (defadvice switch-to-buffer (before save-buffer-now activate)
102 (when buffer-file-name (save-buffer)))
103 (defadvice other-window (before other-window-now activate)
104 (when buffer-file-name (save-buffer)))
105 (defadvice other-frame (before other-frame-now activate)
106 (when buffer-file-name (save-buffer)))
109 ** Unfill a paragraph
111 #+BEGIN_SRC emacs-lisp
112 ;;; It is the opposite of fill-paragraph
113 (defun unfill-paragraph ()
114 "Takes a multi-line paragraph and makes it into a single line of text."
116 (let ((fill-column (point-max)))
117 (fill-paragraph nil)))
118 (define-key global-map "\M-Q" 'unfill-paragraph)
124 (global-set-key [C-tab] "\C-q\t") ; Control tab quotes a tab.
125 (global-set-key "\C-s" 'isearch-forward-regexp)
126 (global-set-key "\C-r" 'isearch-backward-regexp)
127 (define-key esc-map "g" 'goto-line)
128 (define-key esc-map "G" 'what-line)
129 (define-key esc-map "n" 'next-error)
130 (define-key esc-map "p" 'fill-paragraph)
131 (global-set-key [f8] 'shrink-window-horizontally)
132 (global-set-key [f9] 'enlarge-window-horizontally)
133 (global-set-key [f10] 'shrink-window)
134 (global-set-key [f11] 'enlarge-window)
135 (global-set-key [f12] 'other-window)
137 (setq delete-auto-save-files t)
138 (setq-default indent-tabs-mode nil)
139 (setq column-number-mode t)
140 (setq-default truncate-lines t)
142 ;; Treat 'y' or <CR> as yes, 'n' as no.
143 (fset 'yes-or-no-p 'y-or-n-p)
144 (define-key query-replace-map [return] 'act)
145 (define-key query-replace-map [?\C-m] 'act)
148 ** autonewline and electric
151 (setq-default electric-indent-mode nil)
152 (setq-default electric-indent-inhibit t)
153 (add-hook 'after-change-major-mode-hook (lambda() (electric-indent-mode -1)))
158 (require 'whitespace)
159 (setq whitespace-line-column 80) ;; limit line length
160 (setq whitespace-style '(face lines-tail))
161 (add-hook 'prog-mode-hook 'whitespace-mode)
166 (use-package yasnippet
173 ** Rainbow Delimiters
175 [[https://github.com/Fanael/rainbow-delimiters][rainbow-delimiters]] is useful in programming modes because it colorizes
176 nested parentheses and brackets according to their nesting depth.
177 This makes it a lot easier to visually match parentheses in Emacs Lisp
178 code without having to count them yourself.
180 #+begin_src emacs-lisp
182 (use-package rainbow-delimiters
183 :hook (prog-mode . rainbow-delimiters-mode))
191 (add-hook 'c-mode-hook
193 (setq show-trailing-whitespace t)
194 (c-set-style "linux")
195 (c-toggle-auto-state)
197 (setq-default indent-tabs-mode t)
198 (setq-default c-hanging-semi&comma-criteria nil)
199 (setq-default tab-width 8)
200 (setq-default fill-column 80)
201 (define-key ctl-x-map "c" 'compile)
202 (which-function-mode t)))
208 (setq-default compile-command "cd /git/samba/scratch/ && make -j")
215 "Netatalk indentation"
217 (setq-default indent-tabs-mode nil)
218 (setq-default tab-width 4)
219 (setq c-default-style "bsd")
220 (setq c-basic-offset 4))
226 (use-package git-commit
230 (defun my-magit-status()
231 "magit-status in one window"
234 (delete-other-windows))
236 (global-set-key [f1] 'my-magit-status)
237 (define-key esc-map "#" 'magit-diff-visit-file-worktree)
238 (setq ediff-split-window-function 'split-window-horizontally)
242 Flycheck for compile and error check while editing
244 #+BEGIN_SRC emacs-lisp
245 ;(require 'flycheck-ycmd)
246 ;(flycheck-ycmd-setup)
252 https://emacs-lsp.github.io/lsp-mode/page/installation/
254 #+BEGIN_SRC emacs-lisp
257 (add-hook 'c-mode-hook #'lsp)
264 (define-key esc-map "1" 'cscope-display-buffer-toggle)
265 (define-key esc-map "2" 'cscope-pop-mark)
266 (define-key esc-map "3" 'cscope-find-global-definition-no-prompting)
267 (define-key esc-map "4" 'cscope-find-this-symbol)
268 (define-key esc-map "5" 'cscope-history-kill-result)
269 (define-key esc-map "6" 'cscope-display-buffer)
274 (require 'systemtap-mode)
275 (add-hook 'systemtap-mode-hook
277 (setq-default indent-tabs-mode t)
278 (setq-default tab-width 8)
279 (setq show-trailing-whitespace t)
280 (c-toggle-auto-newline nil)))
285 [[https://projectile.mx/][Projectile]] is a project management library for Emacs which makes it a
286 lot easier to navigate around code projects for various languages.
287 Many packages integrate with Projectile so it's a good idea to have it
288 installed even if you don't use its commands directly.
290 #+begin_src emacs-lisp
292 (use-package projectile
293 :diminish projectile-mode
294 :config (projectile-mode)
295 :custom ((projectile-completion-system 'helm))
297 ("C-c p" . projectile-command-map)
299 ;; NOTE: Set this to the folder where you keep your Git repos!
300 (when (file-directory-p "/git")
301 (setq projectile-project-search-path '("/git")))
302 (setq projectile-switch-project-action #'projectile-dired))
304 (use-package counsel-projectile
306 :config (counsel-projectile-mode))
314 #+BEGIN_SRC emacs-lisp
315 (setq org-agenda-files (list "sernet.org"
320 (setq org-todo-keywords
321 '((sequence "TODO(t)" "PROJECT(p)" "PRIVAT(P)" "|" "WAIT(w)" "REPEATING(r)" "MISC(m)" "DONE(d)")))
324 Enable org-bullet mode
326 #+BEGIN_SRC emacs-lisp
327 (require 'org-bullets)
329 (defun my-org-todo-list()
330 "org-todo-list in one window"
333 (delete-other-windows))
335 (add-hook 'org-mode-hook
338 (global-set-key [f4] 'my-org-todo-list)
345 #+BEGIN_SRC emacs-lisp
349 Enable org-tempo for <s
351 #+BEGIN_SRC emacs-lisp
357 #+BEGIN_SRC emacs-lisp
358 (setq org-duration-units
364 ("y" . ,(* 60 8 21 12))))
366 (setq org-effort-durations
371 ;; five-day work week
373 ;; four weeks in a month
374 ("m" . ,(* 60 8 5 4))
375 ;; work a total of 12 months a year --
376 ;; this is independent of holiday and sick time taken
377 ("y" . ,(* 60 8 5 4 12))))
380 ** Display preferences
382 I like seeing a little downward-pointing arrow instead of the usual ellipsis
383 (...) that org displays when there’s stuff under a header.
385 #+BEGIN_SRC emacs-lisp
386 (setq org-ellipsis "⤸")
389 Use syntax highlighting in source blocks while editing.
391 #+BEGIN_SRC emacs-lisp
392 (setq org-src-fontify-natively t)
395 Make TAB act as if it were issued in a buffer of the language’s major mode.
397 #+BEGIN_SRC emacs-lisp
398 (setq org-src-tab-acts-natively t)
403 #+BEGIN_SRC emacs-lisp
404 (setq-default org-hide-leading-stars t)
407 Keep lines small, limit to 76 characters.
409 #+BEGIN_SRC emacs-lisp
410 (setq-default org-ascii-text-width 76)
414 https://lists.gnu.org/archive/html/emacs-orgmode/2017-02/msg00270.html
416 #+BEGIN_SRC emacs-lisp
417 (setq org-duration-format (quote h:mm))
421 #+BEGIN_SRC emacs-lisp
422 (defun sum-estimates (beg end)
425 (let (nums hours days weeks months)
427 (while (re-search-forward "Estimate: \\([0-9]+\\) hour" end t)
428 (push (string-to-number (match-string-no-properties 1)) nums))
429 (setq hours (apply #'+ nums))
433 (while (re-search-forward "Estimate: \\([0-9]+\\) day" end t)
434 (push (string-to-number (match-string-no-properties 1)) nums))
435 (setq days (apply #'+ nums))
439 (while (re-search-forward "Estimate: \\([0-9]+\\) week" end t)
440 (push (string-to-number (match-string-no-properties 1)) nums))
441 (setq weeks (apply #'+ nums))
445 (while (re-search-forward "Estimate: \\([0-9]+\\) month" end t)
446 (push (string-to-number (match-string-no-properties 1)) nums))
447 (setq months (apply #'+ nums))
449 (setq days (+ days (* months 21)))
450 (setq days (+ days (* weeks 5)))
451 (setq days (+ days (/ hours 8)))
452 (setq hours (% hours 8))
454 (message "%s days, %s hours" days hours)
455 (kill-new (format "%s days, %s hours" days hours))
460 Allow export to beamer (for presentations).
462 #+BEGIN_SRC emacs-lisp
466 Disable _ subscript syntax highlight engine.
468 #+BEGIN_SRC emacs-lisp
469 (setq-default org-export-with-sub-superscripts nil)
472 Allow babel to evaluate Emacs Lisp.
474 #+BEGIN_SRC emacs-lisp
475 (org-babel-do-load-languages
476 'org-babel-load-languages
480 Don’t ask before evaluating code blocks.
482 #+BEGIN_SRC emacs-lisp
483 (setq org-confirm-babel-evaluate nil)
486 Enable source code highlighting
488 #+BEGIN_SRC emacs-lisp
492 Page break after TOC:
494 #+BEGIN_SRC emacs-lisp
495 (setq org-latex-toc-command "\\tableofcontents \\clearpage")
498 Use minted for exporting code to PDF
500 #+BEGIN_SRC emacs-lisp
501 (setq org-latex-listings 'minted
502 org-latex-packages-alist '(("" "minted"))
503 org-src-fontify-natively t
504 org-latex-pdf-process
505 '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
506 "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
511 Custom function to archive DONE items.
513 #+BEGIN_SRC emacs-lisp
514 (defun org-archive-done-tasks ()
516 (org-map-entries 'org-archive-subtree "/DONE" 'file))
520 #+begin_src emacs-lisp
521 (defun my-org-clocktable-indent-string (level)
526 (setq level (1- level)
527 str (concat str "--")))
528 (concat str "-> "))))
530 (advice-add 'org-clocktable-indent-string :override #'my-org-clocktable-indent-string)
535 https://geeksocket.in/posts/presentations-org-emacs/
539 (use-package org-tree-slide)
540 (with-eval-after-load "org-tree-slide"
541 (define-key org-tree-slide-mode-map (kbd "<f7>") 'org-tree-slide-move-previous-tree)
542 (define-key org-tree-slide-mode-map (kbd "<f8>") 'org-tree-slide-move-next-tree)
551 (add-to-list 'auto-mode-alist '("/mutt" . mail-mode))
552 (add-to-list 'auto-mode-alist '("/neomutt" . mail-mode))
553 (add-hook 'mail-mode-hook 'turn-on-auto-fill)
555 ** Format flowed retooling fill paragraph
556 #+BEGIN_SRC emacs-lisp
557 (defun my-message-configuration ()
558 "Redefines fill-newline to beahve 3676ishly, and turns off auto fill"
560 (defun my-fill-newline ()
561 ;; Replace whitespace here with one newline, then
562 ;; indent to left margin.
563 (skip-chars-backward " \t")
566 ;; Give newline the properties of the space(s) it replaces
567 (set-text-properties (1- (point)) (point)
568 (fill-text-properties-at (point)))
569 (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
570 (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
572 ;; When refilling later on, this newline would normally not be replaced
573 ;; by a space, so we need to mark it specially to re-install the space
575 (put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
576 ;; If we don't want breaks in invisible text, don't insert
577 ;; an invisible newline.
578 (if fill-nobreak-invisible
579 (remove-text-properties (1- (point)) (point)
582 (not fill-indent-according-to-mode))
583 (fill-indent-to-left-margin)
584 (indent-according-to-mode))
585 ;; Insert the fill prefix after indentation.
586 (and fill-prefix (not (equal fill-prefix ""))
587 ;; Markers that were after the whitespace are now at point: insert
588 ;; before them so they don't get stuck before the prefix.
589 (insert-before-markers-and-inherit fill-prefix)))
591 (add-hook 'mail-mode-hook 'my-message-configuration)
593 ** Format flowed, done manually with M-f
594 #+BEGIN_SRC emacs-lisp
595 (defun as-format-as-flowed-text ()
596 "Format the buffer as flowed text according to RFC 2646.
597 This ensures that appropriate lines should be terminated with a
598 single space, and that \"> \" quoting prefixes are replaced with
599 \">\". Operates on the current region if active, otherwise on
602 (let ((start (if (use-region-p) (region-beginning) (point-min)))
603 (end (if (use-region-p) (region-end) (point-max))))
606 ;; Ensure appropriate lines end with a space
607 (while (re-search-forward "^\\(>+ ?\\)?\\S-.*\\S-$" end t)
608 (replace-match "\\& " t))
610 ;; Replace "> " quoting prefixes with ">"
613 (eolm (make-marker)))
614 (while (setq eol (re-search-forward "^>.*" end t))
615 (set-marker eolm eol)
616 (goto-char (match-beginning 0))
617 (while (looking-at ">")
618 (if (looking-at "> ")
621 (goto-char (marker-position eolm)))))))
623 (define-key esc-map "f" 'as-format-as-flowed-text)
626 #+BEGIN_SRC emacs-lisp
627 (defun my-message-configuration ()
628 "Redefines fill-newline to beahve 3676ishly, and turns off auto fill"
630 (defun my-fill-newline ()
631 ;; Replace whitespace here with one newline, then
632 ;; indent to left margin.
633 (skip-chars-backward " \t")
636 ;; Give newline the properties of the space(s) it replaces
637 (set-text-properties (1- (point)) (point)
638 (fill-text-properties-at (point)))
639 (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
640 (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
642 ;; When refilling later on, this newline would normally not be replaced
643 ;; by a space, so we need to mark it specially to re-install the space
645 (put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
646 ;; If we don't want breaks in invisible text, don't insert
647 ;; an invisible newline.
648 (if fill-nobreak-invisible
649 (remove-text-properties (1- (point)) (point)
652 (not fill-indent-according-to-mode))
653 (fill-indent-to-left-margin)
654 (indent-according-to-mode))
655 ;; Insert the fill prefix after indentation.
656 (and fill-prefix (not (equal fill-prefix ""))
657 ;; Markers that were after the whitespace are now at point: insert
658 ;; before them so they don't get stuck before the prefix.
659 (insert-before-markers-and-inherit fill-prefix)))
662 (add-hook 'message-mode-hook 'my-message-configuration)