Skip to content

channingkuo/skemacs

Repository files navigation

Skemacs Configuration

Table of Contents

Overview

Skemacs is a modular, high-performance Emacs configuration framework. Key features:

  • Independent modules: Each module is fully self-contained (package declaration + config + keybindings)
  • Startup timing: Every module’s load time is recorded; view with M-x skemacs/show-load-times
  • Error isolation: A single module failure won’t break others (condition-case wrapped)
  • Flexible management: Enable/disable modules via config lists, no need to delete files
  • Dynamic splash screen: Real-time loading progress displayed at startup; stats summary above the table, error details (or “no error”) below
  • Smart startup mode: emacs / emacs dir shows splash and waits for Enter; emacs file skips the wait and opens the file directly
  • Deferred package init: package-initialize is deferred until first package install for fast startup
  • Centralized prefix keys: Prefix keys defined in core-keybindings.el, modules bind under them
  • use-package :bind: All custom bindings viewable via M-x describe-personal-keybindings

Architecture

Directory Structure

~/.emacs.d/
├── early-init.el            # GC optimization + native-comp + disable package autoload
├── init.el                  # Entry point (custom.el → core → splash → modules → Enter/file)
├── core/                    # Core infrastructure (no third-party dependencies)
│   ├── core-load-paths.el   # Path constants + load-path setup
│   ├── core-module.el       # Module loading system (timing + error isolation + splash)
│   ├── core-packages.el     # use-package + package.el (deferred initialization)
│   ├── core-ui.el           # Basic UI (toolbar/menubar/scrollbar etc.)
│   ├── core-editor.el       # Editing behavior (parens, selection, folding etc.)
│   ├── core-funcs.el        # Utility functions (navigation, window, clipboard)
│   └── core-keybindings.el  # Prefix key definitions + global keybindings
├── modules/                 # Feature modules (each file is self-contained)
│   ├── init-theme.el        # Theme management (modus + doom + ef + catppuccin)
│   ├── init-completion.el   # Minibuffer completion (Vertico + Orderless + Marginalia + Consult + Embark)
│   ├── init-dired.el        # Dired enhancements (omit mode)
│   ├── init-lsp.el          # LSP configuration (lsp-bridge)
│   ├── init-recentf.el      # Recent files + ibuffer
│   ├── init-highlight-symbol.el # Symbol highlighting
│   ├── init-hydra.el        # Operation panels (hydra)
│   ├── init-avy.el          # Quick jump (avy: char/word/line jump)
│   ├── init-ace-window.el   # Window quick-jump (ace-window)
│   ├── init-mwim.el         # Smart line beginning/end (mwim)
│   ├── init-project.el      # Project management (built-in project.el)
│   ├── init-treemacs.el     # File tree sidebar (treemacs)
│   ├── init-git.el          # Git integration (magit + diff-hl)
│   ├── init-undo-tree.el    # Undo/redo tree with hydra panel
│   ├── init-multiple-cursors.el # Multi-cursor editing with hydra panel
│   ├── init-rainbow-delimiters.el # Rainbow parentheses
│   ├── init-vterm.el        # Terminal emulator (vterm)
│   ├── init-web.el          # Web development (web-mode)
│   ├── init-which-key.el    # Key discovery (which-key)
│   ├── init-agent-shell.el  # AI Agent integration (agent-shell + ACP)
│   ├── init-claude-code-ide.el # Claude Code IDE integration (MCP)
│   ├── init-readonly.el     # Default read-only browsing (view-mode)
│   └── init-tramp.el       # Remote file access via TRAMP (SSH) [disabled]
├── themes/                  # Local theme files (modus-themes, loaded via custom-theme-load-path)
│   ├── modus-themes.el      # Modus themes core library
│   ├── modus-operandi-tinted-theme.el  # Light theme (warm tinted background)
│   └── modus-vivendi-tritanopia-theme.el # Dark theme (black background)
├── lsp-bridge-langserver/   # LSP server override configs (vtsls replaces typescript-language-server)
├── banners/                 # Startup banner files
├── setup-lsp.sh             # LSP environment setup script (Node.js + Python + lsp-bridge)
├── setup-agents.sh          # ACP agent adapter setup script (Claude Code + Cursor + Gemini)
└── custom.el                # Emacs custom-file + module control (skemacs-disabled-modules etc.)

Startup Flow

The startup flow adapts based on how Emacs is invoked:

