;; diese Datei unter dem Namen ~/.emacs speichern! ;; ======== Grundeinstellungen ==================================== (cua-mode 1) ;Cut&Paste mit Strg+C/X/V (setq inhibit-startup-message t) ;kein Emacs-Startbildschirm (setq screen-preserve-screen-position t) ;zurück zur letzten Zeile (setq scroll-step 5) ;bei Scrollen Sprünge von 5 Zeilen (column-number-mode 1) ; ... Spaltennummern in der Statusleiste (abbrev-mode 0) ;kein automatisches expand-abbrev (setq require-final-newline t) ;letzte Zeile automatisch mit Return abschließen (save-place-mode) ;Cursor-Position innerhalb der Datei merken ;; automatische Backups nicht im lokalen Verzeichnis, sondern in ~/.emacs.d/backups/ (setq backup-directory-alist `(("." . ,(concat user-emacs-directory "backups")))) (setq auto-save-file-name-transforms `((".*" ,(concat user-emacs-directory "backups/") t))) ;; Spaltenbreite für Zeilennummern (nur Markdown) (setq-default display-line-numbers-width 4) ;; Abkürzungstabelle automatisch laden und speichern ;; Falls ~/.abbrev_defs nicht existiert, leere Datei anlegen (kein Fehler) (let ((abbrev-file "~/.abbrev_defs")) (unless (file-exists-p abbrev-file) (write-region "" nil abbrev-file)) (read-abbrev-file abbrev-file)) (setq save-abbrevs t) ;automat. speichern ;; ======== Packages ================================================ ;; package.el initialisieren und MELPA-Repo hinzufügen (falls erforderlich) (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize) ;; Paket-Repo aktualisieren (first run / new machine) (when (not package-archive-contents) (package-refresh-contents)) ;; alle erforderlichen Pakete automatisch laden (unless (package-installed-p 'use-package) (package-install 'use-package)) (require 'use-package) (setq use-package-always-ensure t) ;; scratch-Buffer automatisch speichern (https://github.com/Fanael/persistent-scratch) (use-package persistent-scratch :config (persistent-scratch-setup-default)) ;; weiche Zeilenumbrüche mit Einrückung bei Listen etc. (use-package adaptive-wrap :hook (visual-line-mode . adaptive-wrap-prefix-mode)) ;; Spalte mit Zeilennummern / zentrierter Text (use-package visual-fill-column :hook (markdown-mode . visual-fill-column-mode) :config (setq-default visual-fill-column-width 100) (setq visual-fill-column-width 100)) ;; Markdown-Modus (use-package markdown-mode :mode (("\\.text\\'" . markdown-mode) ("\\.md\\'" . markdown-mode)) :hook ((markdown-mode . visual-line-mode) ; soft-wrap long lines (markdown-mode . display-line-numbers-mode) ; show line numbers (markdown-mode . visual-fill-column-mode) ; center text within column width (markdown-mode . (lambda () (setq fill-column 79))))) ; hard-wrap at 79 chars ;; Unfill: mehrzeilige Absätze zu einer langen Zeile verbinden (Shift+F4) (use-package unfill) ;; mehr Komfort im Minibuffer (use-package vertico :config (vertico-mode 1) ; sort buffer list by 'recently shown' (setq vertico-sort-override-function (lambda (candidates) (if (eq minibuffer-history-variable 'buffer-name-history) (let ((hist (symbol-value minibuffer-history-variable))) (sort candidates (lambda (a b) (let ((pa (or (cl-position a hist :test #'equal) most-positive-fixnum)) (pb (or (cl-position b hist :test #'equal) most-positive-fixnum))) (< pa pb))))) candidates)))) (use-package orderless :config (setq completion-styles '(orderless basic))) (use-package marginalia :config (marginalia-mode 1)) ;; schönere Statuszeile (setzt voraus, dass die JetBrains Nerd Fonts ;; installiert und als Emacs-Font verwendet werden) (use-package nerd-icons :config (setq nerd-icons-font-family "JetBrainsMono Nerd Font")) (use-package doom-modeline :after nerd-icons :config (doom-modeline-mode 1) (setq doom-modeline-height 25) (setq doom-modeline-icon t)) ;; Ligaturen (setzt ebenfalls einen Nerd Font voraus) (use-package ligature :config (ligature-set-ligatures 't '("!=" "!==" "->" "<-" "=>" "<=>" ">=" "<=" "//")) (global-ligature-mode t)) ;; ======== Farben ================================================ (set-face-attribute 'line-number nil :height 0.8 :foreground "#ffffff" :background "#dddddd") (set-face-attribute 'link nil :foreground "RoyalBlue3" :underline nil) ;; für Markdown-Modus (with-eval-after-load 'markdown-mode (set-face-attribute 'markdown-italic-face nil :inherit 'italic :foreground "dark magenta" :slant 'italic) (set-face-attribute 'markdown-pre-face nil :inherit 'font-lock-constant-face)) (with-eval-after-load 'doom-modeline (set-face-attribute 'doom-modeline-buffer-modified nil :foreground "firebrick" :weight 'bold)) ;; ======== eigene Funktionen =================================================== (defun expand-abbrev-or-dabbrev () ;Expansion von Abkürzung: F3 (interactive) (unless (expand-abbrev) ;falls keine Abkürzung existiert (dabbrev-expand nil))) ;dynamische Expansion (defvar my-point-register 1 "Hilfsvariable für jump-to-register-1: merkt sich, welches Register aktiv ist.") (defun point-to-register-1 () ;Position in Reg. 1 speichern: F5 (interactive) (setq my-point-register 1) (point-to-register 1)) (defun jump-to-register-1 () ;Position wechseln: F6 (interactive) ;springt zur Position, die mit F5 (if (= my-point-register 1) ; gespeichert wurde ... (progn (setq my-point-register 2) (point-to-register 2) (jump-to-register 1)) (progn (setq my-point-register 1) (point-to-register 1) (jump-to-register 2)))) (defun swap-char () ;zwei Buchstaben an der Cursor-Position (interactive) ;vertauschen: F11 (save-excursion (forward-char) (transpose-chars 1))) (defun change-case () ;Groß- und Kleinschreibung des Zeichens (interactive) ;an der Cursorposition ändern: F12 (let ((zeichen (char-after (point)))) (if (> zeichen 64) (progn (setq zeichen (logxor zeichen 32)) (insert-char zeichen 1) (delete-char 1)) (forward-char 1)))) (defun change-word-case () ;Groß- und Kleinschreibung des ersten (interactive) ;Zeichens eines Worts verändern: F9 (point-to-register 2) (backward-word 1) (change-case) (jump-to-register 2)) (defun unfill-paragraph-and-advance () ;Absatz zusammenfügen und zum nächsten springen: S-F4 (interactive) (unfill-paragraph) (forward-paragraph) (skip-chars-forward "\n") (recenter)) (defun toggle-fill-column-width () ;Zeilenumbruch zwischen 100 und 1000 Zeichen wechseln (interactive) (setq-local visual-fill-column-width (if (eq visual-fill-column-width 100) 1000 100)) (visual-fill-column-mode 1)) ;; ======== Tastenkürzel ====================================================== (global-set-key [f1] 'switch-to-buffer) ;F1 Buffer wechseln (global-set-key [f2] 'other-window) ;F2 Fenster wechseln (global-set-key [f3] 'expand-abbrev-or-dabbrev) ;F3 Abkürzung erweitern (global-set-key [f4] 'fill-paragraph) ;F4 Absatz umbrechen (global-set-key [S-f4] 'unfill-paragraph-and-advance) ;S-F4 Absatz zusammenfügen + nächster (global-set-key [f5] 'point-to-register-1) ;F5 Position speichern (global-set-key [f6] 'jump-to-register-1) ;F6 zu Position springen (global-set-key [f7] 'goto-line) ;F7 goto line (global-set-key [f8] 'toggle-fill-column-width) ;F8 kurze/lange Zeilen (global-set-key [f9] 'change-word-case) ;F9 Groß/Klein Wort (global-set-key [f10] 'undo) ;F10 Undo (global-set-key [f11] 'swap-char) ;F11 Buchst. vertauschen (global-set-key [f12] 'change-case) ;F12 Groß-/Klein ändern ;; Mac-Tastatur: fn+ctrl+cursor to start/end of buffer (global-set-key [C-prior] 'beginning-of-buffer) (global-set-key [C-next] 'end-of-buffer) ;; Guillemets-Eingabe mit Alt+Q / Shift+Alt+Q (defun insert-guillemot1 () (interactive) (insert "«")) (defun insert-guillemot2 () (interactive) (insert "»")) (global-set-key [?\M-q] 'insert-guillemot1) ;Alt+Q: « (global-set-key [?\M-Q] 'insert-guillemot2) ;Shift+Alt+Q: » ;; macOS: rechte Alt-Taste zur Eingabe von Sonderzeichen wie @ oder € verwenden (when (eq system-type 'darwin) (setq mac-right-option-modifier nil) ; LeftAlt + L -> @ etc. )