;; Here are some additional functions/macros that could help you configure Doom: ;; - `load!' for loading external *.el files relative to this one ;; - `use-package!' for configuring packages ;; - `after!' for running code after a package has loaded ;; - `add-load-path!' for adding directories to the `load-path', relative to ;; this file. Emacs searches the `load-path' when you load packages with ;; `require' or `use-package'. ;; - `map!' for binding new keys (setq user-full-name "Julian Mutter" user-mail-address "julian.mutter@comumail.de") (setq doom-theme 'doom-dracula doom-font (font-spec :family "Source Code Pro" :size 14) doom-variable-pitch-font (font-spec :family "DejaVu Sans" :size 15)) (setq display-line-numbers-type 'nil) ;; 'relative (setq-default evil-escape-key-sequence "kj") ;; (after! company ;; (setq company-idle-delay 0.1)) (map! :leader :desc "Open external terminal" "o t" (cmd! (call-process-shell-command "$TERMINAL &" nil 0))) (map! :leader :desc "Open external file explorer" "o e" (cmd! (call-process-shell-command "thunar &" nil 0))) ;; Remap font scaling keybindings to make more sense (map! :desc "Increase font size" :n "C-+" #'text-scale-increase) (map! :desc "Decrease font size" :n "C--" #'text-scale-decrease) (map! :desc "Reset font size" :n "C-=" #'doom/reset-font-size) (map! :desc "Flycheck next error" :nv "g n" #'flycheck-next-error) (map! :desc "Flycheck previous error" :nv "g N" #'flycheck-previous-error) (map! :leader "c X" #'flycheck-list-errors) (map! :desc "Save" :g "C-s" #'fd-save-and-escape) ;; (map! :leader "w 1" #'delete-other-windows) (map! :leader "t p" #'+popup/toggle) ;; Useful for recompiling or running a project (map! :nvi "" #'projectile-repeat-last-command) ;; Do not use autosave when using vim save command (evil-ex-define-cmd "write" #'fd-format-without-autosave) ;; Select other window by number (dotimes (counter 9) (let ((command (format "(map! :leader \"%d\" #'winum-select-window-%d)" (1+ counter) (1+ counter)))) (eval (read command)))) (map! :leader "r" #'quickrun) (defun fd-format-without-autosave() (interactive) (let ((current-prefix-arg 4)) ;; pass universal argument (call-interactively #'save-buffer)) ) (defun fd-save-and-escape() (interactive) (company-abort) (evil-force-normal-state) (save-buffer)) ;; Do not ask before exiting emacs (setq confirm-kill-emacs nil) ;; Open pdf files with external reader (openwith-mode t) (setq openwith-associations '(("\\.pdf\\'" "evince" (file)))) ;; Org settings (setq org-directory "~/Nextcloud/org" org-roam-directory "~/Nextcloud/org/roam") ;; Make all org files agenda files (setq org-agenda-files (list org-directory "~/dev/bachelor-thesis/notes")) (setq org-export-allow-bind-keywords t) ;; Insert timestamp when marking task as done (setq org-log-done #'time) (add-hook 'org-clock-in-hook #'save-buffer) (add-hook 'org-clock-out-hook #'save-buffer) (setq org-pomodoro-manual-break t) ;; Max volume is 65536 since player is paplay (let ((volume "--volume=40000")) (setq org-pomodoro-start-sound-args volume) (setq org-pomodoro-killed-sound-args volume) (setq org-pomodoro-ticking-sound-args volume) (setq org-pomodoro-finished-sound-args volume) (setq org-pomodoro-overtime-sound-args volume) (setq org-pomodoro-long-break-sound-args volume) (setq org-pomodoro-short-break-sound-args volume) ) (setq org-agenda-custom-commands '(("." "Clocking today" agenda "" ((org-agenda-span 1) (org-agenda-start-day "today") (org-agenda-start-with-clockreport-mode t) (org-agenda-start-with-log-mode 'clockcheck) )))) (setq org-agenda-clockreport-parameter-plist '(:link t :maxlevel 2 :fileskip0 t)) ;; :stepskip0 t (setq org-clock-mode-line-total 'today) (map! :map org-mode-map :nvi "C-k" #'org-backward-element) (map! :map org-mode-map :nvi "C-j" #'org-forward-element) (map! :map org-mode-map :nvi "C-h" #'org-up-element) (map! :map org-mode-map :nvi "C-l" #'org-down-element) (map! :map org-mode-map :nvi "M-i" #'org-roam-node-insert) (map! :map org-mode-map :nvi "M-@" #'org-cite-insert) (map! :map doom-leader-notes-map "r r" #'org-roam-node-find) (map! :map doom-leader-notes-map "r t" #'org-roam-buffer-toggle) (map! :map doom-leader-notes-map "s" #'fd-org-notes-search-follow-symlinks) (after! org (add-to-list 'org-capture-templates '("b" "Bachelor todo" entry (file+headline "bachelor/todo.org" "Inbox") "* IDEA %?\n%i\n%T\n%a" :prepend t) )) (defun fd-org-notes-search-follow-symlinks (query) "Alternative to +default/org-notes-search which follows symbolic links for better project inlusion" (interactive (list (if (doom-region-active-p) (buffer-substring-no-properties (doom-region-beginning) (doom-region-end)) ""))) (require 'org) (+vertico-file-search :query query :in org-directory :args '("-L"))) (defun fd-org-latex-preview-buffer () "Show latex preview for whole buffer by running org-latex-preview with C-u C-u" (interactive) (let ((current-prefix-arg '(16))) (call-interactively 'org-latex-preview) )) ;; Custom time format display (setq-default org-display-custom-times nil) (setq org-time-stamp-custom-formats '("<%d.%m.%Y %a>" . "<%d.%m.%Y %a %H:%M>")) ;; Enable org mode like header navigation (map! :map TeX-mode-map :nvi "" #'outline-cycle-buffer) (map! :map TeX-mode-map :nv "C-k" #'outline-backward-same-level) (map! :map TeX-mode-map :nv "C-j" #'outline-forward-same-level) (map! :map TeX-mode-map :nv "C-h" #'outline-up-heading) (map! :map TeX-mode-map :nv "C-l" #'outline-next-heading) ;; Fixes latexindent not finding perl libraries (setenv "PERL5LIB" "~/perl5/lib/perl5") (setq +latex-viewers '(evince)) (use-package! lsp-ltex :after latex :init (setq lsp-ltex-enabled t) (setq lsp-ltex-language "en-US") (setq lsp-ltex-mother-tongue "de-DE")) ;; Do not automatically enable writegood mode (remove-hook! '(org-mode-hook markdown-mode-hook rst-mode-hook asciidoc-mode-hook latex-mode-hook LaTeX-mode-hook) #'writegood-mode) ;; Removing hooks for automatic spell checking set here: https://github.com/hlissner/doom-emacs/blob/develop/modules/checkers/spell/config.el (remove-hook! '(org-mode-hook markdown-mode-hook TeX-mode-hook rst-mode-hook mu4e-compose-mode-hook message-mode-hook git-commit-mode-hook) #'flyspell-mode) (remove-hook! '(yaml-mode-hook conf-mode-hook prog-mode-hook) #'flyspell-prog-mode) ;; (setq ispell-dictionary "english") (setq ispell-personal-dictionary "~/ispell-personal-dictionary") (map! :map doom-leader-toggle-map :desc "Toggle dictionary" "d" #'fd-switch-dictionary) (defun fd-switch-dictionary() (interactive) (let* ((dic ispell-current-dictionary) (change (if (string= dic "german") "english" "german"))) (ispell-change-dictionary change) (message "Dictionary switched from %s to %s" dic change) )) (set-flyspell-predicate! '(latex-mode) #'+latex-flyspell-word-p) (defun +latex-flyspell-word-p () "Return t if point is on a word that should be spell checked. Return nil if on a link url, markup, html, or references." (let ((faces (ensure-list (get-text-property (point) 'face)))) (or (and (memq 'font-lock-comment-face faces) (memq 'markdown-code-face faces)) (not (cl-loop with unsafe-faces = '(font-lock-comment-face ;; font-latex-math-face ;; font-latex-string-face font-lock-keyword-face font-lock-constant-face font-lock-function-name-face font-lock-variable-name-face font-lock-type-face ;; figure captions ) for face in faces if (memq face unsafe-faces) return t))))) ;; (setq lsp-dart-flutter-sdk-dir "~/snap/flutter/common/flutter") ;; (map! :mode dart-mode :leader "r" #'flutter-run-or-hot-reload) ;; Make sniping simpler for german keyboard (setq evil-snipe-scope 'visible) (map! :map evil-snipe-override-mode-map :m "," #'evil-snipe-repeat) (map! :map evil-snipe-override-mode-map :m ";" #'evil-snipe-repeat-reverse) (map! :map evil-snipe-parent-transient-map "," #'evil-snipe-repeat) (map! :map evil-snipe-parent-transient-map ";" #'evil-snipe-repeat-reverse) (add-hook 'matlab-mode-hook (lambda () (add-to-list 'quickrun-file-alist '("\\.m\\'" . "octave")))) ;; (assq-delete-all "objc" quickrun-file-alist) (quickrun-add-command "matlab" '((:command . "octave")) :mode #'matlab-mode ) (quickrun-add-command "octave" '((:command . "octave")) :mode #'octave-mode ) ;; (autoload 'matlab-mode "matlab" "Matlab Editing Mode" t) (add-to-list 'auto-mode-alist '("\\.m$" . matlab-mode)) ;; (setq matlab-indent-function t) ;; (setq matlab-shell-command "/urs/local/bin/matlab") (map! :desc "Toggle case of word" :nv "g C" #'toggle-word-case) (defun toggle-word-case () "Toggle the case of current word or text selection." (interactive) (let ( (deactivate-mark nil) $p1 $p2) (if (use-region-p) (setq $p1 (region-beginning) $p2 (region-end)) (save-excursion (skip-chars-backward "[:alpha:]") (setq $p1 (point)) (skip-chars-forward "[:alpha:]") (setq $p2 (point)))) (let ((first-char-prop (get-char-code-property (char-after $p1) 'general-category))) (cond ((string= "Ll" first-char-prop) ; Lower case (upcase-region $p1 (+ $p1 1))) ((string= "Lu" first-char-prop) ; Upper case (downcase-region $p1 (+ $p1 1))) (t (message "Word does not start with a alphabetic character")))))) (add-hook 'tetris-mode-hook #'turn-off-evil-mode) (map! :map 'doom-leader-project-map :desc "Repeat last command" "SPC" #'projectile-repeat-last-command) (defun fd-pretty-print-dirty-json() (interactive) (let ((new-buffer-contents (shell-command-to-string (format "echo '%s' | newliner" (buffer-string))))) (erase-buffer) (insert new-buffer-contents) (evil-indent (buffer-end -1) (buffer-end +1))) ) (defun fd-inventory-transfer() (interactive) (fd-inventory-transfer-check-if-valid-table) (let ((location-from (string-trim (org-table-get 1 2))) (location-to (string-trim (org-table-get 1 3))) (item-name (string-trim (org-table-get-field 1)))) (let (transfer-amount) (setq transfer-amount (read-number (concat "Transfer from " location-from " to " location-to ": "))) (fd-inventory-transfer-log-transfer transfer-amount item-name location-from location-to) (fd-inventory-transfer-do-transfer transfer-amount) (org-table-align) ))) (defun fd-inventory-transfer-check-if-valid-table () (unless (org-at-table-p) (error "You are not inside a table")) (unless (and (string-match-p "^[[:blank:]]*-?[0-9]+[[:blank:]]*$" (org-table-get-field 2)) (string-match-p "^[[:blank:]]*-?[0-9]+[[:blank:]]*$" (org-table-get-field 3))) (error "Amounts in table are not numbers")) (if (or (string= "" (org-table-get 1 2)) (string= "" (org-table-get 1 3))) (error "No valid table header"))) (defun fd-inventory-transfer-do-transfer(amount) (let* ((amount-from-location (string-to-number (org-table-get-field 2))) (amount-to-location (string-to-number (org-table-get-field 3))) (amount-from-location-new (- amount-from-location amount)) (amount-to-location-new (+ amount-to-location amount))) (progn (org-table-get-field 2 (number-to-string amount-from-location-new)) (org-table-get-field 3 (number-to-string amount-to-location-new))))) (defun fd-inventory-transfer-log-transfer(amount item-name from-location to-location) (save-excursion (let* ((log-heading-point (or (org-find-exact-headline-in-buffer "Transfer log" nil t) (progn (goto-char (org-table-end)) (org-insert-heading) (insert "Transfer log") (point))))) (goto-char log-heading-point) (forward-line) (let ((message (concat "- " (format-time-string "%d.%m.%Y") ": *" (number-to-string amount) "* =" item-name "= from " from-location " to " to-location "\n"))) (insert message)) ))) (defun fd-python-to-latex(regionBegin regionEnd) (interactive (if (use-region-p) (list (region-beginning) (region-end)) (list (point-min) (point-max)))) (shell-command-on-region regionBegin regionEnd "python2latex")) (set-docsets! 'haskell-mode "Haskell") (setq! citar-bibliography '("~/Nextcloud/zotero-sources.bib"))