commit 151ca91962d7534a6fe1db5dcad724e279d09bee Author: Ariane Troche Date: Fri Dec 18 17:11:32 2020 +0100 Grundkonfiguration: init.el mit org-tangle diff --git a/README.org b/README.org new file mode 100644 index 0000000..a68ec79 --- /dev/null +++ b/README.org @@ -0,0 +1,4 @@ +#+STARTUP: overview +#+TITLE: Meine Emacs-Konfiguration + +* Meine Emacs-Konfiguration diff --git a/init.el b/init.el new file mode 100644 index 0000000..fe0de16 --- /dev/null +++ b/init.el @@ -0,0 +1,190 @@ +(require 'package) + +(defvar my-init-el-start-time (current-time) "Time when init.el was started.") + +;; ──────────────────── Performance Optimization ────────────────────── + +(defvar my/gc-cons-threshold (if (display-graphic-p) 16000000 1600000) + "The default value to use for `gc-cons-threshold'. If you experience freezing, +decrease this. If you experience stuttering, increase this.") + +(defvar my/gc-cons-upper-limit (if (display-graphic-p) 400000000 100000000) + "The temporary value for `gc-cons-threshold' to defer it.") + +(defvar my/gc-timer (run-with-idle-timer 10 t #'garbage-collect) + "Run garbarge collection when idle 10s.") + +(defvar default-file-name-handler-alist file-name-handler-alist) + +(setq file-name-handler-alist nil) +(setq gc-cons-threshold my/gc-cons-upper-limit + gc-cons-percentage 0.5) +(add-hook 'emacs-startup-hook + (lambda () + "Restore defalut values after startup." + (setq file-name-handler-alist default-file-name-handler-alist) + (setq gc-cons-threshold my/gc-cons-threshold + gc-cons-percentage 0.1) + + ;; GC automatically while unfocusing the frame + ;; `focus-out-hook' is obsolete since 27.1 + (if (boundp 'after-focus-change-function) + (add-function :after after-focus-change-function + (lambda () + (unless (frame-focus-state) + (garbage-collect)))) + (add-hook 'focus-out-hook 'garbage-collect)) + + ;; Avoid GCs while using `ivy'/`counsel'/`swiper' and `helm', etc. + ;; @see http://bling.github.io/blog/2016/01/18/why-are-you-changing-gc-cons-threshold/ + (defun my/minibuffer-setup-hook () + (setq gc-cons-threshold my/gc-cons-upper-limit)) + + (defun my/minibuffer-exit-hook () + (setq gc-cons-threshold my/gc-cons-threshold)) + + (add-hook 'minibuffer-setup-hook #'my/minibuffer-setup-hook) + (add-hook 'minibuffer-exit-hook #'my/minibuffer-exit-hook))) + +;; ───────────────────────── Package-Archives ───────────────────────── + +;; HACK: DO NOT copy package-selected-packages to init/custom file forcibly. +;; https://github.com/jwiegley/use-package/issues/383#issuecomment-247801751 +(defun my/save-selected-packages (&optional value) + "Set `package-selected-packages' to VALUE but don't save to `custom-file'." + (when value + (setq package-selected-packages value))) +(advice-add 'package--save-selected-packages :override #'my/save-selected-packages) + +;; Archive-Locations +(setq package-archives '(("melpa" . "https://melpa.org/packages/") + ("org" . "http://orgmode.org/elpa/") + ("gnu" . "http://elpa.gnu.org/packages/") + ;;("marmalade" . "https://marmalade-repo.org/packages/") + )) + +;; Initialize packages +(unless (bound-and-true-p package--initialized) ; To avoid warnings in 27 + (setq package-enable-at-startup nil) ; To prevent initializing twice + (package-initialize)) + +(setq load-prefer-newer t) + +;; ──────────────────────────── Load-Path ─────────────────────────── + +(add-to-list 'load-path (expand-file-name "packages/" user-emacs-directory)) + +;; customization + +(setq custom-file (make-temp-file "")) + +;; ─────────────────────────── use-package ────────────────────────── + +;; Setup `use-package' +(unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) + +;; Should set before loading `use-package' +;; (eval-and-compile +(setq use-package-always-ensure t) + ;; (setq use-package-always-defer t) + ;; (setq use-package-expand-minimally t) + ;; (setq use-package-enable-imenu-support t)) + +(eval-when-compile + (require 'use-package)) + +;; Required by `use-package' +(use-package diminish) +(use-package bind-key) +(use-package use-package-chords + :init + :config (key-chord-mode 1) + (setq key-chord-two-keys-delay 0.4) + (setq key-chord-one-key-delay 0.5)) + +;; general dependencies +(require 'cl-lib) +(require 'seq) +(use-package f :demand t) +(use-package dash :demand t) +(use-package ht :demand t) +(use-package s :demand t) +(use-package a :demand t) +(use-package anaphora :demand t) + +;; ─────────────────────────── tangle ────────────────────────── + +;; no tangle without org +(require 'org) +(require 'org-protocol) + +;; from: http://stackoverflow.com/questions/251908/how-can-i-insert-current-date-and-time-into-a-file-using-emacs +(defvar current-date-time-format "%a %b %d %Y-%m-%dT%H:%M:%S " + "Format of date to insert with `insert-current-date-time' func +See help of `format-time-string' for possible replacements") + +;; from: http://stackoverflow.com/questions/251908/how-can-i-insert-current-date-and-time-into-a-file-using-emacs +(defvar current-time-format "%a %H:%M:%S" + "Format of date to insert with `insert-current-time' func. +Note the weekly scope of the command's precision.") + +(defun my/tangle-config-org () + "This function will write all source blocks from =config.org= into =config.el= that are ... +- not marked as =tangle: no= +- doesn't have the TODO state =DISABLED= +- have a source-code of =emacs-lisp=" + (let* ((body-list ()) + (output-file (concat user-emacs-directory "config.el")) + (org-babel-default-header-args (org-babel-merge-params org-babel-default-header-args + (list (cons :tangle output-file))))) + (message "—————• Re-generating %s …" output-file) + (save-restriction + (save-excursion + (org-babel-map-src-blocks (concat user-emacs-directory "config.org") + (let* ( + (org_block_info (org-babel-get-src-block-info 'light)) + (tfile (cdr (assq :tangle (nth 2 org_block_info)))) + (match_for_TODO_keyword) + ) + (save-excursion + (catch 'exit + (org-back-to-heading t) + (when (looking-at org-outline-regexp) + (goto-char (1- (match-end 0)))) + (when (looking-at (concat " +" org-todo-regexp "\\( +\\|[ \t]*$\\)")) + (setq match_for_TODO_keyword (match-string 1))))) + (unless (or (string= "no" tfile) + (string= "DISABLED" match_for_TODO_keyword) + (not (string= "emacs-lisp" lang))) + (add-to-list 'body-list (concat "\n\n;; ------------------------------------------------------------\n" + "(message \"config • " (org-get-heading) " …\")\n\n") + ) + (add-to-list 'body-list body) + )))) + (with-temp-file output-file + (insert ";; ============================================================\n") + (insert ";; Don't edit this file, edit config.org' instead ...\n") + (insert ";; Auto-generated at " (format-time-string current-date-time-format (current-time)) " on host " (system-name) "\n") + (insert ";; ============================================================\n\n") + (insert (apply 'concat (reverse body-list)))) + (message "—————• Wrote %s" output-file)))) + + +;; following lines are executed only when my/tangle-config-org-hook-func() +;; was not invoked when saving config.org which is the normal case: +(let ((orgfile (concat user-emacs-directory "config.org")) + (elfile (concat user-emacs-directory "config.el")) + (gc-cons-threshold most-positive-fixnum)) + (when (or (not (file-exists-p elfile)) + (file-newer-than-file-p orgfile elfile)) + (my/tangle-config-org)) + (load-file elfile)) + +;; when config.org is saved, re-generate config.el: +(defun my/tangle-config-org-hook-func () + (when (string= "config.org" (buffer-name)) + (message "Tangle to config.el ...") + (my/tangle-config-org))) +(add-hook 'after-save-hook 'my/tangle-config-org-hook-func)