1 ;; Added by Package.el. This must come before configurations of
2 ;; installed packages. Don't delete this line. If you don't want it,
3 ;; just comment it out by adding a semicolon to the start of the line.
4 ;; You may delete these explanatory comments.
7 (add-to-list 'load-path "~/.emacs.d/lisp/")
11 ;; Configure printing using CUPS network printer
17 ;; Enable the melpa archive for packages
20 (setq package-enable-at-startup nil)
21 (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
22 (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
23 (add-to-list 'package-archives
24 '("elpy" . "http://jorgenschaefer.github.io/packages/")))
26 (use-package system-packages
29 (use-package modus-themes
31 :demand t ;; Without this, the theme load is deferred due to the
34 ;; Add all customisation prior to loading the themes
35 (setq modus-themes-mixed-fonts t)
37 (modus-themes-select 'modus-vivendi-tinted)
39 :bind ("<f5>" . modus-themes-toggle))
41 (use-package orderless
44 (setq completion-styles '(orderless basic)
45 completion-category-overrides '((file (styles basic partial-completion)))))
47 ;; follow links to version-controlled files without confirming
50 ;; ESS - for working in R
51 (autoload 'R-mode "ess-site.el" "Major mode for editing R source." t)
52 (setq load-path (cons "/usr/share/emacs/site-lisp/ess" load-path))
53 (load "/usr/share/emacs/site-lisp/ess/lisp/ess-site")
54 (setq inferior-julia-program-name "/usr/bin/julia")
56 ;; enable autocomplete
59 ;; Optional customizations
61 (corfu-cycle t) ;; Enable cycling for `corfu-next/previous'
62 (corfu-auto t) ;; Enable auto completion
63 ;; (corfu-separator ?\s) ;; Orderless field separator
64 ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary
65 ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match
66 ;; (corfu-preview-current nil) ;; Disable current candidate preview
67 ;; (corfu-preselect 'prompt) ;; Preselect the prompt
68 ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches
69 ;; (corfu-scroll-margin 5) ;; Use scroll margin
71 ;; Enable Corfu only for certain modes. See also `global-corfu-modes'.
72 ;; :hook ((prog-mode . corfu-mode)
73 ;; (shell-mode . corfu-mode)
74 ;; (eshell-mode . corfu-mode))
76 ;; Recommended: Enable Corfu globally. This is recommended since Dabbrev can
77 ;; be used globally (M-/). See also the customization variable
78 ;; `global-corfu-modes' to exclude certain modes.
85 ;; Bind prefix keymap providing all Cape commands under a mnemonic key.
86 ;; Press C-c p ? to for help.
87 :bind ("C-c p" . cape-prefix-map) ;; Alternative keys: M-p, M-+, ...
88 ;; Alternatively bind Cape commands individually.
89 ;; :bind (("C-c p d" . cape-dabbrev)
90 ;; ("C-c p h" . cape-history)
91 ;; ("C-c p f" . cape-file)
94 ;; Add to the global default value of `completion-at-point-functions' which is
95 ;; used by `completion-at-point'. The order of the functions matters, the
96 ;; first function returning a result wins. Note that the list of buffer-local
97 ;; completion functions takes precedence over the global list.
98 (add-hook 'completion-at-point-functions #'cape-dict) ;; requires words package to be installed on Arch to provide /usr/share/dict/words
99 (add-hook 'completion-at-point-functions #'cape-dabbrev)
100 (add-hook 'completion-at-point-functions #'cape-file)
101 (add-hook 'completion-at-point-functions #'cape-elisp-block)
102 ;; (add-hook 'completion-at-point-functions #'cape-history)
109 (("C-c c" . org-capture)
110 ("C-c l" . org-store-link)
111 ("C-c a" . org-agenda))
113 (org-default-notes-file "~/Nextcloud/notes/inbox.org")
114 (org-agenda-files `(,org-default-notes-file "~/Nextcloud/notes/calendar.org"))
115 (org-capture-bookmark nil)
117 (org-capture-templates
118 '(("f" "Fleeting note" entry
119 (file+headline org-default-notes-file "Notes")
120 "* %?\nEntered on %U\n %i\n %a")
121 ("b" "Tax receipt" item
122 (file "~/Documents/belastingen/FY24-25.org")
124 ("p" "Permanent note" plain
125 (file denote-last-path)
128 :immediate-finish nil
131 ("t" "New task" entry
132 (file+headline org-default-notes-file "Tasks")
134 ("e" "Email follow-up" entry (file+headline org-default-notes-file "Tasks")
135 "* TODO %:fromname: %a %?\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))")))
137 (org-agenda-custom-commands
138 '(("P" "Expired calendar events" ((tags "TIMESTAMP<=\"<now>\"")))
139 ("n" "Agenda and all TODOs" ((agenda "") (alltodo "")))))
142 (defun my/opened-buffer-files ()
143 "Return the list of org files currently opened in emacs"
146 (if (and (buffer-file-name x)
147 (string-match "\\.org$"
148 (buffer-file-name x)))
149 (buffer-file-name x)))
151 (setq org-refile-targets `((my/opened-buffer-files :maxlevel . 9)
152 (,(file-expand-wildcards "~/Nextcloud/notes/*.org") :maxlevel . 1)))
153 (setq org-agenda-skip-scheduled-if-done t)
154 (setq org-agenda-skip-deadline-if-done t)
155 (setq org-agenda-start-on-weekday nil)
156 (setq org-log-done 'time)
157 ;; Automatically flow lines based on window width and use
158 ;; variable width fonts in org-mode.
159 (add-hook 'org-mode-hook 'visual-line-mode)
160 (add-hook 'org-mode-hook 'variable-pitch-mode)
161 ;; org-mode support for R and LaTeX
162 (org-babel-do-load-languages
163 'org-babel-load-languages
167 (use-package org-caldav
170 (setq org-caldav-url "https://owncloud.vanrenterghem.biz/remote.php/dav/calendars/frederik")
171 (setq org-caldav-calendar-id "orgmode")
172 ;; Org filename where new entries from calendar stored
173 (setq org-caldav-inbox "~/Nextcloud/notes/calendar.org")
174 ;; Additional Org files to check for calendar events
175 (setq org-caldav-files nil)
176 ;; Usually a good idea to set the timezone manually
177 (setq org-icalendar-timezone "Australia/Perth"))
182 (setq TeX-auto-save t
184 TeX-view-program-selection
185 '(((output-dvi has-no-display-manager)
187 ((output-dvi style-pstricks)
190 (output-pdf "PDF Tools")
191 (output-html "xdg-open"))))
192 ;; (load "preview-latex.el" nil t t)
195 ;; Automatically switch to various modes
196 (setq auto-mode-alist
197 '(("\\.mdwn\\'" . markdown-mode)
198 ("\\.md\\'" . markdown-mode)
199 ("\\.yarn\\'" . markdown-mode)
200 ("\\.cpp\\'" . c++-mode)
201 ("\\.js\\'" . js-mode)
202 ("\\.json\\'" . js-mode)
203 ("Makefile" . makefile-mode)
204 ("README" . markdown-mode)
205 ("NEWS" . markdown-mode)
206 ("COMMIT_EDITMSG\\'" . text-mode)
207 ("\\.html\\'" . html-mode)
208 ("\\.css\\'" . css-mode)
209 ("\\.yaml\\'" . yaml-mode)
210 ("\\.yml\\'" . yaml-mode)
211 ("\\.ick\\'" . yaml-mode)
212 ("\\.py\\'" . python-mode)
214 ("\\.org\\'" . org-mode)
215 ("\\.tex\\'" . latex-mode)
216 ("\\.sh\\'" . shell-script-mode)
217 ("\\.hs\\'" . haskell-mode)
218 ("\\.el\\'" . emacs-lisp-mode)))
221 (custom-set-variables
222 ;; custom-set-variables was added by Custom.
223 ;; If you edit it by hand, you could mess it up, so be careful.
224 ;; Your init file should contain only one such instance.
225 ;; If there is more than one, they won't work right.
226 '(browse-url-browser-function 'browse-url-firefox)
228 '("8d146df8bd640320d5ca94d2913392bc6f763d5bc2bb47bed8e14975017eea91" "9a977ddae55e0e91c09952e96d614ae0be69727ea78ca145beea1aae01ac78d2" "0cf95236abcf59e05b1ea69b4edd53d293a5baec4fe4c3484543fee99bfd2204" "80b00f3bf7cdbdca6c80aadfbbb03145f3d0aacf6bf2a559301e61109954e30a" default))
229 '(org-export-backends '(ascii html icalendar latex md odt))
230 '(package-selected-packages
231 '(devdocs straight calfw calfw-org engrave-faces org-caldav nov eat mu4e ellama emms mpdel-embark libmpdel pass password-store fontaine osm orderless embark-consult embark consult jinx dired-preview ftable flx nerd-icons-dired nerd-icons all-the-icons-dired marginalia vertico denote ox-rss org-ql org-contrib mustache org-static-blog haskell-mode julia-mode elfeed-protocol ack company magit auctex lsp-mode elpy ## org htmlize leuven-theme lua-mode ess-smart-underscore ess-R-data-view ess))
232 '(use-package-compute-statistics t))
234 ;; custom-set-faces was added by Custom.
235 ;; If you edit it by hand, you could mess it up, so be careful.
236 ;; Your init file should contain only one such instance.
237 ;; If there is more than one, they won't work right.
241 ;; Send mail using SMTP via mail.vanrenterghem.io.
242 (setq send-mail-function 'smtpmail-send-it)
243 (setq smtpmail-smtp-server "mail.vanrenterghem.io"
244 smtpmail-smtp-service 587
245 smtpmail-stream-type 'starttls)
246 (setq user-full-name "Frederik Vanrenterghem"
247 smtpmail-local-domain "vanrenterghem.io"
248 user-mail-address (concat "frederik@" smtpmail-local-domain))
249 ;; Ignored in mu4e as it sets user-agent
250 (setq mail-default-headers
251 (concat "X-Mailer: GNU Emacs " (symbol-value 'emacs-version)))
252 (setq w3m-pop-up-frames t)
254 (global-set-key [remap list-buffers] 'ibuffer)
256 ;;; use pass (~/.password-store)
257 ;;; (see The Unix password store)
261 (auth-source-pass-enable)
262 (setq pass-username-field "Username"))
264 ;; Elfeed news reader from Nextcloud
268 (setq elfeed-use-curl nil)
269 (elfeed-set-timeout 36000)
270 (define-key elfeed-search-mode-map (kbd "*") (lambda () (interactive) (apply 'elfeed-search-toggle-all '(star))))
271 (define-key elfeed-show-mode-map (kbd "*") (lambda () (interactive) (apply 'elfeed-show-tag '(star))))
272 (add-hook 'elfeed-show-mode 'variable-pitch-mode))
274 (use-package elfeed-protocol
278 (setq elfeed-protocol-feeds '(
279 ("owncloud+https://frederik@owncloud.vanrenterghem.biz" :use-authinfo t)
281 (elfeed-protocol-enable))
284 ;; Read and write email using mu4e
287 ;; :ensure-system-package mu ;; Install from aur
289 (setq mail-user-agent 'mu4e-user-agent)
290 ;; Also use mu4e when called from gnus-dired-attach
291 (setq gnus-dired-mail-mode 'mu4e-user-agent
292 mu4e-get-mail-command "mbsync io"
293 mu4e-update-interval 600
294 mu4e-use-fancy-chars t
295 mu4e-view-show-images t
296 mu4e-sent-folder "/Sent"
297 mu4e-drafts-folder "/Drafts"
298 mu4e-trash-folder "/Trash"
299 message-kill-buffer-on-exit t
300 ;;Fixing duplicate UID errors when using mbsync and mu4e
301 mu4e-change-filenames-when-moving t)
302 ;; attach files to mu4e messages by marking the file(s) in dired and pressing C-c RET C-a
303 (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode)
304 ;; Define all bookmarks starting with favourite query used in mailcount modeline
306 '(( :name "Last 24h's messages"
309 :query "date:24h..now AND NOT flag:trashed")
310 ( :name "Unread messages"
311 :query "flag:unread AND NOT flag:trashed"
313 ( :name "Today's messages"
314 :query "date:today..now AND NOT flag:trashed"
316 ( :name "Last 7 days"
317 :query "date:7d..now AND NOT flag:trashed"
320 ( :name "Messages with images"
321 :query "mime:image/* AND NOT flag:trashed"
323 ;; Create custom spam status header and show in message view
324 (add-to-list 'mu4e-header-info-custom
326 ( :name "Spam-Status" ;; long name, as seen in the message-view
327 :shortname "Spam" ;; short name, as seen in the headers view
328 :help "The Spam status" ;; tooltip
329 ;; uses mu4e-fetch-field which is rel. slow, so only appropriate
330 ;; for mu4e-view-fields, and _not_ mu4e-headers-fields
331 :function (lambda (msg)
332 (or (string-join (seq-take (split-string (or (mu4e-fetch-field msg "X-Spam-Status") "") " ") 2) " ") "")))))
333 (add-to-list 'mu4e-view-fields :spam-status)
334 ;; Resize image attachments when sending email
335 (defvar mu4e-resize-image-types '("jpg" "png" "svg" "jpeg")
336 "List of attached image types to resize.")
337 (defvar mu4e-inhibit-resize nil)
338 (defun mu4e-resize-image-attachments ()
339 (unless mu4e-inhibit-resize
342 (mapconcat #'identity mu4e-resize-image-types "\\|")))
344 (message-goto-body-1)
345 (while (re-search-forward
346 (format "<#part.+\\(filename=\"\\)\\(.+\\(\\.%s\\)\\)\""
349 (let* ((infile (match-string-no-properties 2))
350 (outfile (concat (temporary-file-directory)
351 (file-name-nondirectory infile))))
352 (push (format "magick convert %s -resize 1200x1200\\> %s"
353 (shell-quote-argument infile)
354 (shell-quote-argument outfile))
356 (replace-match outfile t t nil 2)))
357 (mapcar #'shell-command cmds)))))
358 (add-hook 'message-send-hook 'mu4e-resize-image-attachments)
359 (defun mu4e-inhibit-resize()
361 (set (make-local-variable 'mu4e-inhibit-resize) t)))
363 ;; Load configuration for website
364 ;(load "mustache-html")
369 :hook (dired-mode . denote-dired-mode)
371 (("C-c n n" . denote)
372 ("C-c n r" . denote-rename-file)
373 ("C-c n l" . denote-link)
374 ("C-c n b" . denote-backlinks))
376 (setq denote-directory "/home/frederik/Nextcloud/notes/")
377 (denote-rename-buffer-mode 1))
379 (use-package nerd-icons
381 ;; The Nerd Font you want to use in GUI
382 ;; "Symbols Nerd Font Mono" is the default and is recommended
383 ;; but you can use any other Nerd Font if you want
384 ;; (nerd-icons-font-family "Symbols Nerd Font Mono")
387 ;; Dired configuration
388 (with-eval-after-load 'dired
390 ;; Set dired-x global variables here. For example:
391 ;; (setq dired-x-hands-off-my-keys nil)
393 (add-hook 'dired-mode-hook
395 ;; Set dired-x buffer-local variables here.
397 (dired-hide-details-mode 1)
398 (nerd-icons-dired-mode 1)
400 (setq delete-by-moving-to-trash t)
401 (setq dired-guess-shell-alist-user
402 '(("\\.\\(png\\|jpe?g\\|tiff\\)" "feh" "xdg-open")
403 ("\\.\\(mp[34]\\|m4a\\|ogg\\|flac\\|webm\\|mkv\\)" "mpv" "xdg-open")
406 ;; Use `vertico' package to get a vertical view of the minibuffer.
410 (setq vertico-resize nil)
413 ;; Persist history over Emacs restarts. Vertico sorts by history position.
414 (use-package savehist
418 ;; Use `marginalia' package. This will display useful
419 ;; annotations next to entries in the minibuffer. For example, when
420 ;; using M-x it will show a brief description of the command as well
421 ;; as the keybinding associated with it (if any).
422 (use-package marginalia
427 ;; Use 'winner' mode to undo and redo windows changes
428 ;; using C-c <left> and C-c <right>.
434 ;; Use a different spell checker, always
438 (keymap-global-set "M-$" #'jinx-correct)
439 :hook (emacs-startup . global-jinx-mode))
446 (keymap-global-set "C-." #'embark-act)
447 (keymap-global-set "C-;" #'embark-dwim))
452 ;; Change default bindings to consult- ones
454 (;; C-x bindings in `ctl-x-map'
455 ("C-x b" . consult-buffer) ;; orig. switch-to-buffer
456 ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
457 ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
458 ;; Other custom bindings
459 ("M-y" . consult-yank-pop))) ;; orig. yank-pop
461 (use-package consult-mu
462 :ensure nil ;; cloned in
463 :load-path "~/.emacs.d/lisp/consult-mu"
464 :after (consult mu4e)
466 ;;maximum number of results shown in minibuffer
467 (consult-mu-maxnum 200)
468 ;;show preview when pressing any keys
469 (consult-mu-preview-key 'any)
470 ;;do not mark email as read when previewed
471 (consult-mu-mark-previewed-as-read nil)
472 ;;do not amrk email as read when selected. This is a good starting point to ensure you would not miss important emails marked as read by mistake especially when trying this package out. Later you can change this to t.
473 (consult-mu-mark-viewed-as-read nil)
474 ;; open the message in mu4e-view-buffer when selected.
475 (consult-mu-action #'consult-mu--view-action)
478 ;; Configure `world-clock'
482 (setq zoneinfo-style-world-list '(("Europe/Brussels" "Leuven")))
483 (add-to-list 'zoneinfo-style-world-list '("Australia/Perth" "Perth")))
486 ;; View PDFs in Emacs
487 (pdf-loader-install) ; On demand loading, leads to faster startup time
488 (setq pdf-misc-print-programm "/usr/bin/lpr")
496 ;; For `eat-eshell-mode'.
497 (add-hook 'eshell-load-hook #'eat-eshell-mode)
498 (setq eshell-visual-commands '()))
504 (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
506 (add-hook 'nov-mode-hook #'variable-pitch-mode))
508 ;; Set some preset fonts
509 (use-package fontaine
512 (setq fontaine-presets
514 :default-family "Iosevka Nerd Font"
516 :variable-pitch-family "Linux Biolinum O"
517 :variable-pitch-weight normal
518 :variable-pitch-height 1.1
519 :italic-family "Iosevka Etoile"
522 :default-family "Iosevka Nerd Font"
524 :variable-pitch-family "Linux Biolinum O"
525 :variable-pitch-weight normal
526 :variable-pitch-height 1.1
527 :italic-family "Iosevka Etoile"
530 :default-family "Fira Mono Nerd Font"
532 :variable-pitch-family "Fira Sans Book"
533 :variable-pitch-weight normal
534 :variable-pitch-height 1.0
537 :default-family "Fira Mono Nerd Font"
539 :variable-pitch-family "Fira Sans Book"
540 :variable-pitch-weight normal
541 :variable-pitch-height 1.0
544 :variable-pitch-family "Libre Baskerville"
545 :variable-pitch-weight normal
546 :variable-pitch-height 1.0
549 :variable-pitch-family "Noto Serif"
550 :variable-pitch-weight normal
551 :variable-pitch-height 1.0
554 :variable-pitch-family "ETBembo"
555 :variable-pitch-weight normal
556 :variable-pitch-height 1.1
559 :variable-pitch-family "Literata"
560 :variable-pitch-weight normal
561 :variable-pitch-height 1.0
567 ("C-h D" . devdocs-lookup))
571 ;; Might want to run this automatically
572 ;; using variable after-focus-change-function
573 (defun my/adjust-font-size-based-on-display ()
574 "Change size of fonts based on monitor."
576 (let* ((display-name (cdr (assq 'name (frame-monitor-attributes))))
577 (font-height (cond ((string-equal display-name "eDP-1") 140)
580 (set-face-attribute 'default (selected-frame) :height font-height)))