emacs: rename fill-newline() redefinitions used by mutt setup
[slow/dotfiles.git] / emacs / .emacs.d / configuration.org
1 #+TITLE: Emacs configuration
2 #+STARTUP: overview
3
4 Much stuff taken from:
5 https://github.com/hrs/dotfiles/blob/master/emacs/.emacs.d/configuration.org
6 https://github.com/daviwil/emacs-from-scratch
7
8 * Set personal information
9
10 #+BEGIN_SRC emacs-lisp
11 (setq user-full-name "Ralph Böhme"
12       user-mail-address "slow@samba.org")
13 #+END_SRC
14
15 * Package managment
16
17 Setup package management with Melpa, nifty!
18
19 #+BEGIN_SRC emacs-lisp
20   (require 'package)
21   (package-initialize)
22   (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
23   (add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/"))
24
25   (unless package-archive-contents
26     (package-refresh-contents))
27
28   (require 'use-package)
29   (setq use-package-always-ensure t)
30 #+END_SRC
31
32 * General Setup
33 ** Load paths
34    #+BEGIN_SRC emacs-lisp
35      (add-to-list 'load-path "~/.emacs.d/lisp/")
36    #+END_SRC
37 ** General setup
38
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
45    #+END_SRC
46
47 ** Keyboard mapping and keybindings
48
49    #+BEGIN_SRC emacs-lisp
50      (setq ns-right-option-modifier 'super)
51      (global-set-key (kbd "C-M-j") 'counsel-switch-buffer)
52    #+END_SRC
53
54 ** smblog-mode
55    #+begin_src emacs-lisp
56      ;; smb-log
57      (require 'smblog)
58      (setq smblog-src-dir "/git/samba/scratch/foo")
59    #+end_src
60 ** Helm
61
62    #+begin_src elisp
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)
67      (helm-mode 1)
68    #+end_src
69 ** powerline
70
71    #+begin_src elisp
72      (use-package all-the-icons
73        :ensure t)
74      (use-package powerline
75        :ensure t
76        :hook (after-init . powerline-default-theme)
77        :custom-face
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"))))
81        )
82    #+end_src
83
84 ** which-key
85
86    #+begin_src elisp
87
88      (use-package which-key
89        :defer 0
90        :diminish which-key-mode
91        :config
92        (which-key-mode)
93        (setq which-key-idle-delay 1))
94
95    #+end_src
96
97 * Editing
98 ** Autosave buffers when changing buffer
99
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)))
107 #+END_SRC
108
109 ** Unfill a paragraph
110
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."
115     (interactive)
116     (let ((fill-column (point-max)))
117       (fill-paragraph nil)))
118   (define-key global-map "\M-Q" 'unfill-paragraph)
119 #+END_SRC
120
121 ** Misc
122
123     #+begin_src elisp
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)
136
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)
141
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)
146     #+end_src
147
148 ** autonewline and electric
149
150    #+begin_src elisp
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)))
154    #+end_src
155 ** Whitespace
156
157    #+begin_src elisp
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)
162    #+end_src
163 ** yasnippet
164
165    #+begin_src elisp
166      (use-package yasnippet
167        :ensure t
168        :config
169        (yas-global-mode 1))
170    #+end_src
171
172 * IDE
173 ** Rainbow Delimiters
174
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.
179
180 #+begin_src emacs-lisp
181
182 (use-package rainbow-delimiters
183   :hook (prog-mode . rainbow-delimiters-mode))
184
185 #+end_src
186
187 ** C
188
189    #+begin_src elisp
190      (require 'cc-mode)
191      (add-hook 'c-mode-hook
192                (lambda ()
193                  (setq show-trailing-whitespace t)
194                  (c-set-style "linux")
195                  (c-toggle-auto-state)
196                  (flycheck-mode t)
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)))
203    #+end_src
204
205 ** Samba
206
207    #+begin_src elisp
208    (setq-default compile-command "cd /git/samba/scratch/ && make -j")
209    #+end_src
210
211 ** Netatalk
212
213    #+begin_src elisp
214      (defun netatalk ()
215        "Netatalk indentation"
216        (interactive)
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))
221    #+end_src
222
223 ** magit
224
225    #+begin_src elisp
226      (use-package git-commit
227        :ensure t)
228      (use-package magit
229        :ensure t)
230      (defun my-magit-status()
231        "magit-status in one window"
232        (interactive)
233        (magit-status)
234        (delete-other-windows))
235
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)
239     #+end_src
240
241 ** flycheck
242 Flycheck for compile and error check while editing
243
244 #+BEGIN_SRC emacs-lisp
245 ;(require 'flycheck-ycmd)
246 ;(flycheck-ycmd-setup)
247 #+END_SRC
248
249 ** lsp
250
251 lsp-mode
252 https://emacs-lsp.github.io/lsp-mode/page/installation/
253
254 #+BEGIN_SRC emacs-lisp
255 (require 'cc-mode)
256 (require 'lsp-mode)
257 (add-hook 'c-mode-hook #'lsp)
258 #+END_SRC
259
260 ** xcsope
261
262    #+begin_src elisp
263      (require 'xcscope)
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)
270    #+end_src
271 ** Sytemtap
272
273    #+begin_src elisp
274      (require 'systemtap-mode)
275      (add-hook 'systemtap-mode-hook
276                (lambda ()
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)))
281    #+end_src
282
283 ** Projectile
284
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.
289
290 #+begin_src emacs-lisp
291
292   (use-package projectile
293     :diminish projectile-mode
294     :config (projectile-mode)
295     :custom ((projectile-completion-system 'helm))
296     :bind-keymap
297     ("C-c p" . projectile-command-map)
298     :init
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))
303
304   (use-package counsel-projectile
305     :after projectile
306     :config (counsel-projectile-mode))
307
308 #+end_src
309 * Org-mode
310 ** Setup
311
312 Task managment setup
313
314 #+BEGIN_SRC emacs-lisp
315   (setq org-agenda-files (list "sernet.org"
316                                "projekt.org"
317                                "slow.org"
318                                "spd.org"))
319
320   (setq org-todo-keywords
321         '((sequence "TODO(t)" "PROJECT(p)" "PRIVAT(P)" "|" "WAIT(w)" "REPEATING(r)" "MISC(m)" "DONE(d)")))
322 #+END_SRC
323
324 Enable org-bullet mode
325
326 #+BEGIN_SRC emacs-lisp
327   (require 'org-bullets)
328
329   (defun my-org-todo-list()
330     "org-todo-list in one window"
331     (interactive)
332     (org-todo-list)
333     (delete-other-windows))
334
335   (add-hook 'org-mode-hook
336      (lambda ()
337        (org-bullets-mode 1)
338        (global-set-key [f4] 'my-org-todo-list)
339       )
340    )
341 #+END_SRC
342
343 Enable org-ref
344
345 #+BEGIN_SRC emacs-lisp
346   (require 'org-ref)
347 #+END_SRC
348
349 Enable org-tempo for <s
350
351 #+BEGIN_SRC emacs-lisp
352   (require 'org-tempo)
353 #+END_SRC
354
355 Customize durations
356
357 #+BEGIN_SRC emacs-lisp
358 (setq org-duration-units
359   `(("min" . 1)
360     ("h" . 60)
361     ("d" . ,(* 60 8))
362     ("w" . ,(* 60 8 5))
363     ("m" . ,(* 60 8 21))
364     ("y" . ,(* 60 8 21 12))))
365
366 (setq org-effort-durations
367    `(("min" . 1)
368     ("h" . 60)
369     ;; eight-hour days
370     ("d" . ,(* 60 8))
371     ;; five-day work week
372     ("w" . ,(* 60 8 5))
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))))
378 #+END_SRC
379
380 ** Display preferences
381
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.
384
385 #+BEGIN_SRC emacs-lisp
386 (setq org-ellipsis "⤸")
387 #+END_SRC
388
389 Use syntax highlighting in source blocks while editing.
390
391 #+BEGIN_SRC emacs-lisp
392 (setq org-src-fontify-natively t)
393 #+END_SRC
394
395 Make TAB act as if it were issued in a buffer of the language’s major mode.
396
397 #+BEGIN_SRC emacs-lisp
398 (setq org-src-tab-acts-natively t)
399 #+END_SRC
400
401 Hide leading stars.
402
403 #+BEGIN_SRC emacs-lisp
404 (setq-default org-hide-leading-stars t)
405 #+END_SRC
406
407 Keep lines small, limit to 76 characters.
408
409 #+BEGIN_SRC emacs-lisp
410 (setq-default org-ascii-text-width 76)
411 #+END_SRC
412
413 Duration in hours:
414 https://lists.gnu.org/archive/html/emacs-orgmode/2017-02/msg00270.html
415
416 #+BEGIN_SRC emacs-lisp
417 (setq org-duration-format (quote h:mm))
418 #+END_SRC
419
420 ** Calculation
421 #+BEGIN_SRC emacs-lisp
422   (defun sum-estimates (beg end)
423     (interactive "r")
424     (save-excursion
425       (let (nums hours days weeks months)
426         (goto-char beg)
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))
430
431         (setq nums nil)
432         (goto-char beg)
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))
436
437         (setq nums nil)
438         (goto-char beg)
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))
442
443         (setq nums nil)
444         (goto-char beg)
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))
448
449         (setq days (+ days (* months 21)))
450         (setq days (+ days (* weeks 5)))
451         (setq days (+ days (/ hours 8)))
452         (setq hours (% hours 8))
453
454         (message "%s days, %s hours" days hours)
455         (kill-new (format "%s days, %s hours" days hours))
456       days hours)))
457 #+END_SRC
458 ** Exporting
459
460 Allow export to beamer (for presentations).
461
462 #+BEGIN_SRC emacs-lisp
463 (require 'ox-beamer)
464 #+END_SRC
465
466 Disable _ subscript syntax highlight engine.
467
468 #+BEGIN_SRC emacs-lisp
469 (setq-default org-export-with-sub-superscripts nil)
470 #+END_SRC
471
472 Allow babel to evaluate Emacs Lisp.
473
474 #+BEGIN_SRC emacs-lisp
475 (org-babel-do-load-languages
476  'org-babel-load-languages
477  '((emacs-lisp . t)))
478 #+END_SRC
479
480 Don’t ask before evaluating code blocks.
481
482 #+BEGIN_SRC emacs-lisp
483 (setq org-confirm-babel-evaluate nil)
484 #+END_SRC
485
486 Enable source code highlighting
487
488 #+BEGIN_SRC emacs-lisp
489 (require 'ox-latex)
490 #+END_SRC
491
492 Page break after TOC:
493
494 #+BEGIN_SRC emacs-lisp
495 (setq org-latex-toc-command "\\tableofcontents \\clearpage")
496 #+END_SRC
497
498 Use minted for exporting code to PDF
499
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"))
507 #+END_SRC
508
509 ** Archiving
510
511 Custom function to archive DONE items.
512
513 #+BEGIN_SRC emacs-lisp
514 (defun org-archive-done-tasks ()
515   (interactive)
516   (org-map-entries 'org-archive-subtree "/DONE" 'file))
517 #+END_SRC
518
519 ** Clocktable
520    #+begin_src emacs-lisp
521      (defun my-org-clocktable-indent-string (level)
522        (if (= level 1)
523            ""
524          (let ((str "^"))
525            (while (> level 2)
526              (setq level (1- level)
527                    str (concat str "--")))
528            (concat str "-> "))))
529
530      (advice-add 'org-clocktable-indent-string :override #'my-org-clocktable-indent-string)
531    #+end_src
532 ** Presenting
533
534    org-tree-slide
535    https://geeksocket.in/posts/presentations-org-emacs/
536
537    #+begin_src elisp
538
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)
543        )
544
545    #+end_src
546
547 * Mailing
548 ** mutt
549
550    #+begin_src elisp
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)
554    #+end_src
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"
559     (turn-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")
564     (insert ?\s)
565     (insert ?\n)
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)) ?|)
571          (match-end 2))
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
574          ;; when we unfill.
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)
580                     '(invisible t)))
581     (if (or fill-prefix
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)))
590   )
591   (add-hook 'mail-mode-hook 'my-message-configuration)
592 #+END_SRC
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
600   the whole buffer."
601     (interactive)
602     (let ((start (if (use-region-p) (region-beginning) (point-min)))
603           (end (if (use-region-p) (region-end) (point-max))))
604       (save-excursion
605         (goto-char start)
606         ;; Ensure appropriate lines end with a space
607         (while (re-search-forward "^\\(>+ ?\\)?\\S-.*\\S-$" end t)
608           (replace-match "\\& " t))
609
610         ;; Replace "> " quoting prefixes with ">"
611         (goto-char start)
612         (let ((eol)
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 "> ")
619                   (replace-match ">")
620                 (forward-char)))
621             (goto-char (marker-position eolm)))))))
622
623   (define-key esc-map "f" 'as-format-as-flowed-text)
624 #+END_SRC
625
626 #+BEGIN_SRC emacs-lisp
627   (defun my-message-configuration ()
628     "Redefines fill-newline to beahve 3676ishly, and turns off auto fill"
629     (turn-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")
634     (insert ?\s)
635     (insert ?\n)
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)) ?|)
641          (match-end 2))
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
644          ;; when we unfill.
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)
650                     '(invisible t)))
651     (if (or fill-prefix
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)))
660   )
661
662   (add-hook 'message-mode-hook 'my-message-configuration)
663 #+END_SRC