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