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)
54 #+begin_src emacs-lisp
57 (setq smblog-src-dir "/git/samba/scratch/foo")
62 (use-package helm :config (require 'helm-config))
63 (global-set-key (kbd "M-x") #'helm-M-x)
64 (global-set-key (kbd "C-x r b") #'helm-filtered-bookmarks)
65 (global-set-key (kbd "C-x C-f") #'helm-find-files)
71 (use-package all-the-icons
73 (use-package powerline
75 :hook (after-init . powerline-default-theme)
77 (powerline-active0 ((t (:inherit mode-line :background "color-255"))))
78 (powerline-active1 ((t (:inherit mode-line :background "color-253" :foreground "black"))))
79 (powerline-active2 ((t (:inherit mode-line :background "color-251" :foreground "black"))))
87 (use-package which-key
89 :diminish which-key-mode
92 (setq which-key-idle-delay 1))
97 ** Autosave buffers when changing buffer
99 #+BEGIN_SRC emacs-lisp
100 (defadvice switch-to-buffer (before save-buffer-now activate)
101 (when buffer-file-name (save-buffer)))
102 (defadvice other-window (before other-window-now activate)
103 (when buffer-file-name (save-buffer)))
104 (defadvice other-frame (before other-frame-now activate)
105 (when buffer-file-name (save-buffer)))
108 ** Unfill a paragraph
110 #+BEGIN_SRC emacs-lisp
111 ;;; It is the opposite of fill-paragraph
112 (defun unfill-paragraph ()
113 "Takes a multi-line paragraph and makes it into a single line of text."
115 (let ((fill-column (point-max)))
116 (fill-paragraph nil)))
117 (define-key global-map "\M-Q" 'unfill-paragraph)
123 (global-set-key [C-tab] "\C-q\t") ; Control tab quotes a tab.
124 (global-set-key "\C-s" 'isearch-forward-regexp)
125 (global-set-key "\C-r" 'isearch-backward-regexp)
126 (define-key esc-map "g" 'goto-line)
127 (define-key esc-map "G" 'what-line)
128 (define-key esc-map "n" 'next-error)
129 (define-key esc-map "p" 'fill-paragraph)
130 (global-set-key [f8] 'shrink-window-horizontally)
131 (global-set-key [f9] 'enlarge-window-horizontally)
132 (global-set-key [f10] 'shrink-window)
133 (global-set-key [f11] 'enlarge-window)
134 (global-set-key [f12] 'other-window)
136 (setq delete-auto-save-files t)
137 (setq-default indent-tabs-mode nil)
138 (setq column-number-mode t)
139 (setq-default truncate-lines t)
141 ;; Treat 'y' or <CR> as yes, 'n' as no.
142 (fset 'yes-or-no-p 'y-or-n-p)
143 (define-key query-replace-map [return] 'act)
144 (define-key query-replace-map [?\C-m] 'act)
147 ** autonewline and electric
150 (setq-default electric-indent-mode nil)
151 (setq-default electric-indent-inhibit t)
152 (add-hook 'after-change-major-mode-hook (lambda() (electric-indent-mode -1)))
157 (require 'whitespace)
158 (setq whitespace-line-column 80) ;; limit line length
159 (setq whitespace-style '(face lines-tail))
160 (add-hook 'prog-mode-hook 'whitespace-mode)
165 (use-package yasnippet)
169 ** Rainbow Delimiters
171 [[https://github.com/Fanael/rainbow-delimiters][rainbow-delimiters]] is useful in programming modes because it colorizes
172 nested parentheses and brackets according to their nesting depth.
173 This makes it a lot easier to visually match parentheses in Emacs Lisp
174 code without having to count them yourself.
176 #+begin_src emacs-lisp
178 (use-package rainbow-delimiters
179 :hook (prog-mode . rainbow-delimiters-mode))
187 (add-hook 'c-mode-hook
189 (setq show-trailing-whitespace t)
190 (c-set-style "linux")
191 (c-toggle-auto-state)
193 (setq-default indent-tabs-mode t)
194 (setq-default c-hanging-semi&comma-criteria nil)
195 (setq-default tab-width 8)
196 (setq-default fill-column 80)
197 (define-key ctl-x-map "c" 'compile)
198 (which-function-mode t)))
204 (setq-default compile-command "cd /git/samba/scratch/ && make -j")
211 "Netatalk indentation"
213 (setq-default indent-tabs-mode nil)
214 (setq-default tab-width 4)
215 (setq c-default-style "bsd")
216 (setq c-basic-offset 4))
223 (defun my-magit-status()
224 "magit-status in one window"
227 (delete-other-windows))
229 (global-set-key [f1] 'my-magit-status)
230 (define-key esc-map "#" 'magit-diff-visit-file-worktree)
231 (setq ediff-split-window-function 'split-window-horizontally)
235 Flycheck for compile and error check while editing
237 #+BEGIN_SRC emacs-lisp
238 ;(require 'flycheck-ycmd)
239 ;(flycheck-ycmd-setup)
245 https://emacs-lsp.github.io/lsp-mode/page/installation/
247 #+BEGIN_SRC emacs-lisp
250 (add-hook 'c-mode-hook #'lsp)
257 (define-key esc-map "1" 'cscope-display-buffer-toggle)
258 (define-key esc-map "2" 'cscope-pop-mark)
259 (define-key esc-map "3" 'cscope-find-global-definition-no-prompting)
260 (define-key esc-map "4" 'cscope-find-this-symbol)
261 (define-key esc-map "5" 'cscope-history-kill-result)
262 (define-key esc-map "6" 'cscope-display-buffer)
267 (require 'systemtap-mode)
268 (add-hook 'systemtap-mode-hook
270 (setq-default indent-tabs-mode t)
271 (setq-default tab-width 8)
272 (setq show-trailing-whitespace t)
273 (c-toggle-auto-newline nil)))
278 [[https://projectile.mx/][Projectile]] is a project management library for Emacs which makes it a
279 lot easier to navigate around code projects for various languages.
280 Many packages integrate with Projectile so it's a good idea to have it
281 installed even if you don't use its commands directly.
283 #+begin_src emacs-lisp
285 (use-package projectile
286 :diminish projectile-mode
287 :config (projectile-mode)
288 :custom ((projectile-completion-system 'helm))
290 ("C-c p" . projectile-command-map)
292 ;; NOTE: Set this to the folder where you keep your Git repos!
293 (when (file-directory-p "/git")
294 (setq projectile-project-search-path '("/git")))
295 (setq projectile-switch-project-action #'projectile-dired))
297 (use-package counsel-projectile
299 :config (counsel-projectile-mode))
307 #+BEGIN_SRC emacs-lisp
308 (setq org-agenda-files (list "sernet.org"
313 (setq org-todo-keywords
314 '((sequence "TODO(t)" "PROJECT(p)" "|" "WAIT(w)" "REPEATING(r)" "MISC(m)" "DONE(d)")))
317 Enable org-bullet mode
319 #+BEGIN_SRC emacs-lisp
320 (require 'org-bullets)
322 (defun my-org-todo-list()
323 "org-todo-list in one window"
326 (delete-other-windows))
328 (add-hook 'org-mode-hook
331 (global-set-key [f4] 'my-org-todo-list)
338 #+BEGIN_SRC emacs-lisp
342 Enable org-tempo for <s
344 #+BEGIN_SRC emacs-lisp
350 #+BEGIN_SRC emacs-lisp
351 (setq org-duration-units
357 ("y" . ,(* 60 8 21 12))))
359 (setq org-effort-durations
364 ;; five-day work week
366 ;; four weeks in a month
367 ("m" . ,(* 60 8 5 4))
368 ;; work a total of 12 months a year --
369 ;; this is independent of holiday and sick time taken
370 ("y" . ,(* 60 8 5 4 12))))
373 ** Display preferences
375 I like seeing a little downward-pointing arrow instead of the usual ellipsis
376 (...) that org displays when there’s stuff under a header.
378 #+BEGIN_SRC emacs-lisp
379 (setq org-ellipsis "⤸")
382 Use syntax highlighting in source blocks while editing.
384 #+BEGIN_SRC emacs-lisp
385 (setq org-src-fontify-natively t)
388 Make TAB act as if it were issued in a buffer of the language’s major mode.
390 #+BEGIN_SRC emacs-lisp
391 (setq org-src-tab-acts-natively t)
396 #+BEGIN_SRC emacs-lisp
397 (setq-default org-hide-leading-stars t)
400 Keep lines small, limit to 76 characters.
402 #+BEGIN_SRC emacs-lisp
403 (setq-default org-ascii-text-width 76)
407 https://lists.gnu.org/archive/html/emacs-orgmode/2017-02/msg00270.html
409 #+BEGIN_SRC emacs-lisp
410 (setq org-duration-format (quote h:mm))
414 #+BEGIN_SRC emacs-lisp
415 (defun sum-estimates (beg end)
418 (let (nums hours days weeks months)
420 (while (re-search-forward "Estimate: \\([0-9]+\\) hour" end t)
421 (push (string-to-number (match-string-no-properties 1)) nums))
422 (setq hours (apply #'+ nums))
426 (while (re-search-forward "Estimate: \\([0-9]+\\) day" end t)
427 (push (string-to-number (match-string-no-properties 1)) nums))
428 (setq days (apply #'+ nums))
432 (while (re-search-forward "Estimate: \\([0-9]+\\) week" end t)
433 (push (string-to-number (match-string-no-properties 1)) nums))
434 (setq weeks (apply #'+ nums))
438 (while (re-search-forward "Estimate: \\([0-9]+\\) month" end t)
439 (push (string-to-number (match-string-no-properties 1)) nums))
440 (setq months (apply #'+ nums))
442 (setq days (+ days (* months 21)))
443 (setq days (+ days (* weeks 5)))
444 (setq days (+ days (/ hours 8)))
445 (setq hours (% hours 8))
447 (message "%s days, %s hours" days hours)
448 (kill-new (format "%s days, %s hours" days hours))
453 Allow export to beamer (for presentations).
455 #+BEGIN_SRC emacs-lisp
459 Disable _ subscript syntax highlight engine.
461 #+BEGIN_SRC emacs-lisp
462 (setq-default org-export-with-sub-superscripts nil)
465 Allow babel to evaluate Emacs Lisp.
467 #+BEGIN_SRC emacs-lisp
468 (org-babel-do-load-languages
469 'org-babel-load-languages
473 Don’t ask before evaluating code blocks.
475 #+BEGIN_SRC emacs-lisp
476 (setq org-confirm-babel-evaluate nil)
479 Enable source code highlighting
481 #+BEGIN_SRC emacs-lisp
485 Page break after TOC:
487 #+BEGIN_SRC emacs-lisp
488 (setq org-latex-toc-command "\\tableofcontents \\clearpage")
491 Use minted for exporting code to PDF
493 #+BEGIN_SRC emacs-lisp
494 (setq org-latex-listings 'minted
495 org-latex-packages-alist '(("" "minted"))
496 org-src-fontify-natively t
497 org-latex-pdf-process
498 '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
499 "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
504 Custom function to archive DONE items.
506 #+BEGIN_SRC emacs-lisp
507 (defun org-archive-done-tasks ()
509 (org-map-entries 'org-archive-subtree "/DONE" 'file))
513 #+begin_src emacs-lisp
514 (defun my-org-clocktable-indent-string (level)
519 (setq level (1- level)
520 str (concat str "--")))
521 (concat str "-> "))))
523 (advice-add 'org-clocktable-indent-string :override #'my-org-clocktable-indent-string)
529 (add-to-list 'auto-mode-alist '("/mutt" . mail-mode))
530 (add-to-list 'auto-mode-alist '("/neomutt" . mail-mode))
531 (add-hook 'mail-mode-hook 'turn-on-auto-fill)
533 ** Format flowed retooling fill paragraph
534 #+BEGIN_SRC emacs-lisp
535 (defun my-message-configuration ()
536 "Redefines fill-newline to beahve 3676ishly, and turns off auto fill"
538 (defun fill-newline ()
539 ;; Replace whitespace here with one newline, then
540 ;; indent to left margin.
541 (skip-chars-backward " \t")
544 ;; Give newline the properties of the space(s) it replaces
545 (set-text-properties (1- (point)) (point)
546 (fill-text-properties-at (point)))
547 (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
548 (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
550 ;; When refilling later on, this newline would normally not be replaced
551 ;; by a space, so we need to mark it specially to re-install the space
553 (put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
554 ;; If we don't want breaks in invisible text, don't insert
555 ;; an invisible newline.
556 (if fill-nobreak-invisible
557 (remove-text-properties (1- (point)) (point)
560 (not fill-indent-according-to-mode))
561 (fill-indent-to-left-margin)
562 (indent-according-to-mode))
563 ;; Insert the fill prefix after indentation.
564 (and fill-prefix (not (equal fill-prefix ""))
565 ;; Markers that were after the whitespace are now at point: insert
566 ;; before them so they don't get stuck before the prefix.
567 (insert-before-markers-and-inherit fill-prefix)))
569 (add-hook 'mail-mode-hook 'my-message-configuration)
571 ** Format flowed, done manually with M-f
572 #+BEGIN_SRC emacs-lisp
573 (defun as-format-as-flowed-text ()
574 "Format the buffer as flowed text according to RFC 2646.
575 This ensures that appropriate lines should be terminated with a
576 single space, and that \"> \" quoting prefixes are replaced with
577 \">\". Operates on the current region if active, otherwise on
580 (let ((start (if (use-region-p) (region-beginning) (point-min)))
581 (end (if (use-region-p) (region-end) (point-max))))
584 ;; Ensure appropriate lines end with a space
585 (while (re-search-forward "^\\(>+ ?\\)?\\S-.*\\S-$" end t)
586 (replace-match "\\& " t))
588 ;; Replace "> " quoting prefixes with ">"
591 (eolm (make-marker)))
592 (while (setq eol (re-search-forward "^>.*" end t))
593 (set-marker eolm eol)
594 (goto-char (match-beginning 0))
595 (while (looking-at ">")
596 (if (looking-at "> ")
599 (goto-char (marker-position eolm)))))))
601 (define-key esc-map "f" 'as-format-as-flowed-text)
604 #+BEGIN_SRC emacs-lisp
605 (defun my-message-configuration ()
606 "Redefines fill-newline to beahve 3676ishly, and turns off auto fill"
608 (defun fill-newline ()
609 ;; Replace whitespace here with one newline, then
610 ;; indent to left margin.
611 (skip-chars-backward " \t")
614 ;; Give newline the properties of the space(s) it replaces
615 (set-text-properties (1- (point)) (point)
616 (fill-text-properties-at (point)))
617 (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
618 (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
620 ;; When refilling later on, this newline would normally not be replaced
621 ;; by a space, so we need to mark it specially to re-install the space
623 (put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
624 ;; If we don't want breaks in invisible text, don't insert
625 ;; an invisible newline.
626 (if fill-nobreak-invisible
627 (remove-text-properties (1- (point)) (point)
630 (not fill-indent-according-to-mode))
631 (fill-indent-to-left-margin)
632 (indent-according-to-mode))
633 ;; Insert the fill prefix after indentation.
634 (and fill-prefix (not (equal fill-prefix ""))
635 ;; Markers that were after the whitespace are now at point: insert
636 ;; before them so they don't get stuck before the prefix.
637 (insert-before-markers-and-inherit fill-prefix)))
640 (add-hook 'message-mode-hook 'my-message-configuration)