Work in the Modal Profile
This chapter activates modal, completes one ordinary editing workflow, uses
the integrated terminal without losing child input, and returns safely to
direct.
Before You Begin
If you enter this chapter directly, first complete Prepare the User Guide Exercises and Use Commands and Interactions. Reset the chapter-owned configuration examples:
"$HOME/odra-guide/kit/bin/odra-guide" reset configuration-examples
The keys below are factory bindings. Personal maps and active components can
change the effective route; use describe-key and describe-keymap-state to
inspect the current result.
Make Modal the Startup Profile
Create ~/odra-guide/config/odra/init.rkt with this complete configuration:
#lang racket/base
(require odra/keymaps)
(provide odra-interaction-profile)
(define odra-interaction-profile
(factory-modal-interaction-profile))
Launch the tutorial note:
odra "$HOME/odra-guide/work/dirs/notes/review.md"
The Status Bar shows NORMAL, and the text cursor is a block. A configuration
failure preserves the last confirmed profile generation. Without this
selection, a clean installation still starts in direct.
For a session-only change, run M-x select-interaction-profile, select
modal, and press Enter. Confirmation starts Normal without rewriting
init.rkt. Select direct through the same command when you want to return.
Move, Insert, and Replace Text
Normal does not insert unmatched printable input. Move with h, j, k, and
l; use 0 and $ for line boundaries, w, b, and e for words, and
gg or G for the buffer boundaries. Arrow, Home, End, Page Up, and Page Down
remain available through their canonical movement commands.
Press i. The Status Bar changes to INSERT, the cursor becomes a bar, and
ordinary text edits the active buffer. Backspace and Delete invoke the same
canonical deletion commands used by Direct. Press Escape or C-[ to return
to Normal. The other factory entry keys are:
| Key | Result |
|---|---|
a |
Move after the current grapheme and enter Insert. |
I, A |
Enter Insert at the first non-whitespace or line-end boundary. |
o, O |
Create a line below or above and enter Insert there. |
R |
Enter Replace at point. |
Insert retains compatible Direct editing bindings. For example, C-w keeps
kill-region, C-y keeps yank, and C-r keeps backward search. Modal
conventions do not replace those delivered Direct meanings while Insert owns
input.
Press R in Normal to enter Replace. The Status Bar changes to REPLACE, and
supporting frontends use an underline cursor. Type over existing text to
replace complete graphemes. Input at the end of the line inserts before the
line break, so replacement never consumes the following line. Press Escape
or C-[ to return to Normal; ordinary undo and redo reverse and restore the
replacement transactions.
Use Counts, Search, and Operators
In Normal, type 3w to move by three word starts. Digits 1 through 9
start a bounded count; 0 is a digit only after a count has started and is
otherwise line-start movement. An overflow or an incompatible counted command
is rejected before movement or mutation.
Press /, enter a literal search pattern, and press Enter. Use n and N to
repeat the confirmed canonical search forward or backward. ? begins the
same search workflow in the opposite direction.
Operators resolve one checked target before changing text:
| Input | Result |
|---|---|
d{movement}, c{movement}, y{movement} |
Delete, change, or copy one movement range. |
dd, cc, yy |
Apply the operator to complete logical lines. |
>, < with a target |
Indent or outdent intersecting logical lines. |
x, X |
Delete the next or previous complete grapheme. |
r<char> |
Replace one complete grapheme and remain Normal. |
p, P |
Paste shared retained text after or before point. |
. |
Repeat the latest admitted semantic change at the current point. |
u, C-r |
Invoke canonical undo or redo. |
Counts compose with operators and movements. Modal delete, change, copy, and paste share Odra's ordinary history, kill ring, clipboard adapter, and named text slots; there is no second modal buffer or unnamed register.
To try semantic repetition, press i, type reviewed, and return to Normal
with Escape. Move to another insertion point and press .. Odra resolves the
recorded Insert entry at the new point and commits the retained text as one
history unit. Press u to reverse only that repeated change and C-r to
restore it.
You can also repeat deletion, change, replacement, indentation, paste, and
named-slot insertion. Operator movements and named slots are resolved from the
current context. If the command catalog or modal profile has changed, or the
current target is unavailable, Odra reports the rejection without changing
the buffer. Run M-x describe-modal-repeat to inspect the bounded record
without displaying its retained text.
Select with Visual States
Press v for Visual Character, V for Visual Line, or C-v for Visual Block.
The Status Bar shows VISUAL, VISUAL LINE, or VISUAL BLOCK. Movement
extends the active buffer's canonical selection. Character and Line use a
linear region; Block derives one logical grapheme-column range per intersected
line. Use o to exchange its active end and anchor.
Apply d, c, or y to any Visual selection. Rectangular copy joins the
selected line ranges with newlines; rectangular delete and change edit all
ranges as one undoable transaction. > and < apply to Character and Line
selections. Delete, copy, indent, and outdent return to Normal; change enters
Insert. Escape or C-[ cancels Visual interaction and returns to Normal.
Invoke Commands and Use Editor Contexts
Press : in Normal or any Visual state, type a canonical command name such
as save-associated-document, and press Enter. : and protected M-x use
the same command catalog and command identities; shorthand aliases such as
:w are not added.
Use the Normal pane prefix to work across views:
| Input | Result |
|---|---|
C-w h, C-w j, C-w k, C-w l |
Focus an adjacent pane. |
C-w s, C-w v |
Split below or to the right. |
C-w c, C-w o, C-w = |
Close, keep only, or balance panes. |
The ordinary buffer candidates, prompts, completion, Darek, Maksym, Ksawery, search, diagnostics, and result surfaces keep their local input maps while active. Closing them restores the compatible modal state. Switching to a different buffer ends a Visual selection because a selection cannot span buffers.
Work in the Integrated Terminal
Run M-x terminal-new. A focused live terminal keeps its terminal-input
context, so ordinary keys go to the child even when the Status Bar says
NORMAL or INSERT. In particular, ordinary Escape is encoded for the
child; it does not leave Insert or change editor state.
Press C-\ C-n to enter modal terminal copy mode. The child keeps running,
and retained terminal text accepts h, j, k, l, 0, $, arrows, Home,
End, Page Up, and Page Down. Use C-SPC to set the mark and M-w to copy.
Press Enter to finish copy mode and return to live input in Normal. Press i
instead to finish copy mode, enter Insert, and return to live child input.
Live input uses the child-owned terminal cursor; copy mode uses a non-blinking
block cursor at the retained-text point.
M-x and C-g remain protected editor recovery routes. Run
M-x terminal-send-next-key, or use its factory C-q binding, to forward one
otherwise intercepted terminal key. The direct profile retains its existing
terminal bindings and pass-through behavior.
Inspect and Recover
Run M-x describe-keymap-state to inspect the selected profile, state,
pending modal composition, and active contextual owner. Use describe-key for
one physical sequence and where-is for the active bindings of one canonical
command.
Press C-g to cancel a pending count, operator, character target, command
entry, prompt, or candidate interaction. A stale view, buffer, state, terminal,
or configuration candidate is rejected without partial mutation; the last
confirmed profile and recovery commands remain available.
Recorded macros, external editor configuration, and external editor plugins remain outside the current modal profile.