Wilson Rejects Doom, Spacemacs Kits to Build Custom Emacs Setup
System Crafters
Building an Emacs configuration from scratch yields far greater understanding than pre-packaged distributions while requiring only a few lines of code to transform the bare editor into a modern productivity environment.
Building an Emacs configuration from the ground up offers significantly deeper understanding of the platform than adopting pre-baked starter distributions like Doom Emacs or Spacemacs. (0:03)
Stripping out Emacs's default visual clutter—including the menu bar, tool bar, scrollbars, and splash screen—requires only five to six lines of basic Emacs Lisp code. (9:44)
Bootstrapping MELPA alongside 'use-package' and setting 'use-package-always-ensure' to true enables fully automated, reproducible package downloading and declarative setup on fresh systems. (21:22)
Modern Emacs ergonomics can be dramatically improved by pairing Ivy and Council for fuzzy command navigation, replacing the mode line with Doom Modeline, and remapping the Caps Lock key to Control. (42:35)
Detailed notes
## Background
Published by David Wilson on the System Crafters YouTube channel on September 12, 2020, this video marks the premiere episode of the "Emacs From Scratch" livestream series. The stream initiates a journey toward building a completely custom Emacs configuration from the ground up while teaching fundamental Emacs concepts and package setup techniques along the way.
## TL;DR
Host David Wilson advocates for configuring GNU Emacs by hand rather than relying on pre-packaged distributions like Doom or Spacemacs, demonstrating the transformation of an out-of-the-box Emacs 27.1 instance into a clean, modern working environment. After stripping away default UI clutter like toolbars, menu bars, and startup screens, he tunes high-DPI font rendering and introduces built-in introspection tools like describe functions. He then sets up third-party package management via MELPA and use-package, integrates command logging, and configures Ivy and Council for streamlined fuzzy-matching completion. Finally, he styles the status bar using doom-modeline and commits the resulting configuration to GitHub using Magit.
## Atmosphere & style
The session carries the relaxed, conversational intimacy of a weekend live-coding stream, blending technical competence with approachable vulnerability. Wilson is unhurried and candid, openly laughing off accidental keystrokes, missing parentheses, and sudden frame suspensions caused by his ingrained Vim muscle memory. Engaging actively with the live chat and recovering smoothly from live hiccups, the host creates a welcoming, collaborative atmosphere that strips away the intimidation often associated with Emacs Lisp.
## Bulletin
- [00:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3s) Building an Emacs configuration from the ground up offers significantly deeper understanding of the platform than adopting pre-baked starter distributions like Doom Emacs or Spacemacs.
- [09:44](https://www.youtube.com/watch?v=74zOY-vgkyw&t=584s) Stripping out Emacs's default visual clutter—including the menu bar, tool bar, scrollbars, and splash screen—requires only five to six lines of basic Emacs Lisp code.
- [21:22](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1282s) Bootstrapping MELPA alongside 'use-package' and setting 'use-package-always-ensure' to true enables fully automated, reproducible package downloading and declarative setup on fresh systems.
- [42:35](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2555s) Modern Emacs ergonomics can be dramatically improved by pairing Ivy and Council for fuzzy command navigation, replacing the mode line with Doom Modeline, and remapping the Caps Lock key to Control.
## Key takeaways
- [00:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3s) Emacs operates as a complete, unified computing and productivity environment capable of managing an entire operating system desktop rather than functioning merely as a text editor.
- [02:23](https://www.youtube.com/watch?v=74zOY-vgkyw&t=143s) David Wilson runs EXWM (Emacs X Window Manager) on GNU Guix Linux to orchestrate buffers, terminals, version control, and native X11 browser windows inside a single interface.
- [09:44](https://www.youtube.com/watch?v=74zOY-vgkyw&t=584s) A minimal, modern aesthetic can be established immediately by disabling the menu bar, tool bar, and startup screen, while swapping audio alerts for a visible bell.
- [12:09](https://www.youtube.com/watch?v=74zOY-vgkyw&t=729s) Emacs 27 introduced HarfBuzz text shaping, improving typography but requiring adjustments to font scaling heights (such as setting Fira Code Retina to 280 for high-DPI displays).
- [14:48](https://www.youtube.com/watch?v=74zOY-vgkyw&t=888s) Emacs is a self-documenting system whose runtime can be inspected live using the describe command family ('describe-variable', 'describe-function', 'describe-face').
- [19:58](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1198s) Connecting package.el to MELPA is essential for modern setups because the default GNU ELPA archive lacks the vast majority of community-maintained packages.
- [21:22](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1282s) Configuring 'use-package' with 'use-package-always-ensure' enables automated, declarative package installation without manual git downloads or imperative require boilerplate.
- [26:36](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1596s) Emacs's automatic background swap files enable full data recovery using 'recover-this-file' following accidental process terminations or terminal suspensions.
- [33:04](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1984s) Rebinding the Escape key to 'keyboard-escape-quit' allows users accustomed to modal editors to cleanly dismiss minibuffer prompts without typing 'C-g'.
- [33:51](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2031s) Activating 'ivy-mode' globally replaces Emacs's bare-bones input prompts with Council and Ivy's interactive fuzzy substring search across files, buffers, and commands.
- [38:30](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2310s) 'use-package' preserves fast startup times by leveraging Elisp autoload declarations, deferring actual package evaluation until a command is invoked.
- [40:01](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2401s) The ':diminish' keyword prevents minor mode proliferation by hiding active minor modes from the mode line to preserve screen real estate.
- [42:35](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2555s) Preventing repetitive strain ('Emacs pinky') involves keeping hands on the home row via minibuffer bindings ('C-j'/'C-k') and remapping the operating system Caps Lock key to Control.
- [47:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2823s) Installing 'doom-modeline' transforms the default text-heavy mode line into a clean, modern status bar featuring file-specific vector icons via 'all-the-icons'.
- [53:31](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3211s) Magit streamlines version control by allowing users to spot whitespace defects, stage hunks, write commit messages, and push to remotes without leaving Emacs.
- [55:46](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3346s) Literate programming with Org mode allows entire system environments—including desktop utilities like Polybar and Dunst—to be defined within a single tangled 'Emacs.org' document.
## Detailed walkthrough
### [00:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3s) Welcome and the Philosophy of Building Emacs from Scratch
David Wilson opens the livestream by introducing a brand-new series dedicated to building a completely custom Emacs configuration from the ground up. Addressing viewers who might only know Emacs by reputation, he challenges the common assumption that it is merely a text editor. As David Wilson explains, “Well, some would call it a text editor, but I consider it more of a like complete productivity environment.” In his view, Emacs acts as a broad platform for virtually anything one might want to do on a computer—from writing code and managing operating system tasks to organizing one's entire daily life. Rather than relying on popular pre-packaged starter kits such as Spacemacs or Doom Emacs, David advocates for hand-crafting a configuration: “So, I think that it's really interesting to dive into how to configure Emacs from the ground up because you learn a lot more from doing it that way as opposed to using a prepackaged configuration system like Spacemacs or Doom Emacs, etc.”
Reflecting on his personal journey, David shares that he first started using Emacs intermittently around 2007. However, it was not until about a year and a half prior to the stream that he dove in deeply, customizing his configuration to take over his entire daily workflow. Today, he practically lives inside Emacs, running EXWM (the Emacs X Window Manager) to drive his desktop display and relying almost entirely on native Emacs packages for his tools. Because this is an interactive live stream, he invites chat participants to ask questions as they go. The plan for the series is to start strictly with the absolute basics, slowly layering on packages, tackling community requests, and gradually evolving the setup into a comprehensive, customized operating environment.
- **David Wilson's Emacs timeline:** Started dabbling around 2007; committed to building a comprehensive, full-time workflow roughly 1.5 years prior (around early 2019).
- **Core philosophy:** Constructing an Emacs setup from scratch yields far greater understanding than adopting pre-baked distributions like Spacemacs or Doom Emacs.
---
[02:23](https://www.youtube.com/watch?v=74zOY-vgkyw&t=143s) Tour of David's Personal Setup and Daily Workflow
Before stripping everything down to start anew, David provides a brief showcase of his personal day-to-day computing environment inside Emacs. Upon logging into his desktop, Emacs launches directly as his full-screen window manager via EXWM, handling both native Emacs buffers and standard X11 graphical applications. While acknowledging that macOS and Windows users cannot run EXWM, he emphasizes that the underlying concepts demonstrate what Emacs is truly capable of achieving. He opens Eshell, the built-in terminal emulator inside Emacs, and navigates his filesystem using Dired, which he has mapped to Vim-style navigational keybindings (`h`, `j`, `k`, `l`).
David then turns to Magit, the Git porcelain for Emacs, navigating through his dotfiles repository to showcase interactive commit staging, hunk manipulation, and history inspection. He considers Magit an unmatched selling point for the editor: “Magit is a super powerful package and I feel like if you've never seen it before, this may be one of the major things that turns you on to Emacs forever, at least even just for for this functionality alone because it's it's super powerful.” Switching between tasks, he highlights how he keeps web browser windows decoupled into individual X11 windows—treating each browser tab as an individual window managed directly via native Emacs buffer switching commands. Finally, he previews his literate configuration file written in Org mode (`Emacs.org`). Through Org mode's structuring, code blocks, and lazy-loading mechanisms, he manages an extensive, intricate configuration inside a single cleanly organized document. Answering a question from chatter James in the chat, David confirms that his underlying operating system is the GNU Guix Linux distribution.
```mermaid
flowchart TD
accTitle: David Wilson's EXWM Desktop Architecture
accDescr: Diagram illustrating how Emacs acts as the window manager orchestrating files, git, terminal, and external apps.
subgraph OS ["Operating System"]
GUIX["GNU Guix Linux"]
end
subgraph Core ["Emacs Desktop Environment"]
EXWM["EXWM (Emacs X Window Manager)"]
ORG["Literate Config (Emacs.org)"]
end
subgraph DailyTools ["Integrated Productivity Tools"]
MAGIT["Magit (Git Version Control)"]
DIRED["Dired (File Manager with Vim Keys)"]
ESHELL["Eshell (Built-in Terminal)"]
XAPPS["X11 Windows (Browsers as Buffers)"]
end
GUIX --> Core
Core --> DailyTools
```
- **Window Management:** Uses EXWM to manage both Emacs buffers and native X11 application windows directly within the Emacs frame.
- **File & Terminal Management:** Employs Eshell for terminal tasks and Dired with custom Vim keys (`hjkl`) for filesystem navigation.
- **Version Control:** Relies heavily on Magit for staging Git diffs, checking commit logs, and repository operations.
- **Literate Configuration:** Main config maintained entirely in Org mode (`Emacs.org`), using headers to segment settings and deferred loading hooks to speed up startup.
- **Operating System:** Running GNU Guix System.
---
[06:34](https://www.youtube.com/watch?v=74zOY-vgkyw&t=394s) Launching Vanilla Emacs and the "Out-of-the-Box" Shock
To begin crafting the clean configuration, David notes that he is running the newly released Emacs 27.1, which had recently landed in GNU Guix. Responding to a viewer named Pepsi, who mentioned installing Doom Emacs alongside EXWM, David notes that while he personally uses `doom-themes` and `doom-modeline`, he never adopted Doom Emacs as a distribution because he had already started building his bespoke setup prior to Doom gaining widespread popularity. To start fresh without loading his own configuration, David touches an empty `init.el` file and launches a nested Emacs instance from within his current session using the CLI flags `emacs -q -l init.el`—a setup he playfully dubs "Emacs-ception."
The vanilla Emacs session immediately appears on screen, presenting an unconfigured white window with microscopic text due to his high-DPI display. David highlights how jarring this initial default experience can be for newcomers who come to Emacs after seeing sleek, modern setups on r/emacs or YouTube:
> “Then you run Emacs for the first time and you see this screen where you've got this kind of toolbar and you've got the menu bar and you've got this welcome screen with the weird old looking Emacs logo, and the colors are kind of crappy and you're probably like, 'Well, I don't know about this. This doesn't really look like my kind of tool.'”
He reassures viewers that turning off the visual cruft is remarkably straightforward. The default experience includes a cluttered graphic icon toolbar, a top menu bar, scroll bars, and a blinding white splash screen. To make the interface tolerable and set up a minimal aesthetic reminiscent of Vim, the first order of business will be disabling these default UI widgets, setting up proper font scaling, and applying a proper dark theme inside `init.el`.
- **Emacs version used:** Emacs 27.1 running on GNU Guix.
- **Clean launch command:** Executing `emacs -q -l init.el` to bypass David's personal dotfiles and load only the targeted clean configuration file.
- **Default out-of-the-box UI elements targeted for removal:** The top menu bar, graphical icon toolbar, vertical scrollbars, and the default GNU splash screen.
[09:44](https://www.youtube.com/watch?v=74zOY-vgkyw&t=584s) Stripping the Default UI and Quieting the Editor
David begins crafting the clean configuration by looking up his own setup to find the settings that simplify the Emacs user interface. Joking that he has "lost the ability to type" this morning, he tracks down the relevant variables. The first goal is eliminating visual clutter, starting by suppressing the startup screen: “I mean it could be useful for some people but for me I prefer to just start from like a blank screen as much as possible.” He copies over snippets to disable unnecessary UI elements like the menu bar and the tool bar, and drops in the setting for `visible-bell`.
Explaining his preference for a visual alert, David notes that he dislikes having his editor beep at him whenever an error occurs—such as hitting backspace on an empty line. Instead, the screen flashes along the top and bottom borders. While he acknowledges that some users find the visual bell annoying—particularly on macOS, where it displays a large triangle across the screen—he feels it remains relatively unobtrusive on Linux. Opening an `eshell` window to launch a fresh Emacs instance using the edited configuration, he verifies the result in full screen: Emacs now drops straight into an empty `*scratch*` buffer, free of menus and toolbars. David highlights how quick this transformation is, pointing out that “it only takes about five six lines of code to get to the point where you have a very simple starting point.”
- Suppressed the default landing screen via startup inhibition settings.
- Disabled the menu bar (`menu-bar-mode`) and tool bar to establish a minimal presentation.
- Enabled `visible-bell` to replace audio beeps with a screen flash upon invalid commands or backspacing past boundaries.
- Confirmed the clean launch directly into the `*scratch*` buffer via an `eshell` subshell.
---
[12:09](https://www.youtube.com/watch?v=74zOY-vgkyw&t=729s) Adjusting Fonts and DPI for Emacs 27
With a clean screen established, David moves to fixing the text rendering so the session is legible. He explains that his font size configuration will appear abnormally large due to DPI scaling changes introduced in recent versions. When upgrading from Emacs 26.3 to Emacs 27.1, his previous font sizes stopped working properly, forcing him to at least double them. He attributes this shift to the adoption of the HarfBuzz text shaping engine, though he praises the upgrade: “now they're using HarfBuzz, which actually has improved the look of the text shapes a lot for me. So, I find that to be a very nice improvement despite the fact that I have to jack up my font size to a ridiculous level.”
Using Swiper—an interactive fuzzy-matching search tool bound to a key shortcut—David navigates his own configuration to locate his `set-face-attribute` calls. He extracts his font settings configured for Fira Code Retina with an eye-popping size value of `280`. Although his background `flycheck` linter briefly complains about the code in his Lisp buffer, he brushes past it. Anticipating chat feedback about constantly quitting and relaunching the editor from the terminal, he decides it is time to open the init file directly within the running instance and evaluate changes live. He also warns viewers that because he is accustomed to Evil mode (Vim emulation), he may occasionally type erratic stray keystrokes while forgetting that normal modal editing is not yet active.
```mermaid
flowchart LR
accTitle: Font and Engine Evolution
accDescr: Diagram showing the transition from Emacs 26 to Emacs 27 with HarfBuzz and required configuration changes.
subgraph Legacy["Emacs 26.3"]
A["Standard Text Engine"] --> B["Standard Font Size Values"]
end
subgraph Modern["Emacs 27.1+"]
C["HarfBuzz Engine"] --> D["Superior Text Shaping"]
C --> E["Higher DPI Scale Values<br>(e.g. Size 280 for Fira Code Retina)"]
end
```
- Selected font: Fira Code Retina.
- Configured via `set-face-attribute` with a height value of `280` to adjust for high-DPI scaling.
- Text rendering improvements credited to the switch to the HarfBuzz shaping engine in Emacs 27.1.
- Searching accomplished via Swiper for fast fuzzy line matching.
---
[14:48](https://www.youtube.com/watch?v=74zOY-vgkyw&t=888s) Introspection with Describe Functions and Applying Themes
To escape the bright default background, David looks for a built-in dark theme, eventually settling on `tango-dark` as a temporary fix. He uses this opportunity to introduce newcomers to Emacs's self-documenting architecture via the `describe` family of commands, typically bound under the `C-h` prefix. “If you've never used Emacs before, one thing that you really should learn about is the, um, help commands or describe commands actually,” David advises, emphasizing how critical `describe-variable`, `describe-function`, `describe-face`, and mode inspectors are for understanding the runtime system.
Responding to viewer comments in the chat, David agrees with James that sharing essential, opinionated package recommendations will be a primary focus of early episodes, as these represent the best exemplar of what Emacs can be. He also responds to Vincent's observation about ditching packages like `undo-tree`, affirming that knowing what to drop is just as important as knowing what to install.
David runs `describe-function` on `load-theme` to inspect its argument signature. When he initially tries to load the theme using a string argument, he encounters an `invalid theme name` error. He quickly catches his mistake, noting that Lisp expects a quoted symbol (such as `'tango-dark`) rather than a string:
```elisp
(load-theme 'tango-dark)
```
Chat member Abdullah helps confirm the syntax. David tries to evaluate the line using `C-x C-e`, but inadvertently hits key sequences tripped up by his Evil muscle memory. He runs `M-x eval-buffer` instead, which cleanly executes the file and applies the dark background. Viewer Dassinone reminds him that `C-x C-e` (`eval-last-sexp`) must be invoked with the cursor positioned immediately after the closing parenthesis of the s-expression.
Reflecting on the system, David notes that while Emacs provides a surprising abundance of built-in tooling that works completely offline without custom extensions, modern workflows thrive on the vibrant package ecosystem available through MELPA, which he prepares to introduce next.
[19:58](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1198s) Package Repositories: ELPA and MELPA
David Wilson explains that beyond Emacs's default tools, there is a vast ecosystem of community packages available to add powerful features. Emacs already includes a built-in package manager; running `M-x list-packages` generates a list of every available package. When David runs it, he notices packages already listed from his main personal setup. He clarifies that while Emacs points to the official GNU ELPA repository by default, the wider Emacs community relies heavily on MELPA (`melpa.org`), which hosts a vastly larger directory of extensions.
```mermaid
flowchart TD
accTitle: Emacs Package Architecture
accDescr: Visual flow showing how package repositories feed into package.el and use-package.
subgraph Repositories ["Package Sources"]
ELPA["GNU ELPA<br/>(Official default)"]
MELPA["MELPA<br/>(Community repository)"]
end
subgraph System ["Emacs Core"]
PKG["package.el<br/>(Built-in manager)"]
UP["use-package<br/>(Configuration macro)"]
end
ELPA --> PKG
MELPA --> PKG
PKG --> UP
```
Browsing `melpa.org`, David highlights how easily users can discover language-specific plugins, pointing to Clojure as an example. “So since Clojure is a Lisp, I think a lot of Clojure users are Emacs fans,” he observes, noting the high affinity Lisp developers have for Emacs. Because MELPA is the central hub for modern packages, configuring Emacs to pull from it is the immediate priority.
- `list-packages`: Built-in function displaying all installable packages.
- ELPA: The official GNU Emacs Lisp Package Archive configured out of the box.
- MELPA: Milkypostman’s Emacs Lisp Package Archive, the primary third-party repository with thousands of updated recipes.
---
[21:22](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1282s) Configuring Repositories and `use-package`
To streamline package management and configuration, David brings in boilerplate code from his personal configuration to bootstrap `use-package`. He removes MELPA Stable for now, preferring the main rolling MELPA archive. He starts by adding `(require 'package)` to ensure all package functions are loaded into the Emacs environment, though he notes it is often autoloaded. He inspects the `package-archives` association list, pointing out that hovering over it displays its docstring in the echo area/minibuffer: `package-archives is an alist archives from which to fetch`.
Next, the script calls `(package-initialize)` to activate the system. To handle clean installations on a brand-new machine, David uses conditional logic: `(unless package-archive-contents (package-refresh-contents))`. This verifies whether an archive cache exists locally; if not, it pulls down fresh lists so Emacs knows which packages exist. After updating archives, the setup checks whether `use-package` is present via `package-installed-p`. David explains a widespread Emacs Lisp naming convention: “Anytime you see a function in Emacs that ends in -p, that is like a predicate function or it's basically a function that returns true or nil I think.” If `(package-installed-p 'use-package)` evaluates to `nil`, Emacs runs `(package-install 'use-package)` and loads it with `(require 'use-package)`.
Finally, David checks the `use-package-always-ensure` variable using `C-h v` (`describe-variable`). The help buffer confirms its default value is `nil`. David explains why setting it to `t` is critical: “In use-package terms, ensure means that whenever you evaluate a use-package form, if ensure is set to true, then it will try to download the package whenever it evaluates that form, which you do want if you are loading up your config from scratch.”
[25:05](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1505s) Evaluating the Buffer and Inspecting `*Messages*`
With the package setup code in `init.el`, David uses `M-x eval-buffer` to evaluate the buffer directly into the running Emacs session. To inspect the downloading and compiling process, he switches to the `*Messages*` buffer.
David points out a handy tip for newcomers: “So, if you ever see a message pop up in the minibuffer at the very bottom of the screen and you're like, 'Oh, it went by too fast. I don't know what actually happened.' If you switch to the messages buffer, make sure to note that there's stars before and after. If you do that, you'll see the contents of all messages that were printed out before.” Looking through the log, he verifies that Emacs successfully contacted MELPA and ELPA, refreshed the package indices, and downloaded `use-package`.
---
[26:36](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1596s) Installing `command-log-mode`, an Accidental Suspension, and File Recovery
To help viewers follow along during the livestream, David installs `command-log-mode` by evaluating `(use-package command-log-mode)`. This package opens a side window showing every key pressed and the associated command triggered. Unsure of the exact interactive command to open the display window, David demonstrates inspecting a package: help windows opened via `describe-function` (`C-h f`) provide direct hyperlinks to the underlying source code (`.el` files), making it easy to skim implementation details and find functions. There, he spots `clm/toggle-command-log-buffer`.
When David runs `clm/toggle-command-log-buffer` and attempts to adjust the layout, he accidentally hits `C-z`: “Oh boy. Wow. Did I just close Emacs? Okay. Control-Z. Don't do that.” In terminal or windowed setups, `C-z` often suspends the Emacs frame. Unsure how to bring the suspended instance back on the spot, he restarts Emacs and reopens `~/.emacs.d/init.el`.
```mermaid
flowchart TD
accTitle: Emacs Crash and Recovery Cycle
accDescr: Sequence showing how an accidental suspension leads to recovering unsaved work from auto-save files.
A["Accidental suspend/exit ('C-z')"] --> B["Restart Emacs"]
B --> C["Open 'init.el'"]
C --> D["Notice Minibuffer prompt:<br/>'Consider running M-x recover-this-file'"]
D --> E["Run 'M-x recover-this-file'"]
E --> F["Confirm auto-save timestamp and restore work"]
```
Upon opening the file, all the recent `use-package` edits appear to be gone. However, the minibuffer prompts him: *Consider running M-x recover-this-file*. David explains that Emacs continuously autosaves work to background swap files. He runs `M-x recover-this-file`, reviews the timestamp comparison buffer, confirms with `yes`, and successfully restores his lost code. After immediately saving and running `eval-buffer`, he turns on `global-command-log-mode` followed by `clm/toggle-command-log-buffer`. To verify it works, he presses `C-h f`, which instantly prints both the keystroke and the bound command `describe-function` in the side pane, confirming the stream visualizer is fully active.
[30:10](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1810s) Completion Frameworks: Choosing Ivy Over Helm
Once the fundamental visual settings are in place, the next crucial addition to a minimal Emacs setup is a completion framework. The two primary powerhouses in this space are Helm and Ivy. Rather than doing an exhaustive deep-dive comparison, the host notes that both share many conceptual similarities but operate with slightly different design mentalities. Ivy is chosen for this configuration because of its minimalist aesthetic and how naturally it fits into daily workflows. However, the host makes it clear that he is open to exploring Helm in a future stream so viewers can contrast the two approaches directly.
Emacs does not force users into an all-or-nothing binary choice. The open ecosystem allows users to install both Ivy and Helm simultaneously, running whichever one is best suited for a specific context. As the host explains: “It's not like you have to pick one and stick with it. It's not like a Vim versus Emacs thing where they're completely incompatible. No, you can do everything all at the same time in Emacs, which is kind of great.”
Turning back to the editor, the host consults his existing personal configuration to grab the Ivy setup. He pastes the introductory Ivy configuration into his `init.el` and evaluates the buffer (`eval-buffer`), triggering the automatic installation via `use-package`. Messages flash in the minibuffer as the Ivy Elisp files compile and load. At first, pressing `C-x C-f` (`find-file`) still triggers the default, bare-bones Emacs completion at the bottom of the frame because global keybindings have not yet been wired up to override the defaults.
[33:04](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1984s) A Crucial Digression: Escaping with the Escape Key
Before sorting out the full Ivy keybindings, the host pauses to fix a muscle-memory annoyance that plagues anyone accustomed to Vim. In stock Emacs, dismissing an active minibuffer prompt or canceling a command typically requires typing `C-g`. Because the host constantly hits the `Escape` key out of habit, he decides to rebind it immediately to prevent frustration.
With this line evaluated, striking `Escape` cleanly cancels out of any active minibuffer prompt or command entry, matching standard modal editor expectations.
[33:51](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2031s) Setting Up Ivy, Council, and Global Completion
Returning to the completion setup, the host discusses the role of Council, which works alongside Ivy to provide enhanced interactive commands. While the core `ivy` package handles general completion functionality, packages like `council` provide specialized wrappers for standard Emacs functions, such as browsing files and switching buffers.
Demonstrating this interactively, running `council-find-file` replaces the plain prompt with a dynamic completion buffer showing the current directory contents. Users can navigate files (such as selecting `README.org`) with the arrow keys and hit Enter to jump right into them, dramatically speeding up file exploration.
A chat participant named Vincent chimes in with a helpful tip: there is no need to write elaborate manual keybindings for standard commands like finding files. Simply activating `ivy-mode` globally with an argument of `1` takes care of everything. Testing this out in real-time confirms Vincent's advice. Running `(ivy-mode 1)` automatically rebinds Emacs's default navigation and file-finding commands across the entire editor.
```mermaid
flowchart TD
accTitle: Ivy and Council Architecture in Emacs
accDescr: Shows how ivy-mode globally rebinds standard Emacs interactive commands to Ivy and Council interfaces.
subgraph UserAction["User Input"]
A["M-x (Alt+X)"]
B["C-x C-f (Find File)"]
C["C-x b (Switch Buffer)"]
end
subgraph IvyLayer["ivy-mode 1"]
D["Minibuffer Completion Engine"]
end
subgraph CouncilCommands["Council Enhanced Replacements"]
E["council-M-x"]
F["council-find-file"]
G["council-switch-buffer"]
end
A --> D --> E
B --> D --> F
C --> D --> G
```
The host also highlights the fundamental role of `M-x`:
- **Meta Key Binding**: In Emacs notation, `M-x` means pressing `Meta` along with `x`. On almost all standard modern keyboards, the `Meta` key maps directly to the `Alt` key (`Alt+x`).
- **Command Discovery**: Running `M-x` via Ivy brings up an interactive searchable list of every available Emacs command.
- **Fuzzy Substring Matching**: Searching does not require typing exact names. For instance, entering `council swift buff` matches `council-switch-buffer` across substrings separated by spaces, making it trivial to locate commands even when their precise names slip your mind.
[37:29](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2249s) Previewing Themes with Council and Setting Wombat
Ivy and Council also provide convenient discovery tools for aesthetics. Running `council-load-theme` opens a live-filtering list of all installed themes. Because the host's active instance is not fully sandboxed from his personal Emacs dotfiles directory, several Doom Emacs themes appear in the list alongside built-in themes.
Browsing the defaults, the host selects `wombat`, a built-in dark theme that he prefers over the previously configured `tango-dark`. To make the visual change persistent across restarts, he updates his `init.el` file:
```elisp
(load-theme 'wombat t)
```
Now, whenever Emacs launches, it boots directly into the Wombat color scheme.
[38:30](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2310s) Understanding the Mechanics of `use-package` and Autoloads
With the editor behaving smoothly, the host pulls up the `use-package` documentation to explain why it is such an essential tool for modern Emacs configurations. In traditional Emacs setups, manually downloading packages from Git repositories requires substantial boilerplate: calling `(require 'package-name)`, turning on modes, manually configuring keymaps, and managing evaluation hooks.
`use-package` abstracts that burden away into clean, declarative blocks. While other configuration helper packages exist, the host favors `use-package` for its proven reliability: “There are some other packages out there that will do things like this for you. I really haven't used them, but I might experiment with that some in this stream series because I don't know, it would be interesting to try them out. But use-package has been very solid for me for years. So, I just kind of stick with it.”
At its simplest, declaring `(use-package <package-name>)` will download and configure the package. Crucially, `use-package` does not eagerly load every package's full codebase at startup. Instead, it relies on Emacs Elisp autoloads. An autoload is a function definition decorated with a special signature telling Emacs not to evaluate or load the underlying package file into memory until the user actually calls that command, keeping startup times fast and lightweight.
[40:01](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2401s) Cleaning the Mode Line with `diminish`
When setting up packages via `use-package`, startup time is minimally affected because Emacs packages with autoloads configured will simply install on demand if missing and expose their commands. David Wilson points out that although the bare-minimum declaration is just `(use-package <name>)`, his configuration includes additional keywords such as `:diminish`.
In default Emacs, the bar running along the bottom of the screen—the mode line—displays crucial session state: current major mode (such as Lisp Interaction mode), file name, row and column position, and every single active minor mode (like Eldoc or Ivy mode). David demonstrates evaluating Ivy mode manually to make it appear in the mode line, while viewer Deepas notes that the command log buffer needed re-enabling via `CLM toggle command log buffer`.
As customizations accumulate, minor modes rapidly proliferate across the mode line, consuming valuable horizontal space and creating visual noise. David advocates for pruning this clutter:
> “So, what I like to do on certain packages is to diminish the mode, which does some stuff behind the scenes so that Emacs will not show the mode name in this list. Um, I don't really know like if people think that's a bad idea, but for me, I like to keep a very minimal view so that I don't have a lot of things distracting me whenever I'm using my editor or when I'm in my environment.”
Adding `:diminish` directly inside the `use-package` block silently strips Ivy’s indicator out of the mode line without disabling its functionality.
[42:35](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2555s) Key Bindings, Mini-Buffer Navigation, and Avoiding Emacs Pinky
The `:bind` directive in `use-package` provides a clean, declarative alternative to scattering low-level `define-key` calls throughout an init file. For example, mapping `C-s` directly to `swiper` inside the Ivy declaration immediately overrides the default search behavior. Beyond global bindings, `:bind` easily hooks into mode-specific maps like `ivy-minibuffer-map`.
David demonstrates remapping navigation inside the minibuffer list to `C-j` and `C-k` for next and previous items, mirroring typical modal editing workflows. This adjustment keeps hands planted firmly on the home row without reaching for arrow keys. He strongly emphasizes ergonomic keyboard habits:
> “If you use a computer a lot all day, if you're a programmer and you're typing on the computer all day, the best thing you can do for your hands to not get super tired is to stay in one place and not jump around a lot or not contort your fingers to do key bindings.”
To completely eliminate the strain known as "Emacs pinky," David remaps Caps Lock to act as a Control key across his operating systems, allowing the pinky to strike Control comfortably without angling the wrist.
```mermaid
flowchart TD
accTitle: Minibuffer Navigation and Remapping Flow
accDescr: Diagram illustrating how use-package binds Swiper to Control-S and maps Control-J and Control-K inside the Ivy minibuffer map.
subgraph Global["Global Scope"]
CS["'C-s' Keychord"] -->|"Triggers"| Swiper["Swiper Search"]
end
subgraph Minibuffer["Ivy Minibuffer Scope (ivy-minibuffer-map)"]
CJ["'C-j' Keychord"] -->|"Navigates"| Down["Next Candidate (Down)"]
CK["'C-k' Keychord"] -->|"Navigates"| Up["Previous Candidate (Up)"]
end
```
- Remapping Caps Lock to Control works natively across Linux, macOS, and Windows.
- Minimizing long reaches to the mouse or trackpad prevents repetitive strain over full workdays.
- An audience member named Alex notes during the stream that the bottom line of the Emacs frame appeared partially cut off in the video feed, which was resolved as a YouTube playback/scaling issue.
- David admits an involuntary muscle-memory habit from Vim: hitting `Escape` repeatedly to clear input, which accidentally dismisses the command log buffer.
[47:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2823s) Upgrading the Mode Line with `doom-modeline`
Viewer Deepas points out in chat that `global-command-log-mode` must be enabled for keystrokes within the minibuffer to display properly in the log buffer, which David immediately confirms after testing `C-j` and `C-k`. Moving to visual ergonomics, David addresses the dated, crowded appearance of the default Emacs mode line, describing it as text-heavy, archaic, and overly distracting.
> “I think the default mode line in Emacs is quite cluttered and um kind of like really just looks old. I mean, if it's all text, characters, and stuff and gives too much information.”
To achieve a modern, distraction-free environment, David turns to `doom-modeline`—the sleek status bar popularized by the Doom Emacs distribution. Fetching the standard minimal setup snippet from the official `doom-modeline` GitHub repository, he pastes the `use-package` declaration into the configuration and evaluates it on the fly using `C-x C-e`.
The mode line transforms instantly, rendering streamlined icons, clean fonts, and focused state indicators. While David prefers a slightly lower vertical height than the stock Doom modeline provides by default, he explains that tuning the customizable mode line height variable alongside the mode line font size allows users to dial in their preferred dimensions. He then begins introducing the `:config` keyword in `use-package` to handle these post-load customizations.
[50:09](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3009s) Configuring Doom Modeline Height and Buffer Icons
David attempts to adjust the vertical height of the newly installed Doom Modeline so it takes up less screen real estate. Checking his own personal configuration file (`Emacs.org`), he notes that he customizes the mode line height setting to 15 under a `:custom` declaration. When pasting the snippet into the experimental configuration, he accidentally introduces a mismatched paren, immediately triggering an unbalanced parenthesis error upon evaluation. “Also, we need something that will show us the parenthesis balance,” he remarks, noting how easy it is to break Elisp code with stray brackets. After briefly encountering a `Void function doom-modeline-height` error due to misplacing the setting under `:config` instead of `:custom`, he fixes the syntax and re-evaluates the block.
Applying visual changes to the mode line dynamically can be tricky. David notes that changes do not always render immediately in the active buffer without a package restart or a buffer switch. To force an update, he opens a `package.json` file in another buffer. While the height adjustment remains subtle, David points out a delightful visual feature enabled by `all-the-icons` and `doom-modeline`: Emacs now automatically displays a distinct Node.js / npm icon right in the mode line corresponding to the file type. Satisfied with the appearance, he decides to leave further fine-tuning for later.
- The target setting for Doom Modeline's height in `use-package` is `:custom (doom-modeline-height 15)`.
- Opening file types with recognized extensions automatically pulls appropriate vector icons into the mode line (e.g., npm/Node.js icons for `package.json`).
---
[52:12](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3132s) Reflections on Writing Custom Config and Planning Future Streams
Stepping back to survey what has been achieved over the course of the inaugural stream, David expresses hope that the walkthrough demystifies Emacs configuration for newcomers. While the resulting `init.el` file is still somewhat unorganized and messy, it provides a functional, attractive foundation using modern package management in remarkably few lines of code. He reassures viewers that future streams will systematically refactor, clean up, and expand the configuration.
Looking ahead to future sessions, David plans to tackle major workflow tools, specifically highlighting Magit and project management packages. He invites the live audience to leave feedback and suggestions, urging viewers to post them as YouTube comments on the recorded video rather than in the live chat window so the recommendations are preserved after the stream concludes.
> “So I hope that with this little intro I have convinced you that writing your own Emacs configuration is not that hard and it doesn't take much code and you can get something that looks really nice very quickly.” — David Wilson
- The live stream chat disappears once broadcast ends, making YouTube video comments and GitHub issues the preferred venues for package requests.
- Future streams will focus on package installation, code organization, and essential development tools like Magit.
---
[53:31](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3211s) Bonus Demo: Staging and Committing with Magit to "runemacs"
As a bonus demonstration before signing off, David exits the test Emacs instance and switches into his daily-driver Emacs environment to commit the newly created configuration to Git using Magit. Invoking `magit-status` via his custom keybinding, he brings up Magit's status buffer. He briefly tries to activate a command log window to show his keypresses, but chuckles when noticing that specific helper is not configured on this particular workstation. Magit displays the untracked and modified files, highlighting an errant trailing whitespace at the end of a line in `init.el`, which David quickly cleans up before staging the file.
```mermaid
flowchart LR
accTitle: Magit Commit and Push Workflow
accDescr: Diagram illustrating the steps David uses inside Emacs with Magit to stage, clean, commit, and push changes to GitHub.
subgraph S1["Magit Status Buffer"]
A["Inspect Untracked Files"] --> B["Detect and Strip Trailing Whitespace"]
B --> C["Stage 'init.el' (s)"]
end
subgraph S2["Commit and Remote Sync"]
C --> D["Open Commit Buffer (c c)"]
D --> E["Message: 'initial commit of init.el' (C-c C-c)"]
E --> F["Push to Remote (P p via SSH)"]
end
```
David presses `c c` to initiate a commit, writes the commit message “initial commit of init.el”, and finishes the commit with `C-c C-c`. He then uses `P p` to push the commit upstream to GitHub via SSH. Switching over to the browser, he navigates to the public repository, which is named `runemacs`. He shares the humorous backstory behind the repository name: Windows distributions of Emacs provide an executable called `runemacs.exe`, which his coworker Chris once mistook for a mystical package. “A coworker of mine whenever he downloaded Emacs—hi, Chris—he saw runemacs and he says, 'Wow, this comes with Rune-Emacs!'” David recounts. In Chris's honor, the repository houses this stream series' code, providing a repository where viewers can clone the files, follow along, or log GitHub issues with questions and package requests.
- Magit provides integrated visual diffs that highlight syntax issues such as trailing whitespace before staging.
- The repository hosting the stream's configuration is located on GitHub under `runemacs`.
---
[55:46](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3346s) Literate Org Mode Dotfiles, Projectile Suggestion, and Sign-Off
Seeing high viewer numbers for the stream gives David confidence that Emacs content resonates strongly with the community. For viewers curious about advanced setups where Emacs functions as a complete desktop environment and window manager, he showcases his personal `dotfiles` repository (`github.com/daviwil/dotfiles`). He explains how he practices literate programming using Org mode: all configuration logic is written inside an `Emacs.org` master document and then automatically tangled out to the appropriate system configuration files upon saving.
```mermaid
flowchart TD
accTitle: Literate Configuration Workflow via Org Mode
accDescr: Flowchart showing how David uses Emacs.org as the single source of truth to tangle system configurations.
A["Emacs.org (Source of Truth)"] -->|"Org Babel / Tangle"| B["Emacs Config (~/.emacs.d)"]
A -->|"Org Babel / Tangle"| C["Desktop Config (Polybar, Dunst)"]
A -->|"Org Babel / Tangle"| D["Linux Distribution Settings"]
```
> “So this this file is like my source of truth whenever I am changing my system configuration and then the sort of files that get created by that are sort of ancillary and I still check them in but they aren't really the ones that I edited.” — David Wilson
David browses his desktop configuration section to illustrate how `Emacs.org` configures not only internal Emacs packages (including EXWM), but also external desktop utilities like Polybar and Dunst. Checking the live stream chat, David responds to viewer Bruno, who suggests covering Projectile. David enthusiastically agrees: “If you do coding with git repositories of various different types of languages and whatnot, you definitely want to use Projectile.” David wraps up the nearly hour-long stream, letting viewers know the next stream will likely occur on Monday or Wednesday, and signs off by reminding viewers to subscribe, ring the notification bell, and keep hacking.
- David's literate dotfiles configure his entire desktop environment, including Polybar, Dunst, and Linux distributions via Org mode.
- Projectile is queued as a priority package for upcoming streams to handle multi-project Git workflows.
## Notable quotes
> [03:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=183s) I think that it's really interesting to dive into how to configure Emacs from the ground up because you learn a lot more from doing it that way as opposed to using a prepackaged configuration system like Spacemacs or Doom Emacs, etc. — David Wilson
> [02:23](https://www.youtube.com/watch?v=74zOY-vgkyw&t=143s) Magit is a super powerful package and I feel like if you've never seen it before, this may be one of the major things that turns you on to Emacs forever — David Wilson
## Video description
In this stream, we'll start creating a completely custom Emacs configuration from scratch! We'll also learn some Emacs basics along the way.
Check out the configuration from this stream here: https://github.com/daviwil/runemacs/tree/3075158cae210060888001c0d76a58a4178f6a00
My Emacs configuration: https://github.com/daviwil/dotfiles/blob/master/Emacs.org
If you enjoy this series, please consider becoming a GitHub Sponsor: https://github.com/sponsors/daviwil
Follow me on Twitter for more Emacs content!
https://twitter.com/SystemCrafters
Chat with the System Crafters community on Discord: https://discord.gg/yVD8Gx6
David Wilson of System Crafters argues that hand-crafting an Emacs setup provides a far deeper understanding of the platform than adopting pre-packaged starter kits like Spacemacs or Doom Emacs. Using Emacs 27.1 on GNU Guix, he demonstrates how a minimal, modern productivity environment can be established in only a few lines of code by stripping legacy defaults and integrating foundational community packages.
The Philosophy of the Ground-Up Setup (0:03)
Rather than treating Emacs as a traditional text editor, Wilson approaches it as a comprehensive computing environment capable of running desktop window management via EXWM, file browsing in Dired, and Git porcelain workflows through Magit. Having explored Emacs intermittently since 2007 before fully integrating it into his daily workflow around 2019, he contends that configuring Emacs from scratch teaches users how its underlying architecture operates. While distributions like Doom Emacs and Spacemacs offer turnkey solutions, building an initial configuration manually prevents reliance on uninspected defaults and simplifies long-term maintenance.
Eliminating Visual Cruft and Modernizing Typography (6:34)
The default 'out-of-the-box' Emacs interface presents a stark white frame, a graphical icon toolbar, a top menu bar, scrollbars, and an audio bell that can feel archaic to modern users. Wilson eliminates these elements in five to six lines of code by disabling menu and tool bars, inhibiting the startup screen to launch directly into an empty scratch buffer, and enabling visible-bell to substitute audio alerts with unobtrusive border flashes.
To address text rendering on high-DPI displays, Wilson notes that Emacs 27.1 introduced the HarfBuzz shaping engine, improving font aesthetics while altering DPI scaling. He configures Fira Code Retina via set-face-attribute using an enlarged height value of 280 to compensate for these engine adjustments, pairing it with dark palettes such as tango-dark and wombat to replace the harsh default white backdrop.
Streamlining Packages with MELPA and Use-Package (19:58)
Modern Emacs workflows depend heavily on third-party libraries distributed through MELPA rather than solely relying on the official GNU ELPA. Wilson bootstraps the built-in package.el archive list, ensures archives are refreshed on initial runs, and installs use-package to replace manual require boilerplate with structured declarative blocks. Setting use-package-always-ensure to true guarantees that declared extensions download automatically across fresh machines without eager startup penalties, taking advantage of Emacs Lisp autoloads that delay full code evaluation until commands are called.
During this setup, Wilson highlights core runtime diagnostics, including inspecting the *Messages* buffer to track background package compilation and using describe commands (C-h f and C-h v) to examine variables and linked source definitions. When an accidental frame suspension occurred via C-z, he demonstrated Emacs's built-in file recovery, running recover-this-file against auto-save files to restore unwritten configuration code.
Interactive Completion and Ergonomic Navigation (30:10)
To replace stock command prompts, Wilson integrates the minimalist Ivy completion framework alongside Council. Activating ivy-mode globally with (ivy-mode 1) automatically wraps default commands like find-file and switch-buffer with dynamic minibuffer filtering and fuzzy substring matching. He also rebinds the Escape key globally to keyboard-escape-quit to match standard modal editor habits.
For keyboard ergonomics, Wilson maps Swiper search to C-s and binds minibuffer navigation to C-j and C-k within ivy-minibuffer-map, keeping hands anchored to the home row without reaching for arrow keys. To mitigate repetitive strain known as 'Emacs pinky,' he advocates system-level remapping of the Caps Lock key to Control. He concludes the interface baseline by adding doom-modeline and diminish, stripping redundant minor mode listings while rendering vector file-type icons.
Wilson pushed the inaugural configuration to a public GitHub repository named runemacs using Magit, noting that while the initial setup was rapidly assembled during a live stream, it forms a functional base. He plans to use subsequent sessions to systematically refactor the init file into a literate Org mode document and layer on project management utilities like Projectile.
## Background
本期视频由 YouTube 频道 System Crafters(主播 David Wilson)于 2020 年 9 月 12 日发布。视频为《Emacs From Scratch》系列直播的第一期,旨在带领观众从完全空白的配置开始,一步步搭建一套现代化且高可用性的纯自定义 Emacs 环境,并在实操中普及 Emacs 基础交互与配置哲学。
## TL;DR
David Wilson 首先展示了自己基于 GNU Guix 与 EXWM 的全套日常生产力工作流,随后通过 `emacs -Q` 打开一个空白的 `init.el` 展开从零实操。他逐一去除了原生 Emacs 的启动屏、菜单栏与提示音视觉噪音,并针对高分辨率屏幕配置了 HarfBuzz 字体与深色主题。接着,他系统引入了社区包管理器 MELPA 与宏工具 `use-package`,搭建起包含 Ivy、Council 及 Swiper 的现代交互补全体系。在为底部 Mode Line 引入 Diminish 净化与 `doom-modeline` 美化后,David 现场演示了通过 Magit 提交成果,并展示了以 Org-mode 文学编程统管整个 Linux 桌面配置的终极形态。
## Atmosphere & style
整场直播洋溢着黑客文化独有的探索精神与极客手艺人式的轻松惬意,氛围真实、透明且互动感极强。David 毫无技术主播的架子,面对因 Vim 肌肉记忆误按 Escape 关掉窗口、触发系统快捷键挂起进程或括号不匹配报错等尴尬插曲时,都能幽默自嘲并现场排错,让高难度的配置过程显得亲切可触。观众在弹幕中频繁提供建议并与主播切磋技巧,整个过程从最初面对原生界面的粗糙劝退感,平稳过渡到亲手调校出高颜值生产力环境后的满满成就感。
## Bulletin
- [00:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3s) 主播 David Wilson 开启全新直播系列,倡导从底层手写 Emacs 配置而非直接使用 Spacemacs 或 Doom Emacs 等预打包发行版,以建立更深入的系统认知与专属工作流。
- [06:32](https://www.youtube.com/watch?v=74zOY-vgkyw&t=392s) 原生 Emacs 27.1 开箱的图形菜单与高对比度界面往往劝退新手,但通过数行 Elisp 代码清理启动页、关闭工具栏与启用深色主题,即可迅速打造现代极简界面。
- [19:58](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1198s) 配置 MELPA 镜像源并搭配 use-package 工具链(配合 use-package-always-ensure),能实现 Emacs 扩展包的按需声明式自动下载与 Autoloads 延迟加载。
- [30:10](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1810s) 引入 Ivy 与 Counsel 补全生态并结合 doom-modeline 状态栏定制,能够在保留高效键盘驱动交互的同时彻底改善编辑器的视觉与导航体验。
## Key takeaways
- [00:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3s) 从零编写 Emacs 配置虽然初期有学习门槛,但相比预打包发行版能让用户真正理解底层运作机制,进而将 Emacs 塑造成涵盖桌面与系统管理的完整生产力平台。
- [02:23](https://www.youtube.com/watch?v=74zOY-vgkyw&t=143s) 在 GNU Guix 结合 EXWM 的架构下,Emacs 可以接管全屏 X11 窗口调度,与 Eshell、Dired 及 Magit 协同构成高度一致的一体化工作环境。
- [09:44](https://www.youtube.com/watch?v=74zOY-vgkyw&t=584s) 通过关闭启动信息、隐藏菜单栏与工具栏,并启用 visual-bell 替代系统蜂鸣,仅需极少量配置代码就能消除原生界面的视觉噪音。
- [12:09](https://www.youtube.com/watch?v=74zOY-vgkyw&t=729s) Emacs 27.1 默认采用 HarfBuzz 文字渲染引擎,大幅提升了字形精细度,但在 High-DPI 屏幕下可能需要大幅调高字体尺寸参数以获得合适显示比例。
- [14:13](https://www.youtube.com/watch?v=74zOY-vgkyw&t=853s) Emacs 内置的 C-h 帮助系统(如 describe-function 与 describe-variable)是日常配置与排障的核心工具,可直接查阅函数说明及 Elisp 源码实现。
- [19:58](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1198s) 引入第三方扩展中心 MELPA 并结合 use-package 宏,可将包下载、依赖管理、模式启动与快捷键绑定统一收拢,避免大量原生 Elisp 模板代码。
- [23:45](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1425s) 将 use-package-always-ensure 设为 t,可确保新环境启动时自动下载配置中声明的所有缺失扩展包。
- [26:39](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1599s) Emacs 拥有完善的后台自动保存机制(#filename#),遇到意外关闭或按 C-z 挂起丢失窗口时,可通过 recover-this-file 命令完整挽救未保存的改动。
- [30:10](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1810s) 补全框架在 Emacs 生态中可自由替换并存,Ivy 配合 Counsel 能够以轻量设计为查找文件、切换缓冲区及 M-x 交互提供强大的空格模糊匹配支持。
- [42:35](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2555s) 为缓解长期输入 Control 组合键导致的“Emacs Pinky”手部劳损,在操作系统底层将 Caps Lock 重映射为 Control 是一项被广泛推荐的人体工学改进方案。
- [40:01](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2401s) 利用 use-package 的 :diminish 属性可隐藏 Mode Line 上冗余的 Minor Mode 标识符,维持状态栏紧凑专注。
- [47:05](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2825s) 采用 doom-modeline 可替换陈旧的纯文本状态栏,通过配合图标库与微调高度参数,为 Emacs 带来现代化的信息呈现。
- [53:17](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3197s) Git 交互神器 Magit 通过 magit-status 界面将暂存、多余空格清理、提交与远程推送等操作简化为极具表现力的键盘快捷流。
- [55:48](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3348s) 借助 Org-mode 的文学编程(Literate Programming)与 Tangle 机制,用户可以将整个操作系统的 dotfiles 统一维护在单一文档中作为唯一的系统配置真实来源。
## Detailed walkthrough
### [00:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3s) 从零构建 Emacs 配置的缘起与理念
主播 David Wilson 正式开启了全新的直播系列,带领观众开启一段在直播中“从零构建一套完全自定义的 Emacs 配置”的冒险之旅。对于许多初学者来说,Emacs 常被视作单纯的文本编辑器,但 David 将其定位为一套“完整的生产力环境”。在他看来,基础的文本编辑只是 Emacs 的一项能力,其核心价值在于提供了一个强大的平台,只要在电脑上处理事务——无论是编写代码、规划个人生活还是进行全方位的系统管理——它几乎无所不能。
针对为何不直接选用开箱即用的发行版,David 旗帜鲜明地阐明了从底层亲手配置的原因:“从零开始探索如何配置 Emacs 是一件非常有趣的事情,因为相比于使用像 Spacemacs 或 Doom Emacs 这种现成的预打包配置系统,以这种方式能学到的东西要多得多。”(“So, I think that it's really interesting to dive into how to configure Emacs from the ground up because you learn a lot more from doing it that way as opposed to using a prepackaged configuration system like Spacemacs or Doom Emacs, etc.”)
回顾自己的折腾史,David 透露自己从 2007 年左右便开始断断续续接触 Emacs,但真正全身心沉浸其中是在一年半前。当时他开始深度定制自己的环境,打造专属的整套工作流,如今他几乎整天都“生活”在 Emacs 当中:
- 桌面环境完全交由基于 Emacs 的 EXWM(Emacs X Window Manager)进行窗口管理。
- 绝大多数日常任务均由 Emacs 插件处理,仅在工作必需等少数无法替代的场景下才切换到外部程序。
- 整个系列将从基础一步一个脚印推进,未来会根据观众互动和弹幕提问尝试引入不同的插件,逐步演化成全功能工作流。
---
### [02:23](https://www.youtube.com/watch?v=74zOY-vgkyw&t=143s) David 的日常工作流展示:EXWM、Magit 与 Org-mode
为了给观众直观展现 Emacs 到底能走多远,David 在着手编写新配置之前快速漫游了自己的日常桌面系统。从桌面登录的一瞬间起,系统便自动启动 Emacs 并由 EXWM 接管全屏显示与全部 X Windows 程序的调度(虽然 Windows 和 macOS 用户无法运行 EXWM,但这展示了 Emacs 的架构潜力)。
在实际操作中,David 展现了几个核心组件的高效协同:
- **Eshell 终端**:内置的高性能终端模拟器,日常项目的跳转与指令执行均在此完成。
- **Dired 文件管理**:利用定制的快捷键配合类似 Vim 的 `hjkl` 方向键,在系统目录结构中极速穿梭。
- **Magit**:强大的 Git 交互界面。David 在展示自己的 `files` 仓库时,调用出 Magit 的提交历史与代码块暂存(staging chunks)界面。他感叹道:“Magit 是一个极其强大的插件,我觉得如果你以前从没见过它,这可能就是让你彻底爱上 Emacs 的最关键功能之一,哪怕仅仅为了这一个功能也完全值得。”(“Magit is a super powerful package and I feel like if you've never seen it before, this may be one of the major things that turns you on to Emacs forever, at least even just for for this functionality alone because it's super powerful.”)
- **多工作区与独立浏览器窗口**:在另一个工作区中运行着外部 X Window 窗口,他的浏览器每一个所谓的“标签页”其实都是独立的浏览器窗口,可以直接借用 Emacs 的 Buffer 切换指令自由穿梭。
- **文学编程配置(Literate Configuration)**:他的个人配置并非杂乱的 Elisp 脚本,而是依托 Org-mode 建立的。Org-mode 不仅是笔记与大纲工具,更是一个支持即时代码块求值的标记语言。借助清晰的各级标题,虽然所有配置集中在一个大文档里,却极易检索与折叠;许多配置块配置了延迟加载,只有在对应插件指令被触发或相关模式激活时才会执行。
弹幕中观众 James X 询问当前使用的是否为 Linux,David 证实这是 Linux 的一个发行版——GNU Guix,并表示 Guix 深度融入了他的日常工作流,后续会专门开辟一期展开讲解。
```mermaid
flowchart TD
accTitle: David Wilson 的日常 Emacs 桌面环境架构
accDescr: 展示以 GNU Guix 为底层,EXWM 为窗口管理中心,贯穿 Eshell、Dired、Magit 以及 Org-mode 文学编程的架构流。
subgraph OS["底座系统"]
GUIX["GNU Guix Linux 发行版"]
end
subgraph Core["核心窗口与平台"]
EXWM["EXWM 窗口管理器<br/>(全面接管屏幕与 X11 程序)"]
end
subgraph Tools["Emacs 核心生产力工作流"]
ESH["Eshell<br/>(内置终端模拟器)"]
DIR["Dired<br/>(Vim 键位 hjkl 目录导航)"]
MAG["Magit<br/>(分支历史、代码块暂存)"]
ORG["Org-mode 文学化配置<br/>(按需延迟求值代码块)"]
end
GUIX --> EXWM
EXWM --> ESH
EXWM --> DIR
EXWM --> MAG
EXWM --> ORG
```
---
### [06:32](https://www.youtube.com/watch?v=74zOY-vgkyw&t=392s) 初遇原生 Emacs 的“开箱劝退”与极简改造开端
告别演示环境后,正式的配置实操拉开序幕。本次直播统一采用当时新发布的 Emacs 27.1 版本。弹幕中有观众 Pepsi 提到自己刚装好了 Doom Emacs 与 EXWM,David 评价这确实是个不错的组合;但他自己更偏向在 Doom Emacs 风靡前就手写配置,仅借鉴了其中的 `doom-modeline` 和 `doom-themes`,早年则用过一段时间 Spacemacs。
为了在一个完全空白的环境下演示,David 在现有的 Emacs 内部运行新的 Emacs 实例(戏称为“Emacs 盗梦空间” emacception)。通过终端执行 `touch init.el` 创建空文件,并使用 `emacs -Q -l init.el` 命令完全屏蔽系统与用户的默认启动配置,加载空白文件启动。
随着一个未经任何雕琢的原生(Vanilla)Emacs 窗口弹出,展现在屏幕上的是许多新手非常熟悉的“劝退画面”:
- 刺眼的大白底色,且在高分辨率屏(High-DPI)下未设置字号,文本小得难以阅读。
- 顶部带有厚重的复古图形工具栏(Toolbar)、菜单栏(Menubar)。
- 居中展示着一张带有老式 Emacs 图标的欢迎屏幕。
David 生动描摹了新手常见的心理落差:大家常在 Reddit 的 r/emacs 或技术视频里看到别人行云流水、界面极其极简酷炫的 Emacs,满怀期待地下载安装,结果一打开看到这套老旧的配色和菜单栏,立刻产生“这根本不是我的菜”的退意。然而,消除这些多余视觉噪音在 Emacs 中其实轻而易举。由于屏幕底色白得让人有些眩目,David 迅速关掉这个原生窗口,在配置缓冲区中进行分屏操作,准备在全新的 `init.el` 中写入基础界面的清理逻辑和主题设定,快速将其调校为符合现代文本编辑器直觉的极简形态。
### [09:44](https://www.youtube.com/watch?v=74zOY-vgkyw&t=584s) 精简界面:关闭启动页、菜单栏与启用可视铃声
主播打开了自己的 Emacs 个人配置,打算从中找出精简界面的相关设置。早上一边打字一边自嘲道:“显然今天早上我已经丧失打字能力了”,随后他找到了相关的设置项。主播计划做的第一件事就是关闭启动问候画面(startup message,即 Emacs 的启动初始欢迎页)。他解释说,尽管对某些新手来说这个欢迎页可能有用,“但对我而言,我更倾向于尽可能从一个空白屏幕开始。”
接着,主播着手移除 Emacs 默认的多余界面元素。他关闭了菜单栏(`menu-bar-mode`),并顺手加入了可视铃声(`visual-bell`)。主播提到自己非常受不了编辑器整天对着人“哔哔”叫,比如在行首误按退格键(Backspace)时发出的蜂鸣;打开可视铃声后,编辑器在报错或触发警告时只会在屏幕顶端和底端闪烁一下。主播在屏幕上按退格键现场演示了这一闪烁效果,并笑着补充道,有些人可能觉得这闪烁也挺烦人,而且在 macOS 上体验尤其差,因为它会直接在眼前弹出一个巨大的三角警示图标,不过在 Linux 下并不怎么突兀,完全可以接受。
随后,主播分屏切回 eshell,重新带上刚刚配置好的 `init.el` 启动 Emacs,并将窗口全屏展示。此时的 Emacs 直接进入了空白的 `*scratch*` 缓冲区,没有菜单栏,也没有工具栏,界面显得极为干净极简。主播感叹道,其实只要五六行代码,就能得到一个非常清爽的初始操作环境。
- 关闭启动欢迎页(Inhibit startup message),默认直接呈现极简环境
- 禁用菜单栏与工具栏,消除多余的 UI 视觉干扰
- 启用 `visual-bell` 替代系统默认蜂鸣声,在 Linux 上仅表现为窗口边缘轻微闪烁
---
### [12:09](https://www.youtube.com/watch?v=74zOY-vgkyw&t=729s) 字体配置与 HarfBuzz 引擎引起的大小差异
接下来,主播准备调大字体,否则在当前的高分辨率屏幕上默认大小根本没法看。他在自己的配置里使用 Swiper(一个支持模糊匹配当前文件所有文本行的检索包)快速查找 `set-face-attribute` 设置。主播解释说,他配置里的字体数值看起来会异常巨大,这是为了补偿高 DPI 缩放。当他从 Emacs 26.3 升级到 27.1 时,以往使用的字体大小全都失效了,必须翻倍甚至调得更大才能看清。据主播推测,这是因为 Emacs 27.1 更换了底层的文字渲染引擎,转而采用了 HarfBuzz。“尽管我不得不把字体大小调到一个荒谬的数值,但我发现这真是一个极好的改进,因为它极大地改善了我这边的字体字形外观。”
主播最终选用了 Fira Code Retina 字体,并将字号设置为看似非常夸张的 280。在将配置复制到新的 init 文件时,后端的 Flycheck 语法检查插件一直在弹提示,主播随手将其忽略。此时主播意识到观众肯定会问:为什么不在当前的 Emacs 实例里直接求值生效,而要一直重新启动 Emacs?他笑着承认了这点,并表示接下来就会直接在 Emacs 里进行动态求值。
```mermaid
flowchart TD
accTitle: Emacs 字体与渲染引擎演进流程
accDescr: 展示从 Emacs 26 到 27 切换至 HarfBuzz 引擎后字形与尺寸配置的变化
subgraph VersionDiff["版本渲染差异"]
V26["Emacs 26.3 渲染引擎<br/>(常规字号配置)"]
V27["Emacs 27.1 HarfBuzz 引擎<br/>(字形表现更优,需 DPI 补偿)"]
end
subgraph Config["当前字体配置"]
FontName["字体名称: Fira Code Retina"]
FontSize["字号参数: 280 (适应高分辨率)"]
FaceAttr["调用 set-face-attribute 生效"]
end
V26 -->|版本升级| V27
V27 --> FaceAttr
FontName --> FaceAttr
FontSize --> FaceAttr
```
- 采用 Swiper 工具进行行内模糊检索定位配置
- Emacs 27.1 默认采用 HarfBuzz 文字渲染引擎,提升了字符渲染精细度
- 为适配高 DPI 显示,将 Fira Code Retina 的尺寸属性设为 280
---
### [14:13](https://www.youtube.com/watch?v=74zOY-vgkyw&t=853s) 缓冲区求值、内置帮助系统与加载深色主题
主播直接在当前的 Emacs 窗口中打开了正在编辑的 `init.el` 配置文件,准备在原地修改并实时求值(eval)。因为主播习惯了使用 Evil 模式(Emacs 上的 Vim 模拟层),在原生键位下编辑时经常因为下意识切换模式或按 Escape 键而输入奇怪的字符,他向观众打预防针,如果看到奇怪的击键请直接忽略。为了避免在刺眼的纯白背景下工作太久,主播决定先临时加载一个 Emacs 自带的深色主题 `tango-dark`。
直播间观众 James 提问,希望在视频尾声了解主播心目中新配置必不可少的核心插件。主播回应称自己确实对此有鲜明的个人观点,接下来的几期直播就会逐步引入这些顶尖扩展,因为“它们某种程度上代表了 Emacs 所能达到的最高水准”。另一位观众 Vincent 则在聊天室提到,其实也可以讲讲哪些插件是可以舍弃的,比如自己几年前就不再使用 `undo-tree`,而且完全不觉得缺了什么;主播赞同地表示,不同阶段该做减法的内容确实一直在变,后面也会对此展开探讨。
在编写加载主题的代码时,主播向新手观众着重推荐了 Emacs 内置的强大自省与求助系统(即以 `C-h` 开头的一系列 `describe-*` 命令,如 `describe-variable`、`describe-function`、`describe-face` 等)。主播通过 `describe-function` 查看了 `load-theme` 的文档说明。当主播在配置文件中直接写下字符串形式的 `"tango-dark"` 并执行求值时,控制台报错提示主题名称无效。聊天室的 Abdullah 及时提示了正确的语法,主播恍然大悟:在 Lisp 语言体系中,这里需要传入一个符号(Symbol)而非字符串(String),即在名称前加一个单引号 `'tango-dark`。随后主播在观众 Dassun91 的提示下确认,光标放在 S 表达式末尾按 `C-x C-e` 即可局部执行,不过他这次直接调用 `M-x eval-buffer` 执行了整个缓冲区。屏幕随即切换成了深色背景,极简的 UI 框架与深色显示正式生效。主播总结道,虽然 Emacs 拥有庞大的开箱即用内置功能,在没有网络连接时非常实用,但社区在 MELPA 上维护的现代包生态系统要活跃生动得多,后续将转向社区扩展的配置。
- 善用帮助命令体系:以 `C-h` 为前缀的帮助系统(如 `C-h f` 查看函数)是掌握 Emacs 的核心工具
- Lisp 语法注意点:`load-theme` 接收的是 `'tango-dark` 符号(Symbol),而非双引号包裹的普通字符串
- 配置求值方法:既可以在 S 表达式末尾按 `C-x C-e` 求值单行表达式,也可以通过 `M-x eval-buffer` 执行整个文件的配置变更
### [19:58](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1198s) 引入包管理器与配置 MELPA 软件源
为了利用开源社区中大量提供优质特性的扩展包,必须为 Emacs 配置扩展包管理机制。Emacs 自带了包管理系统(通过运行 `list-packages` 即可查看所有可用包的列表),其默认仓库是 GNU ELPA。但社区中还有一个规模更大、资源更丰富的镜像源——MELPA(melpa.org)。David 现场打开浏览器展示了 MELPA 网站,指出如果你使用某种特定语言(例如 Clojure),就能在上面找到海量的相关扩展包;他笑着解释道:“因为 Lisp 用户与 Emacs 之间存在天然的亲和力,而 Clojure 本身就是一种 Lisp,所以我认为很多 Clojure 用户都是 Emacs 的忠实粉丝。”为了能够方便地声明和管理这些外部扩展,必须引入社区中广受欢迎的宏工具 `use-package`。
```mermaid
flowchart TD
accTitle: Emacs 包管理器初始化流程
accDescr: 展示 Emacs 启动时如何配置源、刷新索引并自动安装 use-package 的逻辑图
subgraph S1["1. 软件源与包系统就绪"]
A["加载 package 库<br/>(require 'package)"] --> B["设置 package-archives<br/>(添加 MELPA 源)"]
B --> C["初始化包系统<br/>(package-initialize)"]
end
subgraph S2["2. 缓存检查与安装"]
C --> D{"本地是否有缓存<br/>package-archive-contents?"}
D -- "否 (首次启动)" --> E["调用 package-refresh-contents<br/>拉取远程索引"]
D -- "是" --> F{"是否已安装 use-package<br/>(package-installed-p)?"}
E --> F
F -- "否" --> G["执行 package-install 安装"]
F -- "是" --> H["加载 (require 'use-package)"]
G --> H
end
```
随后,David 从自己现成的个人配置中复制了包初始化的标准模版代码,并逐行拆解其内部机制:
- 首先调用 `(require 'package)`,把内置的包管理函数引入运行环境。
- 配置变量 `package-archives`。将光标移动到该变量上时,底部的 Minibuffer 会自动提示它是一个关联列表(alist),用于存储拉取扩展的仓库地址;此处移除了 MELPA Stable,仅保留主分支 MELPA。
- 执行 `(package-initialize)` 唤醒并准备包系统。
- 检测变量 `package-archive-contents` 是否存在。若是崭新的环境或新装的电脑,本地没有任何仓库缓存,代码便会通过 `unless` 触发 `(package-refresh-contents)` 来拉取最新的包列表。
- 检测并安装 `use-package`:使用以 `-p` 结尾的断言函数(Predicate function)`package-installed-p` 判断其是否已就绪(David 顺便普及了 Emacs Lisp 的命名常识:以 `-p` 结尾的函数即断言函数,返回真值或 `nil`)。若未安装,则通过 `(package-install 'use-package)` 下载,并紧接着用 `(require 'use-package)` 加载。
### [23:45](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1425s) 自动化安装配置:use-package-always-ensure
加载好 `use-package` 后,David 引入了一个关键变量配置:`use-package-always-ensure`。他不确定该变量默认是开启还是关闭,于是现场演示了 Emacs 自省功能的威力——按下快捷键 `C-h v`(运行 `describe-variable` 命令),并在提示栏输入 `use-package-always-ensure` 进行查询。
弹出的帮助窗口明确显示其定义位于 `use-package-ensure.el` 中,当前值正是 `nil`。这意味着在默认情况下,Emacs 并不会自动下载缺失的包。关于这一选项的核心意义,David 明确指出:“在 use-package 的术语中,ensure 意味着每当你求值一个 use-package 表达式时,如果 ensure 设为 true,它就会在求值时尝试下载该包;如果你是在一台新机器上从零开始加载配置,并希望确保所使用的全部包在运行前都已下载并安装完毕,这正是你所需要的效果。”将该变量设置为 `t` 后,后续每个 `use-package` 语句就无需重复手动添加 `:ensure t` 标记了。
### [25:05](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1505s) 执行缓冲区求值与查看 *Messages* 日志
写好包管理初始化配置后,必须让其在当前运行的 Emacs 中生效。David 再次使用快捷键 `M-x`(Alt+X),在屏幕左下角的 Minibuffer 中键入并运行了 `eval-buffer` 命令。该命令会读取当前 Emacs Lisp 缓冲区的全部代码,并逐一在当前环境中求值。
由于下载和刷新过程中的很多提示一闪而过,David 顺势讲解了一个至关重要的调试技巧——切换到 `*Messages*` 缓冲区。他特别提醒新手:“如果你在屏幕最底部的 Minibuffer 看到弹出了一条消息,心里想着‘糟糕,闪得太快了,我根本没看清到底发生了什么’,只要切换到 messages 缓冲区——记得名字前后各带一个星号(`*messages*`)——你就能看到之前打印出的所有消息内容。”从该缓冲区的日志可以清晰地确认,Emacs 已经成功连接 MELPA 仓库并下载了索引,随后顺利拉取并安装好了 `use-package` 及其依赖。
### [26:39](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1599s) 安装 command-log-mode、意外挂起与自动保存文件恢复
为了方便直播观众看清操作,David 决定安装一个教学辅助包 `command-log-mode`。它可以在屏幕右侧开辟一个独立子窗口,实时同步敲击的每一个快捷键以及其触发的 Emacs 命令名称。
在写入 `(use-package command-log-mode)` 并求值后,David 记不清开启显示窗口的具体命令。他演示了如何依靠系统自带的自省功能排查:通过 `C-h f`(`describe-function`)调出函数说明面板,在面板中直接点击超链接跳转到包的 Elisp 源代码实现。通过阅读源码,他查到了打开窗口的命令为 `clm/toggle-command-log-buffer`。
然而在调整窗口布局时,David 不慎按到了快捷键组合 `C-z`(终端环境下的挂起挂起进程快捷键,或系统默认挂起快捷键),导致整个 Emacs 窗口瞬间消失。他忍不住惊呼:“天哪!我刚才难道把 Emacs 关了吗?好吧,按了 Control-Z,千万别学我这么干!”由于不知道如何在桌面环境中唤醒被挂起的进程,他只好重新打开 Emacs。
重新打开 `~/.emacs.d/init.el` 后,刚才编写的配置似乎全丢了。但 Emacs 立即在 Minibuffer 底部给出了救命提示:`consider running M-x recover-this-file`。David 详细解释了 Emacs 后台默默运行的安全保护机制:
- Emacs 会在后台为正在编辑的缓冲区定时写入自动保存文件(Auto-save file),防止崩溃或误关导致代码丢失。
- 此时在 Minibuffer 运行 `M-x recover-this-file`,系统会展示自动保存文件的创建日期与时间。
- 输入 `yes` 确认恢复后,刚刚丢失的 `use-package` 和相关配置瞬间全盘复原。
David 随即执行存盘并重新执行 `eval-buffer`,接着运行 `global-command-log-mode` 开启全局监控,并通过 `clm/toggle-command-log-buffer` 调出右侧日志栏。他在主窗口按下 `C-h f`,右侧屏幕立即清晰记录下了按键 `C-h f` 及其对应的映射命令 `describe-function`。至此,扩展包管理体系与键位展示环境均已搭建完毕。
- 关键函数与命令汇总:
- `(require 'package)`:加载 Emacs 内置包管理器。
- `package-archives`:定义包镜像源地址列表的 alist 变量。
- `(package-initialize)`:初始化并激活扩展包环境。
- `(package-refresh-contents)`:从远程镜像源刷新本地包索引信息。
- `package-installed-p`:检测目标扩展包是否已经存在于本地。
- `use-package-always-ensure`:设置为 `t` 时,所有声明的包都会自动执行缺包下载。
- `eval-buffer`:对当前缓冲区的全部 Emacs Lisp 代码重新求值。
- `recover-this-file`:从 Emacs 的 `#filename#` 自动保存机制中挽救未存盘的改动。
- `global-command-log-mode` 与 `clm/toggle-command-log-buffer`:全局监听用户操作并在侧边栏动态打印按键和命令。
### [30:10](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1810s) 引入补全框架:Ivy 与 Helm 的生态选择
在搭建好基础界面外观后,主播指出除了最精简的起步配置外,最关键的模块莫过于补全框架(Completion Framework)。Emacs 生态中最著名的两大主流补全框架是 Helm 和 Ivy。虽然两者在许多底层逻辑上非常相似,但设计哲学略有不同:Helm 功能大而全,而 Ivy 视觉风格更极简,也更符合主播个人的日常工作流。因此本次配置以 Ivy 为主,不过主播也强调后续若观众感兴趣,随时可以在直播中切换并对比 Helm。主播解释道,Emacs 拥有高度开放的生态系统,用户甚至不必像在 Vim 和 Emacs 之间那样非此即彼:“It's not like you have to pick one and stick with it. It's not like a Vim versus Emacs thing where they're completely incompatible. No, you can do everything all at the same time in Emacs, which is kind of great.”
主播打开自己现有的配置文件作为参考,将 Ivy 的基础配置代码复制到当前的 `init.el` 中,并执行 `eval-buffer`(求值整个缓冲区)。此时,底部的 Minibuffer 中闪过正在求值 Ivy 相关的 Emacs Lisp 文件的提示信息,表明 Ivy 正在被下载并加载。
```mermaid
flowchart TD
accTitle: Emacs 补全框架生态示意图
accDescr: 展示 Emacs 内部 Minibuffer 与两大主流补全框架 Helm 及 Ivy 的协作关系。
subgraph Core["Emacs 核心"]
MB["原生 Minibuffer"]
end
subgraph Frameworks["补全框架生态"]
direction TB
HELM["Helm 框架<br/>(功能丰富 / 独立生态)"]
IVY["Ivy 框架<br/>(极简轻量 / 配合 Council)"]
end
MB -.->|"支持共存 / 自由替换"| HELM
MB -->|"本次选用"| IVY
```
### [31:45](https://www.youtube.com/watch?v=74zOY-vgkyw&t=1905s) 临时插曲:绑定 Escape 键与退出机制
在求值完代码后,主播测试默认快捷键 `C-x C-f`(即 `find-file`),发现弹出的依然是 Emacs 原生简陋的底部单行补全界面,而非预期的 Ivy 弹窗。由于尚未配置 Vim 模拟模式(Evil 模式),主播习惯性地按 `Escape` 键试图退出 Minibuffer 却毫无反应,只得停下来解决这个痛点。
在原生 Emacs 中,取消命令或退出 Minibuffer 的标准快捷键是 `C-g`。但对于习惯了 Vim 的开发者而言,高频按 `Escape` 是一种本能反应。为了避免在后续操作中不断受挫,主播做了一个小小的旁白拓展,直接在配置中添加了全局按键映射:通过 `global-set-key` 将 `[escape]` 键绑定到 `keyboard-escape-quit` 命令。这样一来,按 `Escape` 即可像 `C-g` 一样随时关闭 Minibuffer 输入提示。
- 原生 Emacs 取消按键:`C-g`
- 新增兼容映射:`(global-set-key [escape] 'keyboard-escape-quit)`
### [33:51](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2031s) 配置 Ivy Mode 与 Council 交互生态
解决了退出的问题后,主播回到 Ivy 的配置细节。Ivy 的核心包主要负责缓冲区补全等底层支持,而诸如文件查找、缓冲区切换等高层交互命令则由其同系伴生包 Council 提供。主播手动演示了在未完全配置全局快捷键时调用 `council-find-file`:屏幕底部立刻弹出了排列整齐的文件列表,支持方向键即时上下导航,按下回车即可直接打开选中的 `readme.org`。
随后,聊天室中的观众 Vincent 提示,其实并不需要为 `find-file` 逐个单独映射按键,只要开启全局的 `ivy-mode 1`,Ivy 就会自动接管 Emacs 的底层默认交互。主播在本地求值启用 `(ivy-mode 1)` 后验证了这一说法:“And by running that major mode, it's going to set up all the key bindings necessary at a global level for the default Emacs key bindings for finding files, switching buffers, etc.” 启用后,无论是原生的查找文件还是切换缓冲区,都会被无缝替换为美观高效的 Ivy 交互界面。
### [36:06](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2166s) M-x 命令系统与模糊搜索体验
为了展示补全系统的强大威力,主播重新调出快捷键显示窗口,向观众详细普及了 Emacs 中著名的 `M-x` 概念。主播在屏幕上打出 `M-x`,解释其中的 `M` 代表“Meta”,在绝大多数现代键盘上物理映射为 `Alt` 键。`M-x` 是在 Emacs 中调用任何交互式命令(Interactive Command)的核心入口。
在开启了 Ivy 之后,按下 `Alt-x` 呼出的命令列表焕然一新,全面支持模糊匹配(Fuzzy Matching)。用户只需在各个单词片段之间加上空格,例如输入 `council swift buff`,Ivy 就能自动过滤并三角定位出 `council-switch-buffer`。这种机制极大地降低了记忆长命令的负担,即便记不清确切的全名,只要记得几个关键词片段,就能迅速定位到需要的命令并来回切换缓冲区。
- `M` 键(Meta):大多数现代 PC 与 Mac 键盘上对应 `Alt` 键(或 `Option` 键)。
- `M-x`:调用交互式 Emacs Lisp 命令的核心接口。
- 空格模糊匹配:如输入 `council swift buff` 即可精准检索出 `council-switch-buffer`。
### [37:32](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2252s) 通过 Council 预览主题与 use-package 原理解析
利用刚刚配置好的 Council,主播演示了非常实用的主题切换命令 `council-load-theme`。该命令会在底部交互列表中实时列出所有可用的配色方案(包括主播主机上未完全隔离的 Doom 预装主题以及内置主题)。在翻阅预览后,主播选定了内置的 `wombat` 配色,并直接将其写回 `init.el`,替换掉之前设定的 `tango-dark`,使 Emacs 启动即默认加载该深色主题。
随后,主播将话题深入到包管理的核心工具 `use-package`。主播打开浏览器展示 `use-package` 的官方文档,并阐述了它的不可替代性:如果手动从 GitHub 等远程仓库克隆包并逐一配置,配置文件中将充斥着大量繁琐的原生 Elisp 代码来处理 `require`、模式激活(Mode setup)以及按键映射。`use-package` 将这些声明统一收拢,极大地简化了生命周期管理:“With use package, it takes care of all that for you, which I find to be extremely useful.” 主播进一步解释道,`use-package` 在默认情况下甚至不会直接加载整个包,而是利用 Autoloads(自动加载机制)声明函数签名,实现懒加载——在用户真正调用命令之前完全不加载实际代码,从而保障 Emacs 的极速启动。
- 主题变更:从 `tango-dark` 切换为内置的 `wombat`。
- `use-package` 核心优势:统包管理、统一语法、按需绑定,以及通过 Autoloads 机制延迟加载代码。
### [40:01](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2401s) 自动加载与使用 Diminish 净化 Mode Line
在探讨 `use-package` 的性能时,David Wilson 指出只要软件包配置了 autoload(自动加载),延迟加载就不会拖慢 Emacs 的启动时间,因为系统在启动时仅会在包未安装时尝试安装并建立引用,随后按需加载。对于常规用法,只需书写 `(use-package <package-name>)` 即可。
接着他提到了配置中的 `:diminish` 关键字。为了展示其作用,他解释了位于 Emacs 窗口底部的状态栏——Mode Line。Mode Line 通常会显示当前主模式(如 `lisp-interaction-mode`)、编辑的文件名、光标所在的行列号以及当前启用的各种次要模式(Minor Modes,如 `eldoc`)。在手动求值并启用 `ivy-mode` 后,Mode Line 上便立刻多出了“ivy”字样。
此时观众 Deepassen 在聊天室提醒他重新开启按键记录器,David 通过执行 `clm/toggle-command-log-buffer` 重新拉起了命令显示。他进一步解释引入 `:diminish` 的原因:随着配置不断完善,用户会启用大量扩展包自带的 Minor Mode,这会导致 Mode Line 上的模式名称列表变得越来越冗长,既占据宝贵的屏幕空间又显得极其杂乱。通过 `:diminish`,可以在后台对特定模式进行隐藏,使其不出现在状态栏列表中:
> “I don't really know like if people think that's a bad idea, but for me, I like to keep a very minimal view so that I don't have a lot of things distracting me whenever I'm using my editor or when I'm in my environment.”
- Mode Line 默认展示主模式(Major Mode)、次要模式(Minor Mode)、文件状态与行列光标坐标。
- `:diminish` 用于在后台隐藏次要模式的名称,避免插件增多时状态栏被无用文字占满。
```mermaid
flowchart LR
accTitle: Mode Line Minor Mode Display Flow
accDescr: A diagram illustrating how minor modes clutter the mode line without diminish, and how diminish cleans it up.
subgraph WithoutDiminish["未启用 Diminish"]
M1["加载多个 Minor Modes<br/>(Ivy, ElDoc 等)"] --> D1["Mode Line 填满模式文本<br/>杂乱且占用屏幕空间"]
end
subgraph WithDiminish["启用 Diminish"]
M2["加载 Minor Mode<br/>+:diminish 属性"] --> D2["Mode Line 隐藏插件指示符<br/>保持极简与专注界面"]
end
```
---
### [42:35](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2555s) `:bind` 快捷键映射与缓解“Emacs Pinky”的小贴士
除了净化界面,`use-package` 提供的 `:bind` 声明也极大简化了快捷键绑定流程。在传统 Emacs 配置中,用户往往需要繁复地调用 `define-key` 或各种全局按键绑定函数,而 `:bind` 语法非常直观。例如声明对 `C-s` 的映射后,按下快捷键便会直接触发 `swiper`。
在配置 Ivy 时,还可以通过 `:map` 针对特定按键映射表(如 `ivy-minibuffer-map`)定义仅在特定环境下生效的按键。David 分享了自己的高频操作习惯:在 Ivy 弹出 Mini-buffer 选择列表时,他习惯使用 `C-j` 与 `C-k` 代替方向键来上下移动候选项,从而完全不用离开键盘主键区(Home Row)。
由此,David 谈到了所有 Emacs 长期使用者普遍关注的健康隐患——“Emacs 小拇指”(Emacs Pinky)。为了整天输入复杂的控制键组合,小拇指反复向边缘屈伸会导致严重的肌肉与关节劳损。他的解决策略是在操作系统底层直接将 `Caps Lock`(大写锁定键)重映射为 `Control`:
> “Uh if you do that simple little keybinding switch where you replace caps lock with control, it makes your life a whole lot easier in Emacs. So I highly recommend doing that.”
在此期间,观众 Alex 在直播间反馈视频底部的 Emacs 画面似乎被切掉了一半,排查后确认是 YouTube 画面显示比例的局部问题。
- 推荐通过操作系统层级将 `Caps Lock` 改为 `Ctrl`,可在 Linux、macOS 和 Windows 上通用,彻底避免手指过度弯曲。
- 利用 `ivy-minibuffer-map` 把方向切换绑定至 `C-j`(下一项)和 `C-k`(上一项),操作无需移开主键区。
- 程序员全天打字时,减少手臂在键盘与鼠标/触控板之间的来回切换是保护双手疲劳损伤的极佳手段。
---
### [45:17](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2717s) Mini-buffer 导航实操与 Vim 逃逸键的肌肉记忆尴尬
回到代码演示环节,David 尝试调用 `counsel-switch-buffer` 演示 Mini-buffer 下的导航。但由于他多年使用 Vim 键位,下意识按下 `Esc` 试图清理状态,结果直接把刚刚配置好的 `command-log-buffer` 窗口给关掉了。他无奈打趣道:
> “This is what happens whenever you just get like so used to uh to Vim key bindings is that you just hit escape all day long just unconsciously just to clear out whatever you're doing and then it causes problems whenever you don't want it to.”
重新开启记录器后,他在 Mini-buffer 中测试 `C-j` 和 `C-k` 上下移动,但发现侧边栏的命令日志并未捕捉到底部的按键。聊天室中的 Deepassen 再次敏锐指出:必须先运行 `global-command-log-mode`,Mini-buffer 内发生的按键命令才能被全局捕获。David 采纳了建议,命令记录窗口随即正常显示出连续的 `C-j` 与 `C-k` 指令。
- 长期形成 Vim 肌肉记忆的用户在原生 Emacs 中按 `Esc` 会频繁意外关闭活动窗口或取消操作。
- Mini-buffer 内的事件具有特殊隔离性,需开启 `global-command-log-mode` 才能被 Command Log 缓冲区统一记录。
---
### [47:05](https://www.youtube.com/watch?v=74zOY-vgkyw&t=2825s) 美化 Mode Line:引入 Doom Modeline 与高度调优
基础交互调优完毕后,David 转向界面的美化。Emacs 默认的 Mode Line 全是纯文本字符,信息密集且样式陈旧,既容易分散注意力也不够现代化。他展示了自己主力环境中的底部状态栏——极简、带有清晰图标、配色柔和且字号适中,这就是广为人知的 `doom-modeline` 插件。
为了让新建的配置获得现代化外观,David 浏览了 `doom-modeline` 的 GitHub 仓库文档。他指出,默认配置开箱即用度极高,并能和众多主流包无缝集成。他从官方说明中复制了基础声明代码片段粘贴进配置文件,并立即使用 `C-x C-e` 执行求值,Emacs 底部的 Mode Line 瞬间刷新成了整洁现代的 Doom 风格。
不过,刚生效的 `doom-modeline` 默认高度在屏幕上稍显宽大。David 表示在日常使用中,他更喜欢稍微紧凑一些的状态栏,通常可以通过调整相关配置变量并结合 Mode Line 专用字体大小来控制高度。他在文档中查到高度定制项(`doom-modeline-height`),并准备在 `use-package` 中加入 `:config` 语句块来进行调整,以此展开后续关于 `:init` 与 `:config` 阶段区别的技术讲解。
- Emacs 原生 Mode Line 纯文本感过强、信息冗余,容易分散写代码时的专注度。
- `doom-modeline` 提供现代美观的 UI、图标支持及极佳的生态扩展适配。
- 状态栏的高度可以通过包内置变量与字体字号相互配合来达到紧凑协调的视觉效果。
### [50:09](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3009s) 调整 doom-modeline 高度与排查括号错误
主播想要微调一下底部状态栏的高度,便打开自己日常使用的 `Emacs.org` 配置文件进行查阅。他在自己的配置里找到了对应项,发现高度值设为了 `15`,并且是通过 `:custom` 来声明的。于是他将这段配置复制并粘贴到当前正在编写的测试配置中。然而,粘贴后立刻遇到了 Lisp 初学者经常碰到的典型问题——括号不匹配(Unbalanced parenthesis),随后控制台还报错提示未定义函数 `void function doom-modeline-height`。主播自嘲道:“This is what happens whenever you paste it in incorrectly. Also, we need something that will show us the parenthesis balance.”(这就是每次乱粘贴代码时会发生的事;而且我们确实需要搞一个能显示括号匹配状态的工具)。
仔细检查语法结构后,主播意识到自己少套了一层括号,并且写错了 `:custom` 与 `:config` 的层级结构。修正语法并重新执行代码后,界面的高度变化并不明显。主播解释称,修改 `doom-modeline` 的高度后通常需要重启该模式,或者切换到其他 Buffer 才能刷新渲染效果。为了测试,他打开了一个 `package.json` 文件。尽管高度看起来依然比较宽,但他对当前的视觉效果已经相当满意,并指出当打开 `package.json` 时,状态栏上自动出现了一个小巧的 Node.js/npm 图标,这正是 `doom-modeline` 配合图标库所带来的便利与精致感。
- `doom-modeline` 的高度参数可在 `use-package` 的 `:custom` 块中配置为 `(doom-modeline-height 15)`。
- 修改模式栏样式后,Emacs 可能需要重启该 Minor Mode 或切换当前 Buffer 才能触发重绘。
- 在安装 `all-the-icons` 支持后,`doom-modeline` 能够根据打开文件的类型(如识别 `package.json`)自动在状态栏显示对应的语言/生态图标。
### [52:12](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3132s) 第一期成果总结与未来计划
随着基础界面的配置完毕,主播对本场直播的成果进行了总结。他希望能通过这次简单的上手演示消除大家对 Emacs 的畏难情绪:“So I hope that with this little intro I have convinced you that writing your own Emacs configuration is not that hard and it doesn't take much code and you can get something that looks really nice very quickly.”(我希望通过这次小小的入门演示,能让大家相信编写自己的 Emacs 配置其实一点都不难,不需要多少代码,就能迅速配出非常好看的效果)。虽然目前写出来的 `init.el` 结构还比较杂乱、没有做良好的模块化分类,但随着系列直播的推进,后续会逐步重构和完善。
对于接下来的内容安排,主播计划在下一期直播中引入更多实用的扩展包,比如被广泛誉为神器的 Git 客户端 Magit,以及其他日常开发利器。他热情呼吁观众提供建议,欢迎大家在直播聊天室或者视频下方的评论区留言,列出自己想看演示的扩展包。之所以更推荐在评论区留言,是因为直播聊天记录在结束后往往容易被遗漏,留在评论区更便于形成长期的参考记录。
### [53:17](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3197s) 使用 Magit 提交配置与 RunEmacs 的由来
作为本期直播尾声的一个“额外演示”(bonus),主播决定现场演示如何将刚才编写的配置文件提交到 Git。他退出了正在测试的 Emacs 实例,切回自己深度定制的主 Emacs 环境,并重新打开了那个 `init.el`。他按下快捷键唤出了著名的 Git 交互插件 `magit-status`,屏幕上随即弹出一个清晰展示当前 Git 仓库状态的 Buffer。他本想调出按键日志窗口(command log window)向大家展示按键操作,但发现当前这台电脑上的配置尚未调顺,便打消了这个念头。
在 Magit 界面中,主播暂存(stage)了 `init.el`,并顺手清理掉了 Magit 高亮指出的行尾多余空白字符(errant whitespace)。随后他按下快捷键 `c c` 打开提交信息编辑窗口,输入了提交信息 `initial commit of init.el`,通过 `C-c C-c` 完成提交,紧接着按下大写的 `P` 再按 `p` 将代码推送到远程仓库,并输入了 SSH 密钥的 Passphrase。
```mermaid
flowchart TD
accTitle: Magit 提交与推送工作流
accDescr: 展示在 Magit 状态界面中从暂存文件、清理空白字符、提交信息到推送到远程仓库的操作步骤。
subgraph Magit["Magit 工作流 (magit-status)"]
A["打开 magit-status 检查未跟踪/修改文件"]
B["暂存 (Stage) init.el 并清理多余行尾空白"]
C["按 'c c' 输入提交信息: initial commit of init.el"]
D["按 'C-c C-c' 确认本地 Commit"]
E["按 'P p' 输入 SSH 密钥密码并推送到 GitHub"]
A --> B --> C --> D --> E
end
```
代码推送完毕后,主播切到浏览器展示对应的 GitHub 仓库页面。这个仓库被命名为 `runemacs`。主播分享了名字背后的趣事:在 Windows 平台上使用过 Emacs 的人可能见过用于启动程序的 `runemacs.exe`;他的同事 Chris 在初次下载 Emacs 时看到这个文件,曾十分惊讶地感叹道:“Wow, this comes with RuneEmacs!”(哇,这玩意儿还自带‘符文 Emacs’呢!)。为了向同事 Chris 致敬,主播便将这个专门存放纯手工配置的仓库命名为 `runemacs`。他提醒观众,直播里写的所有代码均已公开在 GitHub 上,大家可以直接 Clone 开始 Hack 自己的配置,也可以在仓库的 Issue 中提问、提需求或给出反馈。
- 仓库地址与命令命名源自 Windows 版 Emacs 的可执行文件 `runemacs.exe`,取自同事将“Run Emacs”误读为“Rune Emacs”(符文 Emacs)的内部梗。
- Magit 的常用提交流程:在状态界面按 `s` 暂存变更、按 `c c` 编写提交信息、按 `C-c C-c` 确认提交、按 `P p` 执行 Git Push。
### [55:48](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3348s) 答疑、Org-mode 桌面配置展示与下期预告
主播向聊天室征集最后的问题,并感谢大家的积极参与,指出本场直播创下了他频道以来的最高同时在线观看人数,这让他坚信在接下来的直播中深耕 Emacs 是完全正确的方向。为了满足那些想探索 Emacs 终极形态的硬核观众,主播展示了自己的个人 dotfiles 仓库(`github.com/daviwil/dotfiles`)。他深入讲解了自己的系统构建理念:他不仅仅用 Emacs 编写代码,而是将 Emacs 作为完整的桌面环境和窗口管理器,甚至整个 Linux 系统的所有软件配置全部写在一个通过 Org-mode 组织的文档中。
在展示桌面环境配置时,观众可以看到不仅包含了 Emacs 插件,还通过文学编程(Literate Programming)管理着外部程序,例如状态栏 Polybar、通知守护进程 Dunst 等等。主播解释道:“All these configuration bits actually are used in my system. They just get written out by Org-mode whenever I save changes to the file. So this file is like my source of truth whenever I am changing my system configuration...”(我系统里的所有配置实际上都来源于此。只要我保存文件,Org-mode 就会把它们抽取写入到目标配置文件中。因此,当我想修改系统配置时,这个文件就是我唯一的‘单一真实来源’……)。这种修改 Org 文件并自动纠缠(Tangle)出附属系统配置的方式,也是未来可以专门开播深聊的话题。
在随后的互动中,观众 Bruno 建议:“Maybe demo install projectile”(或许可以演示一下安装 Projectile)。主播对此表示高度赞同,承诺在接下来的几期直播中必定会专门安排一期讲解 Projectile:“If you do coding with git repositories of various different types of languages and whatnot, you definitely want to use Projectile.”(如果你在日常编程中需要处理包含各种语言的 Git 仓库,那你绝对会需要 Projectile)。直播进行到了约一小时,主播宣布本次直播圆满结束。他计划将下一期直播定在下周一或下周三,并提醒观众订阅频道并开启铃铛通知以防错过油管通知,最后以标志性的“Happy hacking”向观众道别。
## Notable quotes
> [00:03](https://www.youtube.com/watch?v=74zOY-vgkyw&t=3s) 从零开始探索如何配置 Emacs 是一件非常有趣的事情,因为相比于使用像 Spacemacs 或 Doom Emacs 这种现成的预打包配置系统,以这种方式能学到的东西要多得多。 — David Wilson
> [02:23](https://www.youtube.com/watch?v=74zOY-vgkyw&t=143s) Magit 是一个极其强大的插件,我觉得如果你以前从没见过它,这可能就是让你彻底爱上 Emacs 的最关键功能之一,哪怕仅仅为了这一个功能也完全值得。 — David Wilson
## Mentioned
David Wilson, System Crafters, Emacs, EXWM, Magit, Org-mode, Doom Emacs, Spacemacs, Eshell, Dired, GNU Guix, Linux, HarfBuzz, Fira Code Retina, Swiper, Flycheck, Evil, MELPA, GNU ELPA, Clojure, use-package, command-log-mode, Ivy, Helm, Council, Diminish, doom-modeline, Projectile, Polybar, Dunst, Git, GitHub, Node.js
## Video description
In this stream, we'll start creating a completely custom Emacs configuration from scratch! We'll also learn some Emacs basics along the way.
Check out the configuration from this stream here: https://github.com/daviwil/runemacs/tree/3075158cae210060888001c0d76a58a4178f6a00
My Emacs configuration: https://github.com/daviwil/dotfiles/blob/master/Emacs.org
If you enjoy this series, please consider becoming a GitHub Sponsor: https://github.com/sponsors/daviwil
Follow me on Twitter for more Emacs content!
https://twitter.com/SystemCrafters
Chat with the System Crafters community on Discord: https://discord.gg/yVD8Gx6
Intro music: Coriolis Effect by logos feat. stefsax, licensed CC-BY
http://ccmixter.org/files/mseq/26296
[Source](https://www.youtube.com/watch?v=74zOY-vgkyw)
Source quotes
[0:03] David Wilson: 从零开始探索如何配置 Emacs 是一件非常有趣的事情,因为相比于使用像 Spacemacs 或 Doom Emacs 这种现成的预打包配置系统,以这种方式能学到的东西要多得多。
[2:23] David Wilson: Magit 是一个极其强大的插件,我觉得如果你以前从没见过它,这可能就是让你彻底爱上 Emacs 的最关键功能之一,哪怕仅仅为了这一个功能也完全值得。
Source quotes
[3:03] David Wilson: I think that it's really interesting to dive into how to configure Emacs from the ground up because you learn a lot more from doing it that way as opposed to using a prepackaged configuration system like Spacemacs or Doom Emacs, etc.
[2:23] David Wilson: Magit is a super powerful package and I feel like if you've never seen it before, this may be one of the major things that turns you on to Emacs forever
Original transcript
[0:03] What's up everybody? David Wilson here
[0:05] and I'm very happy to get started this
[0:07] morning on a new series in uh our live
[0:10] streaming adventures um where we start
[0:13] to build an a custom Emacs configuration
[0:15] from scratch. Um so Emacs, if you don't
[0:20] already know, but I assume you probably
[0:21] have heard of it if you're here. um is a
[0:24] well some would call it a text editor
[0:26] but I consider it more of a like
[0:28] complete productivity environment. Um it
[0:31] does the basic text editing capabilities
[0:33] but uh it provides like a platform for
[0:36] building pretty much anything you would
[0:37] want to do um whenever messing with
[0:39] stuff on a computer um you know writing
[0:42] code or you know organizing your life or
[0:45] you know just managing your computer in
[0:46] general. So, u I think that it's really
[0:49] interesting to dive into how to
[0:52] configure Emacs from the ground up
[0:54] because you learn a lot more from doing
[0:55] it that way as opposed to using a
[0:58] prepackaged configuration system like uh
[1:00] Spacemax or Doom Emacs, etc. Um, so my
[1:05] background with Emacs is that I started
[1:07] using it probably like on and off since
[1:09] about like 2007. Um, but I didn't really
[1:11] get really into Emacs until maybe a year
[1:14] and a half ago where I really got deep
[1:16] into uh customiz customize my
[1:19] configuration and uh trying to figure
[1:21] out what I could do to just make my own
[1:24] full workflow using Emacs. Uh so at at
[1:27] this point I basically live in Emacs all
[1:29] day. I you know use EXWM as my window
[1:32] manager. um I use mostly Emacs packages
[1:36] for everything except for things that I
[1:37] can't do that with like you know
[1:38] applications I need to use for work etc.
[1:40] So um I think it's going to be really
[1:42] interesting for us to dive into um both
[1:44] how I've configured my system and also
[1:46] how you could make your own
[1:48] configuration from scratch uh using
[1:50] similar techniques. So um this is live
[1:53] obviously so if you are here in the chat
[1:55] please say hello and uh please ask
[1:57] questions anytime if you're interested
[1:59] in in any more details about anything
[2:00] that I cover here. Um I I figure we'll
[2:04] probably do a lot of streams about this
[2:05] because there's a lot of things you can
[2:06] do with Emacs. So we're going to start
[2:08] just like from the basics. Uh we're
[2:09] going to start from the ground up and
[2:11] then over time we will probably
[2:13] experiment with different packages based
[2:15] on what people ask about and um try to
[2:18] like build like a full workflow using
[2:19] using Emacs. So, uh, to kick things off,
[2:23] I will I'll go over my configuration,
[2:26] um, a little bit just to s sort of show
[2:28] you what my world looks like on a
[2:29] day-to-day basis, and then we can jump
[2:31] into starting from scratch on a new
[2:33] configuration. So, um, whenever, uh,
[2:35] Emac starts up, or actually, let's take
[2:37] one step further back. Um, whenever I
[2:40] log in to my desktop environment, it
[2:44] boots up Emacs. Emacs takes up the full
[2:46] screen. It uses EXWM to manage the
[2:48] screen and manage any X Windows
[2:50] applications that are being run inside
[2:51] of that. Um, if you're using Windows or
[2:53] Mac OS, unfortunately, you can't use
[2:55] EXWM, but this should still be
[2:57] interesting to you from a sort of
[2:58] conceptual perspective of what's
[3:00] possible with Emacs. So, uh, you can see
[3:03] I'm here in ESL, which is basically a
[3:05] built-in uh, terminal emulator sort of
[3:08] in Emacs. Um, it's pretty powerful. We
[3:10] can go into that um, for in another
[3:14] time. Hi, James. Good morning. Um so
[3:18] from this point usually I will like you
[3:21] know navigate to a particular project.
[3:22] Um so let's just you know open up a file
[3:25] here. So I can hit u find file and then
[3:28] go into the read me for this project. Um
[3:31] and you know we can use deer red to
[3:33] navigate around the file system. So I
[3:35] have a keybinding setup for that where I
[3:37] can you know pop around through
[3:38] different folders. Uh it's very easy to
[3:41] do that. I've got like custom keybinding
[3:42] setup so that it's easy to navigate with
[3:44] them style keys like hjkl etc. Um using
[3:49] uh mgit for git uh functionality. If I
[3:53] go to my files repo
[3:56] you can see that um we can pull up mgit
[3:59] and get really nice things like you know
[4:00] history list or you know staging of
[4:02] chunks or pretty much anything that um
[4:04] you would want to do with git
[4:05] repository. MGIT is a super powerful
[4:08] package and I feel like if you've never
[4:10] seen it before, this may be one of the
[4:12] major things that turns you on to Emacs
[4:13] forever, at least even just for for this
[4:16] functionality alone because uh it's it's
[4:18] super powerful. It saves me a lot of
[4:19] time. So, um I mean that's not really a
[4:23] great run through, I guess, of of what
[4:25] you can do. Um you you can see that I
[4:27] actually have a next Windows window here
[4:29] on another workspace. Um so I have like
[4:31] the the repo for this project we're
[4:34] going to do. Um, and uh I can switch
[4:37] windows pretty easily. I actually use uh
[4:40] separate browser windows for uh every
[4:43] quote unquote tab that I have open. And
[4:45] I can use uh Emacs buffer switching uh
[4:47] commands to switch between those, which
[4:48] is pretty nice. So anyway, uh if you get
[4:52] really into Emacs, you can go really far
[4:54] um and and basically customize your
[4:57] whole computing life, which is pretty
[4:58] cool. Uh I'll quickly bring up my
[5:00] personal Emacs configuration so you can
[5:02] see what that looks like. Um, I've gone
[5:04] with a literal configuration format
[5:06] where we build um, our configuration
[5:09] files out from org mode files. And if
[5:11] you haven't heard of org mode, it's
[5:13] basically like a um, it's an organizer,
[5:16] but it's also kind of like a markup
[5:17] language for writing documents and it
[5:19] can do live code evaluation within
[5:22] blocks inside the file. So, it does a
[5:23] lot of things. It's super powerful.
[5:25] That's another one of these features
[5:26] that you'll hear a lot of people talk
[5:27] about whenever they talk about uh, how
[5:28] cool Emacs is. Uh in this case, we just
[5:31] have a whole file set up here with um a
[5:34] bunch of different sections for all the
[5:35] stuff that's in my configuration. And uh
[5:38] as you can see, there's a lot in here,
[5:40] but uh even though there's a lot in this
[5:42] single file, it's easy for me to manage
[5:44] because of all the headers. You can
[5:45] navigate through headers pretty easily.
[5:47] And um a lot of the configuration blocks
[5:50] don't actually get loaded until um
[5:52] they're they're needed. So some command
[5:53] from the package gets run or a mode gets
[5:56] activated. Uh so it's it's been working
[5:58] pretty well for me in this case. So uh
[6:00] at some point in the future we'll get to
[6:02] this point of using or or mode to uh do
[6:06] our system configuration or EMAC
[6:07] configuration, but for now we're just
[6:08] going to stick with a plain EMAC list
[6:10] file instead. Um James asks asks, excuse
[6:14] me, James X asks, is this Linux? Yes,
[6:17] this is um this is indeed Linux is a
[6:20] distribution of Linux called GNU Geeks.
[6:23] And uh I will also go into that in more
[6:25] detail one day because it actually fits
[6:26] in pretty heavily into my workflow. But
[6:28] for now, we'll just focus uh strictly on
[6:30] Emacs.
[6:32] So um without further ado, how about
[6:35] let's try to um get something started
[6:37] here. So we're going to be using Emacs
[6:40] 27.1 since that came out recently and uh
[6:42] thankfully my DRO has now got that
[6:44] working so I I get the benefit from
[6:46] that.
[6:48] Yes, Pepsi says, "Nice timing. just
[6:51] install Doom Emacs and E exwm. Yeah,
[6:53] that's it's a good combination. I
[6:54] haven't really used Doom EMAC very much.
[6:56] I do use Doom model line and Doom
[6:59] themes. Uh but Doom Emacs I kind of like
[7:02] before that got popular I started
[7:04] working on my own configuration from
[7:06] scratch. So um I never really got into
[7:08] that. I did use Spacemax in the past
[7:10] though and that was that was pretty
[7:11] useful. So let's try to start Emacs
[7:14] without loading my own configuration. Uh
[7:16] so we're basically going to be running
[7:18] Emacs in EMAC here. Here we're going to
[7:19] have a little bit of emacception, but uh
[7:21] it should be it should work fine. We're
[7:23] going to run uh emacs- q, which I think
[7:26] uh inhibits uh startup. And since I do
[7:29] have an empty init here. Oh, I don't
[7:32] have an empty empty in it. Eel. We'll
[7:34] just touch it and
[7:36] make that there. So, we'll say
[7:37] emac-qinit.l.
[7:40] Oh, I think we need to say load.
[7:43] Well, let's use the nice little help
[7:46] here. Oops.
[7:48] I think it's uh load
[7:51] load path
[7:55] load. Okay, it's just dash L. All right,
[7:57] so Emacs-QLinit.
[8:00] And it's going to pop open a vanilla
[8:03] EMAC window.
[8:07] And uh yeah, so we're basically
[8:09] confronted with this white screen and
[8:12] the text is super super small because my
[8:14] screen is high DPI and uh the font isn't
[8:17] set correctly yet. So it's probably not
[8:19] very readable at the moment, but we're
[8:20] going to fix that. So, uh, if you've
[8:23] ever downloaded Emacs, like, so, so
[8:26] imagine this, like you, you've been
[8:27] looking around on like, let's say,
[8:28] Reddit on R/ Emacs or you're looking
[8:31] around at other people's like, you know,
[8:32] configurations or whatever. Um, and
[8:34] you're or someone's video or something
[8:35] where you see them using a cool
[8:36] configuration. Uh, you probably saw like
[8:39] something looked really cool, you know,
[8:40] looked nice and minimal like what I was
[8:42] showing you before. And then you go
[8:43] download Emacs, you're excited to start
[8:45] using it, and you're like, "Okay, this
[8:46] is going to be really nice." Then you
[8:47] you run Emacs for the first time and you
[8:49] see this screen where you've got this
[8:50] kind of toolbar and you've got the menu
[8:52] bar and you've got this welcome screen
[8:54] with the weird old looking Emacs logo.
[8:57] Uh and the colors are kind of crappy and
[8:59] you're probably like, "Well, I don't
[9:00] know about this. This doesn't really
[9:02] look like my kind of tool." Well,
[9:04] thankfully it's easy to turn a lot of
[9:06] this stuff off and then get to a more
[9:07] minimalistic view that you can start
[9:09] from that feels more like what you would
[9:11] expect from an editor. Um or at least if
[9:14] you like minimal editors like Vim, etc.
[9:16] So, we're going to start with that.
[9:18] We're going to try to get rid of some of
[9:19] this stuff in the UI, and then we're
[9:20] going to try to set a theme that will
[9:22] allow us to, you know, tolerate what
[9:24] we're seeing here because this white
[9:25] screen is kind of blinding me right now.
[9:27] All right. So, um I'm going to back out
[9:30] of this real quick so that we don't have
[9:32] to look at that. And then I'm going to
[9:33] open up the init. file.
[9:37] And uh I'm going to cheat a little bit
[9:38] because I have some bits of my
[9:40] configuration that can work for this.
[9:41] So, I'm going to split this window and
[9:44] uh I'll pull up my own configuration.
[9:47] So, uh the first thing that I want to do
[9:50] if I can get down here is find my
[9:54] configuration settings for
[9:56] um simplifying the UI. Apparently, I've
[10:00] buried it. Let's see. Um visual bell. I
[10:04] think it's there.
[10:06] Bell. Yeah. Okay.
[10:09] Match required. Give me a break.
[10:15] Obviously this morning I've lost the
[10:16] ability to type. So um menu menu bar
[10:20] mode. Okay, great. Here we are. So um
[10:24] what one thing we can do let's say the
[10:26] first thing we'll do is we'll just
[10:27] inhibit that startup message which shows
[10:29] you sort of that the landing page in
[10:30] Emacs. I mean it could be useful for
[10:31] some people but for me I prefer to just
[10:33] start from like a blank screen as much
[10:35] as possible. And also we're going to uh
[10:40] set some settings to remove some of
[10:42] these UI elements because we don't
[10:44] really want to see those anymore. So I'm
[10:46] going to get rid of um some of this
[10:48] indentation. I'm copying it over from my
[10:50] from my own configuration.
[10:52] And then um
[10:54] I think that's a good starting point.
[10:56] Actually, let's get rid of the menu bar
[10:57] also. And I'll throw in the bit visual
[11:00] bell. Uh since I tend to prefer not
[11:04] having um my editor beep at me all day
[11:07] long whenever I like hit backspace at
[11:08] the beginning of line or anything like
[11:10] that, I turn on visual bell so that I at
[11:12] least see a flash on the screen. Uh like
[11:15] let's see, can I invoke it? Yeah, you
[11:16] see that the sort of the top and the
[11:17] bottom of the window are flashing right
[11:18] now. Whenever I hit backspace, that's
[11:20] what visual bell looks like. So, um some
[11:22] people find it annoying. Uh, I do find
[11:24] it more annoying on Mac OS because it
[11:26] throws up this huge like triangle thing
[11:28] in front of your face, but uh, at least
[11:30] on Linux, it doesn't seem to be that
[11:31] annoying. So, let's go with that for
[11:33] now. So, um, we will split this window
[11:37] so I can go into eShell again and then
[11:41] we can run Emacs
[11:43] with that init. And let's see what we
[11:45] get. And I'm going to full screen this
[11:48] so you can see it. All right, cool. So
[11:49] now we see that we are initially dropped
[11:51] into the scratch buffer and uh there's
[11:54] no menu bar, there's no uh toolbar and
[11:57] um yeah it's very very minimal and
[12:00] simple presentation. So this is like it
[12:02] only takes about five six lines of code
[12:04] to get to the point where you have a
[12:05] very simple starting point. Um so next
[12:09] we want to uh probably make the font
[12:10] size bigger so that we can actually
[12:12] tolerate using this. So um I'm going to
[12:14] copy over some font settings I have. Um,
[12:16] the values I'm using for the font size
[12:17] are going to seem really, really big,
[12:19] and that's just because I have to
[12:20] compensate for the DPI. For some reason,
[12:23] whenever I updated from EMAC 26.3 to
[12:25] 27.1, the font sizes I was using before
[12:29] don't really work anymore. Uh, I had to
[12:31] like double them at least to make them
[12:33] bigger. And I think the reason why is
[12:34] because they've changed text rendering
[12:36] engines from I'm not sure what it was
[12:38] before, but now they're using
[12:39] Hearthbuzz, which um actually has
[12:41] improved the look of the text shapes a
[12:43] lot for me. So, I find that to be a very
[12:46] nice improvement despite the fact that I
[12:47] have to jack up my font size um to a
[12:50] ridiculous level. So, I'm going to
[12:52] search for face
[12:55] attribute here. And uh if you're
[12:57] wondering what I'm doing for searching
[12:58] right now, I'm using a um a package
[13:02] called Swiper, which allows me to hit a
[13:04] key binding to do fuzzy matching across
[13:06] all the lines in the file. Just makes it
[13:08] really easy to find things whenever I
[13:09] need to uh jump into that. So, I found
[13:12] the wrong one, it seems. Let's go do
[13:14] that again. Face attribute
[13:17] to. Yeah, let's let's go get these
[13:19] absurdly high number font sizes. Uh I'm
[13:22] going to use the uh FRA code retina font
[13:25] for this.
[13:28] So we're going to drop here and we're
[13:30] going to paste this.
[13:34] All right. And uh I'm going to leave
[13:36] that as font size 280 because that's
[13:37] what I'm using right now. Not exactly
[13:39] sure why. Okay. Yeah. Uh, so I have a
[13:41] flych check running on this on my Emacs
[13:43] list buffers and it's trying to help me
[13:44] out, but right now it's a little bit
[13:46] annoying. We'll just ignore that for
[13:47] now. So, let's run this again. And uh, I
[13:51] know some of you are probably thinking,
[13:53] wait, why why don't you just like
[13:54] evaluate this configuration setting
[13:56] right in Emacs instead of keeping
[13:58] instead of continually reloading it?
[14:00] Well, I'm going to start doing that now.
[14:01] So, now we can actually read what's on
[14:03] our screen, which is good. We've got the
[14:05] font size set. We've got a decent font
[14:06] uh, configured. Uh, this looks much
[14:08] better. So uh now what I will do is use
[14:13] well there's okay let's start with uh
[14:16] opening the init file here so that we
[14:18] can start editing it and evaluating
[14:20] changes from from this point. So,
[14:23] whoops. Um, since I use uh evil mode,
[14:27] which we'll get into later, uh, it's
[14:28] basically a Vim emulation mode. Um, I
[14:31] might make some weird edits to the file
[14:33] every now and then because I'm like
[14:34] doing mode changes and stuff and
[14:37] forgetting that I don't have it. But,
[14:38] um,
[14:40] we just ignore any kind of weird text
[14:42] that you see me type in. So, what we
[14:45] want to do, um, first, let's see. I
[14:48] think is it like I really wish I had IV
[14:51] here. Let me figure out what that
[14:53] command is supposed to be. So, if I was
[14:54] to say theme,
[14:57] uh, load theme, enable theme.
[15:01] Let's see what I think it's council
[15:04] theme.
[15:08] We want to pick one that's already built
[15:09] in.
[15:13] We'll go with tango dark. So, this is
[15:16] just going to be temporary so that we
[15:17] don't have to look at this white screen
[15:18] the whole time. Uh James says at the end
[15:21] would we would love to know the top must
[15:22] have packages you like for a new config.
[15:24] Yes, I'll definitely let you know what
[15:25] that is because I have some opinions
[15:27] there. Um I think that what we're going
[15:29] to try to do at least in the first
[15:30] couple streams is to get a configuration
[15:32] together that uh uses some of these top
[15:35] packages that I like uh just because
[15:37] they are kind of like the best exemplar
[15:39] of what Emacs can be. So uh we will
[15:42] definitely get there. Um load theme.
[15:45] Let's see. So, uh, if you've never used
[15:48] Emacs before, uh, one thing that you
[15:51] really should learn about is the, um,
[15:54] help commands or describe commands
[15:56] actually. Um, they are bound to the, um,
[16:01] control H, uh, and then letters under
[16:05] control H, uh, keys,
[16:07] and they allow you to do things like
[16:09] describe variables in Emacs or describe
[16:11] functions in Emacs. And that becomes
[16:12] really helpful when you're trying to
[16:13] figure out how to do certain things or
[16:14] if you want more information on what a
[16:16] variable or a function does. There's
[16:18] also a bunch of things for like
[16:19] describing font faces and describing uh
[16:22] modes and like a lot of stuff. So we'll
[16:25] get into some of that stuff later, but
[16:26] for now I'm going to use this uh
[16:27] describe function to see what load theme
[16:30] does.
[16:32] Ah Vincent says also mention which
[16:35] packages one can do without. For
[16:36] example, a couple years ago I stopped
[16:38] using undo undo tree and haven't missed
[16:40] it. Yeah. Yeah. This is something that
[16:42] is also important uh and it changes over
[16:44] time. Um so yeah I I'll definitely talk
[16:47] about this that as well. So remind me if
[16:49] I don't talk about it at some point.
[16:51] Okay so I used a describe function and
[16:54] that uh I asked it about load theme and
[16:57] now we got this documentation here about
[16:59] what load theme does. So uh the first
[17:01] parameter is a theme and then there is
[17:03] uh some optional parameters for uh no
[17:06] confirm no enable. We're not going to
[17:08] worry about those parameters. The main
[17:09] thing is we want to say what theme you
[17:10] want to load. So I'm going to tell it uh
[17:12] tango dark.
[17:16] And now um I'm going to try to run this
[17:18] code directly from this buffer by using
[17:21] controllx control whoopsie
[17:24] invalid theme name tango dark. That's
[17:26] interesting. I didn't even try to
[17:27] execute it yet. So uh invalid theme
[17:30] name. All right. So let's see
[17:34] if anybody knows the right way to call
[17:36] this just shout it out in the chat.
[17:38] So I use something different than this.
[17:41] Oh actually in my configuration I think
[17:43] I have something for this. So let's see
[17:44] load theme. Ah okay. So um sometimes you
[17:48] have to be aware of
[17:51] what type of parameter gets sent and
[17:53] maybe describe
[17:56] uh describe function was going to tell
[17:59] me that and I just didn't read it.
[18:01] But in this case it wants a symbol
[18:03] instead of a string. And that's sort of
[18:05] a thing in list languages. they have
[18:07] this concept of symbols where uh you can
[18:10] put an arbitrary string as a sort of
[18:13] like a language symbol. So we're going
[18:15] to put this uh single quote in front of
[18:16] this text without quotation marks around
[18:18] it and then we're going to run it. Yes,
[18:20] thank you Abdullah. So um
[18:24] we are going to try to run this. Uh I
[18:27] will select this text first and then
[18:30] controll XR control E and that did not
[18:34] seem to run it. So, let's just evaluate
[18:36] the buffer. So, if you run uh MX,
[18:42] come on.
[18:43] I hit escape too many times because I'm,
[18:45] you know, used to eho mode and it's
[18:47] giving me trouble. So, MX uh eval
[18:49] buffer.
[18:51] All right. Now, we do have the theme
[18:53] loaded. As you can see, we have a nice
[18:55] darker background. I'm not really like a
[18:58] big fan of this theme, but it's gonna
[18:59] get us where we need to go for the time
[19:01] being. So,
[19:03] uh, now we have our theme loaded up and
[19:05] we have our UI looking a lot more
[19:07] minimal, which I think is a great start.
[19:10] So, um, now, you know, we could go into
[19:13] some of the built-in packages that Emac
[19:15] has for doing certain things, which, you
[19:17] know, there's a lot of built-in stuff.
[19:18] One of the things that, um, a lot of
[19:20] people are surprised about whenever they
[19:22] use Emacs is that there's a whole lot of
[19:24] stuff already built in and a lot of
[19:26] stuff that you probably don't really
[19:28] want. But um I think the benefit is that
[19:31] if you don't really have internet access
[19:33] or you don't really want to install
[19:34] custom packages, there's a lot of things
[19:35] already built in the Emacs that you
[19:36] could use for certain things like
[19:39] completion frameworks or um uh thanks
[19:42] Dassin one. Yeah, uh CXE works after the
[19:44] S expression. Thanks. Um there's a lot
[19:47] of things that are already here, but um
[19:49] since we have this uh very healthy,
[19:52] lively ecosystem of Emacs packages on
[19:54] Melpa, which I'll show in a little bit.
[19:56] Um we we'd be better off trying to find
[19:58] things that are out in the world that we
[19:59] can use that are like community packages
[20:00] that uh give us some really nice
[20:02] functionality. So to make it possible to
[20:06] use these packages, um we're going to
[20:08] use a another package called use
[20:10] package. And uh use package basically is
[20:13] a it's kind of like a package manager.
[20:14] There's already a package manager built
[20:15] into Emacs. Like for instance, if we
[20:17] were to run list packages,
[20:20] this is a function that will just give
[20:21] you a list of all the possible packages
[20:23] that are in um oh boy, I think we have a
[20:27] lot of packages here that are from my
[20:28] own Emacs config. That's okay. So, um
[20:30] basically any package that's available
[20:32] on I believe this is ELA. So, there's a
[20:34] like a sort of default package
[20:36] repository for for Emacs called ELPA and
[20:39] that has a lot of packages, but then
[20:40] there's one in the community called
[20:41] Melpa that has a lot more. So if you
[20:43] look for Emacs Melpa
[20:46] then I think it's melpa.org.
[20:48] Yeah. And uh on this site you can go and
[20:51] search around for things that you want
[20:53] to use. Like if you use a specific
[20:54] language you're trying to find packages
[20:55] for like let's say closure.
[20:58] You can see Whoops. You can see that
[21:00] there's a lot of closure packages. Um
[21:03] because you know I think that there's
[21:05] some you know uh
[21:08] affinity from lisp users and emacs. So
[21:11] since closure is a list, I think a lot
[21:12] of Closure users are Emacs fans. So uh
[21:15] we're going to use Melpa as a place to
[21:17] install packages from. But first of all,
[21:19] we just need to get use package set up.
[21:22] So I'm also going to steal some stuff
[21:24] from another configuration that I have
[21:27] here. And I'll explain what all this
[21:29] stuff does whenever I get it turned on.
[21:32] Okay.
[21:36] Okay. So uh first of all what we're
[21:39] going to do in our uh configuration for
[21:42] package loading is we're going to
[21:43] initialize uh package sources. Uh I'm
[21:46] going to get rid of uh Melpa stable for
[21:48] now since we're just going to use things
[21:49] from the main mela repository. Uh first
[21:52] we're going to require the package
[21:54] package which brings into the
[21:55] environment all the package management
[21:57] functions. I think that may be
[21:58] autoloaded but I just have this here as
[21:59] part of my configuration just in case.
[22:01] Uh, and this package archives is a
[22:04] variable that holds all of the different
[22:07] package repositories that you can uh
[22:08] pull packages from. And as you can see
[22:10] when I hovered over this uh right when I
[22:12] put my cursor on this variable name, it
[22:14] tells me down in in the um in the mini
[22:16] buffer that package archives is an alist
[22:18] archives from which to fetch. So uh
[22:21] that's helpful. Now uh we call package
[22:23] initialize which initializes a package
[22:25] system and then prepares it to be used.
[22:28] And we also check whether uh package
[22:31] archive contents is is present because
[22:34] on the very first load like let's say
[22:36] you install your computer from scratch
[22:37] and you wanted to pull down your emac
[22:39] configuration and install everything um
[22:41] you need to look to see whether there's
[22:43] already a package archive clone to your
[22:45] computer or if there's nothing and you
[22:47] need to pull it down. So in this case
[22:49] we're saying unless this archive exists
[22:51] we're going to call package refresh
[22:53] contents which refreshes a package list
[22:56] so that uh the uh future calls to
[22:58] package management functions know what
[23:00] packages packages you're talking about
[23:03] and then um we're going to require oh
[23:06] we're going to try to install use
[23:07] package if it's not already installed.
[23:08] So this package installed P function
[23:11] anytime you see a function in EMAC EMAC
[23:13] that ends in -p that is a like a
[23:16] predicate function or it's basically a
[23:18] function that returns true or true or
[23:19] nil I think and the idea here is that uh
[23:23] you can use it to say is this package
[23:24] installed like I want to see if this
[23:26] package with this particular name is
[23:27] here and if it is return true and in
[23:30] this case we're saying unless it's
[23:31] already installed we're going to use
[23:33] package install which is built into
[23:34] Emacs to install use package and then
[23:37] once we install that we're going load it
[23:38] using require. Um, so now at this point
[23:41] we have use package available to us. And
[23:43] one extra thing that I'm going to do
[23:45] which I don't know if it's by default or
[23:46] if I just did that in my own personal
[23:48] configuration but we can find out very
[23:50] easily by saying um control HV for
[23:54] describe variable and then I'm going to
[23:56] say use package always ensure.
[24:00] So
[24:02] uh we get this helpful window over on
[24:03] this side and I think my uh panel is in
[24:06] the way. Let me kill that. Oh, I need to
[24:09] get out of this first kill panel. Okay.
[24:13] So, um use package insure is a variable
[24:15] defined in use package insure.l. Its
[24:17] value is nil. So, that tells me that um
[24:19] before running this, the default value
[24:21] of the um the variable is nil, which
[24:24] means it doesn't ensure packages on by
[24:26] default. Uh in use package terms, ensure
[24:29] means that whenever you um evaluate a
[24:32] used package form, um if ensure is set
[24:35] to true, then it will try to download
[24:36] the package whenever it evaluates that
[24:38] form, which you do want if you are
[24:40] loading up your config from scratch. And
[24:42] you want to make sure that all of the um
[24:44] uh the packages that you're using are
[24:46] going to be downloaded and installed
[24:48] before they are run. So uh this will
[24:51] make sure that all of them will be
[24:53] insured.
[24:55] So um from from this point I want to
[24:58] like insert one little thing here that
[24:59] is not needed in normal configuration
[25:01] but it's going to be very useful for us
[25:03] going forward. Uh we're going to say uh
[25:05] actually let me let me evaluate all this
[25:06] stuff first before we move any any
[25:08] further. So I'm going to run eval buffer
[25:10] again and I'm using the altx command
[25:13] binding to um to call up in the lower uh
[25:18] lefthand corner of the screen. You can
[25:19] see I'm I'm typing eval buffer. So I'm
[25:21] basically running the eval buffer
[25:22] command and what that does is take the
[25:24] contents of the buffer the the EMAC list
[25:26] buffer and evaluate them into the EMAC
[25:28] environment. So now what it's doing is
[25:31] uh you can see let me switch to the uh
[25:34] messages buffer
[25:39] if I can get there
[25:41] messages. So uh in the messages buffer
[25:44] this is actually a pretty useful thing.
[25:46] So, if you ever see a message pop up in
[25:48] the mini buffer at the very bottom of
[25:49] the screen and you're like, "Oh, it went
[25:50] by too fast. I don't know what actually
[25:52] happened." If you switch to the messages
[25:54] buffer, make sure to to note that
[25:56] there's stars before and after. If you
[25:58] do that, uh you'll see the contents of
[26:00] all messages that were print out printed
[26:02] out before. So, what we want to do right
[26:03] now is see what happened whenever we re
[26:05] reload all of our configuration.
[26:08] So, um let's see.
[26:13] package. Okay, so you can see that it it
[26:15] contacted Melpa to download the package
[26:18] repo there and then it started
[26:20] downloading a bunch of packages that uh
[26:22] we need for our configuration from Ela.
[26:24] Yeah, use packages coming from Ela etc.
[26:27] So uh now we'll move back to our u in
[26:31] excuse me keep hitting escape and it's
[26:33] causing me problems here.
[26:36] We're going to switch back to init.el
[26:39] and we're going to install a package
[26:40] called command log mode. And what that's
[26:43] going to do is pop open a buffer on the
[26:45] right hand side of the screen or pop up
[26:47] in a window uh on the on the right hand
[26:49] of the right hand side of the screen
[26:50] that's going to show us all the key
[26:52] bindings that I'm using while I'm doing
[26:53] things so that you can tell what key
[26:55] bindings I'm using without me telling
[26:56] you and also what commands they run.
[26:58] That's a actually a really useful
[26:59] package. So let's type use package
[27:04] command log mode and I'm going to use x
[27:07] controlxr e to evaluate that. And I
[27:10] can't have actually evaluated that fast.
[27:12] Let's see.
[27:18] Oh, maybe it did. Okay. So, um, we're
[27:21] going to run command log mode.
[27:24] I think there's a command for
[27:28] showing the window, but I don't remember
[27:31] which one it is right now. So, let's
[27:34] see.
[27:38] Yeah, let's
[27:42] let's do that. So, uh, one useful thing
[27:45] that you can do whenever you're trying
[27:46] to figure out how a package works, I
[27:48] mean, obviously you would go try to find
[27:49] documentation first, but um
[27:52] the the describe function or describe
[27:55] variable uh info panels that pop up will
[27:58] give you a link to the code where the um
[28:00] the thing was defined. And if you click
[28:02] on that, we can actually go into the
[28:03] code of the package, which ends up being
[28:05] really helpful for finding certain
[28:06] things. So
[28:08] if I want to toggle the command log
[28:10] buffer, it seems I need to run the CLM
[28:13] toggle command log buffer. So let's try
[28:15] that now. CLM toggle Whoops.
[28:20] toggle command log buffer. All right,
[28:22] there we are. And uh I'm going to move
[28:24] this over a little bit.
[28:27] And let's see if it actually will stick
[28:29] with us.
[28:30] Oh boy. Wow. Did I just close Emacs?
[28:33] Okay. Control- Z. Control-r Z. Don't do
[28:35] that.
[28:38] So, uh, let me get back in there because
[28:39] I think I just killed our Emacs. Or
[28:41] actually, probably what I did was
[28:42] suspend it, but I don't know how to get
[28:44] back from that. So, we'll just go load
[28:46] it again. Okay. I'm going to go back to
[28:50] our init.l file.
[28:53] And, uh, let's see. Uh, one interesting
[28:55] thing about Emacs is that it will save
[28:58] stuff that you're doing in the behind
[28:59] the scenes just in case you crash your
[29:01] Emacs or kill it like I just did. So,
[29:03] you can see down in the mini buffer
[29:05] here, it says, uh, consider running MX
[29:07] recover this file. Uh, as you can see,
[29:09] all of our stuff that we added for, uh,
[29:11] use package is gone now. So, let me try
[29:13] this. Recover this file
[29:18] and recover autosave. It tells me about
[29:21] the date and time whenever the autosave
[29:23] file was uh, created. I'm going to say
[29:24] yes because I want to recover it. So now
[29:26] we're back to where we were and I'm
[29:27] going to save that now so we don't lose
[29:28] it again. Okay. So let's it valve this
[29:30] buffer again.
[29:33] And now I'm also going to run um
[29:38] uh global command log mode
[29:42] so that we can have this in every
[29:44] buffer. And then I'll do the clm toggle
[29:46] command log buffer. Okay, here we are.
[29:48] So now if I do uh if I put my cursor on
[29:51] this and say crl hf you can see over in
[29:55] the right side hand side of the screen I
[29:57] did control hf and then it uh that's
[29:59] mapped to describe function. So this
[30:01] should be pretty helpful going forward.
[30:04] Okay so now we have uh use package set
[30:08] up. We have our basic configuration
[30:10] going where we have something that looks
[30:12] fairly decent. Um moving on from here, I
[30:15] think like the most important package
[30:18] that you can have installed um after
[30:20] just the very very minimum setup is one
[30:22] of the uh main two completion frameworks
[30:26] for Emacs and those are Helm and Ivy. Uh
[30:29] I'm not really going to go into details
[30:31] about what's different between them
[30:32] because there are a lot of similarities.
[30:33] They're just sort of slightly different
[30:35] mentality in some ways. Personally, I
[30:38] prefer Ivy because I find it to look
[30:40] more minimalistic and it sort of fits
[30:42] into my workflow better. So, this is
[30:44] what we're going to use here. However,
[30:45] if people are interested in and looking
[30:47] into Helm, I'm more than happy in a
[30:48] future stream to um to change the
[30:51] configuration to use Helm instead. So,
[30:52] we can kind of compare and contrast
[30:54] those. And also, um because Emacs is
[30:57] sort of like an open ecosystem, you can
[30:58] actually install both of them and use
[31:00] them simultaneously if you want to. Like
[31:01] if there's something that Helm does in
[31:02] one particular context you like better
[31:04] than what what Ivy does, you can use
[31:06] them both and just run them in whatever
[31:07] context is necessary. So it's not like
[31:10] you have to pick one and stick with it.
[31:11] It's not like a Vim versus Emacs thing
[31:13] where they're completely incompatible.
[31:14] No, you can do everything all at the
[31:16] same time in Emacs, which is kind of
[31:17] great. So let's get Ivy set up. Um, I'm
[31:21] going to refer to my uh existing
[31:24] configuration example again because I do
[31:27] not remember
[31:28] the uh default setup for that.
[31:33] So,
[31:35] I won't copy all this yet because uh
[31:38] it's not entirely necessary, but we will
[31:41] talk about some of these configur
[31:42] configuration options in a bit. So I'll
[31:45] paste this stuff in and um
[31:50] save the file and then I will try to run
[31:53] this.
[31:56] I'll eval the buffer and this should
[31:57] cause uh IV to be installed. So you can
[31:59] see down in the in the mini buffer there
[32:01] was some commands you can see like Ivy
[32:02] ELISP files being evaluated. So now um
[32:07] what we can do
[32:10] I'm trying to see if we already have
[32:12] some binding set up for this. Yeah.
[32:15] Okay. Good. So we don't have any binding
[32:16] set up yet. So if I if I were to to say
[32:19] uh control XR+ F to find file, I'm still
[32:22] going to get the normal um find file
[32:24] command um that is bound by default in
[32:27] Emacs. And that just gives you really
[32:29] simple completion in the bottom of the
[32:31] window here. So instead of doing that,
[32:33] what I'm going to do, I need to figure
[32:36] out how to uh
[32:39] to cancel without uh Vim mode set up. So
[32:43] what we're going to do is we're going to
[32:45] uh remap the default binding for find
[32:47] file to use uh Ivy instead. In fact, I
[32:51] think that we can just make that easier
[32:53] by I think there's a command you can run
[32:55] from console. I want to say
[32:58] that does some automatic mapping or
[33:00] remapping of things, but I do not
[33:02] remember at the moment. Ah, okay. Here's
[33:04] one thing I really want to do at the
[33:06] moment that will save me some some pain
[33:08] and suffering here. Uh, we're just going
[33:09] to take a minor digression. Um, I'm
[33:11] going to add this uh little
[33:14] snippet
[33:17] that says for a global set key, whenever
[33:20] you hit escape, it's going to run this
[33:21] keyboard escape quit command. And that's
[33:24] going to be really useful for
[33:26] um keeping me from going crazy because I
[33:30] keep hitting escape because I'm used to
[33:31] using escape all the time. So, let's say
[33:33] if we open find file and I want to get
[33:35] out of that, one way to do that, I
[33:36] think, is hittrlg.
[33:38] Um, but another way would be to hit
[33:40] escape now that we've got this bound.
[33:42] So, if I do this again, hit escape, it
[33:43] will cancel out that uh that mini buffer
[33:45] prompt, which is pretty helpful if you
[33:47] are familiar with Vim key binding. So,
[33:49] that's one thing to keep in mind. So,
[33:51] back to Ivy. Let's see. Um, I really
[33:55] want to find where that configuration is
[33:57] because I'm pretty sure I did not set
[33:59] that up myself. It must be built into
[34:01] council. I think if I
[34:04] just install council, maybe it works.
[34:08] If anybody in the chat knows, just let
[34:09] me know.
[34:13] Okay, I think that it must just be by
[34:16] default in council. So, I'm going to
[34:19] load council. So, uh the thing to know
[34:21] about uh ivy is that um the base
[34:23] functionality is contained within the
[34:25] ivy package and it gives you this sort
[34:26] of buffer completion. In fact, let me
[34:28] just show you what it looks like before
[34:29] I move any further. If I were to run ivy
[34:32] find file, I think or is it is council
[34:36] here? conscious console find file.
[34:40] Um then we get this better completion
[34:42] buffer at the bottom which um lets us
[34:45] see what files are in the current
[34:46] directory and we can also navigate the
[34:48] directories uh in a way that makes
[34:50] sense. Um that was not intended
[34:54] and like if I wanted to go to the
[34:55] readme.org I just use my arrow keys to
[34:57] go to readme.org and press enter and it
[34:59] will open that file. So that does end up
[35:01] being helpful or really helpful for
[35:03] navigating your file system quickly,
[35:05] especially if you get some custom key
[35:07] binding set up to make it more easy to
[35:08] use. So um now we're going to try to get
[35:12] the default binding set up. Uh and I'll
[35:15] show you what buffer switching looks
[35:16] like with ivy. So if I run, uh council
[35:18] switch buffer, then I can switch over to
[35:24] interesting. Okay. Um I'll try that in a
[35:26] second. So I will switch back to
[35:28] init.el. All right. So, uh, Vincent
[35:31] says, uh, that he doesn't have anything
[35:33] special for find file. He just runs IV
[35:34] mode one and it sets everything up.
[35:37] Curiously, it did not do that for me,
[35:39] but let's try running it directly. Now,
[35:41] if this works. All right. So, yes,
[35:45] that's correct. So, all we need to do is
[35:47] run ivy mode one. And by running that
[35:50] major mode, it's going to set up all the
[35:51] key bindings necessary at a global level
[35:53] for um the default EMAC key bindings for
[35:57] finding files, switching buffers, etc.
[35:58] all the sort of common things that you
[36:00] would need to do.
[36:02] So, um to to prove that for switching
[36:04] buffers, I'm going to use Oh, let's get
[36:06] the command window back. I don't know
[36:07] why that disappeared. CLM. Yeah. Now,
[36:09] see how much easier this is. MX is
[36:11] another big one. So, uh anytime you see
[36:13] one see someone talking about MX, uh the
[36:16] M in the front, let me type that out so
[36:18] you know what I'm talking about. M-X.
[36:22] So, hey, Alex. So m-x is a uh a command
[36:28] binding name, but it has special
[36:29] significance in Emacs because this is
[36:31] like the main way that you would run an
[36:33] interactive command in Emacs. So the M
[36:35] stands for meta, but actually that maps
[36:37] to the alt key in most keyboards. I
[36:39] don't really know what other keyboards
[36:40] might have that map to, but for me and
[36:42] for the majority of people that I've
[36:43] heard of, it's alt. So if I press Alt X,
[36:46] we get this list now. And this is coming
[36:48] from Ivy also. It gives us this nice uh
[36:51] view of all of our commands. And uh I
[36:55] can run
[36:57] um which one was I trying to do? Council
[36:59] something. Council switch buffer. Yeah.
[37:01] So I can see I can fuzzy match.
[37:03] Basically if I just type uh out the
[37:05] command bits with spaces in between, I
[37:07] can switch for certain things. So if I
[37:08] type council swift buff, it gives me
[37:11] everything with those uh sort of
[37:13] substrings in it. So that can be really
[37:14] helpful for finding commands that you
[37:15] forgot the name of. If you just know
[37:17] like sort of what you're looking for,
[37:18] you might be able to triangulate it.
[37:21] So, um, now we've, uh, we've used switch
[37:24] buffer and we can go up and down, go
[37:26] back to the init.l. So, at this point, I
[37:29] mean, we've got a pretty decent little
[37:30] configuration going. Uh, there's some
[37:32] other things you can do, which uh, I
[37:34] find really useful if you're sort of
[37:36] exploring a little bit uh, to try to
[37:38] make Emacs look better. You can run a
[37:40] command called uh, council um, let's
[37:43] see, I'm going to type council theme is
[37:44] council load theme. If you can see this
[37:46] down here in the command list, if I run
[37:48] that, it gives me a list of all the
[37:50] custom themes that are available. And
[37:52] you'll see that there's some Doom themes
[37:54] here because I haven't isolated my um my
[37:58] personal Emacs configuration folder with
[38:00] all my packages installed. So,
[38:02] apparently we're seeing some things that
[38:03] shouldn't be here, but uh there is a a
[38:05] small subset that are installed by
[38:07] default, and I believe Wombat is one of
[38:08] them. So, um actually, I think I like
[38:11] that theme better. So, I might just
[38:12] stick with that one. So, if I want to go
[38:14] and make that the default, I could go
[38:15] here to where oops where I set tango
[38:19] dark and then
[38:22] I can uh put this to wombat. And then in
[38:25] my configuration, this should get loaded
[38:27] by default whenever I start up from now
[38:28] on.
[38:30] Okay, so um we're doing pretty good
[38:33] here. We have just a basic
[38:34] configuration. Now, um I want to talk a
[38:36] little bit more about use package and
[38:37] how it works. Um, use package. In fact,
[38:41] we'll pull up the website. Emacs use
[38:44] package. Use package uh simplifies a lot
[38:47] of things that you need to do for
[38:48] configuring Emacs to use a package that
[38:50] you get from the package repos
[38:52] repository. uh if you were to try to
[38:54] download packages yourself from like a
[38:56] GitHub repository and then set them up,
[38:59] you would have to do a lot of extra
[39:01] coding work in your configuration file
[39:03] to uh require the package to set up its
[39:06] mode to setting key bindings, all kinds
[39:08] of stuff like that. Um with use package,
[39:11] it takes care of all that for you, which
[39:12] I find to be extremely useful. There are
[39:14] some other packages out there that will
[39:15] do things like this for you. I really
[39:17] haven't used them, but I might
[39:18] experiment with that some in this uh
[39:20] stream series because I don't know, it
[39:22] would be interesting to try them out.
[39:23] But uh use packages has been very solid
[39:25] for me for years. So, I just kind of
[39:26] stick with it. So, if you go look at
[39:28] their readme, there's quite a lot of
[39:30] stuff here. Explains how to do a lot of
[39:32] things, but the most important stuff is
[39:35] just that um you can just very simply
[39:38] just say use package with a package name
[39:41] and it will just install it for you and
[39:43] make it available. and um it does not
[39:46] load the package by default um or it
[39:50] might load the autoloads for the
[39:51] package. So an autoload is um basically
[39:54] a function that has a special signature
[39:56] on it in an Emacs list package that says
[39:59] don't load my code at all until someone
[40:01] tries to run this function and then load
[40:02] it on demand. So I think if the package
[40:05] has autoload setup, then um this really
[40:08] doesn't uh hurt your startup time
[40:09] because all it does is just try to
[40:10] install the package if it's not there
[40:11] already and then make it available to
[40:13] you. So, but the bare minimum usage is
[40:16] just just that you just have use package
[40:18] and uh the package name. Now, um you
[40:22] might see that I have something called
[40:23] diminish here. Um I probably should take
[40:26] that out so you can see what it's like
[40:27] without it. But uh diminish what that
[40:31] does is uh typically in EMAC there is a
[40:36] uh mode line
[40:38] which is this bar at the bottom of the
[40:41] screen and this gives you details about
[40:44] your um the mode that you're in, the
[40:47] file that you're editing, um the the
[40:49] line column that you're at whenever
[40:50] you're editing the file. It also says um
[40:52] what minor modes you have active and for
[40:54] some reason oh here it is. Yeah, this is
[40:56] the list of uh modes and minor modes. So
[40:59] the main major mode, I should explain
[41:01] that as well, but the main major mode is
[41:03] list interaction mode and there's a
[41:05] minor mode called LDOC installed or
[41:07] activated. So I think with uh the init
[41:10] file
[41:13] uh normally IV would
[41:17] uh have its mode. Yeah, now that I
[41:19] evaluated IV mode, it's showing up here.
[41:21] I'm not not exactly sure why this is not
[41:22] running by default on startup. I'll have
[41:24] to look into that. But um
[41:27] ah yes, that's probably why. So uh
[41:31] whenever I load up the ivy mode, we'll
[41:34] see that it adds this ivy down here. But
[41:37] if you as you start to to have a more
[41:40] Oh, thank you, uh Deepass. And now we
[41:42] want to reenable the command log. So C
[41:46] toggle command log buffer. There we are.
[41:47] Thank you.
[41:49] So, uh, as you get more in-depth in your
[41:52] Emac customization, you're probably
[41:53] going to be using a lot of minor modes,
[41:55] um, for a lot of different packages that
[41:57] are installed, and this list is going to
[41:58] get a lot longer, and it's going to take
[42:00] up more of your screen space, and it's
[42:02] going to be noisy. So, what I like to do
[42:04] on certain packages is to diminish the
[42:07] uh, mode, which does some stuff behind
[42:09] the scenes so that Emacs will not show
[42:11] the mode name in this list. Um, I don't
[42:14] really know like if people think that's
[42:15] a bad idea, but for me, I like to keep a
[42:17] very minimal view so that I don't have a
[42:20] lot of things distracting me whenever
[42:21] I'm using my editor or when I'm in my
[42:22] environment. So, I try to diminish
[42:24] things that aren't necessary. So, this
[42:26] is why I would add this diminish part
[42:27] here. It just keeps that ivy out of uh
[42:31] the uh uh the mode line. Also you can
[42:35] see that there's this bind section and
[42:37] this is super handy because otherwise
[42:39] you would have to do a lot of like uh
[42:41] define key or there's a lot of lot of
[42:43] ways to uh bind key bindings in Emacs
[42:45] but this happens to be a very
[42:47] straightforward way to do it which I
[42:49] find to be very nice. So um you'll have
[42:52] to look at the documentation for for
[42:53] bind because there's a lot of things it
[42:54] can do but at the at the top level what
[42:56] you can do is just say for the command-
[43:00] s or command s keybinding I want you to
[43:02] call swiper. So if I was to hit control
[43:05] S right now, did I say command control
[43:07] S? Uh now that calls up swiper.
[43:11] Um are you saying Alex? Are you saying
[43:13] it's difficult to read right now? Alex
[43:16] says that the bottom of the Emacs window
[43:18] is difficult to read.
[43:20] So uh this binding was set up whenever
[43:24] use package loaded um Ivy. And there's
[43:28] also this idea of uh key bindings that
[43:31] are specific to certain modes like a
[43:33] major mode or a minor mode which right
[43:35] now you see there's like the IV mini
[43:36] buffer map. Um
[43:40] that is like a key binding that's only
[43:42] active for a very particular mode. So,
[43:44] one thing I like to do for ivy that
[43:47] makes a lot more uh convenient for me is
[43:49] that um whenever iive is displayed in
[43:53] the mini buffer, whenever we have that
[43:54] sort of selector list, I like to use
[43:56] controll jlrl k to select the next and
[43:59] previous line so that I don't have to
[44:00] leave my home row of keys. Um, the way
[44:02] that I have my key binding set up in my
[44:04] Linux distribution is that I make caps
[44:07] lock work as a control key so that I
[44:10] have my hand on the home row all the
[44:11] time and I can use my pinky on caps lock
[44:14] to do control instead of like bending my
[44:15] finger down there. Uh, you've probably
[44:17] heard a lot of people talk about uh
[44:18] Emacs pinky because if you have to keep
[44:20] hitting control all day long to do all
[44:22] these key chords and whatnot, uh, it
[44:24] could be really taxing on your finger.
[44:26] Uh if you do that simple little
[44:27] keybinding switch where you replace caps
[44:29] lock with control, it makes your life a
[44:31] whole lot easier in EMAC. So I highly
[44:33] recommend doing that. It is possible to
[44:34] do that across Linux, Mac OS, and
[44:36] Windows. So uh at some point if people
[44:39] want to know how to do that, I can add
[44:41] some instructions to the the read me of
[44:43] this repo so that you can uh you can see
[44:45] that. So Alex says that the bottom line
[44:48] is kind of half cut off.
[44:51] Let's see if I can fix that if possible.
[44:56] Does anybody else notice that where the
[44:57] the bottom line is cut off of the screen
[45:00] capture?
[45:03] Can't tell.
[45:05] Yeah.
[45:09] Ah, okay. So, it's a YouTube problem.
[45:11] All right. Anyway, back to the story.
[45:14] So, um,
[45:17] so what we're going to do is I'm going
[45:18] to show you what it looks like with Ivy.
[45:19] And I think that the command log window
[45:21] here should uh be able to to give us
[45:23] that information. I I just hit escape
[45:24] and it disappeared. That's not cool.
[45:26] Let's Let's pull that back up again. CLM
[45:28] toggle command log buffer. Apparently
[45:30] escape kills it. I need to find a way to
[45:31] make that not happen. So, thanks Bruno.
[45:36] All right. So, I'm going to pull up uh
[45:38] the console switch buffer command. Oh,
[45:43] actually I can do it here. So, now that
[45:45] I'm in um this list, I can hittrl jrl k
[45:48] to go up and down. So, I don't have to
[45:49] use the arrow keys anymore to select
[45:51] these. I can just use control jrl k and
[45:54] uh that helps me to navigate these
[45:56] without leaving the home row. And um if
[45:59] you use a computer a lot all day, if
[46:01] you're a programmer and you're typing on
[46:03] the computer all day, the best thing you
[46:04] can do for your hands to not get super
[46:06] tired is to stay in one place and not
[46:08] jump around a lot or not contort your
[46:10] fingers to do key bindings. Um and also
[46:12] try not to reach through the mouse all
[46:14] the time either or to the touchpad. So
[46:16] um if you can avoid that as much as
[46:18] possible which Emacs does enable in in
[46:20] large part you should try to do that
[46:22] because uh it will save your hands a
[46:24] lot.
[46:25] So um
[46:28] we we see now that we can do that.
[46:30] Unfortunately this uh command window is
[46:32] not showing that probably because it's
[46:33] in the mini buffer. Um unfortunately
[46:35] that's the case. But let's this thing
[46:38] keeps popping away. This is what happens
[46:40] whenever you just get like so used to uh
[46:42] to Vim key bindings is that you just hit
[46:44] escape all day long just unconsciously
[46:46] just to clear out whatever you're doing
[46:47] and then it causes problems whenever you
[46:49] don't want it to. All right. So, um I
[46:52] mean I think that we've gotten to a
[46:54] pretty good place with this today. Um
[46:57] so moving forward, what we what would we
[46:59] want to do? So, uh one big thing we can
[47:03] do to make this look better is to set
[47:05] our mode line um to something more
[47:07] appealing. And if you see what I have in
[47:09] my um
[47:12] setup, I have this nice more minimal
[47:15] looking mode line that has a little bit
[47:16] of icons and some, you know, nice fonts
[47:18] and colors and whatnot. That's Doom mode
[47:20] line. So, if you use Doom Emacs, you
[47:22] probably are familiar with this already.
[47:23] If you've seen um Oh, maybe maybe you're
[47:27] right. Let's try that real quick. Global
[47:29] command log. So, um Deepassen says or
[47:33] Deepassen, I'm sorry if I'm pronouncing
[47:34] your username wrong. Uh it says that uh
[47:37] probably global command log mode needs
[47:38] to be run before the mini buffer
[47:40] commands will show up. And I believe you
[47:42] are correct. So if I go Yep, there we
[47:44] are. So I'm hitting control J in the
[47:46] list and control K and it's going up and
[47:49] down. So very astute observation. I
[47:52] appreciate you telling me that. So um
[47:54] going back to the mode line discussion.
[47:57] Um, yeah, I I find this to be very um
[48:01] minimal, giving me only the information
[48:03] I need to be doing the work that I'm
[48:05] doing. Um, I think the default mode line
[48:07] in Emacs is quite cluttered and um kind
[48:12] of like really just looks old. I mean,
[48:14] if it's all text, characters, and stuff
[48:16] and uh gives too much information. So
[48:19] for your ability to focus and also your
[48:22] sort of a aesthetic pleasure, I guess
[48:24] you could say. Uh having a more minimal
[48:25] mode line that has a nicer style can be
[48:28] can go a long way to making you feel
[48:29] more at home in Emacs. So uh we can try
[48:32] real quick to see if uh Doom mode line
[48:34] is easy to set up in this case. So I'm
[48:36] going to just going to go to the Doom
[48:37] mode line um GitHub repo and see what
[48:40] happens there because I think that the
[48:43] default configuration is pretty good and
[48:45] integrates with a lot of packages that
[48:46] you might use. So, it's a good place to
[48:48] start if you wanted to have a nicer
[48:50] looking modeline. They have a lot of
[48:52] screenshots for what do Modeline can do,
[48:54] which is nice. Um,
[48:58] so, uh, init. Yes. All right. So, we're
[49:00] going to copy just this little snippet
[49:02] here
[49:04] and, um, throw it into our configuration
[49:08] file.
[49:10] And then I'm going to I'm going to
[49:11] execute that with controlx control E.
[49:16] All right. And basically right away it,
[49:19] uh, configures itself to look much
[49:21] nicer. So, um, the one thing I I can say
[49:24] about this is I find the height of the
[49:26] mode line to be a little bit tall for my
[49:28] pleasure. Uh, to start with, um, there
[49:31] is a variable you can use to configure
[49:34] the height. I keep having to open this
[49:36] thing again. And, um,
[49:40] I've had sort of varying success in
[49:43] using it. I mean, obviously, you can see
[49:44] my mode line is not that tall. So um I
[49:47] think there there's a little bit of
[49:49] combination of setting the mode line
[49:50] height plus the uh the font size for the
[49:53] mode line um can help you to manage that
[49:55] size. Let's see what it says here. Size
[49:58] or height. Okay, customizable mode line
[50:01] height. So if we were to set um I think
[50:03] that it's configure. So config. This is
[50:06] another thing in there there are two
[50:08] things for use package I'll describe
[50:09] right quick whenever we do this. But let
[50:10] me just get this uh add added really
[50:12] quickly. Um, and in fact, let me look at
[50:16] my own configuration.
[50:20] Uh, emac.org.
[50:22] So, mode line height.
[50:30] Okay. 15. I have mine set to it's in
[50:32] custom. All right. Cool. It's like this.
[50:35] All right. So, um, I'm going to paste
[50:37] that in
[50:40] and then we'll finish that out. Whoops.
[50:46] All right. Cool.
[50:50] Unbalanced parenthesis. This is what
[50:52] happens whenever you paste it in
[50:54] incorrectly. Also, we need something
[50:55] that will show us the the parenthesis
[50:57] balance.
[50:58] Void function doom mode line height.
[51:01] Really? Oh, okay. I need to have an
[51:03] extra um
[51:06] parenthesis around. This is why it was
[51:08] giving me problems.
[51:12] That's interesting. Let me see what did
[51:13] I do wrong here. Custom that's right.
[51:15] Okay, so config is wrong.
[51:20] We will try running this one more time.
[51:23] Okay, so uh I think that I need to
[51:28] restart Doom mode line for that to work.
[51:32] And it's hard to tell whether it
[51:34] actually did anything, but sometimes it
[51:36] you actually have to go to a different
[51:37] buffer before you will see the effect of
[51:41] doing that. So if I were to go to
[51:43] another file,
[51:46] uh let's say I go to package.json file.
[51:49] Okay, it still seems to be fairly tall,
[51:51] but um suffice it to say um there is
[51:53] some configuration capability there. Um
[51:56] and we won't worry too much about that
[51:57] right now. I mean, I think it looks
[51:59] pretty good as it stands. So uh one
[52:01] thing that you can see here is that we
[52:02] actually have an icon for for Node.js or
[52:04] for npm whenever we open a package.json
[52:06] file. So that's just one of the nice
[52:08] little nicities that um that Doom
[52:10] modeine can give you.
[52:12] So I hope that uh with this little intro
[52:16] I have convinced you that uh writing
[52:18] your own Emac configuration is not that
[52:20] hard and it doesn't take much code and
[52:23] um you can get something that looks
[52:24] really nice uh very quickly. Um this
[52:27] obviously is not organized very well.
[52:29] It's kind looks kind of dirty, but
[52:31] there's a lot of things we can do to fix
[52:32] that up um going forward. So uh we will
[52:35] look into that in future streams. Um I
[52:38] think maybe next time we will try to set
[52:40] up some other uh packages possibly like
[52:43] maggit or um other things that I find to
[52:47] be pretty useful. Um,
[52:50] and please definitely give suggestions
[52:52] if you have other packages you would
[52:53] like to talk about in the future
[52:55] streams. Like either you can give them
[52:57] in the chat or uh ideally in the
[53:00] comments of the video after the stream
[53:02] is done so that we kind of have a
[53:04] history of those because the chat kind
[53:05] of disappears after the stream is gone.
[53:07] But um yeah, for now I think that we can
[53:09] call that finished for this stream. if
[53:12] you want to see the contents of this
[53:14] file. Um, actually I will show you one
[53:17] thing real quick as a little little
[53:19] bonus at the end. I'm going to make a
[53:21] commit of these changes. I'll just back
[53:23] out of this Emacs right now and go back
[53:26] to my own. Let's not save that one. Yes.
[53:28] Exit. Okay. So,
[53:32] I will open up the init.
[53:34] So, this is the actual same file. And uh
[53:36] I'm going to use my keybinding to pull
[53:38] up uh uh mitig status.
[53:42] And uh what this does
[53:45] is it gives us this buffer that tells us
[53:48] about uh the current status of our git
[53:49] repository. And I'll show you what
[53:51] repository that is in a second. Um we
[53:53] have our unttracked files here and I
[53:54] want to commit my init. So I'm going to
[53:56] uh use my keybinding for that. And
[53:59] actually I can pull up a command a nicer
[54:01] looking command log here. Um, since I've
[54:03] set my stuff up correctly. Uh, command
[54:06] log window.
[54:09] Yeah. Okay. On this computer, it's not
[54:10] working. It works on a different
[54:11] computer. We'll do that another time.
[54:13] So, I'm going to stage this file for for
[54:15] commit. And you can actually see that we
[54:16] have all the contents of the file here.
[54:18] Uh, also it helps helpfully shows me
[54:20] that I have some uh errant white space
[54:22] at the end of that line. So, I'm going
[54:24] to get get rid of that. And uh now I'm
[54:27] going to make a commit by hitting CC
[54:30] and initial commit of init.el.
[54:34] And I'm going to hit control ctrl + c to
[54:36] finish that commit. I'm going to hit
[54:38] capital p then p to push it to the repo.
[54:41] And then I'll put in my passphrase
[54:44] um to do ssh o against the repo.
[54:48] And now it's finished. So we can go over
[54:51] to the repo page. Uh, I've got this
[54:53] called,
[54:54] it looks like it's called run emacs. Um,
[54:57] which if you've ever used Emacs on
[55:00] Windows, you've probably seen the run
[55:02] emacs uh command. But, uh, a co-orker of
[55:05] mine whenever he downloaded Emacs. Hi,
[55:06] Chris. Uh, he saw run emacs and he says,
[55:09] "Wow, this comes with RuneMemax." So,
[55:11] uh, we're going to call our custom
[55:12] configuration runemax. Just as an homage
[55:14] to my co-orker Chris. Um, so now I'm
[55:17] going to reload this page and you'll see
[55:18] that init. here. All the stuff that we
[55:21] worked on in this stream is available.
[55:23] So if you want to go and take that and
[55:24] start hacking on your own configuration,
[55:26] please feel free. Um this is another
[55:29] place where you could file issues if you
[55:30] wanted to like ask questions or uh give
[55:33] feedback or you know like request
[55:36] certain packages to be uh given
[55:38] demonstrations of etc. So uh please do
[55:41] feel free to like leave comment on the
[55:42] video or in this repo if you want to see
[55:44] more things in the future. So, um, any
[55:48] final questions from the audience here
[55:49] before we end the stream today? Uh, by
[55:52] the way, thanks a lot for everyone
[55:53] showing up. It's really cool. I think
[55:55] this is the highest viewer count I've
[55:56] had on the stream yet. So, it gives me a
[55:58] lot of, uh, confidence that Emacs is the
[56:00] way to go, at least in the short term,
[56:01] on the streaming front.
[56:05] I'll give people a couple seconds just
[56:06] to ask any questions if uh, they have
[56:09] any.
[56:15] Also, uh if you want to see a more
[56:17] complete system configuration that uh
[56:20] goes far more in depth on Emacs as a
[56:24] desktop environment and window manager,
[56:27] uh check out my dotfiles repo. It's at
[56:29] uh github.com/davywill.files.
[56:32] And if you go down to the readme here, I
[56:35] kind of explain my principles and stuff.
[56:38] kind of lame but uh it links to my
[56:40] different configuration files for so how
[56:42] I configure Emacs, how I configure my
[56:44] desktop environment and how I configure
[56:45] uh my Linux distributions uh all using
[56:48] Emacs all using org mode. So if you were
[56:50] to go to my desktop environment uh
[56:52] configuration, you can see that uh I
[56:54] have a whole lot of stuff here that um
[56:57] configures both Emacs packages and also
[57:00] things like polyar and uh dunst and
[57:02] other programs that kind of put this
[57:04] whole desktop environment together. And
[57:06] all these configuration bits actually
[57:08] are used in my system. They just get
[57:09] written out by org mode whenever I save
[57:11] changes to the file. So this this file
[57:14] is like my source of truth um whenever I
[57:18] am uh changing my system configuration
[57:20] and then the sort of files that get
[57:21] created by that are sort of ancillary
[57:23] and I still check them in but uh but
[57:26] they they aren't really the ones that I
[57:27] edited. I edit my org mode files to
[57:29] configure all my systems. So that's
[57:30] another interesting topic to talk about
[57:32] on another day. Uh, Bruno asks, "Maybe
[57:35] demo install projectile." Yes, that's a
[57:37] great point. I should do that probably
[57:39] on one of the next couple streams. So,
[57:41] uh, yeah, we we will definitely talk
[57:42] about projectile. If you do coding with,
[57:45] um, git repositories of various
[57:47] different types of languages and
[57:48] whatnot, you definitely want to use
[57:50] projectile.
[57:52] Okay. Well, I think I've had your
[57:53] attention for about an hour now, so I'm
[57:55] going to go ahead and call it here. But,
[57:56] uh, thank you again so much for joining
[57:58] us today. Hope to see you at the next
[57:59] stream. Um, I'm gonna target possibly
[58:02] Monday, possibly Wednesday for the
[58:04] stream. So, just keep a lookout uh for
[58:06] that. Uh, subscribe to the channel if
[58:07] you want to be notified whenever uh new
[58:10] streams are scheduled or started on the
[58:12] channel. If you hit subscribe, also hit
[58:14] the bell as well because sometimes
[58:15] YouTube doesn't send out the
[58:16] notifications. I don't know why it does
[58:18] that, but just make sure you hit the
[58:19] bell in case you want to be notified
[58:20] whenever the new live streams are
[58:22] coming. But, uh, anyway, thanks a lot,
[58:24] folks. Uh, we'll see you next time.
[58:25] Happy hacking.