This creates lisp/basemacs-core.el
, which is the starting config for basemacs
. It is where all the defaults are set.
The core of the config – here we install straight.el
, use-package
and general.el
, which are needed by everything else. We also set some sane defaults and other settings.
Set up lexical binding in both early-init.el
and lisp/basemacs-core.el
. The files need to start with this in order for it to work.
;;; early-init.el --- -*- lexical-binding: t -*-
;;; basemacs-core.el --- -*- lexical-binding: t -*-
The early-init.el
file was introduced in Emacs 27. It runs before init.el
, and also before package, and UI initialization happens. Putting things in here can reduce startup time.
Most of this is taken from doom-emacs early-init.el.
This prevents package initialization from happening with package.el
. We use straight.el
for this.
(setq package-enable-at-startup nil)
(fset #'package--ensure-init-file #'ignore)
Resizing the Emacs frame can be a terribly expensive part of changing the font. By inhibiting this, we easily halve startup times with fonts that are larger than the system default.
(setq frame-inhibit-implied-resize t)
Turn off the UI elements.
(push '(menu-bar-lines . 0) default-frame-alist) ;; remove menubar
(push '(tool-bar-lines . 0) default-frame-alist) ;; remove toolbar
(push '(vertical-scroll-bars) default-frame-alist) ;; remove scrollbars
Now we end the file.
(provide 'early-init)
;;; early-init.el ends here
For packages, we use a combination of straight.el for package management and use-package for package configuration.
straight.el: next-generation, purely functional package manager for the Emacs hacker.
Using straight.el
instead of the built-in package.el
for several reasons. For this config, it is mainly because:
- it allows for reproducability with
default.el
, a file that acts as a lockfile for package versions - we can try out packages with ease using
M-x straight-use-package
- it is integrated with
use-package
Install straight.el
using the bootstrap code from it’s README.
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
This should speed things up according to the README:
By setting the variable
straight-cache-autoloads
to a non-nil value, you can cause straight.el to cache the autoloads of all used packages in a single file on disk, and load them from there instead of from the individual package files if they are still up to date. This reduces the number of disk IO operations during startup from O(number of packages) to O(1), so it should improve performance. No other configuration should be necessary to make this work; however, you may wish to callstraight-prune-build
occasionally, since otherwise this cache file may grow quite large over time.
(setq straight-cache-autoloads t)
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.
Now we can install use-package
using straight.el
.
(straight-use-package 'use-package)
use-package
is the heart of this config. All settings after this are configured with it. It is also integrated with straight.el
, allowing us to install packages with :straight t
, e.g.:
(use-package foo
:straight t
:custom
(bar-setting t)
:config
(foo-mode +1))
This example installs a package foo
with straight.el
, sets bar-setting
to true, and turns on foo-mode
. :straight
essentially the same thing as use-package
’s built-in :ensure
, but it uses straight.el
to handle package installation instead of package.el
.
For packages built into Emacs, we can use :straight (:type built-in)
.
Gather statistics, get report with use-package-report
.
(use-package use-package
:straight nil
:custom
(use-package-compute-statistics t))
Note here that we use :straight nil
. This is because use-package
has already been installed. It is not necessarily needed, but it can be handy to explicitly use this, both for clarity and in case straight-use-package-by-default
is set to t
.
This config uses :straight
in all use-package
declarations.
Configuration for all things involving keys.
general.el
provides a more convenient method for binding keys in emacs … Likeuse-package
…
In order to configure keys (and hooks), we use general.el. It gives us the ability to customize keys hooks in use-package
with :general
, and add hooks using :ghook
and :gfhook
. It also provides the functionality to add a leader
key.
Set the leader key as C-c
. This can be customized later on in the config file.
(use-package general
:straight t
:demand t
:init
(defcustom basemacs-leader "C-c"
"Basemacs leader key"
:type 'key-sequence
:group 'basemacs)
(defcustom basemacs-local-leader "C-c m"
"Basemacs local leader key"
:type 'key-sequence
:group 'basemacs)
:config
(general-create-definer base-leader-def
:prefix basemacs-leader)
(general-create-definer base-local-leader-def
:prefix basemacs-local-leader))
which-key
is a minor mode for Emacs that displays the key bindings following your currently entered incomplete command (a prefix) in a popup.
which-key
is a very helpful package because there are a lot of keybindings in Emacs, and this makes them easy to see. It feels like it should be built-in.
Reduce the delay to 0
to make it appear instantaneously.
(use-package which-key
:straight t
:custom
(which-key-idle-delay 0)
:config
(which-key-mode +1))
Set some sane defaults.
Settings for things that are defined in the C source code, so we use emacs
as the package.
(use-package emacs
:straight (:type built-in)
:init
;; answer with y/n instead of typing out yes/no
(defalias 'yes-or-no-p 'y-or-n-p)
:custom
;; load new source files instead of stale elisp bytecode
(load-prefer-newer t)
;; allow emacs to be any size, removes black bars
(frame-resize-pixelwise t))
Refresh (revert in Emacs’ terms) buffers when files change on disk. Makes sure to update any version control info that changes also.
(use-package autorevert
:straight (:type built-in)
:custom
(global-revert-check-vc-info t)
:config
(global-auto-revert-mode +1))
Use utf-8 for everything.
(use-package mule
:straight (:type built-in)
:config
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-language-environment "UTF-8"))
Use the system clipboard for killing/yanking (copying/pasting) and display column information in the modeline.
(use-package simple
:straight (:type built-in)
:custom
;; killing and yanking uses the system clipboard
(save-interprogram-paste-before-kill t)
:config
;; display column info in the modeline
(column-number-mode +1))
When the lines in a file are so long that performance could suffer to an unacceptable degree, we say “so long” to the slow modes and options enabled in that buffer, and invoke something much more basic in their place.
(use-package so-long
:straight (:type built-in)
:config
(global-so-long-mode +1))
Put customizations in custom.el
instead of init.el
. This keeps init.el
clean, which is helpful for version control.
(use-package cus-edit
:straight (:type built-in)
:custom
;; create custom.el if it doesnt exist yet
(custom-file (expand-file-name "custom.el" user-emacs-directory))
:config
(if (file-exists-p custom-file)
(load-file custom-file)))
Settings and plugins that help with programming.
Display line numbers in all programming modes.
(use-package display-line-numbers
:straight (:type built-in)
:ghook
('prog-mode-hook #'display-line-numbers-mode))
That’s all folks!
(provide 'basemacs-core)
;;; basemacs-core.el ends here