You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1309 lines
44 KiB
1309 lines
44 KiB
;;; init.el --- -*- lexical-binding: t -*-
|
|
|
|
(defun my/tangle-config ()
|
|
"Export code blocks from the literate config file."
|
|
(interactive)
|
|
;; prevent emacs from killing until tangle-process has finished
|
|
(add-to-list 'kill-emacs-query-functions
|
|
(lambda ()
|
|
(or (not (process-live-p (get-process "tangle-process")))
|
|
(y-or-n-p "\"my/tangle-config\" is running; kill it? "))))
|
|
(org-babel-tangle-file config-org init-el)
|
|
(message "reloading user-init-file")
|
|
(load-file init-el))
|
|
|
|
(add-hook 'org-mode-hook
|
|
(lambda ()
|
|
(if (equal (buffer-file-name) config-org)
|
|
(my--add-local-hook 'after-save-hook 'my/tangle-config))))
|
|
|
|
(defun my--add-local-hook (hook function)
|
|
"Add buffer-local hook."
|
|
(add-hook hook function :local t))
|
|
|
|
(add-hook 'emacs-startup-hook
|
|
(lambda ()
|
|
(message "Emacs ready in %s with %d garbage collections."
|
|
(format "%.2f seconds"
|
|
(float-time
|
|
(time-subtract after-init-time before-init-time)))
|
|
gcs-done)))
|
|
|
|
;(setq gc-cons-threshold (* 50 1000 1000))
|
|
|
|
(defconst *sys/gui*
|
|
(display-graphic-p)
|
|
"Is emacs running in a gui?")
|
|
|
|
(defconst *sys/linux*
|
|
(string-equal system-type 'gnu/linux)
|
|
"Is the system running Linux?")
|
|
|
|
(defconst *sys/windows*
|
|
(string-equal system-type 'windows-nt)
|
|
"Is the system running Windows?")
|
|
|
|
(defconst *home_desktop*
|
|
(string-equal (system-name) "marc")
|
|
"Is emacs running on my desktop?")
|
|
|
|
(defconst *home_laptop*
|
|
(string-equal (system-name) "laptop")
|
|
"Is emacs running on my laptop?")
|
|
|
|
(defconst *work_local*
|
|
(string-equal (system-name) "PMPCNEU08")
|
|
"Is emacs running at work on the local system?")
|
|
|
|
(defconst *work_remote*
|
|
(or (string-equal (system-name) "PMTS01")
|
|
(string-equal (system-name) "PMTSNEU01"))
|
|
"Is emacs running at work on the remote system?")
|
|
|
|
(defvar MY--PATH_USER_LOCAL (concat user-emacs-directory "user-local/"))
|
|
(defvar MY--PATH_USER_GLOBAL (concat user-emacs-directory "user-global/"))
|
|
|
|
(add-to-list 'custom-theme-load-path (concat MY--PATH_USER_GLOBAL "themes"))
|
|
|
|
(when *sys/linux*
|
|
(defconst MY--PATH_ORG_FILES (expand-file-name "~/Archiv/Organisieren/"))
|
|
(defconst MY--PATH_ORG_FILES_MOBILE (expand-file-name "~/Archiv/Organisieren/mobile/"))
|
|
(defconst MY--PATH_ORG_JOURNAl (expand-file-name "~/Archiv/Organisieren/Journal/"))
|
|
(defconst MY--PATH_ORG_ROAM (file-truename "~/Archiv/Organisieren/")))
|
|
(when *work_remote*
|
|
(defconst MY--PATH_ORG_FILES "p:/Eigene Dateien/Notizen/")
|
|
(defconst MY--PATH_ORG_FILES_MOBILE nil) ;; hacky way to prevent "free variable" compiler error
|
|
(defconst MY--PATH_ORG_JOURNAL nil) ;; hacky way to prevent "free variable" compiler error
|
|
(defconst MY--PATH_START "p:/Eigene Dateien/Notizen/")
|
|
(defconst MY--PATH_ORG_ROAM (expand-file-name "p:/Eigene Dateien/Notizen/")))
|
|
|
|
(setq custom-file (concat MY--PATH_USER_LOCAL "custom.el")) ;; don't spam init.e with saved customization settings
|
|
(setq backup-directory-alist `((".*" . ,temporary-file-directory)))
|
|
(setq auto-save-file-name-transforms `((".*" ,temporary-file-directory)))
|
|
(customize-set-variable 'auth-sources (list (concat MY--PATH_USER_LOCAL "authinfo")
|
|
(concat MY--PATH_USER_LOCAL "authinfo.gpg")
|
|
(concat MY--PATH_USER_LOCAL "netrc")))
|
|
|
|
(defvar elpaca-installer-version 0.7)
|
|
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
|
|
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
|
|
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
|
|
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
|
|
:ref nil :depth 1
|
|
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
|
|
:build (:not elpaca--activate-package)))
|
|
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
|
|
(build (expand-file-name "elpaca/" elpaca-builds-directory))
|
|
(order (cdr elpaca-order))
|
|
(default-directory repo))
|
|
(add-to-list 'load-path (if (file-exists-p build) build repo))
|
|
(unless (file-exists-p repo)
|
|
(make-directory repo t)
|
|
(when (< emacs-major-version 28) (require 'subr-x))
|
|
(condition-case-unless-debug err
|
|
(if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
|
|
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
|
|
,@(when-let ((depth (plist-get order :depth)))
|
|
(list (format "--depth=%d" depth) "--no-single-branch"))
|
|
,(plist-get order :repo) ,repo))))
|
|
((zerop (call-process "git" nil buffer t "checkout"
|
|
(or (plist-get order :ref) "--"))))
|
|
(emacs (concat invocation-directory invocation-name))
|
|
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
|
|
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
|
|
((require 'elpaca))
|
|
((elpaca-generate-autoloads "elpaca" repo)))
|
|
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
|
|
(error "%s" (with-current-buffer buffer (buffer-string))))
|
|
((error) (warn "%s" err) (delete-directory repo 'recursive))))
|
|
(unless (require 'elpaca-autoloads nil t)
|
|
(require 'elpaca)
|
|
(elpaca-generate-autoloads "elpaca" repo)
|
|
(load "./elpaca-autoloads")))
|
|
(add-hook 'after-init-hook #'elpaca-process-queues)
|
|
(elpaca `(,@elpaca-order))
|
|
|
|
;;at work symlinks wont work, and open file limit can be an issue
|
|
(when *work_remote*
|
|
(setq elpaca-queue-limit 12)
|
|
(elpaca-no-symlink-mode))
|
|
|
|
;(setq use-package-always-ensure t)
|
|
(elpaca elpaca-use-package
|
|
;; enable use-package :ensure support for elpaca
|
|
(elpaca-use-package-mode))
|
|
|
|
(elpaca-wait)
|
|
|
|
(defmacro use-feature (name &rest args)
|
|
"Like `use-package' but accounting for asynchronous installation.
|
|
NAME and ARGS are in `use-package'."
|
|
(declare (indent defun))
|
|
`(use-package ,name
|
|
:ensure nil
|
|
,@args))
|
|
|
|
(use-package general
|
|
:ensure t
|
|
:demand t)
|
|
|
|
(use-package diminish
|
|
:ensure t
|
|
:demand t)
|
|
|
|
;;wait for elpaca any time a use-package keyword is added
|
|
(elpaca-wait)
|
|
|
|
(setq-default create-lockfiles nil) ;; disable lock files, can cause trouble in e.g. lsp-mode
|
|
(defalias 'yes-or-no-p 'y-or-n-p) ;; answer with y and n
|
|
(setq custom-safe-themes t) ;; don't ask me if I want to load a theme
|
|
(setq sentence-end-double-space nil) ;; don't coun two spaces after a period as the end of a sentence.
|
|
(delete-selection-mode t) ;; delete selected region when typing
|
|
(use-package saveplace
|
|
:ensure nil
|
|
:config
|
|
(save-place-mode 1) ;; saves position in file when it's closed
|
|
:custom
|
|
(save-place-file (concat MY--PATH_USER_LOCAL "places")))
|
|
(setq save-place-forget-unreadable-files nil) ;; checks if file is readable before saving position
|
|
(global-set-key (kbd "RET") 'newline-and-indent) ;; indent after newline
|
|
(setq save-interprogram-paste-before-kill t) ;; put replaced text into killring
|
|
|
|
;; https://emacs.stackexchange.com/questions/3673/how-to-make-vc-and-magit-treat-a-symbolic-link-to-a-real-file-in-git-repo-just
|
|
(setq find-file-visit-truename t) ;; some programs like lsp have trouble following symlinks, maybe vc-follow-symlinks would be enough
|
|
|
|
(defconst 1mb 1048576)
|
|
(defconst 20mb 20971520)
|
|
(defconst 30mb 31457280)
|
|
(defconst 50mb 52428800)
|
|
|
|
(defun my--defer-garbage-collection ()
|
|
(setq gc-cons-threshold most-positive-fixnum))
|
|
|
|
(defun my--restore-garbage-collection ()
|
|
(run-at-time 1 nil (lambda () (setq gc-cons-threshold 30mb))))
|
|
|
|
(add-hook 'emacs-startup-hook 'my--restore-garbage-collection 100)
|
|
(add-hook 'minibuffer-setup-hook 'my--defer-garbage-collection)
|
|
(add-hook 'minibuffer-exit-hook 'my--restore-garbage-collection)
|
|
|
|
(setq read-process-output-max 1mb) ;; lsp-mode's performance suggest
|
|
|
|
(set-charset-priority 'unicode)
|
|
(setq-default locale-coding-system 'utf-8
|
|
default-process-coding-system '(utf-8-unix . utf-8-unix))
|
|
(set-terminal-coding-system 'utf-8)
|
|
(set-keyboard-coding-system 'utf-8)
|
|
(set-selection-coding-system 'utf-8)
|
|
(if *sys/windows*
|
|
(progn
|
|
(prefer-coding-system 'utf-8-dos)
|
|
(set-clipboard-coding-system 'utf-16-le)
|
|
(set-selection-coding-system 'utf-16-le))
|
|
(prefer-coding-system 'utf-8))
|
|
|
|
(setq-default bidi-paragraph-direction 'left-to-right
|
|
bidi-inhibit-bpa t ;; both settings reduce line rescans
|
|
uniquify-buffer-name-style 'forward
|
|
indent-tabs-mode nil ;; avoid tabs in place of multiple spaces (they look bad in tex)
|
|
indicate-empty-lines t ;; show empty lines
|
|
scroll-margin 5 ;; smooth scrolling
|
|
scroll-conservatively 10000
|
|
scroll-preserve-screen-position 1
|
|
scroll-step 1
|
|
ring-bell-function 'ignore ;; disable pc speaker bell
|
|
visible-bell t)
|
|
(global-hl-line-mode t) ;; highlight current line
|
|
(blink-cursor-mode -1) ;; turn off blinking cursor
|
|
(column-number-mode t)
|
|
|
|
(when *sys/linux*
|
|
(set-face-font 'default "Hack-10"))
|
|
(when *work_remote*
|
|
(set-face-font 'default "Lucida Sans Typewriter-11"))
|
|
|
|
(defun my/toggle-theme ()
|
|
(interactive)
|
|
(when (or *sys/windows* *sys/linux*)
|
|
(if (eq (car custom-enabled-themes) 'plastic)
|
|
(progn (disable-theme 'plastic)
|
|
(load-theme 'leuven))
|
|
(progn
|
|
(disable-theme 'leuven)
|
|
(load-theme 'plastic)))))
|
|
|
|
(bind-key "C-c t" 'my/toggle-theme)
|
|
|
|
(when *sys/windows*
|
|
(mapcar #'disable-theme custom-enabled-themes)
|
|
(load-theme 'tango))
|
|
(when *sys/linux*
|
|
(mapcar #'disable-theme custom-enabled-themes)
|
|
(load-theme 'plastic))
|
|
|
|
(global-visual-line-mode)
|
|
;(diminish 'visual-line-mode)
|
|
(use-package adaptive-wrap
|
|
:ensure t
|
|
:hook
|
|
(visual-line-mode . adaptive-wrap-prefix-mode))
|
|
; :init
|
|
; (when (fboundp 'adaptive-wrap-prefix-mode)
|
|
; (defun me/activate-adaptive-wrap-prefix-mode ()
|
|
; "Toggle `visual-line-mode' and `adaptive-wrap-prefix-mode' simultaneously."
|
|
; (adaptive-wrap-prefix-mode (if visual-line-mode 1 -1)))
|
|
; (add-hook 'visual-line-mode-hook 'me/activate-adaptive-wrap-prefix-mode)))
|
|
|
|
(use-package display-line-numbers
|
|
:ensure nil
|
|
:init
|
|
:hook
|
|
((prog-mode
|
|
org-src-mode) . display-line-numbers-mode)
|
|
:config
|
|
(setq-default display-line-numbers-type 'visual
|
|
display-line-numbers-current-absolute t
|
|
display-line-numbers-with 4
|
|
display-line-numbers-widen t))
|
|
|
|
(use-package rainbow-mode
|
|
:ensure t
|
|
:diminish
|
|
:hook
|
|
((org-mode
|
|
emacs-lisp-mode) . rainbow-mode))
|
|
|
|
(use-package delight
|
|
:if *sys/linux*
|
|
:ensure t)
|
|
|
|
(show-paren-mode t) ;; show other part of brackets
|
|
(setq blink-matching-paren nil) ;; not necessary with show-paren-mode, bugs out on C-s counsel-line
|
|
(use-package rainbow-delimiters
|
|
:ensure t
|
|
:hook
|
|
(prog-mode . rainbow-delimiters-mode))
|
|
|
|
(use-package dired
|
|
:ensure nil
|
|
:custom
|
|
(dired-kill-when-opening-new-dired-buffer t))
|
|
|
|
(use-package bookmark
|
|
:ensure nil
|
|
:custom
|
|
(bookmark-default-file (concat MY--PATH_USER_LOCAL "bookmarks")))
|
|
|
|
;;do I really want this?
|
|
(use-package bookmark+
|
|
:ensure (:host github :repo "emacsmirror/bookmark-plus"))
|
|
|
|
(when *sys/windows*
|
|
(remove-hook 'find-file-hook 'vc-refresh-state)
|
|
; (progn
|
|
; (setq gc-cons-threshold (* 511 1024 1024)
|
|
; gc-cons-percentage 0.5
|
|
; garbage-collection-messages t
|
|
|
|
; (run-with-idle-timer 5 t #'garbage-collect))
|
|
(when (boundp 'w32-pipe-read-delay)
|
|
(setq w32-pipe-read-delay 0))
|
|
(when (boundp 'w32-get-true-file-attributes)
|
|
(setq w32-get-true-file-attributes nil)))
|
|
|
|
(use-package burly
|
|
:ensure t
|
|
:config
|
|
(burly-tabs-mode) ;;open a burly window bookbark in a new tab
|
|
)
|
|
|
|
(use-package recentf
|
|
:ensure nil
|
|
; :defer 1
|
|
:config
|
|
(recentf-mode)
|
|
:custom
|
|
(recentf-exclude '(".*-autoloads\\.el\\'"
|
|
"[/\\]\\elpa/"
|
|
"COMMIT_EDITMSG\\'"))
|
|
(recentf-save-file (concat MY--PATH_USER_LOCAL "recentf"))
|
|
(recentf-max-menu-items 600)
|
|
(recentf-max-saved-items 600))
|
|
|
|
(use-package savehist
|
|
:ensure nil
|
|
:config
|
|
(savehist-mode)
|
|
:custom
|
|
(savehist-file (concat MY--PATH_USER_LOCAL "history")))
|
|
|
|
(use-package undo-tree
|
|
:ensure t
|
|
:diminish undo-tree-mode
|
|
:init
|
|
(global-undo-tree-mode 1)
|
|
:custom
|
|
(undo-tree-auto-save-history nil))
|
|
|
|
(use-package which-key
|
|
:ensure t
|
|
:diminish which-key-mode
|
|
:custom
|
|
(which-key-idle-delay 0.5)
|
|
(which-key-sort-order 'which-key-description-order)
|
|
:config
|
|
(which-key-mode)
|
|
(which-key-setup-side-window-bottom))
|
|
|
|
(use-package abbrev
|
|
:ensure nil
|
|
:diminish abbrev-mode
|
|
:hook
|
|
((text-mode org-mode) . abbrev-mode)
|
|
:init
|
|
(setq abbrev-file-name (concat MY--PATH_USER_GLOBAL "abbrev_tables.el"))
|
|
:config
|
|
(if (file-exists-p abbrev-file-name)
|
|
(quietly-read-abbrev-file))
|
|
(setq save-abbrevs 'silently)) ;; don't bother me with asking for abbrev saving
|
|
|
|
(use-package imenu-list
|
|
:ensure t
|
|
:demand t ; otherwise mode loads too late and won't work on first file it's being activated on
|
|
:config
|
|
(setq imenu-list-focus-after-activation t
|
|
imenu-list-auto-resize t
|
|
imenu-list-position 'right)
|
|
:general
|
|
([f9] 'imenu-list-smart-toggle)
|
|
(:states '(normal insert)
|
|
:keymaps 'imenu-list-major-mode-map
|
|
"RET" '(imenu-list-goto-entry :which-key "goto")
|
|
"TAB" '(hs-toggle-hiding :which-key "collapse")
|
|
"v" '(imenu-list-display-entry :which-key "show") ; also prevents visual mode
|
|
"q" '(imenu-list-quit-window :which-key "quit"))
|
|
:custom
|
|
(org-imenu-depth 4))
|
|
|
|
(use-package eldoc
|
|
:ensure nil
|
|
:diminish eldoc-mode
|
|
:defer t)
|
|
|
|
(use-package meow
|
|
:ensure t
|
|
:config
|
|
(setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
|
|
(meow-motion-overwrite-define-key
|
|
'("j" . meow-next)
|
|
'("k" . meow-prev)
|
|
'("<escape>" . ignore))
|
|
(meow-leader-define-key
|
|
;; SPC j/k will run the original command in MOTION state.
|
|
'("j" . "H-j")
|
|
'("k" . "H-k")
|
|
;; Use SPC (0-9) for digit arguments.
|
|
'("1" . meow-digit-argument)
|
|
'("2" . meow-digit-argument)
|
|
'("3" . meow-digit-argument)
|
|
'("4" . meow-digit-argument)
|
|
'("5" . meow-digit-argument)
|
|
'("6" . meow-digit-argument)
|
|
'("7" . meow-digit-argument)
|
|
'("8" . meow-digit-argument)
|
|
'("9" . meow-digit-argument)
|
|
'("0" . meow-digit-argument)
|
|
'("/" . meow-keypad-describe-key)
|
|
'("?" . meow-cheatsheet))
|
|
(meow-normal-define-key
|
|
'("0" . meow-expand-0)
|
|
'("9" . meow-expand-9)
|
|
'("8" . meow-expand-8)
|
|
'("7" . meow-expand-7)
|
|
'("6" . meow-expand-6)
|
|
'("5" . meow-expand-5)
|
|
'("4" . meow-expand-4)
|
|
'("3" . meow-expand-3)
|
|
'("2" . meow-expand-2)
|
|
'("1" . meow-expand-1)
|
|
'("-" . negative-argument)
|
|
'(";" . meow-reverse)
|
|
'("," . meow-inner-of-thing)
|
|
'("." . meow-bounds-of-thing)
|
|
'("[" . meow-beginning-of-thing)
|
|
'("]" . meow-end-of-thing)
|
|
'("a" . meow-append)
|
|
'("A" . meow-open-below)
|
|
'("b" . meow-back-word)
|
|
'("B" . meow-back-symbol)
|
|
'("c" . meow-change)
|
|
'("d" . meow-delete)
|
|
'("D" . meow-backward-delete)
|
|
'("e" . meow-next-word)
|
|
'("E" . meow-next-symbol)
|
|
'("f" . meow-find)
|
|
'("g" . meow-cancel-selection)
|
|
'("G" . meow-grab)
|
|
'("h" . meow-left)
|
|
'("H" . meow-left-expand)
|
|
'("i" . meow-insert)
|
|
'("I" . meow-open-above)
|
|
'("j" . meow-next)
|
|
'("J" . meow-next-expand)
|
|
'("k" . meow-prev)
|
|
'("K" . meow-prev-expand)
|
|
'("l" . meow-right)
|
|
'("L" . meow-right-expand)
|
|
'("m" . meow-join)
|
|
'("n" . meow-search)
|
|
'("o" . meow-block)
|
|
'("O" . meow-to-block)
|
|
'("p" . meow-yank)
|
|
'("q" . meow-quit)
|
|
'("Q" . meow-goto-line)
|
|
'("r" . meow-replace)
|
|
'("R" . meow-swap-grab)
|
|
'("s" . meow-kill)
|
|
'("t" . meow-till)
|
|
'("u" . meow-undo)
|
|
'("U" . meow-undo-in-selection)
|
|
'("v" . meow-visit)
|
|
'("w" . meow-mark-word)
|
|
'("W" . meow-mark-symbol)
|
|
'("x" . meow-line)
|
|
'("X" . meow-goto-line)
|
|
'("y" . meow-save)
|
|
'("Y" . meow-sync-grab)
|
|
'("z" . meow-pop-selection)
|
|
'("'" . repeat)
|
|
'("<escape>" . ignore))
|
|
; :config
|
|
(meow-global-mode t))
|
|
|
|
(use-package avy
|
|
:ensure t
|
|
:general
|
|
(:prefix "M-s"
|
|
"" '(:ignore t :which-key "avy")
|
|
"w" '(avy-goto-char-2 :which-key "avy-jump")
|
|
"s" '(avy-goto-char-timer :which-key "avy-timer")
|
|
"c" '(:ignore t :which-key "avy copy")
|
|
"c l" '(avy-copy-line :which-key "avy copy line")
|
|
"c r" '(avy-copy-region :which-key "avy copy region")
|
|
"m" '(:ignore t :which-key "avy move")
|
|
"m l" '(avy-move-line :which-key "avy move line")
|
|
"m r" '(avy-move-region :which-key "avy move region")))
|
|
|
|
;; completion ui
|
|
(use-package vertico
|
|
:ensure t
|
|
:init
|
|
(vertico-mode))
|
|
|
|
(use-package corfu
|
|
:ensure t
|
|
:after savehist
|
|
:custom
|
|
(corfu-popupinfo-delay t)
|
|
(corfu-auto t)
|
|
(corfu-cycle t)
|
|
(corfu-auto-delay 0.3)
|
|
(corfu-preselect-first nil)
|
|
(corfu-popupinfo-delay '(1.0 . 0.0)) ;1s for first popup, instant for subsequent popups
|
|
(corfu-popupinfo-max-width 70)
|
|
(corfu-popupinfo-max-height 20)
|
|
:init
|
|
(global-corfu-mode)
|
|
; (corfu-popupinfo-mode) ; causes corfu window to stay
|
|
(corfu-history-mode)
|
|
;; belongs to emacs
|
|
(add-to-list 'savehist-additional-variables 'corfu-history)
|
|
:hook
|
|
(corfu-mode . corfu-popupinfo-mode))
|
|
; :bind
|
|
; (:map corfu-map
|
|
; ("TAB" . corfu-next)
|
|
; ("<C-return>" . corfu-insert)
|
|
; ("C-TAB" . corfu-popupinfo-toggle)))
|
|
|
|
;; (general-define-key
|
|
;; :states 'insert
|
|
;; :definer 'minor-mode
|
|
;; :keymaps 'completion-in-region-mode
|
|
;; :predicate 'corfu-mode
|
|
;; "C-d" 'corfu-info-documentation)
|
|
|
|
(use-package emacs
|
|
:ensure nil
|
|
:init
|
|
;; hide commands in M-x which do not apply to current mode
|
|
(setq read-extended-command-predicate #'command-completion-default-include-p)
|
|
;; enable indentation + completion using TAB
|
|
(setq tab-always-indent 'complete))
|
|
|
|
(use-package cape
|
|
:ensure t
|
|
:bind
|
|
(("C-c p p" . completion-at-point) ;; capf
|
|
("C-c p t" . complete-tag) ;; etags
|
|
("C-c p d" . cape-dabbrev)
|
|
("C-c p h" . cape-history)
|
|
("C-c p f" . cape-file))
|
|
:init
|
|
(advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible) ;; for performance issues with lsp
|
|
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
|
|
(add-to-list 'completion-at-point-functions #'cape-file)
|
|
(add-to-list 'completion-at-point-functions #'cape-history))
|
|
|
|
(use-package kind-icon
|
|
:ensure t
|
|
:after corfu
|
|
:custom
|
|
(kind-icon-default-face 'corfu-default) ;; to compute blended backgrounds correctly
|
|
:config
|
|
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
|
|
|
|
(use-package orderless
|
|
:ensure t
|
|
:init
|
|
(setq completion-styles '(orderless partial-completion basic)
|
|
completion-category-defaults nil
|
|
completion-category-overrides nil))
|
|
; completion-category-overrides '((file (styles partial-completion)))))
|
|
|
|
(use-package consult
|
|
:ensure t
|
|
:bind
|
|
(("C-x C-r" . consult-recent-file)
|
|
("C-x b" . consult-buffer)
|
|
("C-s" . consult-line)
|
|
("C-x r b" . consult-bookmark)) ;replace bookmark-jump
|
|
:config
|
|
;; disable preview for some commands and buffers
|
|
;; and enable it by M-.
|
|
;; see https://github.com/minad/consult#use-package-example
|
|
(consult-customize
|
|
consult-theme :preview-key '(debounce 0.2 any)
|
|
consult-ripgrep consult-git-grep consult-grep
|
|
consult-bookmark consult-recent-file consult-xref
|
|
consult--source-bookmark consult--source-file-register
|
|
consult--source-recent-file consult--source-project-recent-file
|
|
:preview-key '(:debounce 0.2 any)))
|
|
|
|
(use-package marginalia
|
|
:ensure t
|
|
:init
|
|
(marginalia-mode)
|
|
:bind
|
|
(:map minibuffer-local-map
|
|
("M-A" . marginalia-cycle))
|
|
:custom
|
|
;; switch by 'marginalia-cycle
|
|
(marginalia-annotators '(marginalia-annotators-heavy
|
|
marginalia-annotators-light
|
|
nil)))
|
|
|
|
(use-package embark
|
|
:ensure t
|
|
:bind
|
|
(("C-S-a" . embark-act)
|
|
("C-h B" . embark-bindings))
|
|
:init
|
|
(setq prefix-help-command #'embark-prefix-help-command)
|
|
:config
|
|
;; hide modeline of the embark live/completions buffers
|
|
(add-to-list 'display-buffer-alist
|
|
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
|
|
nil
|
|
(window-parameters (mode-line-format . none)))))
|
|
|
|
(use-package embark-consult
|
|
:ensure t
|
|
:after (embark consult)
|
|
:demand t
|
|
:hook
|
|
(embark-collect-mode . embark-consult-preview-minor-mode))
|
|
|
|
(when *sys/linux*
|
|
(use-package tree-sitter
|
|
:ensure t
|
|
:init
|
|
(global-tree-sitter-mode t)
|
|
:hook
|
|
(tree-sitter-after-on . tree-sitter-hl-mode))
|
|
|
|
(use-package tree-sitter-langs
|
|
:ensure t
|
|
:after tree-sitter)
|
|
)
|
|
|
|
(use-package org-ql
|
|
:ensure t
|
|
)
|
|
|
|
;(use-package notmuch
|
|
; :ensure t)
|
|
(use-feature mu4e
|
|
:if *sys/linux*
|
|
; :ensure nil
|
|
:after (org)
|
|
:init
|
|
(require 'mu4e)
|
|
:config
|
|
;; this is set to 't' to avoid mail syncing issues when using mbsync
|
|
(setq mu4e-change-filenames-when-moving t)
|
|
(setq smtpmail-servers-requiring-authorization ".*")
|
|
(setq mu4e-update-interval (* 10 60))
|
|
(setq mu4e-get-mail-command "mbsync -a")
|
|
(setq mu4e-maildir "/mnt/archiv/Dokumente/email")
|
|
(setq mu4e-headers-fields
|
|
'((:human-date . 12)
|
|
(:flags . 6)
|
|
(:from . 22)
|
|
(:to . 25)
|
|
(:subject)))
|
|
|
|
(setq mu4e-contexts
|
|
`( ,(make-mu4e-context
|
|
:name "mail.de"
|
|
:enter-func (lambda () (mu4e-message "switch to mail.de context"))
|
|
:match-func (lambda (msg)
|
|
(when msg
|
|
(string-match-p "^/mailde" (mu4e-message-field msg :maildir))))
|
|
:vars '((user-mail-address . "marc.pohling@mail.de")
|
|
(user-full-name . "Marc Pohling")
|
|
(message-send-mail-function . smtpmail-send-it)
|
|
(smtpmail-smtp-user . "marc.pohling@mail.de")
|
|
(smtpmail-smtp-server . "smtp.mail.de")
|
|
(smtpmail-smtp-service . 587)
|
|
(smtpmail-stream-type . starttls)
|
|
(mu4e-drafts-folder . "/mailde/drafts")
|
|
(mu4e-sent-folder . "/mailde/sent")
|
|
(mu4e-refile-folder . "/mailde/archive")
|
|
(mu4e-trash-folder . "/mailde/trash")))
|
|
,(make-mu4e-context
|
|
:name "web.de"
|
|
:enter-func (lambda () (mu4e-message "switch to web.de context"))
|
|
:match-func (lambda (msg)
|
|
(when msg
|
|
(string-match-p "^/mailde" (mu4e-message-field msg :maildir))))
|
|
:vars '((user-mail-address . "marc.pohling@web.de")
|
|
(user-full-name . "Marc Pohling")
|
|
(mu4e-drafts-folder . "/webde/drafts")
|
|
(mu4e-sent-folder . "/webde/sent")
|
|
(mu4e-refile-folder . "/webde/archive")
|
|
(mu4e-trash-folder . "/webde/trash")))
|
|
,(make-mu4e-context
|
|
:name "gmail loui"
|
|
:enter-func (lambda () (mu4e-message "switch to gmail loui context"))
|
|
:match-func (lambda (msg)
|
|
(when msg
|
|
(string-match-p "^/gmailloui" (mu4e-message-field msg :maildir))))
|
|
:vars '((user-mail-address . "louithelou1@gmail.com")
|
|
(user-full-name . "Loui")
|
|
(message-send-mail-function . smtpmail-send-it)
|
|
(smtpmail-smtp-user . "louithelou1@gmail.com")
|
|
(smtpmail-smtp-server . "smtp.gmail.com")
|
|
(smtpmail-smtp-service . 587)
|
|
(smtpmail-stream-type . starttls)
|
|
(mu4e-drafts-folder . "/gmailloui/drafts")
|
|
(mu4e-sent-folder . "/gmailloui/sent")
|
|
(mu4e-refile-folder . "/gmailloui/archive")
|
|
(mu4e-trash-folder . "/gmailloui/trash")))))
|
|
)
|
|
|
|
(push 'mu4e elpaca-ignored-dependencies)
|
|
|
|
(use-package mu4e-dashboard
|
|
:if *sys/linux*
|
|
:ensure (:host github :repo "rougier/mu4e-dashboard")
|
|
:after mu4e
|
|
:hook
|
|
(mu4e-dashboard-mode . (lambda () (display-line-numbers-mode -1)))
|
|
:custom
|
|
(mu4e-dashboard-file (concat MY--PATH_USER_GLOBAL "mu4e-dashboard.org"))
|
|
:config
|
|
; (require 'mu4e)
|
|
(defun mu4e-dashboard-edit ()
|
|
(interactive)
|
|
(let ((edit-buffer "*edit-mu4e-dashboard*"))
|
|
(when (get-buffer edit-buffer)
|
|
(kill-buffer (get-buffer edit-buffer)))
|
|
(make-indirect-buffer (current-buffer) edit-buffer)
|
|
(switch-to-buffer-other-window (get-buffer edit-buffer))
|
|
(org-mode 1)))
|
|
(display-line-numbers-mode -1)
|
|
(flyspell-mode -1))
|
|
|
|
;(org-add-link-type "outlook" 'my--org-outlook-open)
|
|
;(org-add-link-type "outlooknewmail" 'my--org-outlook-new-mail)
|
|
|
|
(defun my--org-outlook-open (id)
|
|
(w32-shell-execute "open" "outlook" (concat " /select outlook:" id)))
|
|
|
|
(defun my--org-outlook-new-mail (receipients)
|
|
; separate RECEIPIENTS for main, cc and bcc by |
|
|
(setq recp (split-string receipients "|"))
|
|
(setq mailstring (concat " /c ipm.note /m " (nth 0 recp)))
|
|
(if (nth 1 recp)
|
|
; this check has tp be separated because (and..) would stumble over a nil
|
|
(if (not (equal "" (nth 1 recp)))
|
|
(setq mailstring (concat mailstring "&cc=" (nth 1 recp)))))
|
|
(if (nth 2 recp)
|
|
(setq mailstring (concat mailstring "&bcc=" (nth 2 recp))))
|
|
(w32-shell-execute "open" "outlook" mailstring))
|
|
|
|
(defun my/org-outlook-open-test ()
|
|
(interactive)
|
|
(w32-shell-execute "open" "outlook" " /select outlook:000000008A209C397CEF2C4FBA9E54AEB5B1F97F0700846D043B407C5B43A0C05AFC46DC5C630587BE5E020900006E48FF8F6027694BA6593777F542C19E0002A6434D000000"))'
|
|
|
|
(use-package autorevert
|
|
:diminish auto-revert-mode)
|
|
|
|
;(assq-delete-all 'org package--builtins)'
|
|
;(assq-delete-all 'org package--builtin-versions)
|
|
|
|
(defun my--buffer-prop-set (name value)
|
|
"Set a file property called NAME to VALUE in buffer file.
|
|
If the property is already set, replace its value."
|
|
(setq name (downcase name))
|
|
(org-with-point-at 1
|
|
(let ((case-fold-search t))
|
|
(if (re-search-forward (concat "^#\\+" name ":\\(.*\\)")
|
|
(point-max) t)
|
|
(replace-match (concat "#+" name ": " value) 'fixedcase)
|
|
(while (and (not (eobp))
|
|
(looking-at "^[#:]"))
|
|
(if (save-excursion (end-of-line) (eobp))
|
|
(progn
|
|
(end-of-line)
|
|
(insert "\n"))
|
|
(forward-line)
|
|
(beginning-of-line)))
|
|
(insert "#+" name ": " value "\n")))))
|
|
|
|
(defun my--buffer-prop-remove (name)
|
|
"Remove a buffer property called NAME."
|
|
(org-with-point-at 1
|
|
(when (re-search-forward (concat "\\(^#\\+" name ":.*\n?\\)")
|
|
(point-max) t)
|
|
(replace-match ""))))
|
|
|
|
(use-package org
|
|
:ensure t
|
|
; :pin gnu
|
|
:mode (("\.org$" . org-mode))
|
|
:diminish org-indent-mode
|
|
:defer 1
|
|
:hook
|
|
(org-mode . org-indent-mode)
|
|
(org-source-mode . smartparens-mode)
|
|
:bind (("C-c l" . org-store-link)
|
|
("C-c c" . org-capture)
|
|
("C-c a" . org-agenda)
|
|
:map org-mode-map ("S-<right>" . org-shiftright)
|
|
("S-<left>" . org-shiftleft))
|
|
:init
|
|
(defun my--org-agenda-files-set ()
|
|
"Sets default agenda files.
|
|
Necessary when updating roam agenda todos."
|
|
(setq org-agenda-files (list (concat MY--PATH_ORG_FILES "notes.org")
|
|
(concat MY--PATH_ORG_FILES "projects.org")
|
|
(concat MY--PATH_ORG_FILES "tasks.org")))
|
|
(when *sys/linux*
|
|
(nconc org-agenda-files
|
|
(directory-files-recursively MY--PATH_ORG_FILES_MOBILE "\\.org$"))))
|
|
(my--org-agenda-files-set)
|
|
|
|
(defun my--org-skip-subtree-if-priority (priority)
|
|
"Skip an agenda subtree if it has a priority of PRIORITY.
|
|
|
|
PRIORITY may be one of the characters ?A, ?B, or ?C."
|
|
(let ((subtree-end (save-excursion (org-end-of-subtree t)))
|
|
(pri-value (* 1000 (- org-lowest-priority priority)))
|
|
(pri-current (org-get-priority (thing-at-point 'line t))))
|
|
(if (= pri-value pri-current)
|
|
subtree-end
|
|
nil)))
|
|
:config
|
|
(when *work_remote*
|
|
(org-add-link-type "outlook" 'my--org-outlook-open)
|
|
(org-add-link-type "outlooknewmail" 'my--org-outlook-new-mail)
|
|
(setq org-todo-keywords
|
|
'((sequence "OPEN" "TODO" "UNCLEAR" "|" "DONE" "IMPOSSIBLE" "CANCELLED")))
|
|
(setq org-capture-templates
|
|
'(("t" "telephone call" entry
|
|
; (file+olp+datetree (concat MY--PATH_ORG_FILES "phone_calls.org"))
|
|
(file+datetree "p:/Eigene Dateien/Notizen/phone_calls.org")
|
|
"* [%<%Y-%m-%d %H:%M>] %?"
|
|
:empty-lines 0 :jump-to-captured t))))
|
|
(when *sys/linux*
|
|
(setq org-pretty-entities t))
|
|
:custom
|
|
(org-startup-truncated t)
|
|
(org-startup-align-all-tables t)
|
|
(org-src-fontify-natively t) ;; use syntax highlighting in code blocks
|
|
(org-src-preserve-indentation t) ;; no extra indentation
|
|
(org-src-window-setup 'current-window) ;; C-c ' opens in current window
|
|
(org-modules (quote (org-id
|
|
org-habit
|
|
org-tempo))) ;; easy templates
|
|
(org-default-notes-file (concat MY--PATH_ORG_FILES "notes.org"))
|
|
(org-id-locations-file (concat MY--PATH_USER_LOCAL ".org-id-locations"))
|
|
(org-log-into-drawer "LOGBOOK")
|
|
(org-log-done 'time) ;; create timestamp when task is done
|
|
(org-blank-before-new-entry '((heading) (plain-list-item))) ;; prevent new line before new item
|
|
(org-src-tab-acts-natively t)
|
|
;;Sort agenda by deadline and priority
|
|
(org-agenda-sorting-strategy
|
|
(quote
|
|
((agenda deadline-up priority-down)
|
|
(todo priority-down category-keep)
|
|
(tags priority-down category-keep)
|
|
(search category-keep))))
|
|
(org-agenda-custom-commands
|
|
'(("c" "Simple agenda view"
|
|
((tags "PRIORITY=\"A\""
|
|
((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
|
|
(org-agenda-overriding-header "Hohe Priorität:")))
|
|
(agenda ""
|
|
((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
|
|
(org-agenda-span 7)
|
|
(org-agenda-start-on-weekday nil)
|
|
(org-agenda-overriding-header "Nächste 7 Tage:")))
|
|
(alltodo ""
|
|
((org-agenda-skip-function '(or (my--org-skip-subtree-if-priority ?A)
|
|
(org-agenda-skip-if nil '(scheduled deadline))))
|
|
(org-agenda-overriding-header "Sonstige Aufgaben:"))))))))
|
|
|
|
(use-package org-contacts
|
|
:ensure (:host nil :repo "https://repo.or.cz/org-contacts.git")
|
|
:after org
|
|
:custom
|
|
(org-contacts-files (list (concat MY--PATH_ORG_ROAM "contacts.org"))))
|
|
|
|
(use-package emacsql-sqlite-builtin
|
|
:ensure t)
|
|
|
|
(use-package org-roam
|
|
:requires emacsql-sqlite-builtin
|
|
:ensure t
|
|
:defer 2
|
|
:after org
|
|
:init
|
|
(setq org-roam-v2-ack t)
|
|
|
|
(defun my--roamtodo-p ()
|
|
"Return non-nil if current buffer has any todo entry.
|
|
|
|
TODO entries marked as done are ignored, meaning this function
|
|
returns nil if current buffer contains only completed tasks."
|
|
(seq-find
|
|
(lambda (type)
|
|
(eq type 'todo))
|
|
(org-element-map
|
|
(org-element-parse-buffer 'headline)
|
|
'headline
|
|
(lambda (h)
|
|
(org-element-property :todo-type h)))))
|
|
|
|
(defun my--roamtodo-update-tag ()
|
|
"Update ROAMTODO tag in the current buffer."
|
|
(when (and (not (active-minibuffer-window))
|
|
(my--buffer-roam-note-p))
|
|
(save-excursion
|
|
(goto-char (point-min))
|
|
(let* ((tags (my--buffer-tags-get))
|
|
(original-tags tags))
|
|
(if (my--roamtodo-p)
|
|
(setq tags (cons "roamtodo" tags))
|
|
(setq tags (remove "roamtodo" tags)))
|
|
|
|
;;cleanup duplicates
|
|
(when (or (seq-difference tags original-tags)
|
|
(seq-difference original-tags tags))
|
|
(apply #'my--buffer-tags-set tags))))))
|
|
|
|
(defun my--buffer-tags-get ()
|
|
"Return filetags value in current buffer."
|
|
(my--buffer-prop-get-list "filetags" "[ :]"))
|
|
|
|
(defun my--buffer-tags-set (&rest tags)
|
|
"Set TAGS in current buffer.
|
|
If filetags value is already set, replace it."
|
|
(if tags
|
|
(my--buffer-prop-set
|
|
"filetags" (concat ":" (string-join tags ":") ":"))
|
|
(my--buffer-prop-remove "filetags")))
|
|
|
|
(defun my--buffer-tags-add (tag)
|
|
"Add a TAG to filetags in current buffer."
|
|
(let* ((tags (my--buffer-tags-get))
|
|
(tags (append tags (list tag))))
|
|
(apply #'my--buffer-tags-set tags)))
|
|
|
|
(defun my--buffer-tags-remove (tag)
|
|
"Remove a TAG from filetags in current buffer."
|
|
(let* ((tags (my--buffer-tags-get))
|
|
(tags (delete tag tags)))
|
|
(apply #'my--buffer-tags-set tags)))
|
|
|
|
(defun my--buffer-prop-set (name value)
|
|
"Set a file property called NAME to VALUE in buffer file.
|
|
If the property is already set, replace its value."
|
|
(setq name (downcase name))
|
|
(org-with-point-at 1
|
|
(let ((case-fold-search t))
|
|
(if (re-search-forward (concat "^#\\+" name ":\\(.*\\)")
|
|
(point-max) t)
|
|
(replace-match (concat "#+" name ": " value) 'fixedcase)
|
|
(while (and (not (eobp))
|
|
(looking-at "^[#:]"))
|
|
(if (save-excursion (end-of-line) (eobp))
|
|
(progn
|
|
(end-of-line)
|
|
(insert "\n"))
|
|
(forward-line)
|
|
(beginning-of-line)))
|
|
(insert "#+" name ": " value "\n")))))
|
|
|
|
(defun my--buffer-prop-set-list (name values &optional separators)
|
|
"Set a file property called NAME to VALUES in current buffer.
|
|
VALUES are quoted and combined into single string using
|
|
`combine-and-quote-strings'.
|
|
If SEPARATORS is non-nil, it should be a regular expression
|
|
matching text that separates, but is not part of, the substrings.
|
|
If nil it defaults to `split-string-and-unquote', normally
|
|
\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t.
|
|
If the property is already set, replace its value."
|
|
(my--buffer-prop-set
|
|
name (combine-and-quote-strings values separators)))
|
|
|
|
(defun my--buffer-prop-get (name)
|
|
"Get a buffer property called NAME as a string."
|
|
(org-with-point-at 1
|
|
(when (re-search-forward (concat "^#\\+" name ": \\(.*\\)")
|
|
(point-max) t)
|
|
(buffer-substring-no-properties
|
|
(match-beginning 1)
|
|
(match-end 1)))))
|
|
|
|
(defun my--buffer-prop-get-list (name &optional separators)
|
|
"Get a buffer property NAME as a list using SEPARATORS.
|
|
If SEPARATORS is non-nil, it should be a regular expression
|
|
matching text that separates, but is not part of, the substrings.
|
|
If nil it defaults to `split-string-default-separators', normally
|
|
\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t."
|
|
(let ((value (my--buffer-prop-get name)))
|
|
(when (and value (not (string-empty-p value)))
|
|
(split-string-and-unquote value separators))))
|
|
|
|
(defun my--buffer-prop-remove (name)
|
|
"Remove a buffer property called NAME."
|
|
(org-with-point-at 1
|
|
(when (re-search-forward (concat "\\(^#\\+" name ":.*\n?\\)")
|
|
(point-max) t)
|
|
(replace-match ""))))
|
|
|
|
(defun my--buffer-roam-note-p ()
|
|
"Return non-nil if the currently visited buffer is a note."
|
|
(and buffer-file-name
|
|
(string-prefix-p
|
|
(expand-file-name (file-name-as-directory MY--PATH_ORG_ROAM))
|
|
(file-name-directory buffer-file-name))))
|
|
|
|
(defun my--org-roam-filter-by-tag (tag-name)
|
|
(lambda (node)
|
|
(member tag-name (org-roam-node-tags node))))
|
|
|
|
(defun my--org-roam-list-notes-by-tag (tag-name)
|
|
(mapcar #'org-roam-node-file
|
|
(seq-filter
|
|
(my--org-roam-filter-by-tag tag-name)
|
|
(org-roam-node-list))))
|
|
|
|
(defun my/org-roam-refresh-agenda-list ()
|
|
"Add all org roam files with #+filetags: roamtodo"
|
|
(interactive)
|
|
(my--org-agenda-files-set)
|
|
(nconc org-agenda-files
|
|
(my--org-roam-list-notes-by-tag "roamtodo"))
|
|
(setq org-agenda-files (delete-dups org-agenda-files)))
|
|
|
|
(add-hook 'find-file-hook #'my--roamtodo-update-tag)
|
|
(add-hook 'before-save-hook #'my--roamtodo-update-tag)
|
|
|
|
(advice-add 'org-agenda :before #'my/org-roam-refresh-agenda-list)
|
|
(advice-add 'org-todo-list :before #'my/org-roam-refresh-agenda-list)
|
|
|
|
(add-to-list 'org-tags-exclude-from-inheritance "roamtodo")
|
|
:config
|
|
(require 'org-roam-dailies) ;; ensure the keymap is available
|
|
(org-roam-db-autosync-mode)
|
|
;; build the agenda list the first ime for the session
|
|
(my/org-roam-refresh-agenda-list)
|
|
|
|
(when *work_remote*
|
|
(setq org-roam-capture-templates
|
|
'(("n" "note" plain
|
|
"%?"
|
|
:if-new (file+head "notes/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
|
|
:unnarrowed t)
|
|
("i" "idea" plain
|
|
"%?"
|
|
:if-new (file+head "ideas/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
|
|
:unnarrowed t)
|
|
("p" "project" plain
|
|
"%?"
|
|
:target (file+head "projects/${slug}.org" "#+title: ${title}\n#+filetags: :project:\n")
|
|
:unnarrowed t)
|
|
("s" "Sicherheitenmeldung" plain
|
|
"*** TODO [#A] Sicherheitenmeldung ${title}\n :PROPERTIES:\n :ID: %(org-id-uuid)\n:END:\n%u\n"
|
|
:target (file+olp "tasks.org" ("Todos" "Sicherheitenmeldungen")))
|
|
("m" "Monatsbericht" plain
|
|
"*** TODO [#A] Monatsbericht ${title}\n :PROPERTIES:\n :ID: %(org-id-uuid)\n:END:\n%u\n"
|
|
:target (file+olp "tasks.org" ("Todos" "Monatsberichte"))))))
|
|
:custom
|
|
(org-roam-database-connector 'sqlite-builtin)
|
|
(org-roam-directory MY--PATH_ORG_ROAM)
|
|
(org-roam-completion-everywhere t)
|
|
(org-roam-capture-templates
|
|
'(("n" "note" plain
|
|
"%?"
|
|
:if-new (file+head "notes/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
|
|
:unnarrowed t)
|
|
("i" "idea" plain
|
|
"%?"
|
|
:if-new (file+head "ideas/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
|
|
:unnarrowed t)
|
|
))
|
|
:bind (("C-c n l" . org-roam-buffer-toggle)
|
|
("C-c n f" . org-roam-node-find)
|
|
("C-c n i" . org-roam-node-insert)
|
|
:map org-mode-map
|
|
("C-M-i" . completion-at-point)
|
|
:map org-roam-dailies-map
|
|
("Y" . org-roam-dailies-capture-yesterday)
|
|
("T" . org-roam-dailies-capture-tomorrow))
|
|
:bind-keymap
|
|
("C-c n d" . org-roam-dailies-map))
|
|
|
|
;; updated version needed for magit, at least on windows
|
|
(use-package transient
|
|
:ensure t)
|
|
|
|
(use-package magit
|
|
:ensure t
|
|
; :pin melpa-stable
|
|
:defer t
|
|
:init
|
|
; set git-path in work environment
|
|
(if (string-equal user-login-name "POH")
|
|
(setq magit-git-executable "P:/Tools/Git/bin/git.exe")
|
|
)
|
|
:bind (("C-x g" . magit-status)))
|
|
|
|
(defun corfu-lsp-setup ()
|
|
(setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
|
|
'(orderless)))
|
|
|
|
(use-package lsp-mode
|
|
:ensure t
|
|
; :hook
|
|
; ((python-mode . lsp))
|
|
:custom
|
|
(lsp-completion-provider :none)
|
|
(lsp-enable-suggest-server-download nil)
|
|
:hook
|
|
(lsp-completion-mode #'corfu-lsp-setup))
|
|
|
|
;(use-package lsp-ui
|
|
; :ensure t
|
|
; :commands lsp-ui-mode)
|
|
|
|
(use-package lsp-pyright
|
|
:ensure t
|
|
:after (python lsp-mode)
|
|
:custom
|
|
(lsp-pyright-multi-root nil)
|
|
:hook
|
|
(python-mode-hook . (lambda ()
|
|
(require 'lsp-pyright) (lsp))))
|
|
|
|
(setq python-flymake-command '("ruff" "--quiet" "--stdin-filename=stdin" "-"))
|
|
|
|
(use-package sideline
|
|
:ensure t)
|
|
|
|
(use-package sideline-flymake
|
|
:ensure t
|
|
:requires sideline
|
|
:hook
|
|
(flymake-mode . sideline-mode)
|
|
:init
|
|
(setq sideline-flymake-display-mode 'line ; 'point or 'line
|
|
; sideline-backends-left '(sideline-lsp)
|
|
sideline-backends-right '(sideline-flymake)))
|
|
|
|
(use-package yasnippet
|
|
:ensure t
|
|
:defer t
|
|
:diminish yas-minor-mode
|
|
:config
|
|
(setq yas-snippet-dirs (list (concat MY--PATH_USER_GLOBAL "snippets")))
|
|
(yas-global-mode t)
|
|
(yas-reload-all)
|
|
(unbind-key "TAB" yas-minor-mode-map)
|
|
(unbind-key "<tab>" yas-minor-mode-map))
|
|
|
|
(use-package hippie-exp
|
|
:ensure nil
|
|
:defer t
|
|
:bind
|
|
("C-<return>" . hippie-expand)
|
|
:config
|
|
(setq hippie-expand-try-functions-list
|
|
'(yas-hippie-try-expand emmet-expand-line)))
|
|
|
|
(use-package smartparens
|
|
:ensure t
|
|
:diminish smartparens-mode
|
|
:bind
|
|
(:map smartparens-mode-map
|
|
("C-M-f" . sp-forward-sexp)
|
|
("C-M-b" . sp-backward-sexp)
|
|
("C-M-a" . sp-backward-down-sexp)
|
|
("C-M-e" . sp-up-sexp)
|
|
("C-M-w" . sp-copy-sexp)
|
|
("M-k" . sp-kill-sexp)
|
|
("C-M-<backspace>" . sp-slice-sexp-killing-backward)
|
|
("C-S-<backspace>" . sp-slice-sexp-killing-around)
|
|
("C-]" . sp-select-next-thing-exchange))
|
|
:config
|
|
(setq sp-show-pair-from-inside nil
|
|
sp-escape-quotes-after-insert nil)
|
|
(require 'smartparens-config))
|
|
|
|
(use-package elisp-mode
|
|
:ensure nil
|
|
:defer t)
|
|
|
|
(use-package web-mode
|
|
:ensure t
|
|
:defer t
|
|
:mode
|
|
("\\.phtml\\'"
|
|
"\\.tpl\\.php\\'"
|
|
"\\.djhtml\\'"
|
|
"\\.[t]?html?\\'")
|
|
:hook
|
|
(web-mode . smartparens-mode)
|
|
:init
|
|
(if *work_remote*
|
|
(setq exec-path (append exec-path '("P:/Tools/node"))))
|
|
:config
|
|
(setq web-mode-enable-auto-closing t
|
|
web-mode-enable-auto-pairing t))
|
|
|
|
(use-package emmet-mode
|
|
:ensure t
|
|
:defer t
|
|
:hook
|
|
((web-mode . emmet-mode)
|
|
(css-mode . emmet-mode))
|
|
:config
|
|
(unbind-key "C-<return>" emmet-mode-keymap))
|
|
|
|
(use-package rjsx-mode
|
|
:ensure t
|
|
:mode ("\\.js\\'"
|
|
"\\.jsx'"))
|
|
; :config
|
|
; (setq js2-mode-show-parse-errors nil
|
|
; js2-mode-show-strict-warnings nil
|
|
; js2-basic-offset 2
|
|
; js-indent-level 2)
|
|
; (setq-local flycheck-disabled-checkers (cl-union flycheck-disable-checkers
|
|
; '(javascript-jshint)))) ; jshint doesn"t work for JSX
|
|
|
|
(use-package tide
|
|
:ensure t
|
|
:after (rjsx-mode company flycheck)
|
|
; :hook (rjsx-mode . setup-tide-mode)
|
|
:config
|
|
(defun setup-tide-mode ()
|
|
"Setup function for tide."
|
|
(interactive)
|
|
(tide-setup)
|
|
(flycheck-mode t)
|
|
(setq flycheck-check-synta-automatically '(save mode-enabled))
|
|
(tide-hl-identifier-mode t)))
|
|
|
|
;; needs npm install -g prettier
|
|
(use-package prettier-js
|
|
:ensure t
|
|
:after (rjsx-mode)
|
|
:defer t
|
|
:diminish prettier-js-mode
|
|
:hook ((js2-mode rsjx-mode) . prettier-js-mode))
|
|
|
|
(use-package yaml-mode
|
|
:if *sys/linux*
|
|
:ensure t
|
|
:defer t
|
|
:mode ("\\.yml$" . yaml-mode))
|
|
|
|
(use-package ess
|
|
:ensure t
|
|
:defer t
|
|
:init
|
|
(if *work_remote*
|
|
(setq exec-path (append exec-path '("P:/Tools/R/bin/x64"))
|
|
org-babel-R-command "P:/Tools/R/bin/x64/R --slave --no-save")))
|
|
|
|
(use-package project
|
|
:custom
|
|
(project-vc-extra-root-markers '(".project.el" ".project" )))
|
|
|
|
(use-package python
|
|
:if *sys/linux*
|
|
:delight "π "
|
|
:defer t
|
|
:bind (("M-[" . python-nav-backward-block)
|
|
("M-]" . python-nav-forward-block))
|
|
:mode
|
|
(("\\.py\\'" . python-mode)))
|
|
|
|
(use-package pyvenv
|
|
; :if *sys/linux*
|
|
:ensure t
|
|
:defer t
|
|
:after python
|
|
:hook
|
|
(python-mode . pyvenv-mode)
|
|
:custom
|
|
(pyvenv-default-virtual-env-name ".env")
|
|
(pyvenv-mode-line-indicator '(pyvenv-virtual-env-name ("[venv:" pyvenv-virtual-env-name "]"))))
|
|
|
|
|
|
;; formatting to pep8
|
|
;; requires pip install black
|
|
;(use-package blacken
|
|
; :ensure t)
|
|
|
|
(use-package beancount
|
|
:ensure nil
|
|
:if *sys/linux*
|
|
:load-path "user-global/elisp/"
|
|
; :ensure t
|
|
:defer t
|
|
:mode
|
|
("\\.beancount$" . beancount-mode)
|
|
:hook
|
|
(beancount-mode . my/beancount-company)
|
|
:config
|
|
(defun my/beancount-company ()
|
|
(setq-local completion-at-point-functions #'beancount-completion-at-point))
|
|
(setq beancount-filename-main "/home/marc/Archiv/Finanzen/Transaktionen/transactions.beancount"))
|
|
|
|
;(setq gc-cons-threshold (* 2 1000 1000))
|