mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 09:07:21 +01:00
2516 lines
83 KiB
Org Mode
2516 lines
83 KiB
Org Mode
#+title: Emacs Configuration
|
||
#+PROPERTY: header-args:emacs-lisp :tangle programs/emacs/init.el :mkdirp yes
|
||
|
||
** TODO Agenda for this file [1/4]
|
||
- [ ] Content [0/2]
|
||
- [ ] Structure this file in a readable manner
|
||
- [ ] Add commentary to major sections
|
||
- [-] Language [1/2]
|
||
- [X] English across the entire file
|
||
- [ ] Stay in first person
|
||
- [X] Formatting [3/3]
|
||
- [X] One free line at start and end of each source block
|
||
- [X] Uniform indentation across file
|
||
- [X] One free line at the start and end of each header
|
||
- [ ] Finish all TODO blocks in this file
|
||
|
||
|
||
* Initialization
|
||
** Startup performance
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; The default is 800 kilobytes. Measured in bytes.
|
||
|
||
#+end_src
|
||
|
||
** Directory setup
|
||
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; use UTF-8 everywhere
|
||
(set-language-environment "UTF-8")
|
||
|
||
;; set default font size
|
||
(defvar swarsel/default-font-size 130)
|
||
(setq swarsel-standard-font "FiraCode Nerd Font Mono"
|
||
swarsel-alt-font "FiraCode Nerd Font Mono")
|
||
|
||
;; set Nextcloud directory for journals etc.
|
||
(setq swarsel-sync-directory "~/Nextcloud"
|
||
swarsel-emacs-directory "~/.emacs.d"
|
||
swarsel-dotfiles-directory "~/.dotfiles"
|
||
swarsel-projects-directory "~/Documents/GitHub")
|
||
|
||
(setq swarsel-emacs-org-filepath (expand-file-name "Emacs.org" swarsel-dotfiles-directory)
|
||
swarsel-nix-org-filepath (expand-file-name "Nix.org" swarsel-dotfiles-directory))
|
||
|
||
|
||
;; set Emacs main configuration .org names
|
||
(setq swarsel-emacs-org-file "Emacs.org"
|
||
swarsel-anki-org-file "Anki.org"
|
||
swarsel-tasks-org-file "Tasks.org"
|
||
swarsel-archive-org-file "Archive.org"
|
||
swarsel-org-folder-name "org"
|
||
swarsel-obsidian-daily-folder-name "⭐ Personal/Journal"
|
||
swarsel-obsidian-folder-name "Obsidian"
|
||
swarsel-obsidian-vault-name "Main")
|
||
|
||
|
||
;; set directory paths
|
||
(setq swarsel-org-directory (expand-file-name swarsel-org-folder-name swarsel-sync-directory)) ; path to org folder
|
||
(setq swarsel-obsidian-directory (expand-file-name swarsel-obsidian-folder-name swarsel-sync-directory)) ; path to obsidian
|
||
(setq swarsel-obsidian-vault-directory (expand-file-name swarsel-obsidian-vault-name swarsel-obsidian-directory)) ; path to obsidian vault
|
||
(setq swarsel-obsidian-daily-directory (expand-file-name swarsel-obsidian-daily-folder-name swarsel-obsidian-vault-directory)) ; path to obsidian daily folder
|
||
|
||
;; filepaths to certain documents
|
||
(setq swarsel-org-anki-filepath (expand-file-name swarsel-anki-org-file swarsel-org-directory) ; path to anki export file
|
||
swarsel-org-tasks-filepath (expand-file-name swarsel-tasks-org-file swarsel-org-directory)
|
||
swarsel-org-archive-filepath (expand-file-name swarsel-archive-org-file swarsel-org-directory))
|
||
|
||
;; set paths to authentication files (forge)
|
||
;; (setq auth-source-pass-filename "~/.local/share/password-store"
|
||
(setq auth-sources '( "~/.emacs.d/.caldav" "~/.emacs.d/.authinfo.gpg")
|
||
auth-source-cache-expiry nil) ; default is 2h
|
||
|
||
;; set pandoc for markdown compilation
|
||
(setq markdown-command "pandoc")
|
||
|
||
;; set org-caldav-sync-initalization
|
||
(setq swarsel-caldav-synced 0)
|
||
|
||
#+end_src
|
||
|
||
** Package System Setup
|
||
|
||
This is handles by nix, no configuration is needed here. Do note that package.el must stay enabled in early-init.el.
|
||
|
||
** Keeping .emacs.d clean
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; Change the user-emacs-directory to keep unwanted things out of ~/.emacs.d
|
||
(setq user-emacs-directory (expand-file-name "~/.cache/emacs/")
|
||
url-history-file (expand-file-name "url/history" user-emacs-directory))
|
||
|
||
;; Use no-littering to automatically set common paths to the new user-emacs-directory
|
||
(use-package no-littering)
|
||
(setq custom-file (expand-file-name "programs/emacs/custom.el" swarsel-dotfiles-directory))
|
||
(load custom-file t)
|
||
|
||
#+end_src
|
||
|
||
* Behavior
|
||
** General
|
||
|
||
Here I set up some things that are too minor to put under other categories.
|
||
- Firstly we disable to having to type `yes` and `no` and switch it to `y` and `n`.
|
||
- We also enable the marking of trailing whitespaces.
|
||
- Also, make emacs highlight the current line globally
|
||
- Emacs defaults to pausing all display redrawing on any input. This may have been useful previously, but is not necessary nowadays.
|
||
- I also disable the suspend-frame function, as I never use it and it is quite confusing when accidentally hitting the keys for it.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(defalias 'yes-or-no-p 'y-or-n-p)
|
||
;;(setq-default show-trailing-whitespace t)
|
||
(add-hook 'before-save-hook 'delete-trailing-whitespace)
|
||
(global-hl-line-mode 1)
|
||
;; (setq redisplay-dont-pause t) ;; obsolete
|
||
(setq blink-cursor-mode nil) ;; blink-cursor is an unexpected source of slowdown
|
||
(delete-selection-mode 1)
|
||
(setq vc-follow-symlinks t)
|
||
(setq require-final-newline t)
|
||
(winner-mode 1)
|
||
;; less noise when compiling elisp
|
||
(setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
|
||
(setq native-comp-async-report-warnings-errors nil)
|
||
(setq load-prefer-newer t)
|
||
|
||
(setq browse-url-browser-function 'browse-url-firefox)
|
||
;; disable a keybind that does more harm than good
|
||
(global-set-key [remap suspend-frame]
|
||
(lambda ()
|
||
(interactive)
|
||
(message "This keybinding is disabled (was 'suspend-frame')")))
|
||
|
||
#+end_src
|
||
|
||
** Disable GUI distractions
|
||
|
||
These settings are mostly useless in my eyes and provide little more than a distraction.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (scroll-bar-mode -1)
|
||
;; (tool-bar-mode -1)
|
||
;; (tooltip-mode -1)
|
||
;; (menu-bar-mode -1)
|
||
(setq visible-bell nil)
|
||
(setq initial-major-mode 'fundamental-mode
|
||
initial-scratch-message nil)
|
||
|
||
#+end_src
|
||
|
||
** Indentation
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(setq-default indent-tabs-mode nil
|
||
tab-width 2)
|
||
|
||
(setq tab-always-indent 'complete)
|
||
;; dont send nag when creating python files
|
||
(setq python-indent-guess-indent-offset-verbose nil)
|
||
|
||
(use-package highlight-indent-guides
|
||
:hook (prog-mode . highlight-indent-guides-mode)
|
||
:init
|
||
(setq highlight-indent-guides-method 'column)
|
||
;; (setq highlight-indent-guides-method 'character)
|
||
;; (setq highlight-indent-guides-character ?|)
|
||
(setq highlight-indent-guides-responsive 'top)
|
||
)
|
||
;;(set-face--background 'highlight-indent-guides-odd-face "dark slate gray")
|
||
;;(set-face-background 'highlight-indent-guides-even-face "steel blue")
|
||
;;(set-face-foreground 'highlight-indent-guides-character-face "dark violet")
|
||
#+end_src
|
||
|
||
** Scrolling
|
||
|
||
By default, emacs scrolls half a page when reaching the bottom of the buffer. This is extremely annoying.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(setq scroll-step 1
|
||
scroll-margin 4
|
||
scroll-conservatively 101)
|
||
|
||
;; (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ;; one line at a time
|
||
;; (setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
|
||
;; (setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
|
||
|
||
(pixel-scroll-precision-mode 1)
|
||
|
||
;; (use-package fast-scroll
|
||
;; :ensure nil
|
||
;; :init (fast-scroll-mode 1))
|
||
|
||
#+end_src
|
||
|
||
** Create non-existant directories when finding file
|
||
|
||
This function will check if a directory for which a file we want to open exists; if not, it will offer to create the directories for me.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(defun swarsel/with-buffer-name-prompt-and-make-subdirs ()
|
||
(let ((parent-directory (file-name-directory buffer-file-name)))
|
||
(when (and (not (file-exists-p parent-directory))
|
||
(y-or-n-p (format "Directory `%s' does not exist! Create it? " parent-directory)))
|
||
(make-directory parent-directory t))))
|
||
|
||
(add-to-list 'find-file-not-found-functions #'swarsel/with-buffer-name-prompt-and-make-subdirs)
|
||
|
||
#+end_src
|
||
|
||
** Evil
|
||
#+begin_src emacs-lisp
|
||
|
||
;; Emulate vim in emacs
|
||
(use-package evil
|
||
:init
|
||
(setq evil-want-integration t) ; loads evil
|
||
(setq evil-want-keybinding nil) ; loads "helpful bindings" for other modes
|
||
(setq evil-want-C-u-scroll t) ; scrolling using C-u
|
||
(setq evil-want-C-i-jump nil) ; jumping with C-i
|
||
(setq evil-want-Y-yank-to-eol t) ; give Y some utility
|
||
(setq evil-shift-width 2) ; uniform indent
|
||
(setq evil-respect-visual-line-mode t) ; i am torn on this one
|
||
; sane splitting
|
||
(setq evil-split-window-below t)
|
||
(setq evil-vsplit-window-right t)
|
||
:config
|
||
(evil-mode 1)
|
||
(define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state) ; alternative for exiting insert mode
|
||
(define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join) ; dont show help but instead do normal vim delete backwards
|
||
|
||
;; evil undo system
|
||
(evil-set-undo-system 'undo-tree)
|
||
;; Use visual line motions even outside of visual-line-mode buffers
|
||
;; (evil-global-set-key 'motion "j" 'evil-next-visual-line)
|
||
;; (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
|
||
|
||
;; Don't use evil-mode in these contexts, or use it in a specific mode
|
||
(evil-set-initial-state 'messages-buffer-mode 'emacs)
|
||
(evil-set-initial-state 'dashboard-mode 'emacs)
|
||
(evil-set-initial-state 'dired-mode 'emacs)
|
||
(evil-set-initial-state 'cfw:details-mode 'emacs)
|
||
(evil-set-initial-state 'Custom-mode 'emacs) ; god knows why this mode is in uppercase
|
||
|
||
; require a specific evil state
|
||
(evil-set-initial-state 'mu4e-headers-mode 'normal)
|
||
(evil-set-initial-state 'python-inferior-mode 'normal)
|
||
(add-hook 'org-capture-mode-hook 'evil-insert-state)
|
||
(add-to-list 'evil-buffer-regexps '("COMMIT_EDITMSG" . insert)))
|
||
|
||
;; Evil configuration for different modes
|
||
(use-package evil-collection
|
||
:after evil
|
||
:config
|
||
(evil-collection-init)
|
||
(setq forge-add-default-bindings nil))
|
||
|
||
;; enables 2-char inline search
|
||
(use-package evil-snipe
|
||
:after evil
|
||
:demand
|
||
:config
|
||
(evil-snipe-mode +1)
|
||
;; replace 1-char searches (f&t) with this better UI
|
||
(evil-snipe-override-mode +1))
|
||
|
||
;; for parentheses-heavy languades modify evil commands to keep balance of parantheses
|
||
(use-package evil-cleverparens)
|
||
|
||
;; enables surrounding text with S
|
||
(use-package evil-surround
|
||
:config
|
||
(global-evil-surround-mode 1))
|
||
|
||
|
||
|
||
#+end_src
|
||
|
||
** undo-tree
|
||
|
||
Base emacs undo logic is very useful, but not easy to understand. I prefer undo-tree, which makes switching between branches easier and also allows quickly switching back to a much older state using the visualizer
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package undo-tree
|
||
;; :init (global-undo-tree-mode)
|
||
:bind (:map undo-tree-visualizer-mode-map
|
||
("h" . undo-tree-visualize-switch-branch-left)
|
||
("l" . undo-tree-visualize-switch-branch-left)
|
||
("j" . undo-tree-visualize-redo)
|
||
("k" . undo-tree-visualize-undo))
|
||
:config
|
||
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo")))
|
||
)
|
||
(add-hook 'prog-mode-hook 'undo-tree-mode)
|
||
(add-hook 'text-mode-hook 'undo-tree-mode)
|
||
(add-hook 'org-mode-hook 'undo-tree-mode)
|
||
(add-hook 'latex-mode-hook 'undo-tree-mode)
|
||
#+end_src
|
||
|
||
** Move backup files to another location
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(let ((backup-dir "~/tmp/emacs/backups")
|
||
(auto-saves-dir "~/tmp/emacs/auto-saves/"))
|
||
(dolist (dir (list backup-dir auto-saves-dir))
|
||
(when (not (file-directory-p dir))
|
||
(make-directory dir t)))
|
||
(setq backup-directory-alist `(("." . ,backup-dir))
|
||
auto-save-file-name-transforms `((".*" ,auto-saves-dir t))
|
||
auto-save-list-file-prefix (concat auto-saves-dir ".saves-")
|
||
tramp-backup-directory-alist `((".*" . ,backup-dir))
|
||
tramp-auto-save-directory auto-saves-dir))
|
||
|
||
(setq backup-by-copying t ; Don't delink hardlinks
|
||
delete-old-versions t ; Clean up the backups
|
||
version-control t ; Use version numbers on backups,
|
||
kept-new-versions 5 ; keep some new versions
|
||
kept-old-versions 2) ; and some old ones, too
|
||
|
||
#+end_src
|
||
|
||
* Custom Keybindings
|
||
#+begin_src emacs-lisp
|
||
|
||
;; Make ESC quit prompts
|
||
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
|
||
|
||
;; Set up general keybindings
|
||
(use-package general
|
||
:config
|
||
(general-create-definer swarsel/leader-keys
|
||
:keymaps '(normal insert visual emacs)
|
||
:prefix "SPC"
|
||
:global-prefix "C-SPC")
|
||
|
||
(swarsel/leader-keys
|
||
"t" '(:ignore t :which-key "toggles")
|
||
"ts" '(hydra-text-scale/body :which-key "scale text")
|
||
"tl" '(display-line-numbers-mode :which-key "line numbers")
|
||
"tp" '(evil-cleverparens-mode :wk "cleverparens")
|
||
"to" '(olivetti-mode :wk "olivetti")
|
||
"td" '(darkroom-tentative-mode :wk "darkroom")
|
||
"tw" '((lambda () (interactive) (toggle-truncate-lines)) :which-key "line wrapping")
|
||
"m" '(:ignore m :which-key "modes/programs")
|
||
"mm" '((lambda () (interactive) (mu4e)) :which-key "mu4e")
|
||
"mg" '((lambda () (interactive) (magit-list-repositories)) :which-key "magit-list-repos")
|
||
"mc" '((lambda () (interactive) (swarsel/open-calendar)) :which-key "calendar")
|
||
"mp" '(popper-toggle :which-key "popper")
|
||
"md" '(dirvish :which-key "dirvish")
|
||
;; "c" '(:ignore c :which-key "capture")
|
||
;; "cj" '((lambda () (interactive) (org-capture nil "jj")) :which-key "journal")
|
||
;; "cs" '(markdown-download-screenshot :which-key "screenshot")
|
||
"l" '(:ignore l :which-key "links")
|
||
"le" '((lambda () (interactive) (find-file swarsel-emacs-org-filepath)) :which-key "Emacs.org")
|
||
"ls" '((lambda () (interactive) (find-file "/smb:Swarsel@192.168.1.3:")) :which-key "Server")
|
||
"lo" '(dired swarsel-obsidian-vault-directory :which-key "obsidian")
|
||
;; "la" '((lambda () (interactive) (find-file swarsel-org-anki-filepath)) :which-key "anki")
|
||
"ln" '((lambda () (interactive) (find-file swarsel-nix-org-filepath)) :which-key "Nix.org")
|
||
"lp" '((lambda () (interactive) (projectile-switch-project)) :which-key "switch project")
|
||
"lg" '((lambda () (interactive) (magit-list-repositories)) :which-key "list git repos")
|
||
;; "a" '(:ignore a :which-key "anki")
|
||
;; "ap" '(anki-editor-push-tree :which-key "push new cards")
|
||
;; "an" '((lambda () (interactive) (org-capture nil "a")) :which-key "new card")
|
||
;; "as" '(swarsel-anki-set-deck-and-notetype :which-key "change deck and notetype")
|
||
"h" '(:ignore h :which-key "help")
|
||
"hy" '(yas-describe-tables :which-key "yas tables")
|
||
"hb" '(embark-bindings :which-key "current key bindings")
|
||
"h" '(:ignore t :which-key "describe")
|
||
"he" 'view-echo-area-messages
|
||
"hf" 'describe-function
|
||
"hF" 'describe-face
|
||
"hl" '(view-lossage :which-key "show command keypresses")
|
||
"hL" 'find-library
|
||
"hm" 'describe-mode
|
||
"ho" 'describe-symbol
|
||
"hk" 'describe-key
|
||
"hK" 'describe-keymap
|
||
"hp" 'describe-package
|
||
"hv" 'describe-variable
|
||
"hd" 'devdocs-lookup
|
||
"w" '(:ignore t :which-key "window")
|
||
"wl" 'windmove-right
|
||
"wh" 'windmove-left
|
||
"wk" 'windmove-up
|
||
"wj" 'windmove-down
|
||
"wr" 'winner-redo
|
||
"wd" 'delete-window
|
||
"w=" 'balance-windows-area
|
||
"wD" 'kill-buffer-and-window
|
||
"wu" 'winner-undo
|
||
"wr" 'winner-redo
|
||
"w/" 'evil-window-vsplit
|
||
"w-" 'evil-window-split
|
||
"wm" '(delete-other-windows :wk "maximize")
|
||
))
|
||
|
||
;; General often used hotkeys
|
||
(general-define-key
|
||
"C-M-a" (lambda () (interactive) (org-capture nil "a")) ; make new anki card
|
||
;; "C-M-d" 'swarsel-obsidian-daily ; open daily obsidian file and create if not exist
|
||
;; "C-M-S" 'swarsel-anki-set-deck-and-notetype ; switch deck and notetye for new anki cards
|
||
;; "C-M-s" 'markdown-download-screenshot ; wrapper for org-download-screenshot
|
||
"C-c d" 'duplicate-line ; duplicate line on CURSOR
|
||
"C-M-j" 'consult-buffer
|
||
"C-s" 'consult-line
|
||
)
|
||
|
||
#+end_src
|
||
|
||
* UI
|
||
** General
|
||
|
||
- This sets up some basic UI elements
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(setq inhibit-startup-message t)
|
||
|
||
;; (set-fringe-mode nil) ; Give some breathing room
|
||
|
||
;; Increase undo limit and allow for more fine grained undo, base emacs deletes way too much on undo
|
||
(setq undo-limit 80000000
|
||
evil-want-fine-undo t
|
||
auto-save-default t
|
||
password-cache-expiry nil
|
||
)
|
||
|
||
;; (display-time-mode 1)
|
||
(global-subword-mode 1) ; Iterate through CamelCase words
|
||
|
||
(use-package rainbow-mode
|
||
:config (rainbow-mode))
|
||
|
||
|
||
|
||
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
|
||
(add-hook 'text-mode-hook 'display-line-numbers-mode)
|
||
|
||
#+end_src
|
||
|
||
** Looks
|
||
*** Font Configuration
|
||
|
||
- You have to install these fonts manually on Windows: https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip
|
||
- On linux (fedora): 'sudo dnf install fira-code-fonts'
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (defun swarsel/font-setup (frame)
|
||
;; (set-face-attribute 'default nil :font swarsel-standard-font :height swarsel/default-font-size)
|
||
;; ;; Set the fixed pitch face - basically normal text
|
||
;; (set-face-attribute 'fixed-pitch nil :font swarsel-standard-font :height 140)
|
||
;; ;; Set the variable pitch face - basically headers etc
|
||
;; (set-face-attribute 'variable-pitch nil :font swarsel-alt-font :height 100 :weight 'regular)
|
||
;; (set-face-attribute 'region nil :foreground "cyan" :background "gray40" :weight 'bold)
|
||
;; ;; (remove-hook 'after-make-frame-functions #'swarsel/font-setup)
|
||
;; )
|
||
|
||
;; (add-hook 'after-make-frame-functions #'swarsel/font-setup)
|
||
|
||
;; (defun swarsel/font-setup (frame)
|
||
(dolist (face '(default fixed-pitch))
|
||
(set-face-attribute face nil
|
||
:font "FiraCode Nerd Font Mono"))
|
||
(add-to-list 'default-frame-alist '(font . "FiraCode Nerd Font Mono"))
|
||
|
||
(set-face-attribute 'default nil :height 100)
|
||
(set-face-attribute 'fixed-pitch nil :height 1.0)
|
||
|
||
(set-face-attribute 'variable-pitch nil
|
||
:family "IBM Plex Sans"
|
||
:weight 'regular
|
||
:height 1.06)
|
||
;; (enable-theme 'doom-city-lights)
|
||
;; )
|
||
|
||
;; (add-hook 'after-make-frame-functions #'swarsel/font-setup)
|
||
#+end_src
|
||
|
||
*** Color Theme
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package solaire-mode
|
||
:defer t
|
||
:custom (solaire-global-mode +1))
|
||
|
||
(use-package doom-themes
|
||
:defer t
|
||
:hook (server-after-make-frame . (lambda () (load-theme
|
||
'doom-city-lights t)))
|
||
)
|
||
|
||
#+end_src
|
||
|
||
*** Transparent background
|
||
|
||
This is handled by Nix and no longer needed here.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (set-frame-parameter (selected-frame) 'alpha '(95 . 95))
|
||
;; (add-to-list 'default-frame-alist '(alpha . (95 . 95)))
|
||
;; (set-frame-parameter (selected-frame) 'fullscreen 'maximized)
|
||
;; (add-to-list 'default-frame-alist '(fullscreen . maximized))
|
||
|
||
#+end_src
|
||
|
||
*** Variable Pitch Mode
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package mixed-pitch
|
||
:custom
|
||
(mixed-pitch-set-height nil)
|
||
(mixed-pitch-variable-pitch-cursor nil)
|
||
:hook
|
||
(text-mode . mixed-pitch-mode))
|
||
|
||
|
||
#+end_src
|
||
|
||
** Modeline
|
||
|
||
Here I set up the modeline with some information that I find useful. Specficially I am using the doom modeline.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package nerd-icons)
|
||
|
||
;; Adds a more beautiful modeline with less clutter
|
||
(use-package doom-modeline
|
||
:init (doom-modeline-mode)
|
||
:custom
|
||
((doom-modeline-height 22)
|
||
(doom-modeline-indent-info t)))
|
||
|
||
;; Generally show line numbers
|
||
(column-number-mode)
|
||
|
||
;; (unless (string-match-p "^Power N/A" (battery)) ; On laptops...
|
||
;; (display-battery-mode 1))
|
||
|
||
#+end_src
|
||
|
||
** Helper Modes (Ivy..., Vertico..., which-key, helpful)
|
||
*** Vertico and friends
|
||
|
||
Soon I want to try out this new hot stuff - just at the moment there is too much other stuff to do.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package vertico
|
||
:custom
|
||
(vertico-scroll-margin 0)
|
||
(vertico-count 10)
|
||
(vertico-resize t)
|
||
(vertico-cycle t)
|
||
:init
|
||
(vertico-mode)
|
||
(vertico-mouse-mode))
|
||
|
||
(use-package vertico-directory
|
||
:ensure nil
|
||
:after vertico
|
||
:bind (:map vertico-map
|
||
("RET" . vertico-directory-enter)
|
||
("DEL" . vertico-directory-delete-char)
|
||
("M-DEL" . vertico-directory-delete-word))
|
||
;; Tidy shadowed file names
|
||
:hook (rfn-eshadow-update-overlay . vertico-directory-tidy))
|
||
|
||
(use-package orderless
|
||
:custom
|
||
(completion-styles '(orderless flex basic))
|
||
(completion-category-overrides '((file (styles . (partial-completion)))
|
||
(eglot (styles orderless)))))
|
||
|
||
(use-package consult
|
||
:config
|
||
(setq consult-fontify-max-size 1024)
|
||
:bind
|
||
("C-x b" . consult-buffer)
|
||
("C-c <C-m>" . consult-global-mark)
|
||
("C-c C-a" . consult-org-agenda)
|
||
("C-x O" . consult-outline)
|
||
("M-g M-g" . consult-goto-line)
|
||
("M-g i" . consult-imenu)
|
||
("M-s s" . consult-line)
|
||
("M-s M-s" . consult-line-multi))
|
||
|
||
(use-package embark
|
||
:bind
|
||
(("C-." . embark-act)
|
||
("M-." . embark-dwim)
|
||
("C-h B" . embark-bindings))
|
||
:custom
|
||
(prefix-help-command #'embark-prefix-help-command)
|
||
(embark-quit-after-action '((t . nil)))
|
||
:config
|
||
(add-to-list 'display-buffer-alist
|
||
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
|
||
nil
|
||
(window-parameters (mode-line-format . none)))))
|
||
|
||
(use-package embark-consult
|
||
:after (embark consult)
|
||
:demand t ; only necessary if you have the hook below
|
||
;; if you want to have consult previews as you move around an
|
||
;; auto-updating embark collect buffer
|
||
:hook
|
||
(embark-collect-mode . consult-preview-at-point-mode))
|
||
|
||
(use-package marginalia
|
||
:after vertico
|
||
:init
|
||
(marginalia-mode)
|
||
(setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)))
|
||
|
||
(use-package nerd-icons-completion
|
||
:after (marginalia nerd-icons)
|
||
:hook (marginalia-mode . nerd-icons-completion-marginalia-setup)
|
||
:init
|
||
(nerd-icons-completion-mode))
|
||
|
||
|
||
#+end_src
|
||
|
||
*** Ivy + Counsel
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package ivy
|
||
;; :init (ivy-mode 1)
|
||
;; :diminish
|
||
;; :bind (("C-s" . swiper) ; call swiper (find tool)
|
||
;; :map ivy-minibuffer-map
|
||
;; ;("TAB" . ivy-alt-done) ; autocomplete
|
||
;; ("C-l" . ivy-alt-done)
|
||
;; ("C-<right>" . ivy-alt-done) ; for kyria
|
||
;; ("C-h" . counsel-up-directory) ; for kyria
|
||
;; ("C-<left>" . counsel-up-directory) ; for kyria
|
||
;; ("C-j" . ivy-next-line) ; go up and down in ivy using vim keys
|
||
;; ("C-<down>" . ivy-next-line) ; for kyria
|
||
;; ("C-k" . ivy-previous-line)
|
||
;; ("C-<up>" . ivy-previous-line) ; for kyria
|
||
;; :map ivy-switch-buffer-map
|
||
;; ("C-k" . ivy-previous-line)
|
||
;; ("C-<up>" . ivy-previous-line) ; for kyria
|
||
;; ("C-l" . ivy-done)
|
||
;; ("C-<right>" . ivy-done) ; for kyria
|
||
;; ("C-d" . ivy-switch-buffer-kill)
|
||
;; :map ivy-reverse-i-search-map
|
||
;; ("C-k" . ivy-previous-line)
|
||
;; ("C-<up>" . ivy-previous-line) ; for kyria
|
||
;; ("C-d" . ivy-reverse-i-search-kill))
|
||
;; :config
|
||
;; (setq ivy-use-virtual-buffers t)
|
||
;; (setq ivy-count-format "(%d/%d) ")
|
||
;; (setq ivy-wrap t))
|
||
|
||
;; ;; More information about functions in ivy-mode
|
||
;; (use-package ivy-rich
|
||
;; :init
|
||
;; (ivy-rich-mode 1))
|
||
|
||
;; (use-package counsel
|
||
;; :init (counsel-mode 1)
|
||
;; :bind (("C-M-j" . counsel-switch-buffer)
|
||
;; ("M-x" . counsel-M-x)
|
||
;; ("C-x b" . counsel-ibuffer)
|
||
;; ("C-x C-f" . counsel-find-file)
|
||
;; :map minibuffer-local-map
|
||
;; ("C-r" . 'counsel-minibuffer-history))
|
||
;; :config
|
||
;; (setq ivy-initial-inputs-alist nil))
|
||
|
||
#+end_src
|
||
|
||
*** Helpful + which-key: Better help defaults
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package which-key
|
||
:init (which-key-mode)
|
||
:diminish which-key-mode
|
||
:config
|
||
(setq which-key-idle-delay 0.3))
|
||
|
||
;; (use-package helpful
|
||
;; :custom
|
||
;; (counsel-describe-function-function #'helpful-callable)
|
||
;; (counsel-describe-variable-function #'helpful-variable)
|
||
;; :bind
|
||
;; ([remap describe-function] . counsel-describe-function)
|
||
;; ([remap describe-command] . helpful-command)
|
||
;; ([remap describe-variable] . counsel-describe-variable)
|
||
;; ([remap describe-key] . helpful-key))
|
||
|
||
(use-package helpful
|
||
:custom
|
||
(help-select-window t)
|
||
:bind
|
||
(("C-h f" . helpful-callable)
|
||
("C-h v" . helpful-variable)
|
||
("C-h k" . helpful-key)
|
||
("C-h C-." . helpful-at-point)))
|
||
|
||
#+end_src
|
||
|
||
** Text Scaling
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package hydra)
|
||
|
||
;; change the text size of the current buffer
|
||
(defhydra hydra-text-scale (:timeout 4)
|
||
"scale text"
|
||
("j" text-scale-increase "in")
|
||
("k" text-scale-decrease "out")
|
||
("f" nil "finished" :exit t))
|
||
|
||
#+end_src
|
||
|
||
** Ligatures
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package ligature
|
||
:config
|
||
(ligature-set-ligatures 'prog-mode
|
||
'("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
|
||
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
|
||
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
|
||
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
|
||
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
|
||
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
|
||
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
|
||
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
|
||
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
|
||
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
|
||
"##" "#(" "#?" "#_" "%%" ".=" ".." ".?" "+>" "++" "?:" "?="
|
||
"?." "??" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)" "\\\\"
|
||
"://" ";;"))
|
||
(global-ligature-mode t))
|
||
|
||
#+end_src
|
||
|
||
** Popup + Shackle Buffers
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package popper
|
||
:bind (("M-[" . popper-toggle))
|
||
:init
|
||
(setq popper-reference-buffers
|
||
'("\\*Messages\\*"
|
||
("\\*Warnings\\*" . hide)
|
||
"Output\\*$"
|
||
"\\*Async Shell Command\\*"
|
||
"\\*Async-native-compile-log\\*"
|
||
help-mode
|
||
helpful-mode
|
||
"*Occur*"
|
||
"*scratch*"
|
||
"*julia*"
|
||
"*Python*"
|
||
;; ("*tex-shell*" . hide)
|
||
(compilation-mode . hide)))
|
||
(popper-mode +1)
|
||
(popper-echo-mode +1))
|
||
|
||
(use-package shackle
|
||
:config
|
||
(setq shackle-rules '(("*Messages*" :select t :popup t :align right :size 0.3)
|
||
("*Warnings*" :ignore t :popup t :align right :size 0.3)
|
||
("*Occur*" :select t :popup t :align below :size 0.2)
|
||
("*scratch*" :select t :popup t :align below :size 0.2)
|
||
("*Python*" :select t :popup t :align below :size 0.2)
|
||
("*tex-shell*" :ignore t :popup t :align below :size 0.2)
|
||
(helpful-mode :select t :popup t :align right :size 0.35)
|
||
(help-mode :select t :popup t :align right :size 0.4)))
|
||
(shackle-mode 1))
|
||
|
||
#+end_src
|
||
|
||
** Indicate first and last line of buffer
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(setq-default indicate-buffer-boundaries t)
|
||
|
||
#+end_src
|
||
|
||
* Org Mode
|
||
** General
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(defun swarsel/org-mode-setup ()
|
||
(org-indent-mode)
|
||
(variable-pitch-mode 1)
|
||
;;(auto-fill-mode 0)
|
||
(setq display-line-numbers-type 'relative
|
||
display-line-numbers-current-absolute 1
|
||
display-line-numbers-width-start nil
|
||
display-line-numbers-width 6
|
||
display-line-numbers-grow-only 1)
|
||
(add-hook 'org-tab-first-hook 'org-end-of-line)
|
||
(visual-line-mode 1))
|
||
;; (setq evil-auto-indent nil)
|
||
;;(diminish org-indent-mode)
|
||
|
||
;; (defun swarsel/org-font-setup ()
|
||
;; ;; Replace list hyphen with dot
|
||
;; (font-lock-add-keywords 'org-mode
|
||
;; '(("^ *\\([-]\\) "
|
||
;; (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•")))))))
|
||
|
||
(use-package org
|
||
;;:diminish (org-indent-mode)
|
||
:hook (org-mode . swarsel/org-mode-setup)
|
||
:bind ("C-<tab>" . org-fold-outer)
|
||
:config
|
||
(setq org-ellipsis " ⤵"
|
||
org-hide-emphasis-markers t)
|
||
(setq org-startup-folded t)
|
||
(setq org-support-shift-select t)
|
||
;; (setq org-agenda-start-with-log-mode t)
|
||
;; (setq org-log-done 'time)
|
||
;; (setq org-log-into-drawer t)
|
||
(setq org-startup-with-inline-images t)
|
||
(setq org-image-actual-width nil)
|
||
(setq org-format-latex-options '(:foreground "White" :background default :scale 2.0 :html-foreground "Black" :html-background "Transparent" :html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")))
|
||
|
||
;; (setq org-agenda-files
|
||
;; '(swarsel-org-tasks-filepath
|
||
;; swarsel-org-archive-filepath
|
||
;; swarsel-org-anki-filepath))
|
||
(setq org-agenda-files '("/home/swarsel/Calendars/leon_cal.org"))
|
||
|
||
|
||
;; (require 'org-habit)
|
||
;; (add-to-list 'org-modules 'org-habit)
|
||
;; (setq org-habit-graph-column 60)
|
||
|
||
;; (setq org-todo-keywords
|
||
;; '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
|
||
;; (sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANC(k@)")))
|
||
|
||
;; (setq org-refile-targets
|
||
;; '((swarsel-archive-org-file :maxlevel . 1)
|
||
;; (swarsel-anki-org-file :maxlevel . 1)
|
||
;; (swarsel-tasks-org-file :maxlevel . 1)))
|
||
|
||
;; ;; Configure custom agenda views
|
||
;; (setq org-agenda-custom-commands
|
||
;; '(("d" "Dashboard"
|
||
;; ((agenda "" ((org-deadline-warning-days 7)))
|
||
;; (todo "NEXT"
|
||
;; ((org-agenda-overriding-header "Next Tasks")))
|
||
;; (tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))
|
||
|
||
;; ("n" "Next Tasks"
|
||
;; ((todo "NEXT"
|
||
;; ((org-agenda-overriding-header "Next Tasks")))))
|
||
|
||
;; ("W" "Work Tasks" tags-todo "+work-email")
|
||
|
||
;; ;; Low-effort next actions
|
||
;; ("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
|
||
;; ((org-agenda-overriding-header "Low Effort Tasks")
|
||
;; (org-agenda-max-todos 20)
|
||
;; (org-agenda-files org-agenda-files)))
|
||
|
||
;; ("w" "Workflow Status"
|
||
;; ((todo "WAIT"
|
||
;; ((org-agenda-overriding-header "Waiting on External")
|
||
;; (org-agenda-files org-agenda-files)))
|
||
;; (todo "REVIEW"
|
||
;; ((org-agenda-overriding-header "In Review")
|
||
;; (org-agenda-files org-agenda-files)))
|
||
;; (todo "PLAN"
|
||
;; ((org-agenda-overriding-header "In Planning")
|
||
;; (org-agenda-todo-list-sublevels nil)
|
||
;; (org-agenda-files org-agenda-files)))
|
||
;; (todo "BACKLOG"
|
||
;; ((org-agenda-overriding-header "Project Backlog")
|
||
;; (org-agenda-todo-list-sublevels nil)
|
||
;; (org-agenda-files org-agenda-files)))
|
||
;; (todo "READY"
|
||
;; ((org-agenda-overriding-header "Ready for Work")
|
||
;; (org-agenda-files org-agenda-files)))
|
||
;; (todo "ACTIVE"
|
||
;; ((org-agenda-overriding-header "Active Projects")
|
||
;; (org-agenda-files org-agenda-files)))
|
||
;; (todo "COMPLETED"
|
||
;; ((org-agenda-overriding-header "Completed Projects")
|
||
;; (org-agenda-files org-agenda-files)))
|
||
;; (todo "CANC"
|
||
;; ((org-agenda-overriding-header "Cancelled Projects")
|
||
;; (org-agenda-files org-agenda-files)))))))
|
||
|
||
;; (setq org-capture-templates
|
||
;; `(
|
||
;; ("a" "Anki basic"
|
||
;; entry
|
||
;; (file+headline swarsel-org-anki-filepath "Dispatch")
|
||
;; (function swarsel-anki-make-template-string))
|
||
|
||
;; ("A" "Anki cloze"
|
||
;; entry
|
||
;; (file+headline org-swarsel-anki-file "Dispatch")
|
||
;; "* %<%H:%M>\n:PROPERTIES:\n:ANKI_NOTE_TYPE: Cloze\n:ANKI_DECK: 🦁 All::01 ❤️ Various::00 ✨ Allgemein\n:END:\n** Text\n%?\n** Extra\n")
|
||
;; ("t" "Tasks / Projects")
|
||
;; ("tt" "Task" entry (file+olp swarsel-org-tasks-filepath "Inbox")
|
||
;; "* TODO %?\n %U\n %a\n %i" :empty-lines 1)
|
||
|
||
;; ("j" "Journal Entries")
|
||
;; ("jj" "Journal" entry
|
||
;; (file+olp+datetree swarsel-org-journal-filepath)
|
||
;; "\n* %<%I:%M %p> - Journal :journal:\n\n%?\n\n"
|
||
;; ;; ,(dw/read-file-as-string "~/Notes/Templates/Daily.org")
|
||
;; :clock-in :clock-resume
|
||
;; :empty-lines 1)))
|
||
|
||
;; (swarsel/org-font-setup)
|
||
)
|
||
#+end_src
|
||
|
||
** Font Faces
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
|
||
|
||
;; ;; Set faces for heading levels
|
||
;; (with-eval-after-load 'org-faces (dolist (face '((org-level-1 . 1.3)
|
||
;; (org-level-2 . 1.2)
|
||
;; (org-level-3 . 1.15)
|
||
;; (org-level-4 . 1.1)
|
||
;; (org-level-5 . 1.1)
|
||
;; (org-level-6 . 1.1)
|
||
;; (org-level-7 . 1.1)
|
||
;; (org-level-8 . 1.1)))
|
||
;; (set-face-attribute (car face) nil :font swarsel-alt-font :weight 'regular :height (cdr face)))
|
||
|
||
;; ;; Ensure that anything that should be fixed-pitch in Org files appears that way
|
||
;; (set-face-attribute 'org-block nil :inherit '(fixed-pitch))
|
||
;; (set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
|
||
;; (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
|
||
;; (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
|
||
;; (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
|
||
;; (set-face-attribute 'org-checkbox nil :inherit '(fixed-pitch)))
|
||
|
||
#+end_src
|
||
|
||
** org-appear
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; Show hidden emphasis markers
|
||
;; (use-package org-appear
|
||
;; :hook (org-mode . org-appear-mode)
|
||
;; :init
|
||
;; (setq org-appear-autolinks t)
|
||
;; (setq org-appear-autosubmarkers t)
|
||
;; )
|
||
|
||
#+end_src
|
||
|
||
** Heading Bullets
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package org-bullets
|
||
;; :after org
|
||
;; :hook (org-mode . org-bullets-mode)
|
||
;; :custom
|
||
;; (org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
|
||
|
||
#+end_src
|
||
|
||
** Centered org-mode Buffers
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(defun swarsel/org-mode-visual-fill ()
|
||
(setq visual-fill-column-width 150
|
||
visual-fill-column-center-text t)
|
||
(visual-fill-column-mode 1))
|
||
|
||
(use-package visual-fill-column
|
||
:hook (org-mode . swarsel/org-mode-visual-fill))
|
||
|
||
#+end_src
|
||
|
||
** Fix headings not folding sometimes
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(setq org-fold-core-style 'overlays)
|
||
|
||
#+end_src
|
||
|
||
** Babel
|
||
*** Language Configuration
|
||
|
||
- This configures the languages that babel recognizes
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(org-babel-do-load-languages
|
||
'org-babel-load-languages
|
||
'((emacs-lisp . t)
|
||
(python . t)))
|
||
|
||
(push '("conf-unix" . conf-unix) org-src-lang-modes)
|
||
|
||
#+end_src
|
||
|
||
*** old easy structure templates
|
||
|
||
- org 9.2 changed the way structure templates work. This brings back the old way it worked.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(require 'org-tempo)
|
||
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
|
||
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
|
||
(add-to-list 'org-structure-template-alist '("py" . "src python"))
|
||
(add-to-list 'org-structure-template-alist '("nix" . "src nix :tangle"))
|
||
|
||
#+end_src
|
||
|
||
** Auto-tangle Configuration Files
|
||
|
||
- Automatically tangles all configuration blocks in this file to the defined Emacs orgfile
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(defun swarsel/org-babel-tangle-config ()
|
||
(when (string-equal (buffer-file-name)
|
||
swarsel-emacs-org-filepath)
|
||
;; Dynamic scoping to the rescue
|
||
(let ((org-confirm-babel-evaluate nil))
|
||
(org-babel-tangle)))
|
||
(when (string-equal (buffer-file-name)
|
||
swarsel-nix-org-filepath)
|
||
;; Dynamic scoping to the rescue
|
||
(let ((org-confirm-babel-evaluate nil))
|
||
(org-babel-tangle))))
|
||
|
||
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'swarsel/org-babel-tangle-config)))
|
||
|
||
#+end_src
|
||
|
||
** aucTex
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package auctex)
|
||
(setq TeX-auto-save t)
|
||
(setq TeX-save-query nil)
|
||
(setq TeX-parse-self t)
|
||
(setq-default TeX-master nil)
|
||
|
||
;; (add-hook 'LaTeX-mode-hook 'visual-line-mode)
|
||
;; (add-hook 'LaTeX-mode-hook 'flyspell-mode)
|
||
;; (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
|
||
|
||
;; (add-hook 'LaTeX-mode-hook 'turn-on-reftex)
|
||
;; (setq reftex-plug-into-AUCTeX t)
|
||
|
||
#+end_src
|
||
|
||
** TeX
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(add-hook 'markdown-mode-hook
|
||
(lambda ()
|
||
(local-set-key (kbd "C-c C-x C-l") 'org-latex-preview)
|
||
(local-set-key (kbd "C-c C-x C-u") 'markdown-toggle-url-hiding)
|
||
))
|
||
|
||
#+end_src
|
||
|
||
** org-download
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package org-download
|
||
:after org
|
||
:defer nil
|
||
:custom
|
||
(org-download-method 'directory)
|
||
(org-download-image-dir "./images")
|
||
(org-download-heading-lvl 0)
|
||
(org-download-timestamp "org_%Y%m%d-%H%M%S_")
|
||
;;(org-image-actual-width 500)
|
||
(org-download-screenshot-method "grim -g \"$(slurp)\" %s")
|
||
:bind
|
||
("C-M-y" . org-download-screenshot)
|
||
:config
|
||
(require 'org-download))
|
||
|
||
#+end_src
|
||
|
||
** org-fragtog
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package org-fragtog)
|
||
(add-hook 'org-mode-hook 'org-fragtog-mode)
|
||
(add-hook 'markdown-mode-hook 'org-fragtog-mode)
|
||
|
||
#+end_src
|
||
|
||
** Fold current heading
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(defun org-fold-outer ()
|
||
(interactive)
|
||
(org-beginning-of-line)
|
||
(if (string-match "^*+" (thing-at-point 'line t))
|
||
(outline-up-heading 1))
|
||
(outline-hide-subtree)
|
||
)
|
||
|
||
#+end_src
|
||
|
||
** org-modern
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package org-modern
|
||
:config (setq org-modern-block-name
|
||
'((t . t)
|
||
("src" "»" "∥")))
|
||
:hook (org-mode . org-modern-mode))
|
||
|
||
#+end_src
|
||
|
||
* Nix Mode
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package nix-mode
|
||
:mode "\\.nix\\'")
|
||
|
||
#+end_src
|
||
|
||
* Markdown Mode
|
||
** Mode
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package markdown-mode
|
||
:ensure t
|
||
:mode ("README\\.md\\'" . gfm-mode)
|
||
:init (setq markdown-command "multimarkdown")
|
||
:bind (:map markdown-mode-map
|
||
("C-c C-e" . markdown-do)))
|
||
|
||
#+end_src
|
||
|
||
** org-download port
|
||
|
||
This is a section adapted from org-download to make some org-download functions available in markdown mode. I need this because I am still using Obsidian to manage my notes, and that used markdown files.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; https://github.com/mooreryan/markdown-dnd-images
|
||
;; (add-to-list 'load-path "~/.emacs.d/packages")
|
||
;; (require 'markdown-dnd-images)
|
||
;; (setq dnd-save-directory "images")
|
||
|
||
;; (setq dnd-save-buffer-name nil)
|
||
|
||
;; (setq dnd-view-inline t)
|
||
|
||
;; (setq dnd-capture-source nil)
|
||
|
||
;; these next lines provide an interface for org-download in markdown mode for use with obsidian
|
||
|
||
;; (defvar org-download-markdown-link-format
|
||
;; "![[./%s]]\n"
|
||
;; "Format of the file link to insert.")
|
||
|
||
;; (defcustom org-download-markdown-link-format-function #'org-download-markdown-link-format-function-default
|
||
;; "Function that takes FILENAME and returns a org link."
|
||
;; :type 'function)
|
||
|
||
;; (defun org-download-markdown-link-format-function-default (filename)
|
||
;; "The default function of `org-download-link-format-function'."
|
||
;; (if (and (>= (string-to-number org-version) 9.3)
|
||
;; (eq org-download-method 'attach))
|
||
;; (format "[[attachment:%s]]\n"
|
||
;; (org-link-escape
|
||
;; (file-relative-name filename (org-attach-dir))))
|
||
;; (format org-download-markdown-link-format
|
||
;; (org-link-escape
|
||
;; (funcall org-download-abbreviate-filename-function filename)))))
|
||
|
||
;; (defun org-download-markdown-image (link)
|
||
;; "Save image at address LINK to `org-download--dir'."
|
||
;; (interactive "sUrl: ")
|
||
;; (let* ((link-and-ext (org-download--parse-link link))
|
||
;; (filename
|
||
;; (cond ((and (derived-mode-p 'org-mode)
|
||
;; (eq org-download-method 'attach))
|
||
;; (let ((org-download-image-dir (org-attach-dir t))
|
||
;; org-download-heading-lvl)
|
||
;; (apply #'org-download--fullname link-and-ext)))
|
||
;; ((fboundp org-download-method)
|
||
;; (funcall org-download-method link))
|
||
;; (t
|
||
;; (apply #'org-download--fullname link-and-ext)))))
|
||
;; (setq org-download-path-last-file filename)
|
||
;; (org-download--image link filename)
|
||
;; (when (org-download-org-mode-p)
|
||
;; (when (eq org-download-method 'attach)
|
||
;; (org-attach-attach filename nil 'none))
|
||
;; (org-download-markdown-insert-link link filename))
|
||
;; (when (and (eq org-download-delete-image-after-download t)
|
||
;; (not (url-handler-file-remote-p (current-kill 0))))
|
||
;; (delete-file link delete-by-moving-to-trash))))
|
||
|
||
;; (defun org-download-markdown-screenshot (&optional basename)
|
||
;; "Capture screenshot and insert the resulting file.
|
||
;; The screenshot tool is determined by `org-download-screenshot-method'."
|
||
;; (interactive)
|
||
;; (let* ((screenshot-dir (file-name-directory org-download-screenshot-file))
|
||
;; (org-download-screenshot-file
|
||
;; (if basename
|
||
;; (concat screenshot-dir basename) org-download-screenshot-file)))
|
||
;; (make-directory screenshot-dir t)
|
||
;; (if (functionp org-download-screenshot-method)
|
||
;; (funcall org-download-screenshot-method
|
||
;; org-download-screenshot-file)
|
||
;; (shell-command-to-string
|
||
;; (format org-download-screenshot-method
|
||
;; org-download-screenshot-file)))
|
||
;; (when (file-exists-p org-download-screenshot-file)
|
||
;; (org-download-markdown-image org-download-screenshot-file)
|
||
;; (delete-file org-download-screenshot-file))))
|
||
|
||
|
||
;; (defun org-download-markdown-insert-link (link filename)
|
||
;; (let* ((beg (point))
|
||
;; (line-beg (line-beginning-position))
|
||
;; (indent (- beg line-beg))
|
||
;; (in-item-p (org-in-item-p))
|
||
;; str)
|
||
;; (if (looking-back "^[ \t]+" line-beg)
|
||
;; (delete-region (match-beginning 0) (match-end 0))
|
||
;; (newline))
|
||
;; (insert (funcall org-download-annotate-function link))
|
||
;; (dolist (attr org-download-image-attr-list)
|
||
;; (insert attr "\n"))
|
||
;; (insert (if (= org-download-image-html-width 0)
|
||
;; ""
|
||
;; (format "#+attr_html: :width %dpx\n" org-download-image-html-width)))
|
||
;; (insert (if (= org-download-image-latex-width 0)
|
||
;; ""
|
||
;; (format "#+attr_latex: :width %dcm\n" org-download-image-latex-width)))
|
||
;; (insert (if (= org-download-image-org-width 0)
|
||
;; ""
|
||
;; (format "#+attr_org: :width %dpx\n" org-download-image-org-width)))
|
||
;; (insert (funcall org-download-markdown-link-format-function filename))
|
||
;; (org-download--display-inline-images)
|
||
;; (setq str (buffer-substring-no-properties line-beg (point)))
|
||
;; (when in-item-p
|
||
;; (indent-region line-beg (point) indent))
|
||
;; str))
|
||
|
||
;; (defun markdown-download-screenshot ()
|
||
;; (interactive)
|
||
;; (org-mode)
|
||
;; (org-download-markdown-screenshot)
|
||
;; (markdown-mode))
|
||
|
||
;;(add-hook 'markdown-mode-hook (lambda () (org-display-inline-images)))
|
||
|
||
#+end_src
|
||
|
||
* Writing
|
||
** Olivetti
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package olivetti
|
||
:init
|
||
(setq olivetti-body-width 100)
|
||
(setq olivetti-recall-visual-line-mode-entry-state t))
|
||
|
||
#+end_src
|
||
|
||
** darkroom
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package darkroom
|
||
:init
|
||
(setq darkroom-text-scale-increase 3))
|
||
|
||
#+end_src
|
||
|
||
* Development
|
||
** Ripgrep
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package rg)
|
||
|
||
#+end_src
|
||
** Tree-sitter
|
||
|
||
In order to update the language grammars, run the next command below.
|
||
|
||
#+begin_src emacs-lisp :tangle no
|
||
|
||
(mapc #'treesit-install-language-grammar (mapcar #'car treesit-language-source-alist))
|
||
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (setq treesit-language-source-alist
|
||
;; '((bash "https://github.com/tree-sitter/tree-sitter-bash")
|
||
;; (cmake "https://github.com/uyha/tree-sitter-cmake")
|
||
;; (c "https://github.com/tree-sitter/tree-sitter-c")
|
||
;; (cpp "https://github.com/tree-sitter/tree-sitter-cpp")
|
||
;; (css "https://github.com/tree-sitter/tree-sitter-css")
|
||
;; (elisp "https://github.com/Wilfred/tree-sitter-elisp")
|
||
;; (go "https://github.com/tree-sitter/tree-sitter-go")
|
||
;; (html "https://github.com/tree-sitter/tree-sitter-html")
|
||
;; (javascript "https://github.com/tree-sitter/tree-sitter-javascript" "master" "src")
|
||
;; (json "https://github.com/tree-sitter/tree-sitter-json")
|
||
;; (make "https://github.com/alemuller/tree-sitter-make")
|
||
;; (markdown "https://github.com/ikatyang/tree-sitter-markdown")
|
||
;; (python "https://github.com/tree-sitter/tree-sitter-python")
|
||
;; (toml "https://github.com/tree-sitter/tree-sitter-toml")
|
||
;; (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")
|
||
;; (typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")
|
||
;; (rust "https://github.com/tree-sitter/tree-sitter-rust")
|
||
;; (sql "https://github.com/m-novikov/tree-sitter-sql")
|
||
;; (yaml "https://github.com/ikatyang/tree-sitter-yaml")))
|
||
|
||
;; (add-hook 'rustic-mode-hook 'tree-sitter-mode)
|
||
;; (add-hook 'rustic-mode-hook 'tree-sitter-hl-mode)
|
||
|
||
(use-package emacs
|
||
:ensure nil
|
||
:init
|
||
(setq treesit-language-source-alist
|
||
'((bash . ("https://github.com/tree-sitter/tree-sitter-bash"))
|
||
(c . ("https://github.com/tree-sitter/tree-sitter-c"))
|
||
(cmake . ("https://github.com/uyha/tree-sitter-cmake"))
|
||
(cpp . ("https://github.com/tree-sitter/tree-sitter-cpp"))
|
||
(css . ("https://github.com/tree-sitter/tree-sitter-css"))
|
||
(elisp . ("https://github.com/Wilfred/tree-sitter-elisp"))
|
||
(go . ("https://github.com/tree-sitter/tree-sitter-go"))
|
||
(html . ("https://github.com/tree-sitter/tree-sitter-html"))
|
||
(javascript . ("https://github.com/tree-sitter/tree-sitter-javascript"))
|
||
(json . ("https://github.com/tree-sitter/tree-sitter-json"))
|
||
(julia . ("https://github.com/tree-sitter/tree-sitter-julia"))
|
||
(latex . ("https://github.com/latex-lsp/tree-sitter-latex"))
|
||
(make . ("https://github.com/alemuller/tree-sitter-make"))
|
||
(markdown . ("https://github.com/ikatyang/tree-sitter-markdown"))
|
||
(R . ("https://github.com/r-lib/tree-sitter-r"))
|
||
(python . ("https://github.com/tree-sitter/tree-sitter-python"))
|
||
(typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" "typescript/src" "typescript"))
|
||
(rust . ("https://github.com/tree-sitter/tree-sitter-rust"))
|
||
(sql . ("https://github.com/m-novikov/tree-sitter-sql"))
|
||
(toml . ("https://github.com/tree-sitter/tree-sitter-toml"))
|
||
(yaml . ("https://github.com/ikatyang/tree-sitter-yaml"))))
|
||
;; :hook (((rustic-mode) . tree-sitter-mode)
|
||
;; ((rustic-mode) . tree-sitter-hl-mode))
|
||
)
|
||
|
||
(use-package treesit-auto
|
||
:config
|
||
(global-treesit-auto-mode)
|
||
(setq treesit-auto-install 'prompt))
|
||
|
||
|
||
#+end_src
|
||
|
||
** direnv
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package direnv
|
||
;; :init (add-hook 'prog-mode-hook #'direnv-update-environment)
|
||
:custom (direnv-always-show-summary nil)
|
||
:config (direnv-mode))
|
||
|
||
#+end_src
|
||
|
||
** devdocs
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package devdocs)
|
||
|
||
#+end_src
|
||
|
||
** Projectile
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package projectile
|
||
:diminish projectile-mode
|
||
:config (projectile-mode)
|
||
:custom ((projectile-completion-system 'ivy)) ;; integrate ivy into completion system
|
||
:bind-keymap
|
||
("C-c p" . projectile-command-map) ; all projectile commands under this
|
||
:init
|
||
;; NOTE: Set this to the folder where you keep your Git repos!
|
||
(when (file-directory-p swarsel-projects-directory)
|
||
(setq projectile-project-search-path (list swarsel-projects-directory)))
|
||
;(setq projectile-switch-project-action #'projectile-dired) ;list files
|
||
(setq projectile-switch-project-action #'magit-status))
|
||
|
||
;; (use-package counsel-projectile
|
||
;; :config (counsel-projectile-mode))
|
||
|
||
#+end_src
|
||
|
||
** Project.el
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package project
|
||
;; :ensure nil
|
||
;; :bind
|
||
;; (:map project-prefix-map
|
||
;; ("v" . magit-project-status))
|
||
;; :config
|
||
;; (add-to-list 'project-switch-commands '(magit-project-status "Magit" "m")))
|
||
|
||
#+end_src
|
||
|
||
** Magit
|
||
|
||
- setup permanent github auth using Github CLI https://docs.github.com/en/get-started/getting-started-with-git/caching-your-github-credentials-in-git#platform-linux
|
||
- on fedora: 'sudo dnf install gh' and then 'gh auth login'
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package magit
|
||
:config
|
||
(setq magit-repository-directories `((,swarsel-projects-directory . 1)
|
||
(,swarsel-emacs-directory . 0)
|
||
(,swarsel-obsidian-directory . 0)))
|
||
:custom
|
||
(magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) ; stay in the same window
|
||
|
||
#+end_src
|
||
|
||
** Forge
|
||
|
||
NOTE: Make sure to configure a GitHub token before using this package!
|
||
- https://magit.vc/manual/forge/Token-Creation.html#Token-Creation
|
||
- https://magit.vc/manual/ghub/Getting-Started.html#Getting-Started
|
||
- https://magit.vc/manual/ghub/Storing-a-Token.html
|
||
- https://www.emacswiki.org/emacs/GnuPG
|
||
|
||
(1) in practice: github -<> settings -<> developer option -<>
|
||
create classic token with repo; user; read:org permissions
|
||
(2) install GnuGP (and add to PATH)
|
||
(3) create ~/.authinfo.gpg with the following info scheme:
|
||
machine api.github.com login USERNAME^forge password 012345abcdef...
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package forge
|
||
:after magit)
|
||
|
||
(with-eval-after-load 'forge
|
||
(add-to-list 'forge-alist
|
||
'("sgit.iue.tuwien.ac.at"
|
||
"sgit.iue.tuwien.ac.at/api/v1"
|
||
"sgit.iue.tuwien.ac.at"
|
||
forge-gitea-repository)))
|
||
#+end_src
|
||
|
||
** git-timemachine
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package git-timemachine
|
||
:hook (git-time-machine-mode . evil-normalize-keymaps)
|
||
:init (setq git-timemachine-show-minibuffer-details t)
|
||
:general
|
||
(general-nmap "SPC g t" 'git-timemachine-toggle)
|
||
(git-timemachine-mode-map
|
||
"C-k" 'git-timemachine-show-previous-revision
|
||
"C-j" 'git-timemachine-show-next-revision
|
||
"q" 'git-timemachine-quit))
|
||
|
||
#+end_src
|
||
|
||
** Delimiters (brackets)
|
||
|
||
- rainbow-delimiters colors all delimiters, also ones not in current selection
|
||
- paren highlights the current delimiter selection especially bold
|
||
- highlight-parentheses boldly highlights all delimiters in current selection
|
||
|
||
I am not completely sure on electric-pair-mode yet, sometimes it is very helpful, sometimes it annoys me to no end.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package rainbow-delimiters
|
||
:hook (prog-mode . rainbow-delimiters-mode))
|
||
|
||
(use-package highlight-parentheses
|
||
:config
|
||
(setq highlight-parentheses-colors '("black" "white" "black" "black" "black" "black" "black"))
|
||
(setq highlight-parentheses-background-colors '("magenta" "blue" "cyan" "green" "yellow" "orange" "red"))
|
||
(global-highlight-parentheses-mode t))
|
||
|
||
(electric-pair-mode 1)
|
||
(setq electric-pair-preserve-balance nil)
|
||
;; don't try to be overly smart
|
||
(setq electric-pair-delete-adjacent-pairs nil)
|
||
;; don't skip newline when auto-pairing parenthesis
|
||
(setq electric-pair-skip-whitespace-chars '(9 32))
|
||
|
||
#+end_src
|
||
|
||
** IDE
|
||
|
||
This section currently holds three different lsp-client implementations; at the moment I am using eglot; it is very sad that there is no end-all solution. All configs are left in for - I like lsp-mode for the debugging and lsp-bridge because asynchronous lsp is quite nice. However eglot is fast enough and I am mostly working on small projects anyways. Still, it is annoying to not have a debugger readily available.
|
||
|
||
*** DISABLED Company mode
|
||
|
||
The plan is to in the future use Vertico etc. instead and then switch to Corfu. Again, I do not have the time for this yet.
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package company
|
||
;; :after lsp-mode
|
||
;; :hook (lsp-mode . company-mode)
|
||
;; :bind (:map company-active-map
|
||
;; ("<tab>" . company-complete-selection))
|
||
;; (:map lsp-mode-map
|
||
;; ("<tab>" . company-indent-or-complete-common))
|
||
;; :custom
|
||
;; (company-minimum-prefix-length 1)
|
||
;; (company-idle-delay 0.7))
|
||
|
||
;; (use-package company-box
|
||
;; :hook (company-mode . company-box-mode))
|
||
|
||
#+end_src
|
||
|
||
*** IN USE Corfu
|
||
|
||
Currently unused
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package corfu
|
||
;; :custom
|
||
;; (corfu-cycle t)
|
||
;; :init
|
||
;; (global-corfu-mode))
|
||
|
||
(use-package corfu
|
||
:init
|
||
(global-corfu-mode)
|
||
(corfu-history-mode)
|
||
(corfu-popupinfo-mode) ; Popup completion info
|
||
:custom
|
||
(corfu-auto t)
|
||
(corfu-auto-prefix 3)
|
||
(corfu-auto-delay 0.3)
|
||
(corfu-cycle t)
|
||
(corfu-quit-no-match 'separator)
|
||
(corfu-separator ?\s)
|
||
;; (corfu-quit-no-match t)
|
||
(corfu-popupinfo-max-height 70)
|
||
(corfu-popupinfo-delay '(0.5 . 0.2))
|
||
;; (corfu-preview-current 'insert) ; insert previewed candidate
|
||
(corfu-preselect 'prompt)
|
||
(corfu-on-exact-match nil) ; Don't auto expand tempel snippets
|
||
;; Optionally use TAB for cycling, default is `corfu-complete'.
|
||
:bind (:map corfu-map
|
||
("M-SPC" . corfu-insert-separator)
|
||
("<return>" . swarsel/corfu-normal-return)
|
||
;; ("C-<return>" . swarsel/corfu-complete)
|
||
("S-<up>" . corfu-popupinfo-scroll-down)
|
||
("S-<down>" . corfu-popupinfo-scroll-up)
|
||
("C-<up>" . corfu-previous)
|
||
("C-<down>" . corfu-next)
|
||
("<up>" . swarsel/corfu-quit-and-up)
|
||
("<down>" . swarsel/corfu-quit-and-down))
|
||
)
|
||
|
||
|
||
;; dont disrupt file navigation with completions
|
||
(defun swarsel/corfu-normal-return (&optional arg)
|
||
(interactive)
|
||
(corfu-quit)
|
||
(newline)
|
||
)
|
||
|
||
;; (defun swarsel/corfu-complete (&optional arg)
|
||
;; (interactive)
|
||
;; (corfu-complete)
|
||
;; (newline)
|
||
;; )
|
||
|
||
(defun swarsel/corfu-quit-and-up (&optional arg)
|
||
(interactive)
|
||
(corfu-quit)
|
||
(evil-previous-visual-line))
|
||
|
||
(defun swarsel/corfu-quit-and-down (&optional arg)
|
||
(interactive)
|
||
(corfu-quit)
|
||
(evil-next-visual-line))
|
||
|
||
(use-package nerd-icons-corfu)
|
||
|
||
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)
|
||
|
||
(setq nerd-icons-corfu-mapping
|
||
'((array :style "cod" :icon "symbol_array" :face font-lock-type-face)
|
||
(boolean :style "cod" :icon "symbol_boolean" :face font-lock-builtin-face)
|
||
;; ...
|
||
(t :style "cod" :icon "code" :face font-lock-warning-face)))
|
||
|
||
(use-package cape
|
||
;; Bind dedicated completion commands
|
||
;; Alternative prefix keys: C-c p, M-p, M-+, ...
|
||
;; :bind (("C-c p p" . completion-at-point) ;; capf
|
||
;; ("C-c p t" . complete-tag) ;; etags
|
||
;; ("C-c p d" . cape-dabbrev) ;; or dabbrev-completion
|
||
;; ("C-c p h" . cape-history)
|
||
;; ("C-c p f" . cape-file)
|
||
;; ("C-c p k" . cape-keyword)
|
||
;; ("C-c p s" . cape-elisp-symbol)
|
||
;; ("C-c p e" . cape-elisp-block)
|
||
;; ("C-c p a" . cape-abbrev)
|
||
;; ("C-c p l" . cape-line)
|
||
;; ("C-c p w" . cape-dict)
|
||
;; ("C-c p :" . cape-emoji)
|
||
;; ("C-c p \\" . cape-tex)
|
||
;; ("C-c p _" . cape-tex)
|
||
;; ("C-c p ^" . cape-tex)
|
||
;; ("C-c p &" . cape-sgml)
|
||
;; ("C-c p r" . cape-rfc1345))
|
||
:init
|
||
;; Add to the global default value of `completion-at-point-functions' which is
|
||
;; used by `completion-at-point'. The order of the functions matters, the
|
||
;; first function returning a result wins. Note that the list of buffer-local
|
||
;; completion functions takes precedence over the global list.
|
||
(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-elisp-block)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-history)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-keyword)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-tex)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-sgml)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-rfc1345)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-abbrev)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-dict)
|
||
(add-to-list 'completion-at-point-functions #'cape-elisp-symbol)
|
||
;; (add-to-list 'completion-at-point-functions #'cape-line)
|
||
)
|
||
|
||
#+end_src
|
||
|
||
*** rust
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package rustic
|
||
;; :ensure
|
||
;; :bind (:map rustic-mode-map
|
||
;; ("M-j" . lsp-ui-imenu)
|
||
;; ("M-?" . lsp-find-references)
|
||
;; ("C-c C-c l" . flycheck-list-errors)
|
||
;; ("C-c C-c a" . lsp-execute-code-action)
|
||
;; ("C-c C-c r" . lsp-rename)
|
||
;; ("C-c C-c q" . lsp-workspace-restart)
|
||
;; ("C-c C-c Q" . lsp-workspace-shutdown)
|
||
;; ("C-c C-c s" . lsp-rust-analyzer-status))
|
||
;; :config
|
||
|
||
;; (setq rustic-format-on-save t)
|
||
;; (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook))
|
||
|
||
;; (defun rk/rustic-mode-hook ()
|
||
;; ;; so that run C-c C-c C-r works without having to confirm, but don't try to
|
||
;; ;; save rust buffers that are not file visiting. Once
|
||
;; ;; https://github.com/brotzeit/rustic/issues/253 has been resolved this should
|
||
;; ;; no longer be necessary.
|
||
;; (when buffer-file-name
|
||
;; (setq-local buffer-save-without-query t))
|
||
;; (add-hook 'before-save-hook 'lsp-format-buffer nil t))
|
||
|
||
;; (use-package rustic
|
||
;; :config
|
||
;; (setq rustic-format-on-save t)
|
||
;; (setq rustic-lsp-client 'eglot)
|
||
;; :custom
|
||
;; (lsp-rust-analyzer-cargo-watch-command "clippy")
|
||
;; (lsp-rust-analyzer-server-display-inlay-hints t)
|
||
;; :mode ("\\.rs" . rustic-mode))
|
||
|
||
(use-package rustic
|
||
:config
|
||
(setq rustic-format-on-save t)
|
||
(setq rustic-lsp-client 'eglot)
|
||
:mode ("\\.rs" . rustic-mode))
|
||
#+end_src
|
||
|
||
*** Python
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; run the python inferior shell immediately upon entering a python buffer
|
||
(add-hook 'python-mode-hook 'swarsel/run-python)
|
||
|
||
(defun swarsel/run-python ()
|
||
(save-selected-window
|
||
(switch-to-buffer-other-window (process-buffer (python-shell-get-or-create-process (python-shell-parse-command))))))
|
||
#+end_src
|
||
|
||
*** CUDA
|
||
|
||
1. M-x dap-cpptools-setup
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package cuda-mode)
|
||
|
||
;; ;; add path manually;
|
||
;; (add-hook 'cuda-mode-hook
|
||
;; (lambda ()
|
||
;; ( setq c-basic-offset 4
|
||
;; flycheck-cuda-include-path (list "."))
|
||
;; ))
|
||
|
||
#+end_src
|
||
|
||
*** Tramp
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
|
||
|
||
(use-package tramp
|
||
:init
|
||
(setq vc-ignore-dir-regexp
|
||
(format "\\(%s\\)\\|\\(%s\\)"
|
||
vc-ignore-dir-regexp
|
||
tramp-file-name-regexp))
|
||
(setq tramp-default-method "ssh")
|
||
(setq tramp-auto-save-directory
|
||
(expand-file-name "tramp-auto-save" user-emacs-directory))
|
||
(setq tramp-persistency-file-name
|
||
(expand-file-name "tramp-connection-history" user-emacs-directory))
|
||
(setq password-cache-expiry nil)
|
||
(setq tramp-use-ssh-controlmaster-options nil)
|
||
(setq remote-file-name-inhibit-cache nil)
|
||
:config
|
||
(customize-set-variable 'tramp-ssh-controlmaster-options
|
||
(concat
|
||
"-o ControlPath=/tmp/ssh-tramp-%%r@%%h:%%p "
|
||
"-o ControlMaster=auto -o ControlPersist=yes"))
|
||
)
|
||
|
||
|
||
|
||
#+end_src
|
||
|
||
*** Commenting
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package evil-nerd-commenter
|
||
:bind ("M-/" . evilnc-comment-or-uncomment-lines))
|
||
|
||
#+end_src
|
||
|
||
*** yasnippet
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package yasnippet
|
||
:init (yas-global-mode 1)
|
||
:config
|
||
(yas-reload-all)
|
||
)
|
||
|
||
;; (use-package yasnippet-snippets)
|
||
|
||
#+end_src
|
||
|
||
The following block is 100% stolen from Dominik :P
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
|
||
(setq wtf/latex-greek-prefix "'")
|
||
(setq wtf/latex-math-prefix "`")
|
||
(setq wtf/latex-mathbb-prefix "''")
|
||
(setq swarsel/latex-mathcal-prefix "``")
|
||
|
||
(use-package yasnippet
|
||
:config
|
||
(setq swtf/greek-alphabet
|
||
'(("a" . "\\alpha")
|
||
("b" . "\\beta" )
|
||
("g" . "\\gamma")
|
||
("d" . "\\delta")
|
||
("e" . "\\epsilon")
|
||
("z" . "\\zeta")
|
||
("h" . "\\eta")
|
||
("t" . "\\theta")
|
||
("i" . "\\iota")
|
||
("k" . "\\kappa")
|
||
("l" . "\\lambda")
|
||
("m" . "\\mu")
|
||
("n" . "\\nu")
|
||
("x" . "\\xi")
|
||
("p" . "\\pi")
|
||
("r" . "\\rho")
|
||
("s" . "\\sigma")
|
||
("t" . "\\tau")
|
||
("u" . "\\upsilon")
|
||
("f" . "\\phi")
|
||
("c" . "\\chi")
|
||
("v" . "\\psi")
|
||
("o" . "\\omega")))
|
||
|
||
|
||
;; The same for capitalized letters
|
||
(dolist (elem swtf/greek-alphabet)
|
||
(let ((key (car elem))
|
||
(value (cdr elem)))
|
||
(when (string-equal key (downcase key))
|
||
(add-to-list 'swtf/greek-alphabet
|
||
(cons
|
||
(capitalize (car elem))
|
||
(concat
|
||
(substring value 0 1)
|
||
(capitalize (substring value 1 2))
|
||
(substring value 2)))))))
|
||
|
||
(yas-define-snippets
|
||
'latex-mode
|
||
(mapcar
|
||
(lambda (elem)
|
||
(list (concat wtf/latex-greek-prefix (car elem)) (cdr elem) (concat "Greek letter " (car elem))))
|
||
swtf/greek-alphabet))
|
||
|
||
(setq wtf/english-alphabet
|
||
'("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))
|
||
|
||
(dolist (elem wtf/english-alphabet)
|
||
(when (string-equal elem (downcase elem))
|
||
(add-to-list 'wtf/english-alphabet (upcase elem))))
|
||
|
||
|
||
(yas-define-snippets
|
||
'latex-mode
|
||
(mapcar
|
||
(lambda (elem)
|
||
(list (concat wtf/latex-mathbb-prefix elem) (concat "\\mathbb{" elem "}") (concat "Mathbb letter " elem)))
|
||
wtf/english-alphabet))
|
||
|
||
(yas-define-snippets
|
||
'latex-mode
|
||
(mapcar
|
||
(lambda (elem)
|
||
(list (concat swarsel/latex-mathcal-prefix elem) (concat "\\mathcal{" elem "}") (concat "Mathcal letter " elem)))
|
||
wtf/english-alphabet))
|
||
|
||
(setq swtf/latex-math-symbols
|
||
'(("x" . "\\times")
|
||
("*" . "\\cdot")
|
||
("." . "\\ldots")
|
||
("op" . "\\operatorname{$1}$0")
|
||
("o" . "\\circ")
|
||
("V" . "\\forall")
|
||
("v" . "\\vee")
|
||
("w" . "\\wedge")
|
||
("q" . "\\quad")
|
||
("f" . "\\frac{$1}{$2}$0")
|
||
("s" . "\\sum_{$1}^{$2}$0")
|
||
("p" . "\\prod_{$1}^{$2}$0")
|
||
("e" . "\\exists")
|
||
("i" . "\\int_{$1}^{$2}$0")
|
||
("c" . "\\cap")
|
||
("u" . "\\cup")
|
||
("0" . "\\emptyset")))
|
||
|
||
|
||
(yas-define-snippets
|
||
'latex-mode
|
||
(mapcar
|
||
(lambda (elem)
|
||
(let ((key (car elem))
|
||
(value (cdr elem)))
|
||
(list (concat wtf/latex-math-prefix key) value (concat "Math symbol " value))))
|
||
swtf/latex-math-symbols))
|
||
)
|
||
|
||
|
||
|
||
#+end_src
|
||
|
||
|
||
|
||
*** Duplicate Lines
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(defun duplicate-line (arg)
|
||
"Duplicate current line, leaving point in lower line."
|
||
(interactive "*p")
|
||
|
||
;; save the point for undo
|
||
(setq buffer-undo-list (cons (point) buffer-undo-list))
|
||
|
||
;; local variables for start and end of line
|
||
(let ((bol (save-excursion (beginning-of-line) (point)))
|
||
eol)
|
||
(save-excursion
|
||
|
||
;; don't use forward-line for this, because you would have
|
||
;; to check whether you are at the end of the buffer
|
||
(end-of-line)
|
||
(setq eol (point))
|
||
|
||
;; store the line and disable the recording of undo information
|
||
(let ((line (buffer-substring bol eol))
|
||
(buffer-undo-list t)
|
||
(count arg))
|
||
;; insert the line arg times
|
||
(while (> count 0)
|
||
(newline) ;; because there is no newline in 'line'
|
||
(insert line)
|
||
(setq count (1- count)))
|
||
)
|
||
|
||
;; create the undo information
|
||
(setq buffer-undo-list (cons (cons eol (point)) buffer-undo-list)))
|
||
) ; end-of-let
|
||
|
||
;; put the point in the lowest line and return
|
||
(next-line arg))
|
||
|
||
#+end_src
|
||
|
||
*** DISABLED lsp-mode
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package lsp-mode
|
||
;; :ensure t
|
||
;; :init
|
||
;; ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
|
||
;; (setq lsp-keymap-prefix "C-c l")
|
||
;; :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
|
||
;; (python-mode . lsp)
|
||
;; (c++-mode . lsp)
|
||
;; (c-mode . lsp)
|
||
;; (cuda-mode . lsp)
|
||
;; (rustic-mode . lsp)
|
||
;; ;; if you want which-key integration
|
||
;; (lsp-mode . lsp-enable-which-key-integration))
|
||
;; :commands lsp)
|
||
|
||
;; (use-package lsp-ui
|
||
;; :config
|
||
;; (setq lsp-ui-doc-enable t
|
||
;; lsp-ui-doc-show-with-cursor t
|
||
;; lsp-ui-doc-delay 0.5
|
||
;; lsp-ui-doc-max-height 70)
|
||
;; )
|
||
|
||
;; optionally if you want to use debugger
|
||
;; (use-package dap-mode)
|
||
|
||
;; (use-package lsp-treemacs
|
||
;; :after lsp)
|
||
|
||
;; ;; currently there is a bug with the double click behavior that was recently added. Fixed by this
|
||
;; (autoload 'treemacs-define-doubleclick-action "treemacs-mouse-interface" nil nil)
|
||
|
||
;; ;; (use-package flycheck
|
||
;; :hook
|
||
;; ((lsp-mode text-mode) . flycheck-mode)
|
||
;; :config
|
||
;; (define-key flycheck-mode-map flycheck-keymap-prefix nil)
|
||
;; ;;(setq flycheck-keymap-prefix (kbd my-flycheck-prefix))
|
||
;; (define-key flycheck-mode-map flycheck-keymap-prefix
|
||
;; flycheck-command-map))
|
||
|
||
;; ;; (use-package flycheck-posframe
|
||
;; :ensure t
|
||
;; :after flycheck
|
||
;; :config (add-hook 'flycheck-mode-hook #'flycheck-posframe-mode)
|
||
;; :init
|
||
;; (setq
|
||
;; flycheck-posframe-position 'point-top-left-corner
|
||
;; flycheck-posframe-error-prefix "❌ "
|
||
;; flycheck-posframe-info-prefix "ℹ️️️ "
|
||
;; flycheck-posframe-warning-prefix "⚠️ "
|
||
;; flycheck-posframe-prefix "💬 "))
|
||
#+end_src
|
||
|
||
*** IN USE eglot
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package eglot
|
||
:ensure nil
|
||
:hook
|
||
((python-mode
|
||
c-mode
|
||
c++-mode
|
||
) . (lambda () (progn
|
||
(eglot-ensure)
|
||
(add-hook 'before-save-hook 'eglot-format nil 'local))))
|
||
:custom
|
||
(eldoc-echo-area-use-multiline-p nil)
|
||
(completion-category-defaults nil)
|
||
:config
|
||
;; (push '(rustic-ts-mode . eglot-rust-analyzer) eglot-server-programs)
|
||
(push '(rustic-mode . eglot-rust-analyzer) eglot-server-programs)
|
||
(add-to-list 'eglot-server-programs '((rust-mode) . (eglot-rust-analyzer "rust-analyzer")))
|
||
;; (add-to-list 'eglot-server-programs '((python-mode) . ("pylsp")))
|
||
;; (add-to-list 'eglot-server-programs '((c-mode) . ("clangd")))
|
||
:bind (:map eglot-mode-map
|
||
("M-(" . flymake-goto-next-error)
|
||
("C-c ," . eglot-code-actions)))
|
||
|
||
(use-package breadcrumb
|
||
:config (breadcrumb-mode))
|
||
|
||
|
||
#+end_src
|
||
|
||
*** DISABLED lsp-bridge
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package lsp-bridge
|
||
;; :ensure nil
|
||
;; :init
|
||
;; (global-lsp-bridge-mode)
|
||
;; :config
|
||
;; (setq lsp-bridge-enable-debug nil
|
||
;; lsp-bridge-enable-auto-format-code 0
|
||
;; lsp-bridge-python-lsp-server 'pylsp
|
||
;; lsp-bridge-disable-backup nil
|
||
;; lsp-bridge-enable-org-babel 1
|
||
;; acm-enable-search-file-words 0
|
||
;; lsp-bridge-enable-hover-diagnostic 1)
|
||
;; )
|
||
|
||
|
||
|
||
#+end_src
|
||
|
||
** Prevent breaking of hardlinks
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(setq backup-by-copying-when-linked t)
|
||
|
||
#+end_src
|
||
|
||
* File Management
|
||
** Dired
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package dired
|
||
;; :ensure nil
|
||
;; :commands (dired dired-jump)
|
||
;; :bind (("C-x C-j" . dired-jump))
|
||
;; :custom ((dired-listing-switches "-agho --group-directories-first"))
|
||
;; :config
|
||
;; (evil-collection-define-key 'normal 'dired-mode-map
|
||
;; "h" 'dired-single-up-directory
|
||
;; "l" 'dired-single-buffer))
|
||
|
||
;; (use-package dired-single)
|
||
|
||
;; (use-package nerd-icons-dired
|
||
;; :hook
|
||
;; (dired-mode . nerd-icons-dired-mode))
|
||
;; (use-package nerd-icons-completion
|
||
;; :after nerd-icons)
|
||
;; (use-package nerd-icons-ivy-rich)
|
||
;; (use-package nerd-icons-ibuffer)
|
||
;; ;; more colorful dired
|
||
;; (use-package diredfl
|
||
;; :hook
|
||
;; (dired-mode . diredfl-mode))
|
||
|
||
#+end_src
|
||
** Dirvish
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package dirvish
|
||
:init
|
||
(dirvish-override-dired-mode)
|
||
:config
|
||
(dirvish-peek-mode)
|
||
(dirvish-side-follow-mode)
|
||
:custom
|
||
(delete-by-moving-to-trash t)
|
||
(dired-listing-switches
|
||
"-l --almost-all --human-readable --group-directories-first --no-group")
|
||
(dirvish-attributes
|
||
'(vc-state subtree-state nerd-icons collapse file-time file-size))
|
||
(dirvish-quick-access-entries
|
||
'(("h" "~/" "Home")
|
||
("c" "~/.dotfiles/" "Config")
|
||
("d" "~/Downloads/" "Downloads")
|
||
("D" "~/Documents/" "Documents")
|
||
("p" "~/Documents/GitHub/" "Projects")
|
||
("/" "/" "Root")))
|
||
:bind
|
||
(("<C-i> d" . 'dirvish)
|
||
("C-=" . 'dirvish-side)
|
||
:map dirvish-mode-map
|
||
("h" . dired-up-directory)
|
||
("<left>" . dired-up-directory)
|
||
("l" . dired-find-file)
|
||
("<right>" . dired-find-file)
|
||
("j" . evil-next-visual-line)
|
||
("k" . evil-previous-visual-line)
|
||
("a" . dirvish-quick-access)
|
||
("f" . dirvish-file-info-menu)
|
||
("z" . dirvish-history-last)
|
||
("J" . dirvish-history-jump)
|
||
("y" . dirvish-yank-menu)
|
||
("TAB" . dirvish-subtree-toggle)
|
||
("M-f" . dirvish-history-go-forward)
|
||
("M-b" . dirvish-history-go-backward)
|
||
("M-l" . dirvish-ls-switches-menu)
|
||
("M-m" . dirvish-mark-menu)
|
||
("M-t" . dirvish-layout-toggle)
|
||
("M-s" . dirvish-setup-menu)
|
||
("M-e" . dirvish-emerge-menu)
|
||
("M-j" . dirvish-fd-jump)))
|
||
|
||
#+end_src
|
||
** pdf support
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package pdf-tools
|
||
:init
|
||
(if (not (boundp 'pdf-tools-directory))
|
||
(pdf-tools-install))
|
||
:mode ("\\.pdf" . pdf-view-mode))
|
||
|
||
#+end_src
|
||
|
||
** open some file types in external programs
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package openwith)
|
||
(openwith-mode t)
|
||
;; (setq openwith-associations '(("\\.pdf\\'" "evince" (file)) ("\\.xopp\\'" "xournalpp" (file))))
|
||
(setq openwith-associations '(("\\.xopp\\'" "xournalpp" (file))))
|
||
;(setq openwith-associations '(("\\.xopp\\'" "xournalpp" (file))))
|
||
#+end_src
|
||
|
||
** Jupyter
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package ein)
|
||
|
||
#+end_src
|
||
|
||
* Applications
|
||
** Obsidian
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package obsidian
|
||
;; :ensure t
|
||
;; :demand t
|
||
;; :config
|
||
;; (obsidian-specify-path swarsel-obsidian-vault-directory)
|
||
;; (global-obsidian-mode t)
|
||
;; :custom
|
||
;; ;; This directory will be used for `obsidian-capture' if set.
|
||
;; (obsidian-inbox-directory "Inbox")
|
||
;; (bind-key (kbd "C-c M-o") 'obsidian-hydra/body 'obsidian-mode-map)
|
||
;; :bind (:map obsidian-mode-map
|
||
;; ;; Replace C-c C-o with Obsidian.el's implementation. It's ok to use another key binding.
|
||
;; ("C-c C-o" . obsidian-follow-link-at-point)
|
||
;; ;; Jump to backlinks
|
||
;; ("C-c C-b" . obsidian-backlink-jump)
|
||
;; ;; If you prefer you can use `obsidian-insert-link'
|
||
;; ("C-c C-l" . obsidian-insert-wikilink)))
|
||
|
||
#+end_src
|
||
|
||
** Anki
|
||
|
||
*** Basic Anki setup
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (use-package anki-editor
|
||
;; :after org
|
||
;; :bind (:map org-mode-map
|
||
;; ("<f12>" . anki-editor-cloze-region-auto-incr)
|
||
;; ("<f11>" . anki-editor-cloze-region-dont-incr)
|
||
;; ("<f10>" . anki-editor-reset-cloze-number)
|
||
;; ("<f9>" . anki-editor-push-tree))
|
||
;; :hook (org-capture-after-finalize . anki-editor-reset-cloze-number) ; Reset cloze-number after each capture.
|
||
;; :config
|
||
;; (setq anki-editor-create-decks t ;; Allow anki-editor to create a new deck if it doesn't exist
|
||
;; anki-editor-org-tags-as-anki-tags t)
|
||
|
||
;; (defun anki-editor-cloze-region-auto-incr (&optional arg)
|
||
;; "Cloze region without hint and increase card number."
|
||
;; (interactive)
|
||
;; (anki-editor-cloze-region swarsel-anki-editor-cloze-number "")
|
||
;; (setq swarsel-anki-editor-cloze-number (1+ swarsel-anki-editor-cloze-number))
|
||
;; (forward-sexp))
|
||
;; (defun anki-editor-cloze-region-dont-incr (&optional arg)
|
||
;; "Cloze region without hint using the previous card number."
|
||
;; (interactive)
|
||
;; (anki-editor-cloze-region (1- swarsel-anki-editor-cloze-number) "")
|
||
;; (forward-sexp))
|
||
;; (defun anki-editor-reset-cloze-number (&optional arg)
|
||
;; "Reset cloze number to ARG or 1"
|
||
;; (interactive)
|
||
;; (setq swarsel-anki-editor-cloze-number (or arg 1)))
|
||
;; (defun anki-editor-push-tree ()
|
||
;; "Push all notes under a tree."
|
||
;; (interactive)
|
||
;; (anki-editor-push-notes '(4))
|
||
;; (anki-editor-reset-cloze-number))
|
||
;; ;; Initialize
|
||
;; (anki-editor-reset-cloze-number)
|
||
;; )
|
||
|
||
;; (require 'anki-editor)
|
||
|
||
#+end_src
|
||
|
||
*** Own Anki functions
|
||
|
||
- These functions enable you to quickly set the destination note type and deck
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
;; (defvar swarsel-anki-deck nil)
|
||
;; (defvar swarsel-anki-notetype nil)
|
||
;; (defvar swarsel-anki-fields nil)
|
||
|
||
;; (defun swarsel-anki-set-deck-and-notetype ()
|
||
;; (interactive)
|
||
;; (setq swarsel-anki-deck (completing-read "Choose a deck: "
|
||
;; (sort (anki-editor-deck-names) #'string-lessp)))
|
||
;; (setq swarsel-anki-notetype (completing-read "Choose a note type: "
|
||
;; (sort (anki-editor-note-types) #'string-lessp)))
|
||
;; (setq swarsel-anki-fields (progn
|
||
;; (anki-editor--anki-connect-invoke-result "modelFieldNames" `((modelName . ,swarsel-anki-notetype)))))
|
||
;; )
|
||
|
||
;; (defun swarsel-anki-make-template-string ()
|
||
;; (if (not swarsel-anki-deck)
|
||
;; (call-interactively 'swarsel-anki-set-deck-and-notetype))
|
||
;; (setq swarsel-temp swarsel-anki-fields)
|
||
;; (concat (concat "* %<%H:%M>\n:PROPERTIES:\n:ANKI_NOTE_TYPE: " swarsel-anki-notetype "\n:ANKI_DECK: " swarsel-anki-deck "\n:END:\n** ")(pop swarsel-temp) "\n%?\n** " (mapconcat 'identity swarsel-temp "\n\n** ") "\n\n"))
|
||
|
||
;; (defun swarsel-today()
|
||
;; (format-time-string "%Y-%m-%d"))
|
||
|
||
;; (defun swarsel-obsidian-daily ()
|
||
;; (interactive)
|
||
;; (if (not (file-exists-p (expand-file-name (concat (swarsel-today) ".md") swarsel-obsidian-daily-directory)))
|
||
;; (write-region "" nil (expand-file-name (concat (swarsel-today) ".md") swarsel-obsidian-daily-directory))
|
||
;; )
|
||
;; (find-file (expand-file-name (concat (swarsel-today) ".md") swarsel-obsidian-daily-directory)))
|
||
|
||
#+end_src
|
||
|
||
* Email + Calendar
|
||
** make sure mu4e is found
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(let ((mu4epath
|
||
(concat
|
||
(f-dirname
|
||
(file-truename
|
||
(executable-find "mu")))
|
||
"/../share/emacs/site-lisp/mu4e")))
|
||
(when (and
|
||
(string-prefix-p "/nix/store/" mu4epath)
|
||
(file-directory-p mu4epath))
|
||
(add-to-list 'load-path mu4epath)))
|
||
|
||
#+end_src
|
||
|
||
** mu4e
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package mu4e
|
||
:ensure nil
|
||
;; :load-path "/usr/share/emacs/site-lisp/mu4e/"
|
||
;;:defer 20 ; Wait until 20 seconds after startup
|
||
:config
|
||
|
||
;; This is set to 't' to avoid mail syncing issues when using mbsync
|
||
(setq send-mail-function 'smtpmail-send-it)
|
||
(setq mu4e-change-filenames-when-moving t)
|
||
(setq mu4e-mu-binary (executable-find "mu"))
|
||
|
||
(setq mu4e-update-interval 180)
|
||
(setq mu4e-get-mail-command "mbsync -a")
|
||
(setq mu4e-maildir "~/Mail")
|
||
|
||
;; enable inline images
|
||
(setq mu4e-view-show-images t)
|
||
;; use imagemagick, if available
|
||
(when (fboundp 'imagemagick-register-types)
|
||
(imagemagick-register-types))
|
||
|
||
(setq mu4e-drafts-folder "/Drafts")
|
||
(setq mu4e-sent-folder "/Sent Mail")
|
||
(setq mu4e-refile-folder "/All Mail")
|
||
(setq mu4e-trash-folder "/Trash")
|
||
|
||
(setq mu4e-maildir-shortcuts
|
||
'((:maildir "/leon/Inbox" :key ?1)
|
||
(:maildir "/nautilus/Inbox" :key ?2)
|
||
(:maildir "/mrswarsel/Inbox" :key ?3)
|
||
(:maildir "/Sent Mail" :key ?s)
|
||
(:maildir "/Trash" :key ?t)
|
||
(:maildir "/Drafts" :key ?d)
|
||
(:maildir "/All Mail" :key ?a))))
|
||
|
||
(setq user-mail-address "leon.schwarzaeugl@gmail.com"
|
||
user-full-name "Leon Schwarzäugl")
|
||
|
||
#+end_src
|
||
|
||
** mu4e-alert
|
||
|
||
Choose the style you prefer for desktop notifications
|
||
If you are on Linux you can use
|
||
1. notifications - Emacs lisp implementation of the Desktop Notifications API
|
||
2. libnotify - Notifications using the `notify-send' program, requires `notify-send' to be in PATH
|
||
|
||
On Mac OSX you can set style to
|
||
1. notifier - Notifications using the `terminal-notifier' program, requires `terminal-notifier' to be in PATH
|
||
1. growl - Notifications using the `growl' program, requires `growlnotify' to be in PATH
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package mu4e-alert)
|
||
(mu4e-alert-set-default-style 'libnotify)
|
||
(add-hook 'after-init-hook #'mu4e-alert-enable-notifications)
|
||
|
||
(mu4e t)
|
||
#+end_src
|
||
|
||
** Calendar
|
||
|
||
#+begin_src emacs-lisp
|
||
|
||
(use-package org-caldav
|
||
:init
|
||
|
||
(setq org-caldav-url "https://stash.swarsel.win/remote.php/dav/calendars/Swarsele")
|
||
(setq org-caldav-calendars
|
||
'((:calendar-id "personal"
|
||
:inbox "~/Calendars/leon_cal.org")))
|
||
;; (setq org-caldav-backup-file "~/org-caldav/org-caldav-backup.org")
|
||
;; (setq org-caldav-save-directory "~/org-caldav/")
|
||
|
||
:config
|
||
(setq org-icalendar-alarm-time 1)
|
||
;; This makes sure to-do items as a category can show up on the calendar
|
||
(setq org-icalendar-include-todo t)
|
||
;; This ensures all org "deadlines" show up, and show up as due dates
|
||
(setq org-icalendar-use-deadline '(event-if-todo event-if-not-todo todo-due))
|
||
;; This ensures "scheduled" org items show up, and show up as start times
|
||
(setq org-icalendar-use-scheduled '(todo-start event-if-todo event-if-not-todo))
|
||
)
|
||
|
||
(use-package calfw
|
||
:ensure nil
|
||
:bind ("C-c A" . swarsel/open-calendar)
|
||
:init
|
||
(use-package calfw-cal
|
||
:ensure nil)
|
||
(use-package calfw-org
|
||
:ensure nil)
|
||
(use-package calfw-ical
|
||
:ensure nil)
|
||
:config
|
||
(bind-key "g" 'cfw:refresh-calendar-buffer cfw:calendar-mode-map)
|
||
(bind-key "q" 'evil-quit cfw:details-mode-map)
|
||
;; (custom-set-faces
|
||
;; '(cfw:face-title ((t (:foreground "#f0dfaf" :weight bold :height 65))))
|
||
;; )
|
||
)
|
||
|
||
(defun swarsel/open-calendar ()
|
||
(interactive)
|
||
(unless (eq swarsel-caldav-synced 1) (org-caldav-sync) (setq swarsel-caldav-synced 1))
|
||
;; (select-frame (make-frame '((name . "calendar")))) ; makes a new frame and selects it
|
||
;; (set-face-attribute 'default (selected-frame) :height 65) ; reduces the font size of the new frame
|
||
(cfw:open-calendar-buffer
|
||
:contents-sources
|
||
(list
|
||
(cfw:org-create-source "Purple") ; orgmode source
|
||
(cfw:ical-create-source "TISS" "https://tiss.tuwien.ac.at/events/rest/calendar/personal?locale=de&token=4463bf7a-87a3-490a-b54c-99b4a65192f3" "Cyan"))))
|
||
|
||
#+end_src
|
||
|
||
* Startup Application Scripts
|
||
|
||
Yep, none currently.
|
||
|
||
* Emacs startup screen
|
||
#+begin_src emacs-lisp
|
||
;;show mail
|
||
;;(mu4e)
|
||
|
||
(use-package dashboard
|
||
:ensure t
|
||
:config
|
||
(dashboard-setup-startup-hook)
|
||
;; (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")))
|
||
(setq dashboard-display-icons-p t ;; display icons on both GUI and terminal
|
||
dashboard-icon-type 'nerd-icons ;; use `nerd-icons' package
|
||
dashboard-set-file-icons t
|
||
dashboard-items '((recents . 5)
|
||
(projects . 5)
|
||
(agenda . 5))
|
||
dashboard-set-footer nil
|
||
dashboard-banner-logo-title "Welcome to SwarsEmacs!"
|
||
dashboard-image-banner-max-height 300
|
||
dashboard-startup-banner "~/.dotfiles/wallpaper/swarsel.png"
|
||
dashboard-projects-backend 'projectile
|
||
dashboard-set-navigator t
|
||
dashboard-navigator-buttons
|
||
`(;; line1
|
||
((,""
|
||
"SwarselSocial"
|
||
"Browse Swarsele"
|
||
(lambda (&rest _) (browse-url "instagram.com/Swarsele")))
|
||
|
||
(,""
|
||
"SwarselSound"
|
||
"Browse SwarselSound"
|
||
(lambda (&rest _) (browse-url "sound.swarsel.win")) )
|
||
(,""
|
||
"SwarselSwarsel"
|
||
"Browse Swarsel"
|
||
(lambda (&rest _) (browse-url "github.com/Swarsel")) )
|
||
(,""
|
||
"SwarselStash"
|
||
"Browse SwarselStash"
|
||
(lambda (&rest _) (browse-url "stash.swarsel.win")) )
|
||
(,""
|
||
"SwarselSport"
|
||
"Browse SwarselSports"
|
||
(lambda (&rest _) (browse-url "social.parkour.wien/@Lenno")))
|
||
)
|
||
(
|
||
(,""
|
||
"swarsel.win"
|
||
"Browse swarsel.win"
|
||
(lambda (&rest _) (browse-url "swarsel.win")))
|
||
)
|
||
)))
|
||
(setq dashboard-projects-switch-function 'counsel-projectile-switch-project-by-name)
|
||
|
||
|
||
#+end_src
|
||
* Fix gpg hangup bug
|
||
|
||
We need to add this last line, because otherwise gpg will crash on the most recent version when saving a .gpg file within emacs.
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq gc-cons-threshold (* 800 1000 ))
|
||
(fset 'epg-wait-for-status 'ignore)
|
||
#+end_src
|