home · contact · privacy
9964c98df27e6c5c3bc8de63c56e711cc411711a
[config] / bookworm / home_files / user / .emacs.d / init.el
1 ;; general layout
2 ;; ==============
3
4 ;; need no stinkin emacs help screen as start up, and no menu bar
5 (setq inhibit-startup-screen t)
6 (menu-bar-mode -1)
7
8 ;; highlight cursor line, parentheses
9 (global-hl-line-mode 1)
10 (show-paren-mode 1)
11
12 ;; show line numbers, use separator space
13 (global-linum-mode)
14 (setq linum-format "%d ")
15
16 ;; count cursor column, row in mode line
17 (setq column-number-mode t)
18
19 ;; settings to make GUI tolerable
20 (if window-system
21   (progn
22     (add-to-list 'default-frame-alist '(foreground-color . "white"))
23     (add-to-list 'default-frame-alist '(background-color . "black"))
24     (set-face-attribute 'default nil :height 80)
25     (scroll-bar-mode -1)
26     (setq visible-bell t)
27     (setq linum-format "%d")))
28
29 ;; use as default browser what XDG offers
30 (setq-default browse-url-browser-function 'browse-url-xdg-open)
31
32
33
34 ;; general keybindings
35 ;; ===================
36
37 ;; create and use a minimal global map using just the self-insert command
38 ;; bindings and a selection of some to me very common keystrokes
39 (setq minimal-map (make-sparse-keymap))
40 (substitute-key-definition 'self-insert-command 'self-insert-command
41                            minimal-map global-map)
42 (use-global-map minimal-map)
43 (global-set-key (kbd "DEL") 'backward-delete-char-untabify)
44 (global-set-key (kbd "RET") 'newline)
45 (global-set-key (kbd "TAB") 'indent-for-tab-command)
46 (global-set-key (kbd "<up>") 'previous-line)
47 (global-set-key (kbd "<down>") 'next-line)
48 (global-set-key (kbd "<left>") 'left-char)
49 (global-set-key (kbd "<right>") 'right-char)
50 (global-set-key (kbd "<prior>") 'scroll-down-command)
51 (global-set-key (kbd "<next>") 'scroll-up-command)
52 (global-set-key (kbd "M-x") 'execute-extended-command)
53 (global-set-key (kbd "C-g") 'keyboard-quit)
54 ;(global-set-key (kbd "<f3>") 'kmacro-start-macro-or-insert-counter)
55 ;(global-set-key (kbd "<f4>") 'kmacro-end-or-call-macro)
56 ;; note how to switch back to the original map: (use-global-map global-map)
57 (setq shr-map (make-sparse-keymap))  ; got annoying in elfeed-show on URLs
58
59
60
61 ;; minibuffer
62 ;; ==========
63
64 ;; incremental minibuffer completion
65 (icomplete-mode 1)
66
67
68
69 ;; text editing
70 ;; ============
71
72 ;; tabs are evil
73 (setq-default indent-tabs-mode nil)
74 (setq-default tab-width 4)
75 (setq indent-line-function 'insert-tab)
76
77 ;; show trailing whitespace
78 (setq-default show-trailing-whitespace 1)
79
80 ;; on save, ask whether to ensure text file's last line ends in a
81 ;; newline character
82 (setq require-final-newline 1)
83
84 ;; use dedicated directory for version-controlled, endless backups;
85 ;; never delete old versions
86 (setq make-backup-files t
87       backup-directory-alist `(("." . "~/.emacs_backups"))
88       backup-by-copying t
89       version-control t
90       delete-old-versions 1)  ;; neither t nor nil: never delete
91
92
93 ;; package management
94 ;; ==================
95
96 ;; where we get packages from
97 (setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
98                          ("melpa-unstable" . "https://melpa.org/packages/")
99                          ("melpa-stable" . "https://stable.melpa.org/packages/")))
100
101 ;; ensure certain packages are installed (actually, we use Debian repos here)
102 ;; credit to <https://stackoverflow.com/a/10093312>
103 ;(setq package-list '(elfeed ledger-mode))
104 ;(package-initialize)
105 ;(dolist (package package-list)
106 ;  (unless (package-installed-p package)
107 ;    (package-install package)))
108
109
110
111 ;;; window management
112 ;;; =================
113 ;
114 ;;; track window configurations to allow window config undo
115 ;(winner-mode 1)
116
117
118
119 ;; mail setup
120 ;; ==========
121
122 (setq send-mail-function 'smtpmail-send-it)
123 (setq smtpmail-smtp-server "mail.plomlompom.com")
124 (setq smtpmail-smtp-service 465)
125 (setq smtpmail-stream-type 'ssl)
126 (setq smtpmail-smtp-user "plom")
127 (setq mml-secure-openpgp-encrypt-to-self t)
128 (add-hook 'message-setup-hook 'mml-secure-sign-pgpmime)
129
130 ;(setq gnutls-log-level 0)
131
132 ;; if we don't set this, we get this warning:
133 ;;   gnutls.c: [1] Note that the security level of the Diffie-Hellman key exchange
134 ;;   has been lowered to 256 bits and this may allow decryption of the session data
135 (setq gnutls-min-prime-bits 1024)
136
137 ;; there is a WEIRD bug somewhere in /network-stream-open-tls/ that disappears the
138 ;; stream process, seemingly unless the /message/ function is called at the right
139 ;; place (earliest in /nsm-verify-connection/ right before the "cond" there, latest
140 ;; in /network-stream-get-response/ right after "(goto-char start)"; this works
141 ;; unless /inhibit_message/ is set, indicating that writing to the *Messages*
142 ;; buffer is not relevant, but maybe writing to the echo area is); activing the
143 ;; gnutls logging is just a hack to achieve such calls to /message/ in the
144 ;; /network-stream-open-tls/ flow.
145 (setq gnutls-log-level 1) ; miraculously makes smtpmail work
146
147 ;; constructs From: domain if mail composer directly called (from without
148 ;; notmuch), but we don't actually intend to do that
149 ;(setq mail-host-address "plomlompom.com")
150
151 ;; otherwise notmuch becomes extremely slow in some cases
152 (setq-default notmuch-show-indent-content nil)
153
154 ;; this only works if we use notmuch-mua-send instead of message-send
155 (setq notmuch-fcc-dirs '(("plom@plomlompom.com" . "maildir/Sent")))
156
157 ;; this gets rid of "i-did-not-set--mail-host-address--so-tickle-me"
158 ;; in the message ID
159 (setq mail-host-address "plomlompom.com")
160
161 ;; notmuch saved searches
162 (setq notmuch-saved-searches
163       '((:name "inbox" :query "tag:unread and folder:inbox")
164         (:name "all" :query "tag:unread not folder:maildir/Trash")
165         (:name "plomlompom.de" :query "tag:unread and folder:maildir/plomlompom.de")
166         (:name "nebenan" :query "tag:unread and folder:maildir/nebenan")
167         (:name "reflect-info" :query "tag:unread and folder:maildir/reflect-info")
168         (:name "gmail" :query "tag:unread and folder:maildir/gmail.com")
169         (:name "mutter" :query "tag:unread and folder:maildir/mutter")))
170
171
172
173 ;; org mode
174 ;; ========
175
176 ;; unsure why, but to re-set the key map, we not only have to explicitely do it
177 ;; only after org-mode loading, but also have to explicitely overwrite the
178 ;; C-c keybinding; TODO: investigate
179 (with-eval-after-load 'org
180     (setq org-mode-map (make-sparse-keymap))
181     (define-key org-mode-map (kbd "C-c") nil)
182     (define-key org-mode-map (kbd "TAB") 'org-cycle)
183     (define-key org-mode-map (kbd "<backtab>") 'org-shifttab))
184
185 ;; don't truncate lines by default
186 (setq org-startup-truncated nil)
187
188 ;; basic org-capture config
189 (setq org-capture-templates
190       '(("x" "test" plain (file "~/org/notes.org") "%T: %?")))
191 (add-hook 'org-capture-mode-hook 'evil-insert-state)
192
193 ;; agenda view on startup
194 (load-library "find-lisp")
195 (setq org-agenda-files (find-lisp-find-files "~/org" "\.org$"))
196 (setq org-agenda-span 90)
197 (setq org-agenda-use-time-grid nil)
198 (add-hook 'emacs-startup-hook (lambda ()
199                                  (org-agenda-list)
200                                  (switch-to-buffer "*Org Agenda*")
201                                  (other-window 1)))
202
203 ;;; for calendar, use ISO date style
204 ;(setq calendar-date-style 'iso)
205 ;(setq diary-number-of-entries 7)
206 ;(diary)
207 ;(setq org-agenda-time-grid '((today require-timed remove-match)
208 ;                             #("----------------" 0 16 (org-heading t))
209 ;                             (0 200 400 600 800 1000 1200
210 ;                                1400 1600 1800 2000 2200)))
211
212 ;; empty org-agenda-mode keybindings
213 (add-hook 'org-agenda-mode-hook
214           (lambda ()
215             (setq org-agenda-mode-map (make-sparse-keymap))))
216 (add-hook 'org-agenda-mode-hook
217           (lambda ()
218             (use-local-map (make-sparse-keymap))))
219
220 ;; org-publish-all
221 (setq org-publish-project-alist
222       '(
223         ("website"
224          :base-directory "~/org/web/"
225          :base-extension "org"
226          :publishing-directory "~/html/"
227          :recursive t
228          :publishing-function org-html-publish-to-html
229          :headline-levels 4             ; Just the default for this project.
230          :auto-preamble t
231           )))
232
233 ;; use [ki:] syntax to hide stuff from exports
234 (defun classify-information (text backend info)
235   "Replaces '[ki:WHATEVER]' with '[klassifizierte Information]'."
236   (replace-regexp-in-string "\\[ki:[^\]]*\]" "[klassifizierte Information]" text))
237 (add-hook 'org-export-filter-plain-text-functions 'classify-information)
238
239 ;; add HTML validator link to exports
240 (setq org-html-validation-link "<a href=\"https://validator.w3.org/check?uri=referer\">Validate</a>")
241
242
243
244 ;;; Info mode
245 ;;; =========
246
247 (setq Info-mode-map (make-sparse-keymap))
248 (define-key Info-mode-map (kbd "RET") 'Info-follow-nearest-node)
249 (define-key Info-mode-map (kbd "u") 'Info-up)
250 (define-key Info-mode-map (kbd "TAB") 'Info-next-reference)
251 (define-key Info-mode-map (kbd "<backtab>") 'Info-prev-reference)
252 (define-key Info-mode-map (kbd "H") 'Info-history-back)
253 (define-key Info-mode-map (kbd "L") 'Info-history-forward)
254 (define-key Info-mode-map (kbd "I") 'Info-goto-node)
255 (define-key Info-mode-map (kbd "i") 'Info-index)
256
257
258
259 ;; help mode
260 ;; =========
261
262 (setq help-mode-map (make-sparse-keymap))
263 (define-key help-mode-map (kbd "TAB") 'forward-button)
264 (define-key help-mode-map (kbd "RET") 'help-follow)
265 (define-key help-mode-map (kbd "<backtab>") 'backward-button)
266
267
268
269 ;; elfeed
270 ;; ======
271
272 (require 'elfeed)  ; needed so we can set the font faces
273 (set-face-background 'elfeed-search-title-face "magenta")
274 (set-face-background 'elfeed-search-unread-count-face "magenta")
275 (setq elfeed-feeds
276       '("https://capsurvival.blogspot.com/feeds/posts/default"
277         "https://jungle.world/rss.xml"
278         "http://news.dieweltistgarnichtso.net/bin/index.xml"
279         "https://taz.de/!s=&ExportStatus=Intern&SuchRahmen=Online;rss/"
280         "http://www.tagesschau.de/xml/atom"))
281 (setq elfeed-search-mode-map (make-sparse-keymap))
282 (define-key elfeed-search-mode-map (kbd "RET") 'elfeed-search-show-entry)
283 (defun elfeed-search-mark-as-read() (interactive)
284   (elfeed-search-untag-all 'unread))
285 (define-key elfeed-search-mode-map (kbd "r") 'elfeed-search-mark-as-read)
286 (define-key elfeed-search-mode-map (kbd "R") 'elfeed-search-tag-all-unread)
287 (define-key elfeed-search-mode-map (kbd "f") 'elfeed-search-live-filter)
288 (define-key elfeed-search-mode-map (kbd "u") 'elfeed-update)
289 (setq elfeed-show-mode-map (make-sparse-keymap))
290 (define-key elfeed-show-mode-map (kbd "u") 'elfeed)
291 (define-key elfeed-show-mode-map (kbd "TAB") 'shr-next-link)
292 (define-key elfeed-show-mode-map (kbd "<backtab>") 'shr-previous-link)
293 (define-key elfeed-show-mode-map (kbd "a") 'elfeed-show-prev)
294 (define-key elfeed-show-mode-map (kbd "d") 'elfeed-show-next)
295 (define-key elfeed-show-mode-map (kbd "y") 'shr-copy-url)
296 (define-key elfeed-show-mode-map (kbd "RET") 'shr-browse-url)
297
298
299
300 ;; eww
301 ;; ===
302
303 (setq eww-mode-map (make-sparse-keymap))
304 (define-key eww-mode-map (kbd "TAB") 'shr-next-link)
305 (define-key eww-mode-map (kbd "<backtab>") 'shr-previous-link)
306 (define-key eww-mode-map (kbd "H") 'eww-back-url)
307 (define-key eww-mode-map (kbd "L") 'eww-forward-url)
308
309
310
311 ;; ledger
312 ;; ======
313 (setq ledger-mode-map (make-sparse-keymap))
314 (define-key ledger-mode-map (kbd "TAB") 'completion-at-point)
315
316
317
318 ;;; plomvi mode
319 ;;; ===========
320
321 (defvar plomvi-return-combo (kbd "C-c"))
322 (load "~/public_repos/plomvi.el/plomvi.el")
323 (plomvi-global-mode 1)