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:
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