From 3a7d14ff0088a912a8c0e4b844dc4e661ee97189 Mon Sep 17 00:00:00 2001 From: Gene Pasquet Date: Tue, 11 Feb 2025 22:32:24 +0000 Subject: Refactor the crap out of Bedrock --- README.md | 299 ++++----------------------------------------------- early-init.el | 42 -------- early-substrate.el | 33 ++++++ extras/base.el | 195 --------------------------------- extras/dev.el | 104 ------------------ extras/email.el | 30 ------ extras/org-intro.txt | 91 ---------------- extras/org.el | 161 --------------------------- extras/researcher.el | 99 ----------------- extras/vim-like.el | 36 ------- extras/writer.el | 62 ----------- init.el | 256 ------------------------------------------- substrate.el | 228 +++++++++++++++++++++++++++++++++++++++ 13 files changed, 282 insertions(+), 1354 deletions(-) delete mode 100644 early-init.el create mode 100644 early-substrate.el delete mode 100644 extras/base.el delete mode 100644 extras/dev.el delete mode 100644 extras/email.el delete mode 100644 extras/org-intro.txt delete mode 100644 extras/org.el delete mode 100644 extras/researcher.el delete mode 100644 extras/vim-like.el delete mode 100644 extras/writer.el delete mode 100644 init.el create mode 100644 substrate.el diff --git a/README.md b/README.md index 57e2c53..d26ee10 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,39 @@ -# Emacs Bedrock +# Emacs Substrate -Stepping stones to a better Emacs experience - -## Synopsis - -An *extremely* minimal Emacs starter kit uses just one external package by default, and only GNU-ELPA packages on an opt-in basis. Intended to be copied once and then modified as the user grows in knowledge and power. - -As of 2024-02-07, Bedrock is officially hosted on [Codeberg](https://codeberg.org/ashton314/emacs-bedrock). - -Mirrors: - - [Old project on SourceHut](https://sr.ht/~ashton314/emacs-bedrock/) - - [GitHub](https://github.com/ashton314/emacs-bedrock) (just a place holder) +A clean basis to organically grow your config onto. **NOTICE:** Requires Emacs 29.1 or better. ## Description -This is a minimal Emacs starter kit. Like, *really* minimal. Here's the short of the philosophy: +This is a minimal Emacs base config. Here's the short of the philosophy: - Focus on using default, built-in Emacs behavior - - Yes, we all love our fancy third-party packages. This starter kit focuses on what is built-in to Emacs. Why? Because there are too many good packages and picking and choosing the best is a joy we leave to the user. - - - Explain every customization and encourage modification - - The goal of this starter kit is to encourage end-user adaptation and growth. All of the `.el` files should be legible and, more importantly, justify in plain English the rationale for adding the configuration they do. - + - Emacs-lisp centric, encourage configuration through code + - Allow update and upgrade of substrate - No magic - We keep things *crushingly* simple here. That means no fancy loadable modules or whatnot. Everything is as straight-forward as can be. +## Installation -There are two files of interest: `early-init.el` and `init.el`. +To install emacs-substrate, clone this repository somewhere, then create the files: -### `early-init.el` +```lisp +;; ~/.emacs.d/early-init.el +(add-to-list 'load-path "") -The early init file uses *strictly* built-in Emacs features to do the following: - - - Improve startup time - - Set up initial frame behavior - -### `init.el` - -This is where the meat of all configuration goes. This file: +(require 'early-substrate) +``` - - Add minor UI niceties (e.g. clock in the tab-bar, full-screen by default, etc.) - - Set the default theme (`modus-vivendi`) - - Turn on discovery aids (e.g. `help-quick`, [which-key](https://github.com/justbur/emacs-which-key), etc.) +```lisp +;; ~/.emacs.d/init.el +(require 'substrate) -### Trying this out without committing too hard +;; Set custom variables here -Emacs 29.1 added the handy `--init-directory` flag. This means that you can run `emacs --init-directory path/to/emacs-bedrock/` and all the customizations and package installations will be isolated to the project directory. Emacs should only add files that are already in the `.gitignore`. +(substrate-init) -Once you're happy, you should just copy `init.el` and `early-init.el` to `~/.emacs.d/`. +;; The rest of your config below +``` ## Screenshots @@ -63,155 +45,10 @@ Basic code editing: line numbers and `hl-line-mode`. ![Editing the source code of Emacs Bedrock's init.el file while using Bedrock configuration](screenshots/basic_code_editing.png) -`which-key` package in action: hit `C-x` and wait for a second to get a pop-up window of what all next available keybindings are. - -![Which key package in motion](screenshots/which_key.gif) - -[Movie of `which-key` in motion](screenshots/which_key.mov) - -Basic completion: hit `TAB` twice to pull up the `*Completions*` buffer, then `TAB` once again to automatically put the cursor into that buffer. (Configurable to pull up and auto-select faster, of course, but this behaves closer to the stock Emacs experience.) - -![Still from the built-in completion interface, new with Emacs 29.1](screenshots/basic_builtin_completion.png) - -Basic completion interface in action. - -![GIF of the completion interface in action](screenshots/basic_completion.gif) - -[Movie of the completion interface in action](screenshots/basic_completion.mov) - -A bunch of bells and whistles: - - - Vertico completion framework enabled (`base.el` extra) - - Consult enabled for buffer-switching preview (`base.el` extra) - - Corfu completion-at-point enabled (`base.el` extra) - - Smooth scrolling (enabled by default) - -[Movie of all the bells and whistles turned on](screenshots/everything_demo.mov) - -## Extras - -For those who'd like a little more help in tailoring Emacs for specific purposes, the `extras/` folder contains a few Emacs Lisp files with example configurations for various packages. You can copy just the config you want into `init.el` or include them wholesale via `(load-file "~/.emacs.d/extras/file-name.el")`. - -**NOTE:** If you copy the `extras/` directory to `~/.emacs.d/` or wherever you're setting `user-emacs-directory`, then simply incrementing the appropriate lines in the `init.el` file should work. - -Extras: - - - Base UI Enhancements - - Development tools - - Org-mode - - Vim refugee - - Researcher - - Email (TODO: mu4e, EBDB) - -#### Base UI Enhancements: `extras/base.el` - -Packages this extra adds: - - - [Avy](https://github.com/abo-abo/avy) - - [Embark](https://github.com/oantolin/embark) - - [Vertico](https://github.com/minad/vertico) - - [Marginalia](https://github.com/minad/marginalia/) - - [Corfu](https://github.com/minad/corfu) - - [Consult](https://github.com/minad/consult) - - [Orderless](https://github.com/oantolin/orderless) - - [wgrep](https://github.com/mhayashi1120/Emacs-wgrep) - -Along with a few ancillary packages that enhance the above. - -These are some of the best UI enhancements that Emacs has to offer. Vertico and Consult make common operations like searching files, switching buffers, etc. a breeze. Corfu enhances the "completion at point" (aka "tab-to-complete") to show a little popup window like what you'd be used to in e.g. VS Code. - -Avy is the fastest way to move around in a buffer, and it can do a *lot*.[^1] Embark is kind of like a right-click context menu, but entirely keyboard driven. - -wgrep makes grep buffers editable. This means you can `consult-ripgrep` → search project → `embark-act` → `embark-export` → `wgrep-change-to-wgrep-mode` to do search-and-replace across an entire project in one fell swoop. See [Warp Factor Refactoring](https://lambdaland.org/posts/2023-05-31_warp_factor_refactor/) for more on this workflow. - -#### Development tools: `extras/dev.el` - -Packages this extra adds: - - - [magit](https://magit.vc) - - Markdown, YAML, and JSON modes - -Magit is the best Git interface in the known universe. Some people use Emacs just so they can use Magit. It's that good. Entry point is bound to `C-c g` by default. - -Built-in packages that this extra configures: - - - [Eglot](https://github.com/joaotavora/eglot) ([Language Server Protocol (LSP) client](https://microsoft.github.io/language-server-protocol/)) - - Treesit ([Tree-Sitter](https://github.com/tree-sitter) support) - -Both of these packages are new in Emacs 29. **Be sure to run `M-x treesit-install-language-grammar` to install the language grammar you'll need before editing a file the respective language for the first time!** This is a quirk of how the built-in tree-sitter works; packages like [treesit-auto](https://github.com/renzmann/treesit-auto) can help with this if it becomes too much of an annoyance. - -#### Org-mode: `extras/org.el` - -This extra configures `org-mode`. There is a *lot* that Bedrock cannot configure out of the box—you will need to modify all variables to fit your file system and needs, as explained in comments in the file. - -#### Vim refugee: `extras/vim-like.el` - -Packages this extra adds: - - - [Evil](https://github.com/emacs-evil/evil) - -If you like Vim keybindings, then this is the extra for you. It configures `evil-mode` and enables it, so you get Vim-like keybindings all throughout Emacs. I understand that this is the best Vim emulation outside of Vim itself. I use `evil-mode` in all my work. - -Other packages that I use personally, but are not on GNU or non-GNU ELPA and so left out of the config include: - - - [Evil-Collection](https://github.com/emacs-evil/evil-collection) Add Evil-friendly keybindings to lots of corners of Emacs - - [Evil-Leader](https://github.com/cofi/evil-leader) Setting a prefix (i.e. "leader") key - - [Origami](https://github.com/gregsexton/origami.el) Code folding - -#### Researcher: `extras/researcher.el` - -Packages this extra includes: - - - [Citar](https://github.com/emacs-citar/citar) - - [Denote](https://protesilaos.com/emacs/denote) - -Citar provides a completing-read interface into your bibliography and can automatically insert citations in LaTeX, Markdown, and org-mode. - -Denote is a simple note taking system that doesn't rely on any tools except some common Unix utilities like `grep` and `find`. - -Citar lives in [Melpa](https://melpa.org/), so you will need to [add Melpa to your package-archives](https://melpa.org/#/getting-started). - -#### Writing: `extras/writer.el` - -Packages this extra adds: - - - [Jinx](https://github.com/minad/jinx) - - [Olivetti](https://github.com/rnkn/olivetti) - -Jinx is the spell-checker you will wish every program had. - -Olivetti automatically balances window margins so your text stays nice and centered—handy for wide monitors. - -#### Email `extras/email.el` +## Philosophy TODO -## Using - -Clone this repository wherever. Then you should copy `early-init.el`, `init.el`, and (optionally, recommended) `extras/` into your `~/.emacs.d/` repository: - -```bash -git clone https://codeberg.org/ashton314/emacs-bedrock.git -mkdir -p ~/.emacs.d/ -cp emacs-bedrock/early-init.el ~/.emacs.d/ -cp emacs-bedrock/init.el ~/.emacs.d/ -cp -r emacs-bedrock/extras ~/.emacs.d/ -``` - -Fire up Emacs and you're good to go! - -### Philosophy - -Many people are looking for a good set of defaults and some easy-to-use switches that let Emacs get out of the way and let them work on what they want to. This is fine. This is not what Bedrock tries to do. - -Emacs is the most customizable piece of software in existence. (No citation needed.) My goal with Bedrock is to make Emacs a little nicer by enabling some things that I personally think should be enabled by default. Bedrock goes a little further by suggesting a few well-built packages that go on to enhance the experience. - -Bedrock encourages inspection and modification. I don't plan on making some core that periodically gets updated. You can think of this as just some guy's config that you wanted to adopt. - -As an example of a deliberate choice, the `help-quick` buffer pops open on startup. Once a user has gotten used to this, they can just go into their `init.el` file and modify it themselves to remove that hook if they don't like it. It's a simple one-line change, and only users who are ready for it will do it. - -When I started learning Emacs, my dad gave me his `.emacs` file. (That's what we used back in ye olden days instead of `.emacs.d/init.el` and stuff.) I used it without modification for many years. Eventually I learned how to write my own functions and customizations. This package aims to give other users a similar experience. When someone comes to me and expresses their desire to learn Emacs, I can point them at this to help them get over the initial hump, but not coddle them so much that they're afraid or unable to change things to their liking. - ## Requirements Emacs 29.1 or later. @@ -223,102 +60,8 @@ Emacs 29.1 is, as of 2023-09-04, the latest stable release. The specific feature - Built-in tree-sitter support - Built-in LSP client (Eglot) -## Development - -This is version `1.3.1`. - -As of `1.0.0`, no new `use-package` declarations will be added to `init.el`. No promises on the extras! - -I welcome any feedback you may have. You can [open issues](https://todo.sr.ht/~ashton314/emacs-bedrock) or [drop me a line](https://lambdaland.org/#contact) directly with any comments or suggestions. - -Thanks to all the folks who have contributed suggestions and bug reports. Thank you also for being patient with me as I work on this project as a hobby. :) - -### Roadmap - -See the [issue tracker](https://codeberg.org/ashton314/emacs-bedrock/issues) on Codeberg. - -## Changelog - - - 1.4.0 - - 2024-12-14 - - Add `extras/writer.el`. - - - 1.3.1 - - Fix consult-history binding in Eshell to not override `isearch-backwards`. (#13) - - - 1.3.0 - - Change magit keybinding to standard `C-x g`; drop non-standard ones. (Thanks Vincent Conus!) - - Don't set `C-s` to `consult-line` in `extras/base.el`; instead, use the recommended keybindings from the Consult manual. (Thanks Enzo Do rosario, Thomas Riccardi, and Preston Hunt for discussion!) - - Add sample Denote config. - - Improve latency by slowing down auto-revert polling. (Thanks Jeff Johnson!) - - - 1.2.0 - - 2023-09-21 - - Add packages [Cape](https://github.com/minad/cape) (+ basic configuration) and wgrep. Add a binding for `consult-ripgrep`. - - - 1.1.0 - - 2023-09-08 - - Rename "mixins" → "extras", as mixin has the flavor of being some kind of special thingy. "Extra" gets at the purpose of these files. - - - 1.0.0 - - 2023-09-04 - - First "stable" release! Line number width improved, fix default load paths, expand Eglot and Vertico config, fix Corfu load. - - - 0.2.1 - - 2023-06-20 - - Minor bug fixes; add Embark package. - - - 0.2.0 - - 2023-03-14 - - Flesh out the `mixin/vim-like.el` so that there's *some* Vim configuration. - - - 0.1.0 - - 2023-01-17 - - Begin work on `mixin/org.el`, turn on windmove-mode. - - - 0.0.2 - - 2023-01-03 - - Reorganize to slim down `early-init.el` and add the first mixin files. - - - 0.0.1 - - 2023-01-03 - - Initial "release". - -## Authors +## Credits Creator and maintainer: - Ashton Wiersdorf https://lambdaland.org - -Contributors: - - - Justin Koh - - George Kettleborough - - Enzo Do Rosario - - Ed Singleton - - Vincent Conus - -[^1]: https://karthinks.com/software/avy-can-do-anything/ diff --git a/early-init.el b/early-init.el deleted file mode 100644 index 9782b87..0000000 --- a/early-init.el +++ /dev/null @@ -1,42 +0,0 @@ -;;; ________ _______ __ __ -;;; / | / \ / | / | -;;; $$$$$$$$/ _____ ____ ______ _______ _______ $$$$$$$ | ______ ____$$ | ______ ______ _______$$ | __ -;;; $$ |__ / \/ \ / \ / |/ | $$ |__$$ |/ \ / $$ |/ \ / \ / $$ | / | -;;; $$ | $$$$$$ $$$$ |$$$$$$ /$$$$$$$//$$$$$$$/ $$ $$ -(windmove-default-keybindings 'control) ; You can use other modifiers here - -;; Fix archaic defaults -(setopt sentence-end-double-space nil) - -;; Make right-click do something sensible -(when (display-graphic-p) - (context-menu-mode)) - -;; Don't litter file system with *~ backup files; put them all inside -;; ~/.emacs.d/backup or wherever -(defun bedrock--backup-file-name (fpath) - "Return a new file path of a given file path. -If the new path's directories does not exist, create them." - (let* ((backupRootDir (concat user-emacs-directory "emacs-backup/")) - (filePath (replace-regexp-in-string "[A-Za-z]:" "" fpath )) ; remove Windows driver letter in path - (backupFilePath (replace-regexp-in-string "//" "/" (concat backupRootDir filePath "~") ))) - (make-directory (file-name-directory backupFilePath) (file-name-directory backupFilePath)) - backupFilePath)) -(setopt make-backup-file-name-function 'bedrock--backup-file-name) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; -;;; Discovery aids -;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Show the help buffer after startup -(add-hook 'after-init-hook 'help-quick) - -;; which-key: shows a popup of available keybindings when typing a long key -;; sequence (e.g. C-x ...) -(use-package which-key - :ensure t - :config - (which-key-mode)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; -;;; Minibuffer/completion settings -;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; For help, see: https://www.masteringemacs.org/article/understanding-minibuffer-completion - -(setopt enable-recursive-minibuffers t) ; Use the minibuffer whilst in the minibuffer -(setopt completion-cycle-threshold 1) ; TAB cycles candidates -(setopt completions-detailed t) ; Show annotations -(setopt tab-always-indent 'complete) ; When I hit TAB, try to complete, otherwise, indent -(setopt completion-styles '(basic initials substring)) ; Different styles to match input to candidates - -(setopt completion-auto-help 'always) ; Open completion always; `lazy' another option -(setopt completions-max-height 20) ; This is arbitrary -(setopt completions-detailed t) -(setopt completions-format 'one-column) -(setopt completions-group t) -(setopt completion-auto-select 'second-tab) ; Much more eager -;(setopt completion-auto-select t) ; See `C-h v completion-auto-select' for more possible values - -(keymap-set minibuffer-mode-map "TAB" 'minibuffer-complete) ; TAB acts more like how it does in the shell - -;; For a fancier built-in completion option, try ido-mode, -;; icomplete-vertical, or fido-mode. See also the file extras/base.el - -;(icomplete-vertical-mode) -;(fido-vertical-mode) -;(setopt icomplete-delay-completions-threshold 4000) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; -;;; Interface enhancements/defaults -;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Mode line information -(setopt line-number-mode t) ; Show current line in modeline -(setopt column-number-mode t) ; Show column as well - -(setopt x-underline-at-descent-line nil) ; Prettier underlines -(setopt switch-to-buffer-obey-display-actions t) ; Make switching buffers more consistent - -(setopt show-trailing-whitespace nil) ; By default, don't underline trailing spaces -(setopt indicate-buffer-boundaries 'left) ; Show buffer top and bottom in the margin - -;; Enable horizontal scrolling -(setopt mouse-wheel-tilt-scroll t) -(setopt mouse-wheel-flip-direction t) - -;; We won't set these, but they're good to know about -;; -;; (setopt indent-tabs-mode nil) -;; (setopt tab-width 4) - -;; Misc. UI tweaks -(blink-cursor-mode -1) ; Steady cursor -(pixel-scroll-precision-mode) ; Smooth scrolling - -;; Use common keystrokes by default -(cua-mode) - -;; Display line numbers in programming mode -(add-hook 'prog-mode-hook 'display-line-numbers-mode) -(setopt display-line-numbers-width 3) ; Set a minimum width - -;; Nice line wrapping when working with text -(add-hook 'text-mode-hook 'visual-line-mode) - -;; Modes to highlight the current line with -(let ((hl-line-hooks '(text-mode-hook prog-mode-hook))) - (mapc (lambda (hook) (add-hook hook 'hl-line-mode)) hl-line-hooks)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; -;;; Tab-bar configuration -;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Show the tab-bar as soon as tab-bar functions are invoked -(setopt tab-bar-show 1) - -;; Add the time to the tab-bar, if visible -(add-to-list 'tab-bar-format 'tab-bar-format-align-right 'append) -(add-to-list 'tab-bar-format 'tab-bar-format-global 'append) -(setopt display-time-format "%a %F %T") -(setopt display-time-interval 1) -(display-time-mode) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; -;;; Theme -;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(use-package emacs - :config - (load-theme 'modus-vivendi)) ; for light theme, use modus-operandi - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; -;;; Optional extras -;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Uncomment the (load-file …) lines or copy code from the extras/ elisp files -;; as desired - -;; UI/UX enhancements mostly focused on minibuffer and autocompletion interfaces -;; These ones are *strongly* recommended! -;(load-file (expand-file-name "extras/base.el" user-emacs-directory)) - -;; Packages for software development -;(load-file (expand-file-name "extras/dev.el" user-emacs-directory)) - -;; Vim-bindings in Emacs (evil-mode configuration) -;(load-file (expand-file-name "extras/vim-like.el" user-emacs-directory)) - -;; Org-mode configuration -;; WARNING: need to customize things inside the elisp file before use! See -;; the file extras/org-intro.txt for help. -;(load-file (expand-file-name "extras/org.el" user-emacs-directory)) - -;; Email configuration in Emacs -;; WARNING: needs the `mu' program installed; see the elisp file for more -;; details. -;(load-file (expand-file-name "extras/email.el" user-emacs-directory)) - -;; Tools for academic researchers -;(load-file (expand-file-name "extras/researcher.el" user-emacs-directory)) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; -;;; Built-in customization framework -;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(custom-set-variables - ;; custom-set-variables was added by Custom. - ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. - ;; If there is more than one, they won't work right. - '(package-selected-packages '(which-key))) -(custom-set-faces - ;; custom-set-faces was added by Custom. - ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. - ;; If there is more than one, they won't work right. - ) - -(setq gc-cons-threshold (or bedrock--initial-gc-threshold 800000)) diff --git a/substrate.el b/substrate.el new file mode 100644 index 0000000..6dc93a5 --- /dev/null +++ b/substrate.el @@ -0,0 +1,228 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; .⌒. ▗▄▄▖▗ ▖ ▗▖ ▗▄ ▄▄ ▄▄ ▗ ▖▗▄▄ ▄▄ ▄▄▄▖▗▄▄ ▗▖ ▄▄▄▖▗▄▄▖ ;;; +;;; .# #. ▐ ▐▌▐▌ ▐▌ ▗▘ ▘▐▘ ▘ ▐▘ ▘▐ ▌▐ ▌▐▘ ▘ ▐ ▐ ▝▌ ▐▌ ▐ ▐ ;;; +;;; / \ ▐▄▄▖▐▐▌▌ ▌▐ ▐ ▝▙▄ ▝▙▄ ▐ ▌▐▄▄▘▝▙▄ ▐ ▐▄▄▘ ▌▐ ▐ ▐▄▄▖ ;;; +;;; (,,,___,,,) ▐ ▐▝▘▌ ▙▟ ▐ ▝▌ ▝▌▐ ▌▐ ▌ ▝▌ ▐ ▐ ▝▖ ▙▟ ▐ ▐ ;;; +;;; ) ( ▐▄▄▖▐ ▌▐ ▌ ▚▄▘▝▄▟▘ ▝▄▟▘▝▄▄▘▐▄▄▘▝▄▟▘ ▐ ▐ ▘▐ ▌ ▐ ▐▄▄▖ ;;; +;;; (___) ;;; +;;; ;;; +;;; init.el ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Guardrail +(when (< emacs-major-version 29) + (error "Emacs Substrate only works with Emacs 29 and newer; you have version %s" emacs-major-version)) + +;;; Custom variables + +(defgroup substrate nil "Custom options for substrate") +(defcustom substrate-initialise-packages t + "Initialise the substrate package system (straight.el)" + :type 'boolean :group 'substrate) +(defcustom substrate-enable-windmove t + "Enable windmove to hop around windows with ctrl+arrow" + :type 'boolean :group 'substrate) +(defcustom substrate-display-startup-help t + "Show a help window on startup" + :type 'boolean :group 'substrate) +(defcustom substrate-enable-which-key t + "Use which-key to list available key combos" + :type 'boolean :group 'substrate) +(defcustom substrate-display-line-numbers t + "Display line numbers on buffers" + :type 'boolean :group 'substrate) +(defcustom substrate-enable-cua-mode t + "Enable CUA mode or not" + :type 'boolean :group 'substrate) +(defcustom substrate-configure-theme t + "Configure the default theme (evangelion) as part of the substrate init" + :type 'boolean :group 'substrate) + + +(defun substrate-init () + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;; + ;;; Basic settings + ;;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; Package initialization + ;; + (when substrate-initialise-packages + (defvar bootstrap-version) + (let ((bootstrap-file + (expand-file-name + "straight/repos/straight.el/bootstrap.el" + (or (bound-and-true-p straight-base-dir) + user-emacs-directory))) + (bootstrap-version 7)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage) + (setq straight-use-package-by-default t))) + + (setopt initial-major-mode 'fundamental-mode) ; default mode for the *scratch* buffer + (setopt display-time-default-load-average nil) ; this information is useless for most + + ;; Automatically reread from disk if the underlying file changes + (setopt auto-revert-avoid-polling t) + ;; Some systems don't do file notifications well; see + ;; https://todo.sr.ht/~ashton314/emacs-bedrock/11 + (setopt auto-revert-interval 5) + (setopt auto-revert-check-vc-info t) + (global-auto-revert-mode) + + ;; Save history of minibuffer + (savehist-mode) + + ;; Move through windows with Ctrl- + (when substrate-enable-windmove + (windmove-default-keybindings 'control)) ; You can use other modifiers here + + ;; Fix archaic defaults + (setopt sentence-end-double-space nil) + + ;; Make right-click do something sensible + (when (display-graphic-p) + (context-menu-mode)) + + ;; Don't litter file system with *~ backup files; put them all inside + ;; ~/.emacs.d/backup or wherever + (defun substrate--backup-file-name (fpath) + "Return a new file path of a given file path. +If the new path's directories does not exist, create them." + (let* ((backupRootDir (concat user-emacs-directory "emacs-backup/")) + (filePath (replace-regexp-in-string "[A-Za-z]:" "" fpath )) ; remove Windows driver letter in path + (backupFilePath (replace-regexp-in-string "//" "/" (concat backupRootDir filePath "~") ))) + (make-directory (file-name-directory backupFilePath) (file-name-directory backupFilePath)) + backupFilePath)) + (setopt make-backup-file-name-function 'substrate--backup-file-name) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; Discovery aids +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; Show the help buffer after startup + (when substrate-display-startup-help + (add-hook 'after-init-hook 'help-quick)) + + ;; which-key: shows a popup of available keybindings when typing a long key + ;; sequence (e.g. C-x ...) + (use-package which-key + :ensure t + :if substrate-enable-which-key + :config + (which-key-mode)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; Minibuffer/completion settings +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; For help, see: https://www.masteringemacs.org/article/understanding-minibuffer-completion + + (setopt enable-recursive-minibuffers t) ; Use the minibuffer whilst in the minibuffer + (setopt completion-cycle-threshold 1) ; TAB cycles candidates + (setopt completions-detailed t) ; Show annotations + (setopt tab-always-indent 'complete) ; When I hit TAB, try to complete, otherwise, indent + (setopt completion-styles '(basic initials substring)) ; Different styles to match input to candidates + + (setopt completion-auto-help 'always) ; Open completion always; `lazy' another option + (setopt completions-max-height 20) ; This is arbitrary + (setopt completions-detailed t) + (setopt completions-format 'one-column) + (setopt completions-group t) + (setopt completion-auto-select 'second-tab) ; Much more eager + ;(setopt completion-auto-select t) ; See `C-h v completion-auto-select' for more possible values + + (keymap-set minibuffer-mode-map "TAB" 'minibuffer-complete) ; TAB acts more like how it does in the shell + + ;; For a fancier built-in completion option, try ido-mode, + ;; icomplete-vertical, or fido-mode. See also the file extras/base.el + + ;(icomplete-vertical-mode) + ;(fido-vertical-mode) + ;(setopt icomplete-delay-completions-threshold 4000) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; Interface enhancements/defaults +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; Mode line information + (setopt line-number-mode t) ; Show current line in modeline + (setopt column-number-mode t) ; Show column as well + + (setopt x-underline-at-descent-line nil) ; Prettier underlines + (setopt switch-to-buffer-obey-display-actions t) ; Make switching buffers more consistent + + (setopt show-trailing-whitespace nil) ; By default, don't underline trailing spaces + (setopt indicate-buffer-boundaries 'left) ; Show buffer top and bottom in the margin + + ;; Enable horizontal scrolling + (setopt mouse-wheel-tilt-scroll t) + (setopt mouse-wheel-flip-direction t) + + ;; We won't set these, but they're good to know about + ;; + ;; (setopt indent-tabs-mode nil) + ;; (setopt tab-width 4) + + ;; Misc. UI tweaks + (blink-cursor-mode -1) ; Steady cursor + (pixel-scroll-precision-mode) ; Smooth scrolling + + ;; Use common keystrokes by default + (when substrate-enable-cua-mode + (cua-mode)) + + ;; Display line numbers in programming mode + (when substrate-display-line-numbers + (add-hook 'prog-mode-hook 'display-line-numbers-mode) + (setopt display-line-numbers-width 3)) ; Set a minimum width + + ;; Nice line wrapping when working with text + (add-hook 'text-mode-hook 'visual-line-mode) + + ;; Modes to highlight the current line with + (let ((hl-line-hooks '(text-mode-hook prog-mode-hook))) + (mapc (lambda (hook) (add-hook hook 'hl-line-mode)) hl-line-hooks)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; Tab-bar configuration +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; Show the tab-bar as soon as tab-bar functions are invoked + (setopt tab-bar-show 1) + + ;; Add the time to the tab-bar, if visible + (add-to-list 'tab-bar-format 'tab-bar-format-align-right 'append) + (add-to-list 'tab-bar-format 'tab-bar-format-global 'append) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; Theme +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (use-package evangelion-theme + :if substrate-configure-theme + :config (load-theme 'evangelion t)) + +;;; Relegate automatic custom variables to their own file. + (setq custom-file (expand-file-name "custom-vars.el")) + +) ;; End substrate-init + +(provide 'substrate) +;;; End of substrate.el -- cgit v1.2.3