# Normal mode (emacs / emacs . / emacs ~/dir)
early-init.el → init.el → custom.el → splash → core/*.el → modules/*.el → Press Enter → dired

# File mode (emacs file.txt / emacs -nw file.txt)
early-init.el → init.el → custom.el → splash → core/*.el → modules/*.el → open file (no wait)
  1. early-init.el — Set GC threshold to 800MB, disable package autoload, hide UI elements
  2. init.el — Bootstrap core/ into load-path, require core-load-paths and core-module
  3. custom.el — Load user customizations (skemacs-disabled-modules etc.) before module loading
  4. skemacs--splash-init — Display banner, stats placeholder (“Loading modules…”), and table header in *skemacs* buffer
  5. skemacs-load-core-module — Load remaining core files (each line appears in real-time)
  6. skemacs-load-all-modules — Scan modules/ directory, load each (real-time display)
  7. emacs-startup-hook — Restore GC to 16MB, finalize splash screen, detect startup mode:
    • Normal mode (no file argument): wait for Enter, then dismiss splash and open dired
    • File mode (file argument detected): skip wait, dismiss splash and switch to file buffer

Module System

The module system is provided by core/core-module.el:

Variable / FunctionDescription
skemacs-module-listModule list to load; nil = auto-scan modules/
skemacs-disabled-modulesDisabled module list (highest priority)
skemacs-load-timesTiming data (("name" . seconds) ...)
skemacs-module-errorsError records (("name" . "message") ...)
skemacs-load-moduleLoad a single module (condition-case isolation)
skemacs-load-all-modulesLoad all enabled modules
skemacs--started-with-file-pDetect if Emacs was started with a file argument
skemacs/show-load-timesInteractive command: show formatted timing report

Timing report example (M-x skemacs/show-load-times):

Startup Timing Report
────────────────────────────────────────────────────────
  Module                             Time  Status
────────────────────────────────────────────────────────
  core-packages                       59ms  OK
  core-ui                              6ms  OK
  core-editor                          4ms  OK
  core-funcs                         589us  OK
  core-keybindings                   839us  OK
────────────────────────────────────────────────────────
  Total: 71ms    | 5 loaded | 0 disabled | 0 errors

Key Bindings Reference

Prefix Keys

Prefix keys are defined in core-keybindings.el. Modules bind commands under these prefixes:

PrefixKeymap NamePurpose
C-jskemacs-prefixMain prefix
C-j oskemacs-org-prefixOrg-related
C-j pskemacs-project-prefixProject mgmt
C-j sskemacs-search-prefixSearch (Consult)
C-j fskemacs-filetree-prefixFile tree (Treemacs)
C-j gskemacs-git-prefixGit (Magit)
C-j jskemacs-jump-prefixJump (Avy)
C-j vskemacs-terminal-prefixTerminal (Vterm)
C-j askemacs-agent-prefixAI Agent (agent-shell)
C-j cskemacs-claude-prefixClaude Code IDE (MCP)
C-j Tskemacs-theme-prefixTheme management
C-j l(lsp-bridge bindings)LSP commands
C-j u(hydra-undo-tree)Undo tree panel
C-j m(multiple-cursors)Multi-cursor commands
C-j h(highlight-symbol)Symbol highlight
C-x wskemacs-window-prefixWindow ops
C-x bskemacs-buffer-prefixBuffer ops

Global Key Bindings

These keybindings depend on no third-party packages, defined in core-keybindings.el:

Navigation

KeyFunctionDescription
M-nskemacs/next-ten-linesMove 10 lines down
M-pskemacs/previous-ten-linesMove 10 lines up
C-opop-global-markJump back to prev mark
M-/dabbrev-expandText completion

Editing

KeyFunctionDescription
C-j C-kkill-whole-lineKill entire line
C-c C-yskemacs/copy-to-clipboardCopy to clipboard

Window Management

KeyFunctionDescription
C-x oace-windowQuick jump window
C-x w hwindmove-leftMove to left window
C-x w jwindmove-downMove to below window
C-x w kwindmove-upMove to above window
C-x w lwindmove-rightMove to right window
C-x w ssplit-window-belowSplit horizontally
C-x w vsplit-window-rightSplit vertically
C-x w Sskemacs/split-window-horizontallySplit & switch down
C-x w Vskemacs/split-window-verticallySplit & switch right
C-x w rhydra-window-resize/bodyWindow resize panel

In the resize panel (C-x w r), press keys repeatedly to adjust window size:

KeyFunctionDescription
hskemacs/shrink-window-horizontallyShrink horizontally
lskemacs/enlarge-window-horizontallyEnlarge horizontally
jskemacs/shrink-windowShrink vertically
kskemacs/enlarge-windowEnlarge vertically
qquitExit resize panel

Buffer Management (C-x b prefix)

KeyFunctionDescription
C-x b bconsult-buffer ¹Switch buffer (+ recentf + bookmark)
C-x b nnext-bufferNext buffer
C-x b pprevious-bufferPrevious buffer
C-x b kkill-bufferKill buffer
C-x b rrecentf-openRecent files (completing-read)
C-x b Rrecentf-open-filesRecent files (list window)
C-x b libufferBuffer list (ibuffer)

¹ Enhanced by init-completion.el; falls back to switch-to-buffer if module disabled.

Config & Tools

KeyFunctionDescription
C-j ndisplay-line-numbers-modeToggle line numbers
C-j rskemacs/toggle-line-numbers-typeToggle relative/absolute
C-j tskemacs/show-load-timesShow load times

Completion & Search Bindings

Provided by init-completion.el (Vertico + Orderless + Marginalia + Consult + Embark).

Minibuffer Completion

M-x and all completing-read prompts are automatically enhanced:

ComponentEffect
VerticoVertical candidate list in minibuffer
OrderlessSpace-separated fuzzy matching (e.g. fn js → find-file-js)
MarginaliaAnnotations next to candidates (docstring, type, keybinding)
SavehistPersist minibuffer history across sessions

Search & Navigation (C-j s prefix)

KeyFunctionDescription
C-j s sconsult-lineSearch lines in current buffer
C-j s rconsult-ripgrepRipgrep search in project
C-j s fconsult-findFind file by name
C-j s gconsult-grepGrep search
C-j s oconsult-outlineJump to heading/outline
C-j s iconsult-imenuJump to symbol (imenu)
C-j s Iconsult-imenu-multiJump to symbol (cross-buffer)
C-j s bconsult-bookmarkOpen bookmark

Standard Emacs Prefix Bindings (M-g / M-s)

The same commands are also available under Emacs standard prefixes:

KeyFunctionDescription
M-g gconsult-goto-lineGo to line number
M-g oconsult-outlineJump to outline heading
M-g iconsult-imenuJump to symbol
M-g Iconsult-imenu-multiJump to symbol (cross-buffer)
M-s lconsult-lineSearch lines in buffer
M-s rconsult-ripgrepRipgrep search in project
M-s fconsult-findFind file by name
M-s gconsult-grepGrep search

Embark (Context Actions)

KeyFunctionDescription
C-.embark-actContext menu on current candidate
C-;embark-dwimExecute default action
C-h Bembark-bindingsShow all embark key bindings
M-Amarginalia-cycleCycle annotation detail (minibuffer)

Vertico Directory Navigation (in find-file etc.)

KeyFunctionDescription
RETvertico-directory-enterEnter directory / open file
DELvertico-directory-delete-charDelete path component
M-DELvertico-directory-delete-wordDelete word in path

Mwim Bindings

Provided by init-mwim.el. Smart C-a / C-e that cycles between code boundaries and line boundaries.

KeyFunctionDescription
C-amwim-beginning1st press: beginning of code; 2nd press: line start
C-emwim-end1st press: end of code (before comments); 2nd press: line end

Highlight Symbol Bindings

Provided by init-highlight-symbol.el. Automatically highlights all occurrences of the symbol under cursor in prog-mode buffers.

KeyFunctionDescription
C-j h nhighlight-symbol-nextJump to next same symbol
C-j h phighlight-symbol-prevJump to previous same symbol
C-j h hhighlight-symbol-at-pointToggle highlight current symbol
C-j h rhighlight-symbol-query-replaceRename symbol in buffer

Theme Bindings

Provided by init-theme.el. Manages themes with system dark/light mode auto-detection.

KeyFunctionDescription
C-j T Tskemacs/switch-themeChoose theme (completing-read)
C-j T nskemacs/cycle-themeCycle to next theme in list
C-j T tskemacs/toggle-light-darkToggle between light and dark theme

Undo Tree Bindings

Provided by init-undo-tree.el. Replaces Emacs default linear undo with a tree-based undo system. Uses hydra panel for quick undo/redo operations.

KeyFunctionDescription
C-j uhydra-undo-tree/bodyOpen undo tree hydra panel

In the undo tree panel (C-j u):

KeyFunctionDescription
pundo-tree-undoUndo
nundo-tree-redoRedo
vundo-tree-visualizeVisualize undo tree
qquitExit panel

Project Management Bindings

Provided by init-project.el. Uses Emacs built-in project.el (28+) for project management based on version control (Git etc.) root detection.

KeyFunctionDescription
C-j p pproject-switch-projectSwitch to another project
C-j p fproject-find-fileFind file in project
C-j p gproject-find-regexpRegexp search in project
C-j p dproject-diredDired at project root
C-j p bproject-switch-to-bufferSwitch buffer within project
C-j p cproject-compileCompile in project
C-j p eproject-eshellEshell at project root
C-j p kproject-kill-buffersKill all project buffers
C-j p !project-shell-commandShell command at project root
C-j p &project-async-shell-commandAsync shell command

Treemacs Bindings

Provided by init-treemacs.el. File tree sidebar for project navigation.

KeyFunctionDescription
C-j f ttreemacsToggle treemacs sidebar
C-j f streemacs-find-fileLocate current file in tree
C-j f dtreemacs-select-directorySelect directory
C-j f atreemacs-add-project-to-workspaceAdd project to workspace

Avy Bindings

Provided by init-avy.el. Fast cursor jumping to any visible position via avy.

Quick Access

KeyFunctionDescription
C-;avy-goto-word-1Type 1 char, jump to word beginning
C-'avy-goto-char-2Type 2 chars, jump to match
M-g gavy-goto-lineJump to any visible line
M-g wavy-goto-word-1Jump to word beginning

Jump Prefix (C-j j)

KeyFunctionDescription
C-j j cavy-goto-charJump to any character
C-j j wavy-goto-word-1Jump to word beginning
C-j j lavy-goto-lineJump to any line
C-j j tavy-goto-char-timerTimed char search (0.5s timeout)

Git Bindings

Provided by init-git.el. Full Git integration via Magit.

KeyFunctionDescription
C-j g gmagit-statusOpen Magit status panel
C-j g lmagit-log-currentCurrent branch log
C-j g bmagit-blame-additionFile blame (line-by-line)
C-j g dmagit-diff-buffer-fileDiff current file
C-j g fmagit-log-buffer-fileLog for current file
C-j g smagit-stage-fileStage current file
C-j g umagit-unstage-fileUnstage current file

Multiple Cursors Bindings

Provided by init-multiple-cursors.el. Multi-cursor editing with C-j m prefix.

KeyFunctionDescription
C-j m nmc/mark-next-like-thisMark next occurrence
C-j m pmc/mark-previous-like-thisMark previous occurrence
C-j m amc/mark-all-like-thisMark all occurrences
C-j m lmc/edit-linesCursor on each selected line
C-j m smc/mark-all-in-region-regexpMark by regexp in region
C-j m Nmc/skip-to-next-like-thisSkip current, mark next
C-j m Pmc/skip-to-previous-like-thisSkip current, mark previous
C-j m 0mc/insert-numbersInsert incremental numbers
C-j m \vertmc/vertical-alignAlign cursors by input char
C-S-<mouse-1>mc/toggle-cursor-on-clickToggle cursor at click point

Vterm Bindings

Provided by init-vterm.el. High-performance terminal emulator via vterm (based on libvterm C library).

KeyFunctionDescription
C-j v vvtermOpen new vterm terminal
C-j v tskemacs/vterm-toggleToggle vterm (switch to existing or create new)
C-j v ovterm-other-windowOpen vterm in another window

AI Agent Bindings

Provided by init-agent-shell.el. AI coding agent integration via agent-shell powered by ACP (Agent Client Protocol).

KeyFunctionDescription
C-j a aagent-shellStart/reuse any Agent
C-j a cagent-shell-anthropic-start-claude-codeStart Claude Code
C-j a uagent-shell-cursor-start-agentStart Cursor Agent
C-j a gagent-shell-google-start-geminiStart Gemini CLI
C-j a nagent-shell-new-shellNew Agent Shell
C-j a iagent-shell-insert-fileInsert file as context

Shell-internal keybindings:

KeyFunctionDescription
RETsubmit promptSend prompt to agent
M-Jinsert newlineNewline without sending
C-c C-cagent-shell-interruptInterrupt current operation
TABnext itemNavigate to next element
S-TABprevious itemNavigate to previous element

Claude Code IDE Bindings

Provided by init-claude-code-ide.el. Native Claude Code CLI integration via claude-code-ide, powered by MCP (Model Context Protocol). Creates a bidirectional bridge between Claude and Emacs, enabling Claude to access LSP, xref, tree-sitter, and other Emacs capabilities.

KeyFunctionDescription
C-j c cclaude-code-ideStart/switch Claude Code
C-j c mclaude-code-ide-menuOpen command menu (transient)
C-j c pclaude-code-ide-send-promptSend prompt from minibuffer
C-j c rclaude-code-ide-resumeResume previous session
C-j c kclaude-code-ide-continueContinue most recent conversation
C-j c sclaude-code-ide-list-sessionsList all active sessions
C-j c tclaude-code-ide-toggleToggle window visibility
C-j c Tclaude-code-ide-toggle-recentToggle most recent (global)
C-j c @claude-code-ide-insert-at-mentionedMention selected text
C-j c qclaude-code-ide-stopStop Claude Code

Terminal-internal keybindings (in Claude Code vterm buffer):

KeyFunctionDescription
M-RETclaude-code-ide-insert-newlineInsert newline in prompt
C-\claude-code-ide-send-escapeSend escape key

Readonly / View-Mode Bindings

Provided by init-readonly.el. All files opened via find-file enter view-mode (read-only browsing) by default. Press C-x C-q to exit read-only and start editing.

Navigation

KeyFunctionDescription
SPCscroll downScroll one page down
DELscroll upScroll one page up
d / uhalf-page down/upScroll half page
n / pnext/previous lineMove by line
<beginning-of-bufferJump to buffer start
>end-of-bufferJump to buffer end

Search

KeyFunctionDescription
sisearch-forwardIncremental search
risearch-backwardReverse incremental search
/ or \regex searchRegular expression search

Exit

KeyFunctionDescription
qquitExit view-mode and close buffer
eexitExit view-mode, keep buffer
C-x C-qread-only-modeExit read-only, enter editing mode

Org Mode Bindings

KeyFunctionDescription
C-j o oskemacs/open-org-directoryOpen ~/org dir
C-j o aorg-agendaOrg Agenda
C-j o corg-captureOrg Capture
C-j o lorg-store-linkStore link
C-j o iorg-insert-linkInsert link
C-j o C-piimage-modeImage preview
C-j o <up>org-priority-upIncrease priority
C-j o <down>org-priority-downDecrease priority

Core Files

early-init.el

Loaded by Emacs 27+ before init.el and before GUI initialization:

  • Set GC threshold to 800MB (reduce pauses during startup)
  • Disable package.el automatic loading
  • Native compilation optimization (Emacs 28+)
  • Disable toolbar/menubar/scrollbar early (avoid GUI flicker)

init.el

Entry point:

  1. Record startup time
  2. Bootstrap core/ into load-path
  3. Load custom.el early (module control variables take effect before loading)
  4. Initialize splash screen with banner
  5. Load core modules (real-time display in splash)
  6. Load feature modules (real-time display in splash)
  7. On emacs-startup-hook: restore GC, show summary, detect startup mode
    • emacs / emacs dir → wait for Enter, then open dired
    • emacs file → skip wait, directly open file buffer

core-load-paths.el

Defines path constants (skemacs-dir, skemacs-core-dir, skemacs-modules-dir, skemacs-local-dir, skemacs-themes-dir, skemacs-cache-dir), ensures directories exist, adds them to load-path. Also registers themes/ in custom-theme-load-path for local theme discovery.

core-module.el

Module loading system with dynamic splash screen. See Module System section.

Splash screen layout:

Banner
[ Press Enter to continue ]
Emacs XX.X  |  Skemacs Configuration  |  Starting time: X.XXXs
Total: XXXms  |  N loaded  |  N disabled  |  N errors    ← stats summary
────────────────────────────────────────────────────────
  Module                             Time  Status
────────────────────────────────────────────────────────
  core-packages                       59ms  OK
  ...
────────────────────────────────────────────────────────

                      no error                           ← or error details

During loading, “Loading modules…” is shown in the stats position and replaced with actual statistics after all modules finish loading. Error details (if any) or “no error” are displayed below the table.

core-packages.el

Package manager configuration:

  • Tsinghua mirror sources (GNU + NonGNU + MELPA)
  • MELPA official as fallback
  • use-package initialization (always-ensure, expand-minimally)
  • Deferred package-initialize: only runs when first package install is needed
  • Network proxy (commented out by default, enable as needed)

core-ui.el

Basic UI configuration:

  • Platform detection (skemacs-is-mac, skemacs-is-linux, skemacs-is-windows)
  • Disable startup welcome screen
  • Confirm before quit
  • Disable toolbar / menubar / scrollbar
  • Column number display, pixel scroll, silent bell

core-editor.el

Editing behavior:

  • Auto-pair brackets (electric-pair-mode)
  • Paren highlighting (show-paren-mode)
  • Selection replacement (delete-selection-mode)
  • Code folding (hs-minor-mode)
  • Auto-revert files (global-auto-revert-mode)

core-funcs.el

Utility functions (skemacs/ namespace):

  • Navigation: next-ten-lines, previous-ten-lines
  • Window: split-window-vertically, split-window-horizontally, shrink/enlarge-window
  • Clipboard: copy-to-clipboard (cross-platform macOS/Linux/Windows)
  • Display: toggle-line-numbers-type (relative/absolute)
  • Org: open-org-directory

core-keybindings.el

Defines prefix keys and global keybindings independent of packages. See Key Bindings Reference.

Feature Modules

All modules reside in modules/ and are loaded alphabetically. Each is self-contained with package declarations, configuration, and keybindings.

init-theme.el

Theme management with system appearance auto-detection. Supports both local themes (bundled in themes/) and third-party theme packages (auto-installed via use-package).

System Auto-Detection

On macOS, automatically detects system dark/light mode at startup via AppleInterfaceStyle. Configurable via:

VariableDefaultDescription
skemacs-dark-thememodus-vivendi-tritanopiaTheme used when system is dark
skemacs-light-thememodus-operandi-tintedTheme used when system is light
skemacs-default-theme(auto-detected)Startup theme based on system mode
skemacs-theme-list(all available themes)Candidate list for theme switching

Included Themes

SourceThemes
Local (Modus)modus-operandi-tinted (light), modus-vivendi-tritanopia (dark)
doom-themesdoom-one, doom-vibrant, doom-dracula, doom-gruvbox, doom-nord, etc.
ef-themesef-autumn, ef-spring, ef-summer, ef-winter, ef-dark, ef-light, etc.
catppuccincatppuccin (mocha flavor)

Key Functions

FunctionDescription
skemacs/switch-themeInteractive theme selection (completing-read)
skemacs/cycle-themeCycle to next theme in skemacs-theme-list
skemacs/toggle-light-darkToggle between light and dark theme
skemacs/load-themeLoad a specific theme by symbol name

See Theme Bindings for keybindings.

init-completion.el

Modern minibuffer completion framework replacing the default completing-read UI:

PackageRole
verticoVertical candidate list UI in the minibuffer
vertico-directoryPath-aware navigation (DEL deletes path component)
orderlessFlexible matching: space-separated terms, any order
marginaliaRich annotations beside candidates
consultEnhanced search, navigation, and buffer commands
embarkContext-actions on candidates (like a right-click menu)
embark-consultIntegration bridge between Embark and Consult
savehistPersist minibuffer history across sessions (built-in)

See Completion & Search Bindings for all keybindings.

init-which-key.el

Displays available keybinding hints after pressing a prefix key. Uses Emacs 30+ built-in which-key.

init-recentf.el

Tracks recently opened files (recentf-mode) and provides ibuffer as an enhanced buffer list.

KeyCommandDescription
C-x b rrecentf-openRecent files (completing)
C-x b Rrecentf-open-filesRecent files (list)
C-x b libufferBuffer list

init-dired.el

Dired enhancements: auto-enable dired-omit-mode to hide clutter files (.DS_Store, Thumbs.db, etc.).

init-lsp.el

LSP integration via lsp-bridge for code intelligence (completion, diagnostics, navigation). Includes language server setup script (setup-lsp.sh) which:

  • Installs Node.js, Volar, vtsls, and TypeScript
  • Creates Python virtual environment for lsp-bridge dependencies
  • Clones lsp-bridge source code
  • Generates langserver override configs (lsp-bridge-langserver/) to use vtsls instead of typescript-language-server for TypeScript, JavaScript, TSX, and JSX files

init-web.el

Web development support via web-mode for HTML, CSS, JSX, Vue, and template files.

init-highlight-symbol.el

Highlights all occurrences of the symbol under cursor in prog-mode buffers via the highlight-symbol package.

  • Auto-highlights after 0.3s idle time
  • Jump between occurrences with C-j h n / C-j h p
  • Query-replace symbol in buffer with C-j h r

See Highlight Symbol Bindings for all keybindings.

init-avy.el

Fast cursor jumping to any visible position via avy. Type a few characters and avy overlays hint characters on all matching positions — press the hint to jump there instantly.

  • Searches across all visible windows (avy-all-windows t)
  • Uses home row keys (a s d f g h j k l) for hint characters
  • Background dimming for better hint visibility
  • avy-goto-char-timer timeout: 0.5s (configurable via avy-timeout-seconds)

See Avy Bindings for keybindings.

init-ace-window.el

Quick window jumping via ace-window. Replaces the built-in other-window on C-x o:

  • When 2 windows: jumps directly to the other window
  • When 3+ windows: displays a numbered label on each window for quick selection
  • Uses home row keys (a s d f g h j k l) for window labels
KeyFunctionDescription
C-x oace-windowJump to window (replaces default)

init-mwim.el

Smart line beginning/end navigation via mwim (Move Where I Mean). Enhances the default C-a and C-e behavior:

  • C-a (mwim-beginning): first press moves to beginning of code (skipping indentation), second press moves to actual line start (column 0)
  • C-e (mwim-end): first press moves to end of code (before trailing comments), second press moves to actual line end

See Mwim Bindings for keybindings.

init-undo-tree.el

Tree-based undo/redo via undo-tree, replacing Emacs default linear undo. Provides a hydra panel (C-j u) for quick undo/redo operations and a visual undo tree browser.

  • global-undo-tree-mode enabled globally
  • Auto-save undo history disabled (undo-tree-auto-save-history nil)
  • Depends on hydra (:after hydra)

See Undo Tree Bindings for keybindings.

init-project.el

Project management via Emacs built-in project.el (28+). Automatically detects project root via version control (Git etc.) and provides project-scoped file finding, searching, compilation, and buffer management.

Project Discovery

Beyond default VC-based detection, the following marker files are also recognized as project roots:

Marker FileLanguage/Tool
.projectCustom marker
MakefileMake
package.jsonNode.js
Cargo.tomlRust
go.modGo
pyproject.tomlPython
pom.xmlJava (Maven)
build.gradleJava (Gradle)

Switch Project Menu

When switching projects (C-j p p), a menu is displayed with available actions:

KeyAction
fFind file
gFind regexp
dDired
eEshell
bSwitch buffer
cCompile

See Project Management Bindings for all keybindings.

init-treemacs.el

File tree sidebar via treemacs. Provides a project-aware file explorer with Git status integration, file watching, and directory collapsing.

PackageRole
treemacsFile tree sidebar (main package)
treemacs-magitGit status integration (after magit operations)
treemacs-icons-diredTreemacs icons in dired buffers (GUI only)

Configuration

SettingValueDescription
treemacs-width35Sidebar width in characters
treemacs-is-never-other-windowtC-x o skips treemacs window
treemacs-collapse-dirs3Collapse up to 3 consecutive single-child dirs
treemacs-follow-modetAuto-follow current buffer
treemacs-filewatch-modetAuto-refresh on filesystem changes
treemacs-indent-guide-style'lineShow indentation guide lines

Note: treemacs-icons-dired only activates in GUI Emacs (display-graphic-p). In terminal Emacs it is skipped to avoid garbled icons without Nerd Font.

See Treemacs Bindings for keybindings.

init-git.el

Git integration via Magit (full Git client) and diff-hl (gutter modification markers).

PackageRole
magitComplete Git porcelain: stage, commit, push, pull, rebase, blame, log
diff-hlFringe/margin markers showing added/changed/deleted lines

Configuration

  • Magit status opens in the same window (no split)
  • Commit message editor sets fill-column to 72 with indicator line
  • diff-hl enabled globally; auto-refreshes after magit operations
  • In terminal Emacs, diff-hl uses margin mode (no fringe available)

See Git Bindings for keybindings.

init-multiple-cursors.el

Multi-cursor editing via multiple-cursors, with keybindings under C-j m prefix.

PackageRole
multiple-cursorsCreate and manage multiple cursors simultaneously

Usage

  1. Select a word or region
  2. Use C-j m n / C-j m p to incrementally add cursors on matching occurrences
  3. Use C-j m N / C-j m P to skip unwanted matches
  4. Use C-j m a to mark all matches at once
  5. Use C-j m l to place a cursor on each line of a selected region
  6. Type normally — all cursors edit simultaneously
  7. Press C-g to exit multi-cursor mode

Additional entry point: C-S-<mouse-1> toggles a cursor at click position.

See Multiple Cursors Bindings for all keybindings.

init-rainbow-delimiters.el

Colorizes nested parentheses/brackets/braces by depth via rainbow-delimiters. Each nesting level gets a distinct color, making it easy to visually match delimiters. Especially useful for Lisp-family languages.

  • Enabled automatically in all prog-mode buffers
  • No keybindings (purely visual enhancement)

init-vterm.el

High-performance terminal emulator via vterm, based on the libvterm C library. Supports full terminal features (colors, cursor movement, scrolling) with performance far exceeding ansi-term.

Dependencies

First-time loading auto-compiles the C module. System requirements:

OSInstall CommandNotes
macOSbrew install cmake libtoollibtool installs as glibtool; system Apple libtool is incompatible
Ubuntusudo apt install cmake libtool-bin

Configuration

SettingValueDescription
vterm-max-scrollback10000Maximum scrollback lines
vterm-kill-buffer-on-exittAuto-close buffer when shell exits
vterm-shell$SHELL or /bin/zshUse system default shell
vterm-buffer-name-string"vterm: %s"Buffer naming pattern

Toggle Function

skemacs/vterm-toggle (C-j v t) provides smart switching:

  • If currently in vterm: switch back to previous buffer
  • If not in vterm: switch to an existing vterm buffer, or create a new one

See Vterm Bindings for keybindings.

init-agent-shell.el

AI coding agent integration via agent-shell, powered by ACP (Agent Client Protocol). Provides a native Emacs comint-mode shell to interact with multiple AI agents through a unified interface.

Supported Agents

AgentACP AdapterBinaryDescription
Claude Code@zed-industries/claude-code-acpclaude-code-acpAnthropic Claude Code
Cursor Agent@blowmage/cursor-agent-acpcursor-agent-acpCursor IDE agent
Gemini CLI@google/gemini-cligeminiGoogle Gemini (--experimental-acp)

Setup

ACP adapters are installed into the project-local nodejs/ directory via setup-agents.sh:

cd ~/.emacs.d && bash setup-agents.sh

This uses the same built-in Node.js (nodejs/bin/node) as setup-lsp.sh. Adapter binaries are installed to nodejs/bin/.

Path Isolation

To avoid conflicts with other Node.js versions in system $PATH, the module does not modify global exec-path or $PATH. Instead:

  • agent-shell-*-command is set to the full path of each binary (e.g. nodejs/bin/claude-code-acp)
  • agent-shell-*-environment provides an independent PATH for each agent subprocess, ensuring #!/usr/bin/env node resolves to the project-local nodejs/bin/node

Authentication

Each agent requires one-time authentication before first use:

AgentMethod
Claude CodeLogin-based OAuth (browser opens automatically on first start)
Cursor AgentPre-authenticate via cursor-agent login in terminal
Gemini CLILogin-based OAuth (browser opens automatically on first start)

Alternatively, API keys can be set via environment variables (ANTHROPIC_API_KEY, GEMINI_API_KEY).

See AI Agent Bindings for keybindings.

init-claude-code-ide.el

Native Claude Code CLI integration via claude-code-ide, powered by MCP (Model Context Protocol). Unlike simple terminal wrappers, this creates a bidirectional bridge between Claude and Emacs — Claude can access Emacs’ LSP, xref, tree-sitter, imenu, and project features through MCP tools.

Features

FeatureDescription
MCP ToolsClaude accesses xref, tree-sitter, imenu, project info via MCP
IDE Diff (ediff)Visual diff with interactive editing before applying changes
Multi-projectEach project gets its own Claude session, auto-detected
DiagnosticsFlycheck/Flymake integration for error awareness
Selection trackingClaude knows your current file and selected text
Side windowClaude opens in a configurable side window (default: right)

Installation

Installed via use-package :vc from GitHub (requires Emacs 30+). No manual setup needed beyond having the Claude Code CLI in $PATH.

Configuration

SettingValueDescription
claude-code-ide-terminal-backend'vtermTerminal backend (vterm or eat)
claude-code-ide-use-side-windowtUse side window
claude-code-ide-window-side'rightWindow position
claude-code-ide-window-width90Window width (columns)
claude-code-ide-focus-on-opentAuto-focus on open
claude-code-ide-use-ide-difftUse ediff for code changes

MCP Tools

Enabled via claude-code-ide-emacs-tools-setup in :config. Built-in tools:

ToolDescription
xref-find-referencesFind all references to a symbol in project
xref-find-aproposFind symbols matching a pattern across project
treesit-infoGet tree-sitter syntax tree information
imenu-list-symbolsList all symbols in a file
project-infoGet project directory, files, etc.

See Claude Code IDE Bindings for keybindings.

init-readonly.el

Default read-only file browsing via Emacs built-in view-mode. All files opened via find-file (C-x C-f) automatically enter view-mode, preventing accidental edits. Press C-x C-q to exit read-only mode and start editing.

Why view-mode

  • Prevents accidental changes to files you’re only reading
  • Provides convenient single-key navigation (SPC, n, p, q, etc.)
  • Zero dependencies — uses Emacs built-in view-mode

See Readonly / View-Mode Bindings for all keybindings.

init-tramp.el

[Disabled by default] — Remote file access via Emacs built-in TRAMP (Transparent Remote Access, Multiple Protocols). Transparently edit files on remote servers as if they were local.

Usage

Use C-x C-f (or C-x d for directories) and enter a remote path:

Path FormatDescription
/ssh:user@host:/path/to/fileBasic SSH access
/ssh:user@host#2222:/pathNon-default port
/ssh:myalias:/pathSSH config alias
/ssh:user@host\vert{}sudo:host:/etc/confRemote sudo editing
/sudo::/etc/hostsLocal sudo
/ssh:user@jump\vert{}ssh:user@target:/pMulti-hop (jump host)

Configuration

SettingValueDescription
tramp-default-method"ssh"Default connection method
tramp-verbose1Minimal logging (0=silent, 10=most verbose)
remote-file-name-inhibit-cachenilEnable file name cache for performance
tramp-use-ssh-controlmaster-optionstReuse SSH ControlMaster connections

Remote paths also disable vc (version control) queries to avoid slow Git lookups over SSH.

Enabling

Remove "init-tramp" from skemacs-disabled-modules in custom.el.

For best performance, configure SSH connection multiplexing in ~/.ssh/config:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

init-hydra.el

Provides repeatable operation panels via the hydra package. Currently includes:

Window Resize Panel (C-x w r)

A sticky panel for adjusting window size. Press C-x w r to enter, then use h/j/k/l repeatedly to resize, q to quit.

KeyFunctionDescription
hskemacs/shrink-window-horizontallyShrink horizontally
lskemacs/enlarge-window-horizontallyEnlarge horizontally
jskemacs/shrink-windowShrink vertically
kskemacs/enlarge-windowEnlarge vertically
qquitExit resize panel

Adding New Modules

Module Template

Create a new file in modules/ following this template:

;;; init-xxx.el --- Short description -*- lexical-binding: t -*-
;;; Commentary:
;; Describe the module's purpose and included packages.

;;; Code:

(use-package some-package
  :ensure t
  :defer t                              ; Lazy load when possible
  :hook (some-mode . some-package-mode) ; Or use :commands
  :bind
  (("C-j x" . some-command)            ; Keybindings defined in module
   :map some-mode-map
   ("C-c x" . another-command))
  :init
  ;; which-key description (if which-key is loaded)
  (with-eval-after-load 'which-key
    (which-key-add-key-based-replacements "C-j x" "description"))
  :config
  (setq some-option t))

(provide 'init-xxx)
;;; init-xxx.el ends here

Module Management

Auto-scan Mode (default)

All .el files in modules/ are loaded in alphabetical order.

Manual Module List

Add to custom.el (loaded before modules):

(setq skemacs-module-list
      '("init-theme"
        "init-which-key"
        "init-completion"
        "init-navigation"))

Disable Specific Modules

Add to custom.el:

(setq skemacs-disabled-modules
      '("init-vterm"
        "init-treemacs"))

Usage Guide

First Time Setup

  1. Install Emacs 29.1+
  2. Clone/copy this config to ~/.emacs.d/
  3. Install system dependencies for vterm (terminal emulator):
    # macOS
    brew install cmake libtool
    # Ubuntu
    sudo apt install cmake libtool-bin
        
  4. (Optional) Install ACP agent adapters for AI coding agents:
    cd ~/.emacs.d && bash setup-agents.sh
        
  5. Start Emacs — packages install automatically when modules need them
  6. Add feature modules in modules/ as needed
  7. Set up Org directory:
    mkdir -p ~/org
        

Daily Workflow

Quick Jump (Avy)

  1. C-; — Jump to word beginning (type 1 char)
  2. C-' — Jump to position (type 2 chars)
  3. C-j j t — Timed char search (type then wait)
  4. M-g g — Jump to any visible line

Search & Navigation (Consult)

  1. C-j s s — Search lines in current buffer
  2. C-j s r — Ripgrep search across project
  3. C-j s f — Find file by name
  4. C-j s o — Jump to outline heading
  5. C-j s i — Jump to symbol (imenu)
  6. C-. — Context actions on any candidate (Embark)

Project Management

  1. C-j p p — Switch to another project
  2. C-j p f — Find file in current project
  3. C-j p g — Regexp search in project
  4. C-j p d — Dired at project root
  5. C-j p b — Switch buffer within project
  6. C-j p c — Compile in project

Window Management

  1. C-x o — Quick jump to window (ace-window)
  2. C-x w v/s — Split windows
  3. C-x w h/j/k/l — Navigate between windows
  4. C-x w r — Resize panel (h/j/k/l to adjust, q to quit)
  5. C-x b b — Switch buffer (Consult: includes recentf + bookmarks)

File Tree (Treemacs)

  1. C-j f t — Toggle treemacs sidebar
  2. C-j f s — Locate current file in tree
  3. C-j f a — Add project to workspace

Multi-Cursor Editing

  1. C-j m n / C-j m p — Add cursors on next/previous match
  2. C-j m a — Mark all same occurrences
  3. C-j m l — One cursor per line
  4. C-S-click — Toggle cursor at mouse position

Git (Magit)

  1. C-j g g — Open Magit status panel
  2. C-j g l — View current branch log
  3. C-j g b — Blame current file
  4. C-j g d — Diff current file
  5. C-j g s / C-j g u — Stage / unstage current file

Terminal (Vterm)

  1. C-j v v — Open new terminal
  2. C-j v t — Toggle terminal (switch to existing or create new)
  3. C-j v o — Open terminal in another window

AI Agent (agent-shell)

  1. C-j a a — Start or reuse any AI agent (selection menu)
  2. C-j a c — Start Claude Code session
  3. C-j a u — Start Cursor Agent session
  4. C-j a g — Start Gemini CLI session
  5. C-j a i — Insert file as context
  6. C-j a n — Start a new agent shell (even if one exists)

Claude Code IDE (MCP)

  1. C-j c c — Start or switch to Claude Code (project-aware)
  2. C-j c m — Open command menu (transient)
  3. C-j c p — Send prompt from minibuffer
  4. C-j c r — Resume previous session
  5. C-j c k — Continue most recent conversation
  6. C-j c t — Toggle Claude window visibility
  7. C-j c @ — Mention selected text in prompt
  8. C-j c s — List all active sessions

Org Mode Workflow

  1. C-j o a — View agenda
  2. C-j o c — Quick capture
  3. C-j o o — Open org directory

Config Management

  1. C-x a i R — Reload config
  2. C-j t — View module load times

Performance Monitoring

View Load Report

  • Automatically printed to *Messages* after startup
  • M-x skemacs/show-load-times — Open dedicated report buffer
  • C-j t — Shortcut access

GC Strategy

Phasegc-cons-thresholdNotes
During startup800MBReduce GC pauses, fast startup
After startup16MBNormal operation, free memory

Troubleshooting

Startup Errors

  1. emacs --debug-init — View full error backtrace
  2. emacs -Q — Test with vanilla Emacs
  3. Check *Messages* and *Warnings* buffers
  4. Module errors won’t break startup; they’re recorded in skemacs-module-errors

View Keybindings

  1. C-h k — Describe what a key does
  2. C-h b — List all current bindings
  3. C-h B — Embark bindings overview (if init-completion loaded)
  4. M-x describe-personal-keybindings — View all :bind custom bindings

Slow Startup

  1. M-x skemacs/show-load-times — Find the slowest module
  2. Modules marked SLOW (>0.5s) need optimization
  3. Try adding :defer t to slow modules for lazy loading

Package Install Failures

  1. Check network connection and proxy settings
  2. M-x package-refresh-contents — Refresh package index
  3. Delete ~/.emacs.d/elpa/ and restart
  4. Uncomment proxy settings in core-packages.el

About

Emacs Config

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors