(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)