home

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit ac98aa7037360e343f6438ca6d8801f57c112d05
parent 5b9dd2920e30d5cedbc4b3cadd2be077e63fcacb
Author: Vincent Demeester <vincent@sbr.pm>
Date:   Fri,  3 Jul 2020 17:42:04 +0200

tools/emacs: migrated {early-,}init.el to tangled…

… Those files are tangled from my notes.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>

Diffstat:
Mtools/emacs/early-init.el | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mtools/emacs/init.el | 180++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
2 files changed, 220 insertions(+), 50 deletions(-)

diff --git a/tools/emacs/early-init.el b/tools/emacs/early-init.el @@ -1,30 +1,86 @@ -;;; early-init.el --- -*- lexical-binding: t -*- -;; PkgStartup +;; Early initialization +;; :PROPERTIES: +;; :header-args: :tangle ~/src/home/tools/emacs/early-init.el +;; :header-args+: :comments org +;; :CUSTOM_ID: h:ec67a339-378c-4c2c-93f8-9ce62308cccb +;; :END: +;; +;; Starting with Emacs 27, an =early-init.el= file can be used to do early configuration +;; and optimization. +;; +;; #+begin_quote +;; Emacs can now be configured using an early init file. The file is called ~early-init.el~, +;; in ~user-emacs-directory~. It is loaded very early in the startup process: before +;; graphical elements such as the tool bar are initialized, and before the package manager is +;; initialized. The primary purpose is to allow customizing how the package system is +;; initialized given that initialization now happens before loading the regular init file +;; (see below). +;; +;; We recommend against putting any customizations in this file that don't need to be set up +;; before initializing installed add-on packages, because the early init file is read too +;; early into the startup process, and some important parts of the Emacs session, such as +;; 'window-system' and other GUI features, are not yet set up, which could make some +;; customization fail to work. +;; #+end_quote +;; +;; We can use this to our advantage and optimize the initial loading of emacs. +;; +;; - Before Emacs 27, the init file was responsible for initializing the package manager by +;; calling `package-initialize'. Emacs 27 changed the default behavior: It now calls +;; `package-initialize' before loading the init file. + + (setq package-enable-at-startup nil) -;; -PkgStartup -;; FrameResize + + +;; - Let's inhibit resizing the frame at early stage. + + (setq frame-inhibit-implied-resize t) -;; -FrameResize -;; DisableUI + + +;; - I never use the /menu-bar/, or the /tool-bar/ or even the /scroll-bar/, so we can safely +;; disable those very very early. + + (menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1) (horizontal-scroll-bar-mode -1) -;; -DisableUI -;; GarbageCollection + + +;; - Finally we can try to avoid garbage collection at startup. The garbage collector can +;; easily double startup time, so we suppress it at startup by turning up ~gc-cons-threshold~ +;; (and perhaps ~gc-cons-percentage~) temporarily. + + (setq gc-cons-threshold 402653184 gc-cons-percentage 0.6) -;; -GarbageCollection -;; FileNameHandler + + +;; - Another small optimization concerns on =file-name-handler-alist= : on every .el and .elc +;; file loaded during start up, it has to runs those regexps against the filename ; setting +;; it to ~nil~ and after initialization finished put the value back make the initialization +;; process quicker. + + (defvar file-name-handler-alist-original file-name-handler-alist) (setq file-name-handler-alist nil) -;; -FileNameHandler -;; EarlyThemeSetup + + +;; However, it is important to reset it eventually. Not doing so will cause garbage +;; collection freezes during long-term interactive use. Conversely, a ~gc-cons-threshold~ +;; that is too small will cause stuttering. This will be done at the end. +;; +;; - It's also possible to put the theme *and* the font in =early-init.el= to speed the +;; start. + + (defvar contrib/after-load-theme-hook nil "Hook run after a color theme is loaded using `load-theme'.") @@ -69,9 +125,7 @@ This is used internally by `sbr/modus-themes-toggle'." (add-hook 'contrib/after-load-theme-hook 'sbr/modus-operandi-custom) (sbr/modus-operandi) -;; -EarlyThemeSetup -;;-EarlyFontSetup (defconst font-height 130 "Default font-height to use.") ;; Middle/Near East: שלום, السّلام عليكم @@ -102,13 +156,15 @@ This is used internally by `sbr/modus-themes-toggle'." ;; in this file and can conflict with later config (particularly where the ;; cursor color is concerned). (advice-add #'x-apply-session-resources :override #'ignore) -;;+EarlyFontSetup -;; AfterInitHook + + +;; - Reseting garbage collection and file-name-handler values. + + (add-hook 'after-init-hook `(lambda () (setq gc-cons-threshold 67108864 ; 64mb gc-cons-percentage 0.1 file-name-handler-alist file-name-handler-alist-original) (garbage-collect)) t) -;; -AfterInitHook diff --git a/tools/emacs/init.el b/tools/emacs/init.el @@ -1,7 +1,8 @@ -;;; init.el --- -*- lexical-binding: t -*- -;;; Commentary: -;;; init configuration file for GNU Emacs -;;; Code: +;; Initialization +;; +;; I am using the [[https://archive.casouri.cat/note/2020/painless-transition-to-portable-dumper/index.html][portable dump]] feature (/to speed things up/) *but* I want to also start +;; without =pdump=, so I need to take both cases into account. + (defvar sbr-dumped nil "non-nil when a dump file is loaded (because dump.el sets this variable).") @@ -21,44 +22,109 @@ ;; add load-path’s and load autoload files (package-initialize)) -;; +CheckVer + + +;; First thing first, let's define a =emacs-start-time= constant to be able to compute the +;; time Emacs took to start. + + +(defconst emacs-start-time (current-time)) + + + +;; My configuration do not support Emacs version lower than 26. + + (let ((minver 26)) (unless (>= emacs-major-version minver) (error "Your Emacs is too old -- this configuration requires v%s or higher" minver))) -(defconst emacs-start-time (current-time)) + + +;; One thing though, I am currently not necessarily running Emacs 27, so I am going to need +;; to have the same configuration in ~init.el~ for a little bit of time. +;; +;; /Note: the lowest emacs version I wanna support is 26 (as of today, might evolve)/ + ;; load early-init.el before Emacs 27.0 (unless (>= emacs-major-version 27) (message "Early init: Emacs Version < 27.0") (load (expand-file-name "early-init.el" user-emacs-directory))) -;; -CheckVer -;; Inhibit + + +;; We also want our configuration to be working the same on any computer, this means we want +;; to define every option by ourselves, not relying on default files (~default.el~) that +;; would be set by our distribution. This is where =inhibit-default-init= comes into play, +;; setting it to non-nil inhibit loading the ~default~ library. +;; +;; We also want to inhibit some initial default start messages and screen. The default screen +;; will be as bare as possible. + + (setq inhibit-default-init t) ; Disable the site default settings (setq inhibit-startup-message t inhibit-startup-screen t) -;; -Inhibit -;; Confirm + + +;; Let's also use =y= or =n= instead of =yes= and =no= when exiting Emacs. + + (setq confirm-kill-emacs #'y-or-n-p) -;; -Confirm -;; DefaultMode + + +;; One last piece to the puzzle is the default mode. Setting it to fundamental-mode means we +;; won't load any /heavy/ mode at startup (like =org-mode=). We also want this scratch buffer +;; to be empty, so let's set it as well + + (setq initial-major-mode 'fundamental-mode initial-scratch-message nil) -;; -DefaultMode -;; Unicode +;; Unicode all the way +;; :PROPERTIES: +;; :CUSTOM_ID: h:df45a01a-177d-4909-9ce7-a5423e0ea20f +;; :END: +;; +;; By default, all my systems are configured and support =utf-8=, so let's just make it a +;; default in Emacs ; and handle special case on demand. + + (prefer-coding-system 'utf-8) (set-default-coding-systems 'utf-8) (set-language-environment 'utf-8) (set-selection-coding-system 'utf-8) (set-terminal-coding-system 'utf-8) -;; -Unicode -;;; UsePackageSetup +;; Package management with =use-package= +;; :PROPERTIES: +;; :CUSTOM_ID: h:112262a1-dd4d-4a50-a9e2-85b36bbbd95b +;; :END: +;; +;; =use-package= is a tool that streamlines the configuration of packages. It handles +;; everything from assigning key bindings, setting the value of customisation options, +;; writing hooks, declaring a package as a dependency for another, and so on. +;; +;; #+begin_quote +;; The =use-package= macro allows you to isolate package configuration in your =.emacs= file +;; in a way that is both performance-oriented and, well, tidy. I created it because I have +;; over 80 packages that I use in Emacs, and things were getting difficult to manage. Yet +;; with this utility my total load time is around 2 seconds, with no loss of functionality! +;; #+end_quote +;; +;; With =use-package= we can improve the start-up performance of Emacs in a few fairly simple +;; ways. Whenever a command is bound to a key it is configured to be loaded only once +;; invoked. Otherwise we can specify which functions should be autoloaded by means of the +;; =:commands= keyword. +;; +;; We need to setup the emacs package system and install =use-package= if not present +;; already. + + (require 'package) (setq package-archives @@ -108,11 +174,24 @@ (eval-when-compile (require 'use-package)) -;; -UsePackageSetup + +;; Early environment setup +;; +;; I want to *force* ==SSH_AUTH_SOCK= in Emacs to use my gpg-agent. + (setenv "SSH_AUTH_SOCK" "/run/user/1000/gnupg/S.gpg-agent.ssh") -;; CustomFile +;; =custom.el= +;; :PROPERTIES: +;; :CUSTOM_ID: h:1ddaf27e-ff7c-424e-8615-dd0bd22b685f +;; :END: +;; +;; When you install a package or use the various customisation interfaces to tweak things to +;; your liking, Emacs will append a piece of elisp to your init file. I prefer to have that +;; stored in a separate file. + + (defconst vde/custom-file (locate-user-emacs-file "custom.el") "File used to store settings from Customization UI.") @@ -128,18 +207,40 @@ (write-region "" nil custom-file)) (load vde/custom-file 'no-error 'no-message)) -;; -CustomFile -;; NoBuiltinOrg +;; Remove built-in =org-mode= +;; :PROPERTIES: +;; :CUSTOM_ID: h:9462c0d7-03be-4231-8f22-ce1a04be32b1 +;; :END: +;; +;; I want to make sure I am using the installed version of =orgmode= (from my org +;; configuration) instead of the built-in one. To do that safely, let's remove the built-in +;; version out of the load path. + + (require 'cl-seq) (setq load-path (cl-remove-if (lambda (x) (string-match-p "org$" x)) load-path)) -;; -NoBuiltinOrg -;; LoadCfgFunc +;; Loading configuration files +;; :PROPERTIES: +;; :CUSTOM_ID: h:d6aebc56-aadb-4b01-8404-bb922d12f8a8 +;; :END: +;; +;; This =org-mode= document /tangles/ into several files in different folders : +;; - ~config~ for my configuration +;; - ~lisp~ for imported code or library I've written and not yet published +;; +;; I used to load them by hand in the ~init.el~ file, which is very cumbersome, so let's try +;; to automatically load them. I want to first load the file in the ~lisp~ folder as they are +;; potentially used by my configuration (in ~config~). +;; +;; Let's define some functions that would do the job. + + (defun vde/el-load-dir (dir) "Load el files from the given folder" (let ((files (directory-files dir nil "\.el$"))) @@ -150,9 +251,13 @@ "Return hostname in short (aka wakasu.local -> wakasu)" (string-match "[0-9A-Za-z-]+" system-name) (substring system-name (match-beginning 0) (match-end 0))) -;; -LoadCfgFunc -;; CfgConstant + + +;; Let's define some constants early, based on the system, and the environment, to be able to +;; use those later on to skip some package or change some configuration accordingly. + + (defconst *sys/gui* (display-graphic-p) "Are we running on a GUI Emacs ?") @@ -184,21 +289,33 @@ (defvar *sys/light* (not *sys/full*) "Is it a light system ?") -;; -CfgConstant -;; CfgLoad + + +;; Now, in order to load ~lisp~ and ~config~ files, it's just a matter of calling this +;; function with the right argument. + + (add-to-list 'load-path (concat user-emacs-directory "lisp/")) (add-to-list 'load-path (concat user-emacs-directory "lisp/vorg")) (require 'init-func) (vde/el-load-dir (concat user-emacs-directory "/config/")) -;; -CfgLoad -;; CfgHostLoad + + +;; Finally, I want to be able to load files for a specific machine, in case I need it (not +;; entirely sure why yet but…) + + (if (file-exists-p (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el"))) (load-file (downcase (concat user-emacs-directory "/hosts/" (vde/short-hostname) ".el")))) -;; -CfgHostLoad -;; LastInit +;; Counting the time of loading +;; :PROPERTIES: +;; :CUSTOM_ID: h:2b645e95-6776-4f5b-a318-e5a915943881 +;; :END: + + (let ((elapsed (float-time (time-subtract (current-time) emacs-start-time)))) (message "Loading %s...done (%.3fs)" load-file-name elapsed)) @@ -210,6 +327,3 @@ (time-subtract (current-time) emacs-start-time)))) (message "Loading %s...done (%.3fs) [after-init]" ,load-file-name elapsed))) t) -;; -LastInit - -;;; init.el ends here