emacs.d/init.el
2023-10-03 09:56:20 +02:00

594 lines
23 KiB
EmacsLisp
Executable file

(add-to-list 'load-path (expand-file-name "~/.emacs.d/bundle/"))
;;; bundle--defaults
;; General user interface and appearance
(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(horizontal-scroll-bar-mode -1)
(global-hl-line-mode 1)
(display-time-mode 1)
(global-prettify-symbols-mode -1)
(set-fringe-mode 10)
(setq display-time-format " W%V %a %d %b %Y %R %z")
(setq display-time-24hr-format t)
;; Cursor and mouse
(column-number-mode 1)
(mouse-wheel-mode 1)
(blink-cursor-mode -1)
;; Customization for locale, environment and computer
(setq calendar-location-name "Nuremberg, DE"
calendar-latitude 49.4
calendar-longitude 11.0
;; calendar-location-name "Nuremberg, DE"
european-calendar-style t
calendar-christian-all-holidays-flag t
calendar-date-style (quote iso)
calendar-view-diary-initially-flag t
calendar-week-start-day 1
calendar-intermonth-text
'(propertize
(format "%2d"
(car
(calendar-iso-from-absolute
(calendar-absolute-from-gregorian
(list month day year )))))
'font-lock-face 'font-lock-function-name-face))
(setq ispell-program-name "hunspell")
(setq grep-command "grep -i -nH -e ")
(when (eq system-type 'gnu/linux)
(setq shell-file-name "/bin/bash")
(setq tex-shell-file-name "/bin/bash"))
;; Files and sessions
(setq auto-save-timeout 60)
;; Tabs, spaces, lines and parenthesis
(show-paren-mode 1)
(setq indent-tabs-mode nil)
(setq line-spacing nil)
(setq make-backup-files nil)
(setq tab-width 4)
(setq sentence-end-double-space nil)
(setq next-line-add-newlines t)
(setq require-final-newline t)
;; Miscellaneous
(require 'cl-lib)
(setq default-major-mode 'text-mode)
(setq inhibit-startup-buffer-menu t inhibit-startup-screen t)
(setq tramp-default-method "ssh")
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(add-hook 'text-mode-hook 'turn-on-auto-fill)
(defalias 'yes-or-no-p 'y-or-n-p)
;; ;; Mode line
;; (setq mode-line-format
;; '((""
;; mode-line-modified
;; mode-line-frame-control "%b %z%n "
;; mode-name
;; vc-mode
;; " "
;; mode-line-position
;; mode-line-misc-info
;; minor-mode-alist
;; mode-line-end-spaces "%-"
;; )))
;; Disable line numbers in modes
;; (dolist (mode '(org-mode-hook term-mode-hook shell-mode-hook eshell-mode-hook))
;; (add-hook mode (lambda () (display-line-numbers-mode 0))))
(add-hook 'after-save-hook
'executable-make-buffer-file-executable-if-script-p)
(global-set-key (kbd "M-i") 'imenu)
(global-set-key (kbd "C-x C-b") 'ibuffer-list-buffers)
;;(global-set-key (kbd "M-[") 'tab-bar-history-back)
;;(global-set-key (kbd "M-]") 'tab-bar-history-forward)
(add-hook 'diary-display-hook 'fancy-diary-display)
(add-hook 'today-visible-calendar-hook 'calendar-mark-today)
(add-hook 'write-file-hooks 'delete-trailing-whitespace)
(add-hook 'diary-list-entries-hook 'diary-include-other-diary-files)
(add-hook 'diary-mark-entries-hook 'diary-mark-included-diary-files)
(setq compilation-ask-about-save nil)
(setq vc-handled-backends '(Git Hg)) ;; Only use Git and Hg for VC
(setq horizontal-scroll-bar nil)
(setq vertical-scroll-bar nil)
(setq default-frame-alist
'((font . "MonoLisa-11")
(width . 92)
(height . 62)
(alpha . 100)))
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1) ((meta)) ((control) . text-scale)))
(require 'ido)
(setq ido-enable-flex-matching t)
(setq ido-everywhere t)
(setq ido-create-new-buffer 'always)
;(setq ido-file-extensions-order '(".org" ".lisp" ".py" ".txt" ".el" ".epub"))
(ido-mode t)
(fido-mode 1) ; replace icomplete mode
;;;
;;; bundle--encoding
;; UTF-8 FTW
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq default-buffer-file-coding-system 'utf-8)
(setenv "PYTHONIOENCODING" "UTF-8")
;;;
;;; bundle--holidays
(setq holiday-oriental-holidays
'(()))
(setq holiday-islamic-holidays
'(()))
(setq holiday-bahai-holidays
'(()))
(setq holiday-hebrew-holidays
'(()))
(setq holiday-general-holidays
'((holiday-fixed 1 1 "Neujahr")
(holiday-fixed 5 1 "1. Mai")
(holiday-fixed 10 3 "Tag der Deutschen Einheit")))
(setq holiday-christian-holidays
'((holiday-float 12 0 -4 "1. Advent" 24)
(holiday-float 12 0 -3 "2. Advent" 24)
(holiday-float 12 0 -2 "3. Advent" 24)
(holiday-float 12 0 -1 "4. Advent" 24)
(holiday-fixed 12 25 "1. Weihnachtstag")
(holiday-fixed 12 26 "2. Weihnachtstag")
(holiday-fixed 1 6 "Heilige Drei Könige")
(holiday-easter-etc -48 "Rosenmontag")
;; (holiday-easter-etc -3 "Gründonnerstag")
(holiday-easter-etc -2 "Karfreitag")
(holiday-easter-etc 0 "Ostersonntag")
(holiday-easter-etc +1 "Ostermontag")
(holiday-easter-etc +39 "Christi Himmelfahrt")
(holiday-easter-etc +49 "Pfingstsonntag")
(holiday-easter-etc +50 "Pfingstmontag")
(holiday-easter-etc +60 "Fronleichnam")
(holiday-fixed 8 15 "Mariae Himmelfahrt")
(holiday-fixed 11 1 "Allerheiligen")
;; (holiday-float 11 3 1 "Buss- und Bettag" 16)
(holiday-float 11 0 1 "Totensonntag" 20)))
;;;
;;; bundle--server
(require 'server)
;; Start a server if (server-running-p) does not return t (e.g. if it
;; returns nil or :other)
(or (eq (server-running-p) t)
(server-start))
;;;
;;; bundle--customfile
(use-package doom-themes
:init
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-one t))
(defvar mk/hyperspec-dir-locations
'("d:/visua/projects/personal/lisp-docs/HyperSpec-7-0/HyperSpec/"
"~/projects/personal/lisp-docs/HyperSpec-7-0/HyperSpec/"
"~/lisp-docs/HyperSpec-7-0/HyperSpec/"
"~/sites/HyperSpec/")
"List of possible locations where the local HyperSpec could reside.")
(defun mk/find-dir (x)
"Recursively search for a valid directory from a list X of directories.
Returns the first valid directory, or nil if none found."
(cond ((null x) nil)
((file-directory-p (car x)) (car x))
(t (mk/find-dir (cdr x)))))
(defun mk/hyperspec-dir ()
"Finds and returns the URI of the local HyperSpec directory.
Uses `mk/hyperspec-dir-locations' to find the directory."
(let ((dir-prefix (if (eq system-type 'windows-nt)
"file:///" ; windows needs three slashes
"file://"))
(dir (mk/find-dir mk/hyperspec-dir-locations)))
(if dir
(concat dir-prefix (expand-file-name dir))
nil)))
(setq common-lisp-hyperspec-root (mk/hyperspec-dir))
;; OS SETTINGS
(when (eq system-type 'gnu/linux)
(setq custom-file "~/.emacs.d/bundle/custom_gnu.el"
browse-url-secondary-browser-function 'browse-url-firefox))
(when (eq system-type 'windows-nt)
(setq custom-file "~/.emacs.d/bundle/custom_win32.el")
(setq org-babel-python-command "python")
(when (string= (system-name) "EVG02667NB")
(cd "d:/opt")
(setq custom-file "~/.emacs.d/bundle/custom_win32_EVG02667NB.el")))
;; CUSTOM_FILE
(load custom-file :noerror)
;;;
(load "bundle--package")
(load "bundle--org")
(load "bundle--ux")
;;; bundle--latex.el --- Configuration for Org-mode LaTeX export and AUCTeX
;;; Commentary:
;; This file contains configurations for exporting Org-mode files to LaTeX
;; PDFs using XeLaTeX. It sets up custom packages, table settings, and source
;; code listings. Also, it includes settings for AUCTeX package for enhanced
;; .tex file editing.
;;
;; Features:
;; - Uses the XeLaTeX compiler for PDF generation.
;; - Sets up various LaTeX packages like 'listings', 'booktabs', 'xcolor', etc.
;; - Provides custom LaTeX class based on KOMA-script for specific formatting.
;; - Enables SumatraPDF for PDF viewing on Windows, and Evince on other systems.
;;
;; Installation:
;; Add this file to your load-path and then add `(require 'bundle--latex)`
;; to your init.el file.
;;
;; Usage:
;; Simply save this configuration and restart Emacs or re-evaluate the buffer.
;;; Code:
;; Org-mode LaTeX export settings
(require 'ox-latex)
;; Add custom LaTeX packages
(setq org-latex-packages-alist '(("" "listings")
("" "booktabs")
("AUTO" "polyglossia" t ("xelatex" "lualatex"))
("" "grffile")
("" "unicode-math")
("" "xcolor")))
;; Define the process to convert Org to PDF using XeLaTeX
(setq org-latex-pdf-process '("latexmk -xelatex -shell-escape -quiet -f %f"))
;; Set the compiler to XeLaTeX
(setq org-latex-compiler "xelatex")
;; Enable listings and other table-related features
(setq org-latex-listings t)
(setq org-latex-tables-booktabs t)
(setq org-latex-images-centered t)
;; Customize the appearance of listings (source code blocks)
(setq org-latex-listings-options
'(("basicstyle" "\\ttfamily")
("showstringspaces" "false")
("keywordstyle" "\\color{blue}\\textbf")
("commentstyle" "\\color{gray}")
("stringstyle" "\\color{green!70!black}")
("stringstyle" "\\color{red}")
("frame" "single")
("numbers" "left")
("numberstyle" "\\ttfamily")
("columns" "fullflexible")))
;; Set the input encoding
(setq org-latex-inputenc-alist '((\"utf8\" . \"utf8x\")))
;; Define custom LaTeX class with specific formatting
(with-eval-after-load 'ox-latex
(add-to-list 'org-latex-classes
'("koma-general"
"\\documentclass[a4paper,10pt,captions=tableheading,twoside=false]{scrartcl}
\\linespread{1.25}
\\usepackage{fontspec}
\\defaultfontfeatures{Mapping=tex-text, RawFeature={+zero}}
\\setmainfont{Noto Sans}[BoldFont=*-Medium,ItalicFont=*-Italic]
\\setsansfont{Noto Sans}[BoldFont=*-Medium,ItalicFont=*-Italic]
\\setmonofont{Noto Sans Mono}[BoldFont=*-Medium,Scale=0.8]
\\usepackage{geometry}
\\geometry{a4paper,left=2cm,right=2cm,top=1.6cm,bottom=1.6cm}
\\usepackage{fancyhdr}
\\pagestyle{fancy}
\\fancyhf{}
\\fancyhead[L]{\\leftmark} % Left header
\\fancyhead[R]{\\thepage} % Right header"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
;; Set default LaTeX class
(setq org-latex-default-class "koma-general")
;; Load KOMA letter support
(eval-after-load 'ox '(require 'ox-koma-letter))
;; TeX mode settings for editing .tex files
(setq TeX-auto-save t) ; Enable auto-save
(setq TeX-electric-math (cons "$" "$")) ; Shortcut for math mode
(if (eq system-type 'windows-nt)
(progn
(setq TeX-view-program-list '(("SumatraPDF" "~/AppData/Local/SumatraPDF/SumatraPDF.exe %o")))
(setq TeX-view-program-selection '((output-pdf "SumatraPDF"))))
(setq TeX-view-program-selection '((output-pdf "Evince"))))
(setq TeX-source-correlate-start-server t) ; Enable source-correlate
(setq TeX-master nil) ; Default master file
(setq TeX-engine 'xetex) ; Set engine to XeTeX
(setq TeX-command-extra-options "-shell-escape") ; Allow shell escape
(use-package tex
:defer t
:ensure auctex
:hook ((LaTeX-mode . turn-on-reftex)
(LaTeX-mode . flyspell-mode)
(LaTeX-mode . LaTeX-math-mode)))
;;; bundle--latex.el ends here
(load "bundle--mk")
;;; bundle--linux.el --- A bundle of useful Linux information
;;; Commentary:
;; This file contains a variety of Emacs Lisp functions that provide
;; helpful descriptions for Linux directories, commands, and options.
;;; Code:
(defvar linux-filesystem-alist
'(( "/" . "Root directory, the base of the filesystem hierarchy")
("/bin" . "Essential command binaries, needed for booting")
("/boot" . "Bootloader files, kernel, and other files needed during booting")
("/dev" . "Device files representing hardware components")
("/etc" . "System-wide configuration files")
("/home" . "User home directories")
("/lib" . "Shared libraries and kernel modules")
("/media" . "Mount points for removable media like CDs and USBs")
("/mnt" . "Temporary mount points for filesystems")
("/opt" . "Optional application software packages")
("/proc" . "Virtual filesystem providing info about processes and system")
("/root" . "Home directory for the root user")
("/sbin" . "Essential system binaries, usually for the root user")
("/srv" . "Data directories for services like HTTP, FTP, etc.")
("/sys" . "Virtual filesystem for kernel objects")
("/tmp" . "Temporary files, cleared on reboot")
("/usr" . "User binaries, documentation, libraries, etc.")
("/var" . "Variable files like logs, databases, etc."))
"Alist mapping Linux directories to their descriptions.")
(defun describe-linux-directory (dirname)
"Describe the purpose of a Linux directory.
Takes DIRNAME as an argument and prints its description."
(interactive "sEnter Linux directory name (e.g., /bin): ")
(let ((description (assoc-default dirname linux-filesystem-alist)))
(if description
(message "%s: %s" dirname description)
(message "Unknown directory: %s" dirname))))
(defvar bash-regex-alist
'(("empty line" . "^$")
("backslash" . "\\\\")
("line starts with a dot" . "^\\.")
("line ends with a dot" . "\\.$")
("line starts with a dollar sign" . "^\\$")
("line starts with a caret" . "^\\^")
("left square bracket" . "\\[")
("right square bracket" . "\\]")
("entire line" . "^.*$")
("any alphanumeric character" . "[a-zA-Z0-9]")
("IP Address" . "\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b")
("email" . "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}")
("hex color code" . "#[a-fA-F0-9]{6}")
("date in yyyy-mm-dd" . "\\b\\d{4}-\\d{2}-\\d{2}\\b")
("time in hh:mm:ss" . "\\b\\d{2}:\\d{2}:\\d{2}\\b")
("words without vowels" . "\\b[^aeiou\s]+\\b"))
"Alist mapping Bash regular expressions to their descriptions.")
(defun describe-bash-regex (regex)
"Describe the purpose of a Bash regular expression.
Takes REGEX as an argument and prints its description."
(interactive "sEnter Bash regex (e.g., empty line): ")
(let ((description (assoc-default regex bash-regex-alist)))
(if description
(message "%s: %s" regex description)
(message "Unknown regular expression: %s" regex))))
(defvar linux-process-commands-alist
'(("ps" . "Shows a snapshot of the current processes")
("top" . "Displays dynamic real-time view of system stats and processes")
("htop" . "An interactive process viewer, similar to top but more feature-rich")
("pgrep" . "Looks up processes based on name and other attributes")
("pstree" . "Displays the process tree in a tree-like diagram")
("ps -e" . "Lists all the processes running on the system")
("ps aux" . "Displays detailed information about all processes")
("kill" . "Terminates processes by sending signals")
("killall" . "Kills all processes that match the given name")
("pkill" . "Send signals to processes based on name and other attributes"))
"Alist mapping Linux process-checking commands to their descriptions.")
(defun describe-linux-process-command (command)
"Describe the purpose of a Linux process-checking command.
Takes COMMAND as an argument and prints its description."
(interactive "sEnter Linux process command (e.g., ps): ")
(let ((description (assoc-default command linux-process-commands-alist)))
(if description
(message "%s: %s" command description)
(message "Unknown command: %s" command))))
(defvar linux-logfiles-alist
'(("/var/log/syslog" . "System messages, including the messages that are logged during system startup")
("/var/log/auth.log" . "Security/authorization information, including user logins and authentication")
("/var/log/kern.log" . "Kernel logs")
("/var/log/cron.log" . "Logs for cron jobs")
("/var/log/messages" . "General system activity logs")
("/var/log/boot.log" . "System boot log")
("/var/log/daemon.log" . "Background daemon log messages")
("/var/log/dpkg.log" . "Logs for package installations and removals")
("/var/log/mail.log" . "Mail server logs")
("/var/log/user.log" . "User-level messages"))
"Alist mapping Linux log files to their descriptions.")
(defun describe-linux-logfile (logfile)
"Describe the purpose of a Linux log file.
Takes LOGFILE as an argument and prints its description."
(interactive "sEnter Linux log file path (e.g., /var/log/syslog): ")
(let ((description (assoc-default logfile linux-logfiles-alist)))
(if description
(message "%s: %s" logfile description)
(message "Unknown log file: %s" logfile))))
(defvar linux-basic-commands-alist
'(("list directory contents" . "ls")
("change directory" . "cd")
("move or rename files" . "mv")
("copy files" . "cp")
("remove files or directories" . "rm")
("print working directory" . "pwd")
("display variable value" . "echo")
("create an empty file" . "touch")
("change file permissions" . "chmod")
("change file ownership" . "chown"))
"Alist mapping basic Linux command descriptions to their commands.")
(defun describe-basic-linux-command (command)
"Describe the purpose of a basic Linux command.
Takes COMMAND as an argument and prints its description."
(interactive "sEnter basic Linux command (e.g., ls): ")
(let ((description (assoc-default command linux-basic-commands-alist)))
(if description
(message "%s: %s" command description)
(message "Unknown command: %s" command))))
(defvar chown-options-alist
'(("-R" . "Operate on files and directories recursively")
("--from" . "Change the owner and/or group of each file only if its current owner and/or group match specified values")
("--no-dereference" . "Affect symbolic links instead of the files they point to")
("--preserve-root" . "Fail when attempting to operate recursively on '/'")
("--reference" . "Use owner and group of a reference file")
("-c" . "Report when a change is made")
("-f" . "Suppress most error messages")
("-v" . "Output a diagnostic for every file processed"))
"Alist mapping chown command options to their descriptions.")
(defun describe-chown-option (option)
"Describe the purpose of a chown option.
Takes OPTION as an argument and prints its description."
(interactive "sEnter chown option (e.g., -R): ")
(let ((description (assoc-default option chown-options-alist)))
(if description
(message "%s: %s" option description)
(message "Unknown chown option: %s" option))))
(defvar chmod-options-alist
'(("-R" . "Operate on files and directories recursively")
("--preserve-root" . "Avoid operating recursively on '/'")
("-c" . "Report when a change is made")
("-f" . "Suppress most error messages")
("-v" . "Output a diagnostic for every file processed")
("--reference" . "Use mode of a reference file")
("-w" . "Remove write permission")
("-x" . "Remove execute permission")
("-u" . "Set user ID on execution")
("-g" . "Set group ID on execution"))
"Alist mapping chmod command options to their descriptions.")
(defun describe-chmod-option (option)
"Describe the purpose of a chmod option.
Takes OPTION as an argument and prints its description."
(interactive "sEnter chmod option (e.g., -R): ")
(let ((description (assoc-default option chmod-options-alist)))
(if description
(message "%s: %s" option description)
(message "Unknown chmod option: %s" option))))
(defvar ssh-use-cases-alist
'(("remote login" . "ssh user@host")
("run command" . "ssh user@host 'command'")
("file transfer" . "scp file.txt user@host:/path/")
("secure ftp" . "sftp user@host")
("port forwarding" . "ssh -L local_port:remote_host:remote_port user@host")
("dynamic port forwarding" . "ssh -D port user@host")
("remote port forwarding" . "ssh -R remote_port:local_host:local_port user@host")
("tunneling" . "ssh -L local_port:remote_host:remote_port user@host -f -N")
("agent forwarding" . "ssh -A user@host")
("ssh multiplexing" . "ssh -M -S /tmp/ssh_socket user@host; ssh -S /tmp/ssh_socket user@host"))
"Alist mapping SSH use cases to their corresponding commands.")
(defun describe-ssh-use-case (use-case)
"Describe the SSH command for a given use case."
(interactive "sEnter the SSH use case: ")
(let ((command (assoc-default use-case ssh-use-cases-alist)))
(if command
(message "Command for %s: %s" use-case command)
(message "Use case not found"))))
(defvar mk/remote-*host-aliases*
'(("website" . "marcus@u1.marcuskammer.dev")
("playground" . "marcus@u1.metaebene.dev"))
"Alist mapping friendly host names to actual SSH-compatible host strings.")
(defun mk/remote--get-real-host (alias)
"Lookup the real host name based on a given ALIAS."
(or (cdr (assoc alias mk/remote-*host-aliases*)) alias))
(defun mk/remote--systemctl-service (alias service command)
"Execute a systemctl COMMAND on a systemd SERVICE on a remote host identified by ALIAS.
ALIAS is a string that specifies the remote host; it can be an
alias defined in `mk/remote-*host-aliases*'.
SERVICE is the name of the systemd service to operate on.
COMMAND is the systemctl command to execute on the service (e.g.,
'start', 'stop', 'status')."
(let* ((host (mk/remote--get-real-host alias))
(buffer (generate-new-buffer (format "*%s-%s-%s*" alias service command)))
(process-name (format "systemctl-%s-%s" command service))
(sentinel (lambda (process signal)
(when (memq (process-status process) '(exit signal))
(message "Process: %s %s" process signal)))))
(make-process
:name process-name
:buffer buffer
:command `("ssh" ,host "sudo" "systemctl" ,command ,service)
:sentinel sentinel)))
(defmacro mk/remote-define-systemctl-functions (&rest actions)
"Dynamically create functions to interact with systemd services on a remote host.
Each function will be named `mk/remote-ACTION-service', where
ACTION is one of the symbols in ACTIONS. The functions will take
an ALIAS and SERVICE as arguments and call
`mk/remote--systemctl-service' accordingly."
`(progn
,@(mapcar
(lambda (action)
`(defun ,(intern (format "mk/remote-%s-service" action)) (alias service)
(interactive "sEnter the host alias or name: \nsEnter the service name: ")
(mk/remote--systemctl-service alias service ,(symbol-name action))))
actions)))
(mk/remote-define-systemctl-functions start stop status)