Scamx is a modal editing framework designed for Emacs. By adopting a modular, multi-layered architecture, it integrates seamlessly with existing Emacs keybindings while minimizing reliance on modifier keys. Rather than redefining core functionality, Scamx focuses on providing ergonomic and consistent access to the powerful commands already available within Emacs.
(use-package scamx
:ensure t
:vc (:url "https://github.com/MagiFeeney/scamx/")
:config
(electric-pair-mode))Note: For the full setup, please reference
scamx-anchor.el.
Scamx maximizes ergonomics through a multi-layered modal architecture, reusing a compact set of keys across four global core modes while allowing seamless, mode-specific customization.
- Normal (
gto return): The base mode for basic navigation and invoking other modes. - Convert Mode (
cprefix): Bolder, structural editing (words, paragraphs, sexps). - Visit Mode (
vprefix): Navigates, views, and manages buffers and windows. - X Mode (
xprefix): Sequence commands for system, buffer, and macro management.
Scamx also provides an additional layer, Motion Mode, which can be customized for specific major modes (e.g. Org mode). By default, Motion Mode starts as a blank state unless the target mode already defines a default keymap, such as in Dired or Magit. Users can freely bind any function to any key according to their workflow.
Tip: You can seamlessly switch between these native modes and scamx. Enter Normal mode with
gand revert back to Emacs' default state with`.
Base navigation and editing. Use ` for motion mode, ? for help, and g to cancel/exit.
| Key | Action | Key | Action |
|---|---|---|---|
/ |
M-x |
w / y |
Copy / Yank |
x/c/v |
Enter X / Convert / Visit mode | u / r |
Undo / Redo |
i |
Insert (gg to exit) |
k |
Kill line at point/region |
a / e |
Move to beginning / end of line | t |
Select to char |
d / h |
Delete forward / backward (or region) | z / Z |
Zap up to char / Zap to char |
o / O |
Open line below / above | q / Q |
Quit buffer / Goto line |
n / p |
Next / Previous line | l |
Recenter top/bottom |
f / b |
Forward / Backward char | \ |
Delete horizontal space |
j / m |
Newline (RET) / Back to indentation |
! / $ |
Shell command / Ispell word |
s |
Isearch minor mode | % |
Query replace |
= |
Mark word | ; / ' |
Comment line / region |
SPC |
Set mark command | , / . |
Mark inside / outside pairs dwim |
<backspace> |
Kill whole line | - |
Negative argument prefix |
| Key | Action | Key | Action |
|---|---|---|---|
[ / ] |
Mark previous / next like this | < / > |
Skip to previous / next like this |
: |
Mark all like this | " |
Edit lines |
@ |
Mark all words like this | # |
Mark all in region |
Triggered via c from Normal mode. Built for structural editing. Exit with g.
| Key | Action | Key | Action |
|---|---|---|---|
/ |
M-x |
a / e / j |
Backward kill sexp / Kill sexp / Raise sexp |
n / p |
Forward / Backward paragraph | ( / ) |
Backward / Forward list |
f / b |
Forward / Backward word | [ / ] |
Backward / Forward sexp |
d / h |
Kill / Backward kill word (or region) | { / } |
Backward / Forward up list |
k |
Kill paragraph (or region) | < / > |
Move beginning / end of defun |
w / y |
Copy / Yank | = / , |
Mark sexp / Mark defun |
u / r |
Undo / Redo | s |
Allow one Normal mode key to execute |
Triggered via v from Normal mode. Built for window and workspace management. Exit with g.
| Key | Action | Key | Action |
|---|---|---|---|
l / c / s |
Last / Clone / Scratch buffer | 0 / 1 |
Delete window / Delete other windows |
n / p |
Next / Previous buffer | = / w |
Balance windows / Swap window |
f / b |
Other window / Prev window (any frame) | m / M |
Minimize / Maximize window |
d / D |
Scroll page down / Other page down | | / _ |
Split horizontally / vertically |
u / U |
Scroll page up / Other page up | + / - |
Enlarge / Shrink window horizontally |
a / e |
Scroll line up / line down | j |
Move cursor to top/center/bottom |
r |
Revert buffer | ( / ) |
Tear off window / Delete frame |
Triggered via x from Normal mode. (To view X mode commands dynamically, type x ?).
| Key | Action | Key | Action |
|---|---|---|---|
f / s / c |
Open / Save / Save & Close Emacs | b / l / k |
Switch / List / Kill buffer |
z |
Minimize window | x |
Exchange point and mark |
h |
Select whole buffer | SPC |
Pop to mark command |
<tab> |
Indent region | n / = |
Duplicate line / Adjust text scale |
( / ) / e |
Start / End / Call macro | : / . |
Eval expression / last sexp |
[ / ] |
Backward / Forward page | \ / ~ |
Copy file path to kill ring / Shutdown |
j |
Dired jump | o / m |
Org mode map / Set mode map |
* |
Calculator | ESC |
Repeat complex command |
Triggered via ? from Normal mode. Exit with q.
| Key | Action | Key | Action |
|---|---|---|---|
k / c |
Describe key / Describe key briefly | p / m |
Describe package / Describe mode |
f / b |
Describe function / bindings | t / d |
Tutorial / Debugging tutorial |
s / v |
Search command / keyword | i / r |
Info overview / Find manual |
\ / e |
Describe input method / View Messages | C-q / ? |
Quick toggle / Further options |
- Minibuffer: Defaults to Insert mode (
i). Typeggto leave insert mode, usen/pto select candidates, and<RET>to confirm. Usegto abort.
Note: Visit mode (
v) works here, allowing back-and-forth movement between the minibuffer and other buffers. You can also usec(Convert mode)n/pto loop through history.
- Isearch (
s): Prompts in the minibuffer. Hit<RET>to finish input, then usen/pto loop through buffer candidates. Presssagain to search a new string (oreto modify the last string), orgto exit. - Mark Management: Hit
SPCtwice to set a mark, andx SPCto return to it. You can invoke Convert mode over a mark, execute commands, and return to Normal mode while retaining the mark. - Negative Arguments: Combine
-with directional commands (e.g.,- tto select backward to a char,- kto kill backward a line).
Motion Mode complements the core layers by providing a private, mode-specific set of keybindings. It is particularly useful for modes that define specialized functions or keybinding overrides.
For example, in Org mode, navigating between headings normally requires C-c C-n and C-c C-p. With Scamx, these commands can be rebound to simpler keys such as n and p, enabling a more streamlined workflow. The same approach can be extended to other frequently used commands. Users are free to customize both the bindings and the underlying functions according to their preferences.
(scamx-motion-define-key
'("g" . meow-motion-exit) ; applied globally
(org-mode
'("=" . org-mark-element)
'("n" . org-next-visible-heading)
'("p" . org-previous-visible-heading)
'("RET" . org-meta-return)
'("t" . org-insert-todo-heading)
'("h" . org-insert-heading-respect-content)
'("j" . org-insert-todo-heading-respect-content)
'("f" . org-shiftright)
'("b" . org-shiftleft)
'("u" . org-shiftup)
'("d" . org-shiftdown)
'("l" . org-insert-link)
'("i" . org-toggle-inline-images)
'(">" . org-goto-calendar)
'("e" . org-set-effort)
'("C-i" . org-clock-in)
'("C-o" . org-clock-out))
;; add more here
)- Visit Mode: May occasionally mishandle the
*Messages*buffer on the first navigation attempt. - Command Conflicts: Occur in natively one-key oriented modes (e.g.,
dired-mode,image-mode,magit-mode). Ifgconflicts with a nativerevert buffer, userin Visit mode instead.
- Add more functions to convert mode (e.g., up-list, kill-sexp).
- Integrate with
multiple-cursors. - Merge
meowof things command series into a generalized, DWIM-style zap command. - Allow single Normal mode commands to execute inside Convert mode (similar to
C-oin Vim). - Implement Motion mode as buffer-wise.
- Improve selection mechanics for the inside/outside of balanced expressions.
- Implement Scamx multiple cursors