Archived
Initial commit for v1.0 of Simply Emacs.
This commit is contained in:
Executable
+248
@@ -0,0 +1,248 @@
|
||||
;;; init-cheatsheet.el --- In-Emacs keybinding reference -*- lexical-binding: t; -*-
|
||||
|
||||
;;; Commentary:
|
||||
;; A static reference buffer listing this config's custom keybindings,
|
||||
;; opened as a non-blocking side window — same window-management model as
|
||||
;; the build panel in `init-build.el' — so it can be toggled in and out of
|
||||
;; view without interrupting whatever else is on screen.
|
||||
;;
|
||||
;; Content is real Markdown, viewed read-only via `markdown-view-mode'
|
||||
;; (from the `markdown-mode' package already pulled in by `init-dev.el')
|
||||
;; so headers/tables/code spans get proper fontification for free.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'markdown-mode) ; markdown-view-mode; make the dep explicit
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*Cheatsheet\\*"
|
||||
(display-buffer-reuse-window display-buffer-in-side-window)
|
||||
(side . left)
|
||||
(window-width . 0.4)))
|
||||
|
||||
(defconst my/cheatsheet-text
|
||||
"# SimplyEmacs Cheat Sheet
|
||||
|
||||
Custom keybindings layered on top of vanilla Emacs. Toggle this buffer
|
||||
any time with `C-c /`.
|
||||
|
||||
Many keys use a project/fallback pattern (`my/project-or`): one action
|
||||
inside a known project, a `consult`-based fallback everywhere else.
|
||||
|
||||
## Navigation & Search *(Evil normal/motion state)*
|
||||
|
||||
| Key | In a project | Fallback |
|
||||
|------------|----------------------------|-------------------|
|
||||
| `C-e` | `project-dired` | `dired-jump` |
|
||||
| `C-m` | `project-switch-to-buffer` | `consult-buffer` |
|
||||
| `C-f` | `consult-ripgrep` | `consult-ripgrep` |
|
||||
| `C-p` | `project-find-file` | `consult-fd` |
|
||||
| `C-s` | `consult-line` | |
|
||||
| `<return>` | `evil-ret` | |
|
||||
|
||||
`C-f` runs `consult-ripgrep` everywhere — it already scopes to the
|
||||
project root when there is one, so it needs no project/fallback split.
|
||||
|
||||
## Projects
|
||||
|
||||
| Key | Action |
|
||||
|-----------|-------------------------------------------------------------------------------|
|
||||
| `C-c C-p` | Switch project — saves & closes current project's buffers first, then prompts |
|
||||
|
||||
Projects are rescanned from `~/Projects` on every startup (direct
|
||||
children only, no symlinks, most-recently-modified first). Jumping into
|
||||
a dependency's source keeps the *current project* pinned to your last
|
||||
real project instead of hijacking to it.
|
||||
|
||||
## Build
|
||||
|
||||
| Key | Action |
|
||||
|-----------|-----------------------------------------------------------|
|
||||
| `C-c C-c` | Run `./build.sh` from project root (saves buffers first) |
|
||||
| `C-c C-o` | Same, but prompts for extra args to append |
|
||||
| `C-j` | Toggle the `*compilation*` output panel (right side, 35%) |
|
||||
|
||||
Requires `build.sh` at the project root; output is a real `compile`
|
||||
buffer, so `M-g n` / `M-g p` jump between errors.
|
||||
|
||||
## Dev / Eglot (LSP)
|
||||
|
||||
Wired up for Odin (`.odin`, tree-sitter + `odin-ts-mode` + OLS).
|
||||
|
||||
| Key | Action |
|
||||
|------------|----------------------------------|
|
||||
| `C-c r` | `eglot-rename` |
|
||||
| `C-c a` | `eglot-code-actions` |
|
||||
| `K` norm | Full hover doc in a focused pane |
|
||||
| `q` or `K` | Close the hover pane |
|
||||
|
||||
Add a new language: new `;;;; <Language>` section in `init-dev.el`.
|
||||
|
||||
## Git (Magit)
|
||||
|
||||
`C-c C-g` opens `magit-status` (replaces the lazygit TUI). Magit keeps
|
||||
its own native keys — nothing reimplemented — evil's normal state just
|
||||
shadows most of them by default, so they're restored below plus a couple
|
||||
of hjkl navigation aliases.
|
||||
|
||||
### Workflow
|
||||
|
||||
- Expand only the file you're working on with `TAB`.
|
||||
- Move between hunks with `j` / `k`.
|
||||
- Press `s` on a hunk to stage only that hunk.
|
||||
- Continue staging related hunks until they form a single logical change.
|
||||
- Press `c c` to create a commit from the staged changes.
|
||||
- Repeat for the remaining hunks, creating small, focused commits instead of one large commit.
|
||||
|
||||
> **Tip:** If a single hunk contains unrelated changes, press `e` to edit the patch before staging, allowing you to split the changes into separate commits.
|
||||
|
||||
| Key | Action |
|
||||
|-----------|----------------------|
|
||||
| `j` / `n` | next section |
|
||||
| `s` | stage |
|
||||
| `k` / `p` | previous section |
|
||||
| `u` | unstage |
|
||||
| `h` | up to parent section |
|
||||
| `U` | unstage all |
|
||||
| `RET` | visit thing at point |
|
||||
| `x` | discard |
|
||||
| `g r` | refresh |
|
||||
| `q` | quit / bury buffer |
|
||||
|
||||
**Popups** *(transient menus)*:
|
||||
|
||||
| Key | Action |
|
||||
|-----|----------------|
|
||||
| `c` | commit |
|
||||
| `m` | merge |
|
||||
| `d` | diff |
|
||||
| `r` | rebase |
|
||||
| `b` | branch |
|
||||
| `t` | tag |
|
||||
| `l` | log |
|
||||
| `z` | stash |
|
||||
| `f` | fetch |
|
||||
| `e` | ediff |
|
||||
| `F` | pull |
|
||||
| `$` | process buffer |
|
||||
| `P` | push |
|
||||
|
||||
Covers the daily-driver surface, not magit's entire command set —
|
||||
anything not listed falls through to evil's default on that key
|
||||
(harmless, just `<escape>`).
|
||||
|
||||
## Dired
|
||||
|
||||
Evil `hjkl` grafted onto stock dired commands, remapped only so evil
|
||||
doesn't swallow dired's own letters.
|
||||
|
||||
| Key | Action |
|
||||
|-------------|---------------------------|
|
||||
| `j` / `k` | next / previous line |
|
||||
| `d` | flag for deletion |
|
||||
| `h` | up a directory |
|
||||
| `x` | execute flagged deletions |
|
||||
| `l` / `RET` | open file or directory |
|
||||
| `D` | delete now, no flag step |
|
||||
| `q` | quit window |
|
||||
| `R` | rename / move |
|
||||
| `SPC` / `m` | mark |
|
||||
| `C` | copy |
|
||||
| `u` | unmark |
|
||||
| `y` | copy filename as kill |
|
||||
| `U` | unmark all |
|
||||
| `!` | shell command on file(s) |
|
||||
| `t` | toggle marks |
|
||||
| `+` / `f` | create directory |
|
||||
| `g r` | refresh listing |
|
||||
| `a` | create empty file |
|
||||
| `(` | toggle file details |
|
||||
|
||||
## Evil *(buffer editing only — dired/magit/etc. keep native binds)*
|
||||
|
||||
**Ex commands:**
|
||||
|
||||
| Command | Action |
|
||||
|---------|---------------------|
|
||||
| `:w` | save buffer |
|
||||
| `:q` | kill current buffer |
|
||||
| `:wq` | save and kill Emacs |
|
||||
|
||||
**Insert state:**
|
||||
|
||||
| Key | Action |
|
||||
|-------|----------------------------------------------------|
|
||||
| `TAB` | insert a literal tab (overrides major-mode indent) |
|
||||
|
||||
## In-buffer Completion (Corfu)
|
||||
|
||||
Auto-popup after 2 characters, 0.15s delay.
|
||||
|
||||
| Key | Action |
|
||||
|-----------------|--------------------|
|
||||
| `C-n` / `TAB` | next candidate |
|
||||
| `C-p` / `S-TAB` | previous candidate |
|
||||
| `RET` | insert selection |
|
||||
| `<escape>` | quit completion |
|
||||
|
||||
## Minibuffer Completion
|
||||
|
||||
Vertico *(centered posframe)* + orderless matching + marginalia +
|
||||
consult. Type fragments in any order to filter.
|
||||
|
||||
## Misc / Global
|
||||
|
||||
| Key | Action |
|
||||
|----------------|-----------------------------------|
|
||||
| `C-S-p` | `execute-extended-command` (M-x) |
|
||||
| `<escape>` | acts like `C-g` everywhere |
|
||||
| *(any prefix)* | which-key shows available options |
|
||||
|
||||
## Look & Feel
|
||||
|
||||
Theme: **gruvbox-dark-hard**, background/fringe/line-numbers darkened
|
||||
to `#111111`. Font: JetBrainsMono Nerd Font @ 12pt. Line numbers and
|
||||
current-line highlight on globally; scroll margin 15 lines.
|
||||
"
|
||||
"Reference text shown by `my/toggle-cheatsheet'.")
|
||||
|
||||
(define-derived-mode my/cheatsheet-mode markdown-view-mode "Cheatsheet"
|
||||
"Read-only `markdown-view-mode' variant for the keybinding cheat sheet.")
|
||||
|
||||
(with-eval-after-load 'evil
|
||||
(evil-define-key '(normal motion) my/cheatsheet-mode-map
|
||||
(kbd "q") #'quit-window))
|
||||
|
||||
(defun my/cheatsheet-buffer ()
|
||||
"Return the cheatsheet buffer, creating and populating it on first use."
|
||||
(let ((buf (get-buffer-create "*Cheatsheet*")))
|
||||
(with-current-buffer buf
|
||||
(unless (derived-mode-p 'my/cheatsheet-mode)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(insert my/cheatsheet-text)
|
||||
(my/cheatsheet-mode)
|
||||
(goto-char (point-min)))))
|
||||
buf))
|
||||
|
||||
(defun my/toggle-cheatsheet ()
|
||||
"Toggle a non-blocking side window showing this config's cheat sheet.
|
||||
Same show/hide-only-the-window behaviour as `my/toggle-build-panel' —
|
||||
doesn't rebuild the buffer each time, just shows or hides it."
|
||||
(interactive)
|
||||
(let* ((buf (my/cheatsheet-buffer))
|
||||
(win (get-buffer-window buf)))
|
||||
(if win
|
||||
(delete-window win)
|
||||
(display-buffer buf))))
|
||||
|
||||
;; Bound globally (not evil-scoped), matching the build panel keys, so it
|
||||
;; works the same from normal state, insert state, or anywhere else.
|
||||
(global-set-key (kbd "C-c /") #'my/toggle-cheatsheet)
|
||||
|
||||
(with-eval-after-load 'which-key
|
||||
(which-key-add-key-based-replacements
|
||||
"C-c /" "cheatsheet"))
|
||||
|
||||
(provide 'init-cheatsheet)
|
||||
;;; init-cheatsheet.el ends here
|
||||
Reference in New Issue
Block a user