]> git.vanrenterghem.biz Git - Dotty.git/blob - emacs/.emacs.d/init.el
ddb78c4f31983253f79376063bb04d811ca16f1c
[Dotty.git] / emacs / .emacs.d / init.el
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.
5 (package-initialize)
7 (add-to-list 'load-path "~/.emacs.d/lisp/")
9 (tool-bar-mode -1)
11 ;; Configure printing using CUPS network printer
12 (setq lpr-switches
13       (append '("-o raw"
14                 "-o media=A4")
15               lpr-switches))
17 ;; Enable the melpa archive for packages
18 (use-package package
19   :config
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
27   :ensure t)
29 (use-package modus-themes
30   :ensure t
31   :demand t ;; Without this, the theme load is deferred due to the
32             ;; bind keyword below
33   :init
34   ;; Add all customisation prior to loading the themes
35   (setq modus-themes-mixed-fonts t)
36   :config
37   (modus-themes-select 'modus-vivendi-tinted)
38   (variable-pitch-mode)
39   :bind ("<f5>" . modus-themes-toggle))
41 (use-package orderless
42   :ensure t
43   :config
44   (setq completion-styles '(orderless basic)
45         completion-category-overrides '((file (styles basic partial-completion)))))
47 ;; follow links to version-controlled files without confirming
48 vc-follow-symlinks t
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
57 (use-package company
58   :ensure t
59   :bind(:map company-active-map
60              ("<return>" . nil)
61              ("RET" . nil)
62              ("C-<return>" . company-complete-selection)
63              ([tab]    . company-complete-common)            
64              ("TAB"    . company-complete-common))
65   :config
66   (setq ispell-complete-word-dict
67    (expand-file-name (concat user-emacs-directory "aspell_words.txt")))
68   ;(defun my/text-mode-hook ()
69   ;  (setq-local company-backends
70 ;               '((company-dabbrev company-ispell :separate)
71  ;                 company-files)))
72  ; (add-hook 'text-mode-hook #'my/text-mode-hook)
73   (global-company-mode 1))
75 (use-package org
76   :ensure t
77   :bind
78   (("C-c c" . org-capture)
79    ("C-c l" . org-store-link)
80    ("C-c a" . org-agenda))
81   :custom
82   (org-default-notes-file "~/Nextcloud/notes/inbox.org")
83   (org-agenda-files `(,org-default-notes-file "~/Nextcloud/notes/calendar.org"))
84   (org-capture-bookmark nil)
85   ;; Capture templates
86   (org-capture-templates
87    '(("f" "Fleeting note" item
88       (file+headline org-default-notes-file "Notes")
89       "* %?\nEntered on %U\n  %i\n  %a")
90      ("b" "Tax receipt" item
91       (file "~/Documents/belastingen/FY24-25.org")
92       "* %t %a\n") 
93      ("p" "Permanent note" plain
94       (file denote-last-path)
95       #'denote-org-capture
96       :no-save t
97       :immediate-finish nil
98       :kill-buffer t
99       :jump-to-captured t)
100      ("t" "New task" entry
101       (file+headline org-default-notes-file "Tasks")
102       "* TODO %i%?")
103      ("e" "Email follow-up" entry (file+headline org-default-notes-file "Tasks")
104       "* TODO %:fromname: %a %?\nDEADLINE: %(org-insert-time-stamp (org-read-date nil t \"+2d\"))")))
105   ;; Agenda views
106   (org-agenda-custom-commands
107    '(("P" "Expired calendar events" ((tags "TIMESTAMP<=\"<now>\"")))
108      ("n" "Agenda and all TODOs"  ((agenda "") (alltodo "")))))
109   :config
110   (setq org-agenda-skip-scheduled-if-done t)
111   (setq org-agenda-skip-deadline-if-done t)
112   (setq org-agenda-start-on-weekday nil)
113   ;; Automatically flow lines based on window width and use
114   ;; variable width fonts in org-mode.
115   (add-hook 'org-mode-hook 'visual-line-mode)
116   (add-hook 'org-mode-hook 'variable-pitch-mode)
117   ;; org-mode support for R and LaTeX
118   (org-babel-do-load-languages
119    'org-babel-load-languages
120    '((R . t)
121      (latex . t))))
123 (use-package org-caldav
124   :ensure t
125   :config
126   (setq org-caldav-url "https://owncloud.vanrenterghem.biz/remote.php/dav/calendars/frederik")
127   (setq org-caldav-calendar-id "orgmode")
128   ;; Org filename where new entries from calendar stored
129   (setq org-caldav-inbox "~/Nextcloud/notes/calendar.org")
130   ;; Additional Org files to check for calendar events
131   (setq org-caldav-files nil)
132   ;; Usually a good idea to set the timezone manually
133   (setq org-icalendar-timezone "Australia/Perth"))
135 (use-package tex
136   :ensure auctex
137   :config
138   (setq TeX-auto-save t
139         TeX-parse-self t
140         TeX-view-program-selection
141    '(((output-dvi has-no-display-manager)
142       "dvi2tty")
143      ((output-dvi style-pstricks)
144       "dvips and gv")
145      (output-dvi "xdvi")
146      (output-pdf "PDF Tools")
147      (output-html "xdg-open"))))
148 ;; (load "preview-latex.el" nil t t)
151 ;; Automatically switch to various modes
152 (setq auto-mode-alist
153     '(("\\.mdwn\\'" . markdown-mode)
154       ("\\.md\\'" . markdown-mode)
155       ("\\.yarn\\'" . markdown-mode)
156       ("\\.js\\'" . js-mode)
157       ("\\.json\\'" . js-mode)
158       ("Makefile" . makefile-mode)
159       ("README" . markdown-mode)
160       ("NEWS" . markdown-mode)
161       ("COMMIT_EDITMSG\\'" . text-mode)
162       ("\\.html\\'" . html-mode)
163       ("\\.css\\'" . css-mode)
164       ("\\.yaml\\'" . yaml-mode)
165       ("\\.yml\\'" . yaml-mode)
166       ("\\.ick\\'" . yaml-mode)
167       ("\\.py\\'" . python-mode)
168       ("\\.R\\'" . R-mode)
169       ("\\.org\\'" . org-mode)
170       ("\\.tex\\'" . latex-mode)
171       ("\\.sh\\'" . shell-script-mode)
172       ("\\.hs\\'" . haskell-mode)
173       ("\\.el\\'" . emacs-lisp-mode)))
176 (custom-set-variables
177  ;; custom-set-variables was added by Custom.
178  ;; If you edit it by hand, you could mess it up, so be careful.
179  ;; Your init file should contain only one such instance.
180  ;; If there is more than one, they won't work right.
181  '(browse-url-browser-function 'browse-url-firefox)
182  '(custom-safe-themes
183    '("8d146df8bd640320d5ca94d2913392bc6f763d5bc2bb47bed8e14975017eea91" "9a977ddae55e0e91c09952e96d614ae0be69727ea78ca145beea1aae01ac78d2" "0cf95236abcf59e05b1ea69b4edd53d293a5baec4fe4c3484543fee99bfd2204" "80b00f3bf7cdbdca6c80aadfbbb03145f3d0aacf6bf2a559301e61109954e30a" default))
184  '(org-export-backends '(ascii html icalendar latex md odt))
185  '(package-selected-packages
186    '(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))
187  '(use-package-compute-statistics t))
188 (custom-set-faces
189  ;; custom-set-faces was added by Custom.
190  ;; If you edit it by hand, you could mess it up, so be careful.
191  ;; Your init file should contain only one such instance.
192  ;; If there is more than one, they won't work right.
193  )
196 ;; Send mail using SMTP via mail.vanrenterghem.io.
197 (setq send-mail-function    'smtpmail-send-it)
198 (setq smtpmail-smtp-server "mail.vanrenterghem.io"
199       smtpmail-smtp-service 587
200       smtpmail-stream-type 'starttls)
201 (setq user-full-name "Frederik Vanrenterghem"
202       smtpmail-local-domain "vanrenterghem.io"
203       user-mail-address (concat "frederik@" smtpmail-local-domain))
204 ;; Ignored in mu4e as it sets user-agent
205 (setq mail-default-headers
206       (concat "X-Mailer: GNU Emacs " (symbol-value 'emacs-version))) 
207 (setq w3m-pop-up-frames t)
209 (global-set-key [remap list-buffers] 'ibuffer)
211 ;;; use pass (~/.password-store)
212 ;;; (see The Unix password store)
213 (use-package pass
214   :ensure t
215   :config
216   (auth-source-pass-enable)
217   (setq pass-username-field "Username"))
219 ;; Elfeed news reader from Nextcloud
220 (use-package elfeed
221   :ensure t
222   :config
223   (setq elfeed-use-curl nil)
224   (elfeed-set-timeout 36000)
225   (define-key elfeed-search-mode-map (kbd "*") (lambda () (interactive) (apply 'elfeed-search-toggle-all '(star))))
226   (define-key elfeed-show-mode-map (kbd "*") (lambda () (interactive) (apply 'elfeed-show-tag '(star))))
227   (add-hook 'elfeed-show-mode 'variable-pitch-mode))
229 (use-package elfeed-protocol
230   :ensure t
231   :after elfeed
232   :config
233   (setq elfeed-protocol-feeds '(
234                                 ("owncloud+https://frederik@owncloud.vanrenterghem.biz" :use-authinfo t)
235         ))
236   (elfeed-protocol-enable))
239 ;; Read and write email using mu4e
240 (use-package mu4e
241   :ensure nil
242   ;; :ensure-system-package mu ;; Install from aur
243   :config
244   (setq mail-user-agent 'mu4e-user-agent)
245   ;; Also use mu4e when called from gnus-dired-attach
246   (setq gnus-dired-mail-mode 'mu4e-user-agent
247         mu4e-get-mail-command "mbsync io"
248         mu4e-update-interval 600
249         mu4e-use-fancy-chars t
250         mu4e-view-show-images t
251         mu4e-sent-folder   "/Sent"
252         mu4e-drafts-folder "/Drafts"
253         mu4e-trash-folder  "/Trash"
254         message-kill-buffer-on-exit t
255         ;;Fixing duplicate UID errors when using mbsync and mu4e
256         mu4e-change-filenames-when-moving t)
257   ;; attach files to mu4e messages by marking the file(s) in dired and pressing C-c RET C-a
258   (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode)
259   ;; Define all bookmarks starting with favourite query used in mailcount modeline
260   (setq mu4e-bookmarks
261         '(( :name "Last 24h's messages"
262           :key ?l
263           :favorite y
264           :query "date:24h..now AND NOT flag:trashed")
265         ( :name "Unread messages"
266           :query "flag:unread AND NOT flag:trashed"
267           :key ?u)
268         ( :name "Today's messages"
269           :query "date:today..now AND NOT flag:trashed"
270           :key ?t)
271         ( :name "Last 7 days"
272           :query "date:7d..now AND NOT flag:trashed"
273           :hide-unread t
274           :key ?w)
275         ( :name "Messages with images"
276           :query "mime:image/* AND NOT flag:trashed"
277           :key ?p)))
278   ;; Create custom spam status header and show in message view
279   (add-to-list 'mu4e-header-info-custom
280                '(:spam-status .
281                               ( :name "Spam-Status"     ;; long name, as seen in the message-view
282                                 :shortname "Spam"      ;; short name, as seen in the headers view
283                                 :help "The Spam status" ;; tooltip
284                                 ;; uses mu4e-fetch-field which is rel. slow, so only appropriate
285                                 ;; for mu4e-view-fields, and _not_ mu4e-headers-fields
286                                 :function (lambda (msg)
287                                             (or (string-join (seq-take (split-string (or (mu4e-fetch-field msg "X-Spam-Status") "") " ") 2) " ") "")))))
288   (add-to-list 'mu4e-view-fields :spam-status)
289   ;; Resize image attachments when sending email
290   (defvar mu4e-resize-image-types '("jpg" "png" "svg" "jpeg")
291     "List of attached image types to resize.")
292   (defvar mu4e-inhibit-resize nil)
293   (defun mu4e-resize-image-attachments ()
294     (unless mu4e-inhibit-resize
295       (let (cmds
296             (image-types
297              (mapconcat #'identity mu4e-resize-image-types "\\|")))
298         (save-excursion
299           (message-goto-body-1)
300           (while (re-search-forward 
301                   (format "<#part.+\\(filename=\"\\)\\(.+\\(\\.%s\\)\\)\""
302                           image-types)
303                   nil t)
304             (let* ((infile (match-string-no-properties 2))
305                    (outfile (concat (temporary-file-directory)
306                                     (file-name-nondirectory infile))))
307               (push (format "magick convert %s -resize 1200x1200\\> %s"
308                             (shell-quote-argument infile)
309                             (shell-quote-argument outfile))
310                     cmds)
311               (replace-match outfile t t nil 2)))
312           (mapcar #'shell-command cmds)))))
313   (add-hook 'message-send-hook 'mu4e-resize-image-attachments)
314   (defun mu4e-inhibit-resize()
315     (interactive)
316     (set (make-local-variable 'mu4e-inhibit-resize) t)))
318 ;; Load configuration for website
319 ;(load "mustache-html")
321 ;; Denote config
322 (use-package denote
323   :ensure t
324   :hook (dired-mode . denote-dired-mode)
325   :bind
326   (("C-c n n" . denote)
327    ("C-c n r" . denote-rename-file)
328    ("C-c n l" . denote-link)
329    ("C-c n b" . denote-backlinks))
330   :config
331   (setq denote-directory "/home/frederik/Nextcloud/notes/")
332   (denote-rename-buffer-mode 1))
334 (use-package nerd-icons
335   ;; :custom
336   ;; The Nerd Font you want to use in GUI
337   ;; "Symbols Nerd Font Mono" is the default and is recommended
338   ;; but you can use any other Nerd Font if you want
339   ;; (nerd-icons-font-family "Symbols Nerd Font Mono")
340   )
342 ;; Dired configuration
343 (with-eval-after-load 'dired
344   (require 'dired-x)
345   ;; Set dired-x global variables here.  For example:
346   ;; (setq dired-x-hands-off-my-keys nil)
347   )
348 (add-hook 'dired-mode-hook
349           (lambda ()
350             ;; Set dired-x buffer-local variables here.
351             (dired-omit-mode 1)
352             (dired-hide-details-mode 1)
353             (nerd-icons-dired-mode 1)
354             ))
355 (setq delete-by-moving-to-trash t)
356 (setq dired-guess-shell-alist-user
357       '(("\\.\\(png\\|jpe?g\\|tiff\\)" "feh" "xdg-open")
358         ("\\.\\(mp[34]\\|m4a\\|ogg\\|flac\\|webm\\|mkv\\)" "mpv" "xdg-open")
359                 (".*" "xdg-open")))
361 ;; Use `vertico' package to get a vertical view of the minibuffer.
362 (use-package vertico
363   :ensure t
364   :config
365   (setq vertico-resize nil)
366   (vertico-mode 1))
368 ;; Persist history over Emacs restarts. Vertico sorts by history position.
369 (use-package savehist
370   :init
371   (savehist-mode))
373 ;; Use `marginalia' package.  This will display useful
374 ;; annotations next to entries in the minibuffer.  For example, when
375 ;; using M-x it will show a brief description of the command as well
376 ;; as the keybinding associated with it (if any).
377 (use-package marginalia
378   :ensure t
379   :config
380   (marginalia-mode 1))
382 ;; Use 'winner' mode to undo and redo windows changes
383 ;; using C-c <left> and C-c <right>.
384 (use-package winner
385   :ensure t
386   :config
387   (winner-mode 1))
389 ;; Use a different spell checker, always
390 (use-package jinx
391   :ensure t
392   :config
393   (keymap-global-set "M-$" #'jinx-correct)
394   :hook (emacs-startup . global-jinx-mode))
397 ;; Bind embark
398 (use-package embark
399   :ensure t
400   :config
401   (keymap-global-set "C-." #'embark-act)
402   (keymap-global-set "C-;" #'embark-dwim))
404 (use-package consult
405   :ensure t
406   :config
407   ;; Change default bindings to consult- ones
408   :bind
409   (;; C-x bindings in `ctl-x-map'
410    ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
411    ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
412    ("C-x r b" . consult-bookmark)            ;; orig. bookmark-jump
413    ;; Other custom bindings
414    ("M-y" . consult-yank-pop)))              ;; orig. yank-pop
416 (use-package consult-mu
417   :ensure nil ;; cloned in
418   :load-path "~/.emacs.d/lisp/consult-mu"
419   :after (consult mu4e)
420   :custom
421   ;;maximum number of results shown in minibuffer
422   (consult-mu-maxnum 200)
423   ;;show preview when pressing any keys
424   (consult-mu-preview-key 'any)
425   ;;do not mark email as read when previewed
426   (consult-mu-mark-previewed-as-read nil)
427   ;;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.
428   (consult-mu-mark-viewed-as-read nil)
429   ;; open the message in mu4e-view-buffer when selected.
430   (consult-mu-action #'consult-mu--view-action)
431   )
433 ;; Configure `world-clock'
434 (use-package time
435   :ensure nil
436   :config
437   (setq zoneinfo-style-world-list '(("Europe/Brussels" "Leuven")))
438   (add-to-list 'zoneinfo-style-world-list '("Australia/Perth" "Perth")))
441 ;; View PDFs in Emacs
442 (pdf-loader-install) ; On demand loading, leads to faster startup time
443 (setq pdf-misc-print-programm "/usr/bin/lpr")
444   
445 (use-package magit
446   :ensure t)
448 (use-package eat
449   :ensure t
450   :config
451    ;; For `eat-eshell-mode'.
452   (add-hook 'eshell-load-hook #'eat-eshell-mode)
453   (setq eshell-visual-commands '()))
455 ;; Read ePub files
456 (use-package nov
457   :ensure t
458   :init
459   (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
460   :config
461   (add-hook 'nov-mode-hook #'variable-pitch-mode))
463 ;; Set some preset fonts
464 (use-package fontaine
465   :ensure t
466   :config
467   (setq fontaine-presets
468       '((regular-1
469          :default-family "Iosevka Nerd Font"
470          :default-height 120
471          :variable-pitch-family "Linux Biolinum O"
472          :variable-pitch-weight normal
473          :variable-pitch-height 1.1
474          :italic-family "Iosevka Etoile"
475          :line-spacing 1)
476         (large-1
477          :default-family "Iosevka Nerd Font"
478          :default-height 150
479          :variable-pitch-family "Linux Biolinum O"
480          :variable-pitch-weight normal
481          :variable-pitch-height 1.1
482          :italic-family "Iosevka Etoile"
483          :line-spacing 1)
484         (regular-2
485          :default-family "Fira Mono Nerd Font"
486          :default-height 140
487          :variable-pitch-family "Fira Sans Book"
488          :variable-pitch-weight normal
489          :variable-pitch-height 1.0
490          :line-spacing 1)
491         (large-2
492          :default-family "Fira Mono Nerd Font"
493          :default-height 140
494          :variable-pitch-family "Fira Sans Book"
495          :variable-pitch-weight normal
496          :variable-pitch-height 1.0
497          :line-spacing 1)
498         (ereader-Baskerville
499          :variable-pitch-family "Libre Baskerville"
500          :variable-pitch-weight normal
501          :variable-pitch-height 1.0
502          :line-spacing 1)
503         (ereader-Noto-Serif
504          :variable-pitch-family "Noto Serif"
505          :variable-pitch-weight normal
506          :variable-pitch-height 1.0
507          :line-spacing 1)
508         (ereader-Bembo-Tufte
509          :variable-pitch-family "ETBembo"
510          :variable-pitch-weight normal
511          :variable-pitch-height 1.1
512          :line-spacing 1)
513         (ereader-Literata
514          :variable-pitch-family "Literata"
515          :variable-pitch-weight normal
516          :variable-pitch-height 1.0
517          :line-spacing 1))))
519 ;; Custom functions
521 ;; Might want to run this automatically
522 ;; using variable after-focus-change-function
523 (defun my/adjust-font-size-based-on-display ()
524   "Change size of fonts based on monitor."
525   (interactive)
526   (let* ((display-name (cdr (assq 'name (frame-monitor-attributes))))
527          (font-height (cond ((string-equal display-name "eDP-1") 140) 
528                             (t 120) ;; default
529                             )))
530     (set-face-attribute 'default (selected-frame) :height font-height)))