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)
68 (define-key helm-find-files-map (kbd "C-i") 'helm-ff-TAB)
73 (use-package all-the-icons
75 (use-package powerline
77 ; :hook (after-init . powerline-default-theme)
79 (powerline-active0 ((t (:inherit mode-line :background "color-255"))))
80 (powerline-active1 ((t (:inherit mode-line :background "color-253" :foreground "black"))))
81 (powerline-active2 ((t (:inherit mode-line :background "color-251" :foreground "black"))))
88 (use-package doom-modeline
90 :hook (after-init . doom-modeline-mode)
98 (use-package which-key
100 :diminish which-key-mode
103 (setq which-key-idle-delay 1))
108 ** Autosave buffers when changing buffer
110 #+BEGIN_SRC emacs-lisp
111 (defadvice switch-to-buffer (before save-buffer-now activate)
112 (when buffer-file-name (save-buffer)))
113 (defadvice other-window (before other-window-now activate)
114 (when buffer-file-name (save-buffer)))
115 (defadvice other-frame (before other-frame-now activate)
116 (when buffer-file-name (save-buffer)))
119 ** Unfill a paragraph
121 #+BEGIN_SRC emacs-lisp
122 ;;; It is the opposite of fill-paragraph
123 (defun unfill-paragraph ()
124 "Takes a multi-line paragraph and makes it into a single line of text."
126 (let ((fill-column (point-max)))
127 (fill-paragraph nil)))
128 (define-key global-map "\M-Q" 'unfill-paragraph)
134 (global-set-key [C-tab] "\C-q\t") ; Control tab quotes a tab.
135 (global-set-key "\C-s" 'isearch-forward-regexp)
136 (global-set-key "\C-r" 'isearch-backward-regexp)
137 (define-key esc-map "g" 'goto-line)
138 (define-key esc-map "G" 'what-line)
139 (define-key esc-map "n" 'next-error)
140 (define-key esc-map "p" 'fill-paragraph)
141 (global-set-key [f8] 'shrink-window-horizontally)
142 (global-set-key [f9] 'enlarge-window-horizontally)
143 (global-set-key [f10] 'shrink-window)
144 (global-set-key [f11] 'enlarge-window)
145 (global-set-key [f12] 'other-window)
147 (setq delete-auto-save-files t)
148 (setq-default indent-tabs-mode nil)
149 (setq column-number-mode t)
150 (setq-default truncate-lines t)
152 ;; Treat 'y' or <CR> as yes, 'n' as no.
153 (fset 'yes-or-no-p 'y-or-n-p)
154 (define-key query-replace-map [return] 'act)
155 (define-key query-replace-map [?\C-m] 'act)
158 ** autonewline and electric
161 (setq-default electric-indent-mode nil)
162 (setq-default electric-indent-inhibit t)
163 (add-hook 'after-change-major-mode-hook (lambda() (electric-indent-mode -1)))
168 (require 'whitespace)
169 (setq whitespace-line-column 80) ;; limit line length
170 (setq whitespace-style '(face lines-tail))
171 (add-hook 'prog-mode-hook 'whitespace-mode)
176 (use-package yasnippet
183 ** Rainbow Delimiters
185 [[https://github.com/Fanael/rainbow-delimiters][rainbow-delimiters]] is useful in programming modes because it colorizes
186 nested parentheses and brackets according to their nesting depth.
187 This makes it a lot easier to visually match parentheses in Emacs Lisp
188 code without having to count them yourself.
190 #+begin_src emacs-lisp
192 (use-package rainbow-delimiters
193 :hook (prog-mode . rainbow-delimiters-mode))
201 (add-hook 'c-mode-hook
203 (setq show-trailing-whitespace t)
204 (c-set-style "linux")
205 (c-toggle-auto-state)
207 (setq-default indent-tabs-mode t)
208 (setq-default c-hanging-semi&comma-criteria nil)
209 (setq-default tab-width 8)
210 (setq-default fill-column 80)
211 (define-key ctl-x-map "c" 'compile)
212 (which-function-mode t)))
218 (setq-default compile-command "cd /git/samba/scratch/ && make -j")
225 "Netatalk indentation"
227 (setq-default indent-tabs-mode nil)
228 (setq-default tab-width 4)
229 (setq c-default-style "bsd")
230 (setq c-basic-offset 4))
236 (use-package git-commit
240 (defun my-magit-status()
241 "magit-status in one window"
244 (delete-other-windows))
246 (global-set-key [f1] 'my-magit-status)
247 (define-key esc-map "#" 'magit-diff-visit-file-worktree)
248 (setq ediff-split-window-function 'split-window-horizontally)
252 Flycheck for compile and error check while editing
254 #+BEGIN_SRC emacs-lisp
255 ;(require 'flycheck-ycmd)
256 ;(flycheck-ycmd-setup)
262 https://emacs-lsp.github.io/lsp-mode/page/installation/
264 #+BEGIN_SRC emacs-lisp
265 (use-package lsp-mode
270 (lsp-enable-which-key-integration t)
272 (lsp-enable-indentation nil)
273 (lsp-enable-on-type-formatting nil)
275 (add-hook 'c-mode-hook #'lsp)
280 [[https://emacs-lsp.github.io/lsp-ui/][lsp-ui]] is a set of UI enhancements built on top of =lsp-mode= which
281 make Emacs feel even more like an IDE. Check out the screenshots on
282 the =lsp-ui= homepage (linked at the beginning of this paragraph) to
283 see examples of what it can do.
285 #+begin_src emacs-lisp
288 :hook (lsp-mode . lsp-ui-mode)
290 (lsp-ui-doc-position 'bottom))
296 [[https://github.com/emacs-lsp/lsp-treemacs][lsp-treemacs]] provides nice tree views for different aspects of your
297 code like symbols in a file, references of a symbol, or diagnostic
298 messages (errors and warnings) that are found in your code.
300 Try these commands with =M-x=:
302 - =lsp-treemacs-symbols= - Show a tree view of the symbols in the current file
303 - =lsp-treemacs-references= - Show a tree view for the references of the symbol under the cursor
304 - =lsp-treemacs-error-list= - Show a tree view for the diagnostic messages in the project
306 This package is built on the [[https://github.com/Alexander-Miller/treemacs][treemacs]] package which might be of some
307 interest to you if you like to have a file browser at the left side of
308 your screen in your editor.
310 #+begin_src emacs-lisp
312 (use-package lsp-treemacs
322 (define-key esc-map "1" 'cscope-display-buffer-toggle)
323 (define-key esc-map "2" 'cscope-pop-mark)
324 (define-key esc-map "3" 'cscope-find-global-definition-no-prompting)
325 (define-key esc-map "4" 'cscope-find-this-symbol)
326 (define-key esc-map "5" 'cscope-history-kill-result)
327 (define-key esc-map "6" 'cscope-display-buffer)
332 (require 'systemtap-mode)
333 (add-hook 'systemtap-mode-hook
335 (setq-default indent-tabs-mode t)
336 (setq-default tab-width 8)
337 (setq show-trailing-whitespace t)
338 (c-toggle-auto-newline nil)))
343 [[https://projectile.mx/][Projectile]] is a project management library for Emacs which makes it a
344 lot easier to navigate around code projects for various languages.
345 Many packages integrate with Projectile so it's a good idea to have it
346 installed even if you don't use its commands directly.
348 #+begin_src emacs-lisp
350 (use-package projectile
351 :diminish projectile-mode
352 :config (projectile-mode)
353 :custom ((projectile-completion-system 'helm))
355 ("C-c p" . projectile-command-map)
357 ;; NOTE: Set this to the folder where you keep your Git repos!
358 (when (file-directory-p "/git")
359 (setq projectile-project-search-path '("/git")))
360 (setq projectile-switch-project-action #'projectile-dired))
362 (use-package counsel-projectile
364 :config (counsel-projectile-mode))
372 #+BEGIN_SRC emacs-lisp
373 (setq org-agenda-files (list "sernet.org"
378 (setq org-todo-keywords
379 '((sequence "TODO(t)" "TEAM(T)" "PROJECT(p)" "PRIVAT(P)" "REPEATING(r)" "|" "WAIT(w)" "DONE(d)")))
382 Enable org-bullet mode
384 #+BEGIN_SRC emacs-lisp
385 (require 'org-bullets)
387 (defun my-org-todo-list()
388 "org-todo-list in one window"
391 (delete-other-windows))
393 (add-hook 'org-mode-hook
396 (global-set-key [f4] 'my-org-todo-list)
403 #+BEGIN_SRC emacs-lisp
407 Enable org-tempo for <s
409 #+BEGIN_SRC emacs-lisp
415 #+BEGIN_SRC emacs-lisp
416 (setq org-duration-units
422 ("y" . ,(* 60 8 21 12))))
424 (setq org-effort-durations
429 ;; five-day work week
431 ;; four weeks in a month
432 ("m" . ,(* 60 8 5 4))
433 ;; work a total of 12 months a year --
434 ;; this is independent of holiday and sick time taken
435 ("y" . ,(* 60 8 5 4 12))))
438 ** Display preferences
440 I like seeing a little downward-pointing arrow instead of the usual ellipsis
441 (...) that org displays when there’s stuff under a header.
443 #+BEGIN_SRC emacs-lisp
444 (setq org-ellipsis "⤸")
447 Use syntax highlighting in source blocks while editing.
449 #+BEGIN_SRC emacs-lisp
450 (setq org-src-fontify-natively t)
453 Make TAB act as if it were issued in a buffer of the language’s major mode.
455 #+BEGIN_SRC emacs-lisp
456 (setq org-src-tab-acts-natively t)
461 #+BEGIN_SRC emacs-lisp
462 (setq-default org-hide-leading-stars t)
465 Keep lines small, limit to 76 characters.
467 #+BEGIN_SRC emacs-lisp
468 (setq-default org-ascii-text-width 76)
472 https://lists.gnu.org/archive/html/emacs-orgmode/2017-02/msg00270.html
474 #+BEGIN_SRC emacs-lisp
475 (setq org-duration-format (quote h:mm))
479 #+BEGIN_SRC emacs-lisp
480 (defun sum-estimates (beg end)
483 (let (nums hours days weeks months)
485 (while (re-search-forward "Estimate: \\([0-9]+\\) hour" end t)
486 (push (string-to-number (match-string-no-properties 1)) nums))
487 (setq hours (apply #'+ nums))
491 (while (re-search-forward "Estimate: \\([0-9]+\\) day" end t)
492 (push (string-to-number (match-string-no-properties 1)) nums))
493 (setq days (apply #'+ nums))
497 (while (re-search-forward "Estimate: \\([0-9]+\\) week" end t)
498 (push (string-to-number (match-string-no-properties 1)) nums))
499 (setq weeks (apply #'+ nums))
503 (while (re-search-forward "Estimate: \\([0-9]+\\) month" end t)
504 (push (string-to-number (match-string-no-properties 1)) nums))
505 (setq months (apply #'+ nums))
507 (setq days (+ days (* months 21)))
508 (setq days (+ days (* weeks 5)))
509 (setq days (+ days (/ hours 8)))
510 (setq hours (% hours 8))
512 (message "%s days, %s hours" days hours)
513 (kill-new (format "%s days, %s hours" days hours))
518 Allow export to beamer (for presentations).
520 #+BEGIN_SRC emacs-lisp
524 Disable _ subscript syntax highlight engine.
526 #+BEGIN_SRC emacs-lisp
527 (setq-default org-export-with-sub-superscripts nil)
530 Allow babel to evaluate Emacs Lisp.
532 #+BEGIN_SRC emacs-lisp
533 (org-babel-do-load-languages
534 'org-babel-load-languages
538 Don’t ask before evaluating code blocks.
540 #+BEGIN_SRC emacs-lisp
541 (setq org-confirm-babel-evaluate nil)
544 Enable source code highlighting
546 #+BEGIN_SRC emacs-lisp
550 Page break after TOC:
552 #+BEGIN_SRC emacs-lisp
553 (setq org-latex-toc-command "\\tableofcontents \\clearpage")
556 Use minted for exporting code to PDF
558 #+BEGIN_SRC emacs-lisp
559 (setq org-latex-listings 'minted
560 org-latex-packages-alist '(("" "minted"))
561 org-src-fontify-natively t
562 org-latex-pdf-process
563 '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
564 "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
569 Custom function to archive DONE items.
571 #+BEGIN_SRC emacs-lisp
572 (defun org-archive-done-tasks ()
574 (org-map-entries 'org-archive-subtree "/DONE" 'file))
578 #+begin_src emacs-lisp
579 (defun my-org-clocktable-indent-string (level)
584 (setq level (1- level)
585 str (concat str "--")))
586 (concat str "-> "))))
588 (advice-add 'org-clocktable-indent-string :override #'my-org-clocktable-indent-string)
593 https://geeksocket.in/posts/presentations-org-emacs/
597 (use-package org-tree-slide)
598 (with-eval-after-load "org-tree-slide"
599 (define-key org-tree-slide-mode-map (kbd "<f7>") 'org-tree-slide-move-previous-tree)
600 (define-key org-tree-slide-mode-map (kbd "<f8>") 'org-tree-slide-move-next-tree)
609 (add-to-list 'auto-mode-alist '("/mutt" . mail-mode))
610 (add-to-list 'auto-mode-alist '("/neomutt" . mail-mode))
611 (add-hook 'mail-mode-hook 'turn-on-auto-fill)
613 ** Format flowed retooling fill paragraph
614 #+BEGIN_SRC emacs-lisp
615 (defun my-message-configuration ()
616 "Redefines fill-newline to beahve 3676ishly, and turns off auto fill"
618 (defun my-fill-newline ()
619 ;; Replace whitespace here with one newline, then
620 ;; indent to left margin.
621 (skip-chars-backward " \t")
624 ;; Give newline the properties of the space(s) it replaces
625 (set-text-properties (1- (point)) (point)
626 (fill-text-properties-at (point)))
627 (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
628 (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
630 ;; When refilling later on, this newline would normally not be replaced
631 ;; by a space, so we need to mark it specially to re-install the space
633 (put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
634 ;; If we don't want breaks in invisible text, don't insert
635 ;; an invisible newline.
636 (if fill-nobreak-invisible
637 (remove-text-properties (1- (point)) (point)
640 (not fill-indent-according-to-mode))
641 (fill-indent-to-left-margin)
642 (indent-according-to-mode))
643 ;; Insert the fill prefix after indentation.
644 (and fill-prefix (not (equal fill-prefix ""))
645 ;; Markers that were after the whitespace are now at point: insert
646 ;; before them so they don't get stuck before the prefix.
647 (insert-before-markers-and-inherit fill-prefix)))
649 (add-hook 'mail-mode-hook 'my-message-configuration)
651 ** Format flowed, done manually with M-f
652 #+BEGIN_SRC emacs-lisp
653 (defun as-format-as-flowed-text ()
654 "Format the buffer as flowed text according to RFC 2646.
655 This ensures that appropriate lines should be terminated with a
656 single space, and that \"> \" quoting prefixes are replaced with
657 \">\". Operates on the current region if active, otherwise on
660 (let ((start (if (use-region-p) (region-beginning) (point-min)))
661 (end (if (use-region-p) (region-end) (point-max))))
664 ;; Ensure appropriate lines end with a space
665 (while (re-search-forward "^\\(>+ ?\\)?\\S-.*\\S-$" end t)
666 (replace-match "\\& " t))
668 ;; Replace "> " quoting prefixes with ">"
671 (eolm (make-marker)))
672 (while (setq eol (re-search-forward "^>.*" end t))
673 (set-marker eolm eol)
674 (goto-char (match-beginning 0))
675 (while (looking-at ">")
676 (if (looking-at "> ")
679 (goto-char (marker-position eolm)))))))
681 (define-key esc-map "f" 'as-format-as-flowed-text)
684 #+BEGIN_SRC emacs-lisp
685 (defun my-message-configuration ()
686 "Redefines fill-newline to beahve 3676ishly, and turns off auto fill"
688 (defun my-fill-newline ()
689 ;; Replace whitespace here with one newline, then
690 ;; indent to left margin.
691 (skip-chars-backward " \t")
694 ;; Give newline the properties of the space(s) it replaces
695 (set-text-properties (1- (point)) (point)
696 (fill-text-properties-at (point)))
697 (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?")
698 (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|)
700 ;; When refilling later on, this newline would normally not be replaced
701 ;; by a space, so we need to mark it specially to re-install the space
703 (put-text-property (1- (point)) (point) 'fill-space (match-string 1)))
704 ;; If we don't want breaks in invisible text, don't insert
705 ;; an invisible newline.
706 (if fill-nobreak-invisible
707 (remove-text-properties (1- (point)) (point)
710 (not fill-indent-according-to-mode))
711 (fill-indent-to-left-margin)
712 (indent-according-to-mode))
713 ;; Insert the fill prefix after indentation.
714 (and fill-prefix (not (equal fill-prefix ""))
715 ;; Markers that were after the whitespace are now at point: insert
716 ;; before them so they don't get stuck before the prefix.
717 (insert-before-markers-and-inherit fill-prefix)))
720 (add-hook 'message-mode-hook 'my-message-configuration)