Getting started
Introduction
GNU Readline provides rich command-line editing with Emacs or Vi keybindings, history navigation, and programmable completion.
Default Mode
Readline defaults to Emacs mode. Most commands use Ctrl key combinations.
# Check current mode in Bash
set -o | grep -E 'emacs|vi'
# Switch to Vi mode
set -o vi
# Switch back to Emacs mode
set -o emacs
Quick Example
# Type a command
echo hello world
# Press Ctrl-a to jump to start
# Press Ctrl-e to jump to end
# Press Ctrl-w to delete word backwards
# Press Ctrl-k to kill to end of line
Configuration File
Readline settings are configured in ~/.inputrc:
# ~/.inputrc
set editing-mode emacs
set completion-ignore-case on
set show-all-if-ambiguous on
Emacs Mode - Movement
Character Movement
| Keybinding | Description |
|---|---|
Ctrl-f |
Forward one character |
Ctrl-b |
Backward one character |
Alt-f |
Forward one word |
Alt-b |
Backward one word |
Line Movement
| Keybinding | Description |
|---|---|
Ctrl-a |
Beginning of line |
Ctrl-e |
End of line |
Ctrl-xx |
Toggle between start and current position |
Screen Movement
| Keybinding | Description |
|---|---|
Ctrl-l |
Clear screen (keep current line) |
Alt-< |
Move to first history line |
Alt-> |
Move to last history line |
Emacs Mode - Editing
Character Deletion
| Keybinding | Description |
|---|---|
Ctrl-d |
Delete character under cursor |
Backspace |
Delete character before cursor |
Alt-d |
Delete word forward |
Alt-Backspace |
Delete word backward |
Killing (Cut)
| Keybinding | Description |
|---|---|
Ctrl-k |
Kill to end of line |
Ctrl-u |
Kill to beginning of line |
Ctrl-w |
Kill word backward |
Alt-k |
Kill to end of sentence |
Yanking (Paste)
| Keybinding | Description |
|---|---|
Ctrl-y |
Yank (paste) last killed text |
Alt-y |
Rotate kill ring and yank next |
Ctrl-] |
Character search forward |
Alt-Ctrl-] |
Character search backward |
Changing Case
| Keybinding | Description |
|---|---|
Alt-u |
Uppercase word |
Alt-l |
Lowercase word |
Alt-c |
Capitalize word |
Emacs Mode - History
History Navigation
| Keybinding | Description |
|---|---|
Ctrl-p |
Previous history entry |
Ctrl-n |
Next history entry |
Alt-< |
Beginning of history |
Alt-> |
End of history |
History Search
| Keybinding | Description |
|---|---|
Ctrl-r |
Reverse incremental search |
Ctrl-s |
Forward incremental search |
Alt-p |
Reverse search (non-incremental) |
Alt-n |
Forward search (non-incremental) |
History Expansion
!! # Last command
!n # Command number n
!-n # nth command back
!string # Most recent command starting with string
!?string? # Most recent command containing string
^old^new # Replace old with new in last command
!!:s/old/new/ # Substitute in last command
History Modifiers
!$ # Last argument of previous command
!^ # First argument of previous command
!* # All arguments of previous command
!:n # nth argument of previous command
!:n-m # Arguments n through m
Completion
Basic Completion
| Keybinding | Description |
|---|---|
Tab |
Complete filename/command |
Alt-? |
List possible completions |
Alt-* |
Insert all completions |
Alt-/ |
Complete filename |
Completion Types
| Keybinding | Description |
|---|---|
Alt-~ |
Complete username |
Alt-$ |
Complete variable |
Alt-@ |
Complete hostname |
Alt-! |
Complete command |
Completion Configuration
# ~/.inputrc
set completion-ignore-case on
set show-all-if-ambiguous on
set visible-stats on
set mark-symlinked-directories on
set colored-stats on
set completion-map-case on
Vi Mode
Enable Vi Mode
# In shell
set -o vi
# In ~/.inputrc
set editing-mode vi
set keymap vi
Insert Mode
| Keybinding | Description |
|---|---|
i |
Insert at cursor |
I |
Insert at line start |
a |
Append after cursor |
A |
Append at line end |
Esc |
Enter command mode |
Command Mode - Movement
| Keybinding | Description |
|---|---|
h |
Move left |
l |
Move right |
w |
Next word |
b |
Previous word |
0 |
Line start |
^ |
First non-blank |
$ |
Line end |
Command Mode - Editing
| Keybinding | Description |
|---|---|
x |
Delete character |
dw |
Delete word |
dd |
Delete line |
D |
Delete to end of line |
c |
Change |
cc |
Change line |
yy |
Yank line |
p |
Paste after |
P |
Paste before |
u |
Undo |
Command Mode - History
| Keybinding | Description |
|---|---|
k |
Previous history |
j |
Next history |
/ |
Search backward |
? |
Search forward |
n |
Repeat search |
N |
Reverse search |
Configuration (.inputrc)
Basic Settings
# ~/.inputrc
set editing-mode emacs
set bell-style none
set completion-ignore-case on
set show-all-if-ambiguous on
set visible-stats on
set mark-symlinked-directories on
set colored-stats on
set colored-completion-prefix on
Conditional Settings
# Apply settings only in Bash
$if Bash
set completion-ignore-case on
set show-all-if-ambiguous on
$endif
# Apply settings only in Python
$if Python
set editing-mode vi
$endif
Custom Key Bindings
# Map Ctrl-Space to complete
"\C-@": complete
# Map Alt-h to show help
"\eh": "\C-ahelp \C-m"
# Map Up/Down to history search
"\e[A": history-search-backward
"\e[B": history-search-forward
# Map Ctrl-p/Ctrl-n to history search
"\C-p": history-search-backward
"\C-n": history-search-forward
Macros
# Define text macro
"\C-xg": "git status\n"
# Multi-line macro
"\C-xp": "ps aux | grep "
# Insert current date
"\C-xd": "\C-a\C-k$(date +%Y-%m-%d) "
Advanced Features
Numeric Arguments
| Keybinding | Description |
|---|---|
Alt-1 to Alt-9 |
Set numeric argument |
Alt-- |
Negative argument |
Ctrl-u |
Universal argument (×4) |
# Delete 5 characters forward
Alt-5 Ctrl-d
# Move 3 words backward
Alt-3 Alt-b
# Repeat command 4 times
Ctrl-u command
Transpose
| Keybinding | Description |
|---|---|
Ctrl-t |
Transpose characters |
Alt-t |
Transpose words |
Special Commands
| Keybinding | Description |
|---|---|
Ctrl-v |
Quoted insert (literal next char) |
Ctrl-g |
Abort current operation |
Alt-r |
Revert line |
Ctrl-_ |
Undo |
Alt-Ctrl-y |
Yank first argument of previous command |
Spell Checking
# ~/.inputrc
set enable-spell-check on
# In Bash 4.3+
shopt -s dirspell
shopt -s cdspell
History Management
History Commands
# View history
history
# Clear history
history -c
# Delete entry number 5
history -d 5
# Append current session to history file
history -a
# Read history file
history -r
# Write history to file
history -w
History Variables
# Bash history configuration
export HISTSIZE=10000 # Commands in memory
export HISTFILESIZE=20000 # Commands in file
export HISTCONTROL=ignoreboth # Ignore duplicates and space-prefixed
export HISTIGNORE="ls:cd:pwd" # Ignore specific commands
export HISTTIMEFORMAT="%F %T " # Add timestamps
History File
# Default history file
~/.bash_history
# Change history file location
export HISTFILE=~/.my_history
# Disable history file
export HISTFILE=/dev/null
Practical Examples
Command Line Editing Workflow
# Type a long command
echo "Hello, this is a very long command"
# Made a mistake? Fix it quickly:
Ctrl-a # Jump to start
Alt-f # Move forward to "this"
Alt-d # Delete "this"
# Type "that"
Alt-f # Move to "long"
Ctrl-k # Kill rest of line
# Type new ending
History Search Example
# Previously ran: docker ps -a
# Now need similar command
Ctrl-r # Start reverse search
# Type: docker
# Press Ctrl-r again to cycle through matches
# Press Enter to execute or Esc to edit
Macro Example
# ~/.inputrc
# Git commit macro
"\C-xc": "git add . && git commit -m ''"
# After setup:
# Type commit message
Ctrl-x c
# Cursor positioned in quotes
# Type message and press Enter
Quick Directory Navigation
# ~/.inputrc
# Jump to common directories
"\eh": "cd ~\n"
"\ep": "cd ~/Projects\n"
"\ed": "cd ~/Documents\n"
# Usage:
Alt-h # Go home
Alt-p # Go to Projects
Common Use Cases
Fix Typos Quickly
# Typed: grp pattern file
Ctrl-a # Go to start
Ctrl-f # Move to 'g'
Ctrl-f # Move to 'r'
e # Insert 'e' (now 'gerp')
Ctrl-f # Move to 'p'
p # Insert 'p' (now 'grep')
Reuse Arguments
# Copy file
cp /very/long/path/to/file.txt /another/long/path/
# Edit the file just copied
vim Alt-. # Insert last argument
# Or: vim !$
Quick Text Manipulation
# Typed: hello world
Alt-b # Back to 'world'
Alt-u # Uppercase -> 'WORLD'
Ctrl-a # Start of line
Alt-c # Capitalize -> 'Hello'
Gotchas
Alt Key Not Working
Problem: Alt key combinations don't work in some terminals.
Solution:
# macOS Terminal: Enable "Use Option as Meta key"
# Preferences > Profiles > Keyboard > Use Option as Meta key
# iTerm2: Set Left/Right Option key to Esc+
# Preferences > Profiles > Keys > Left/Right Option Key > Esc+
# Or use Esc as alternative:
# Instead of Alt-f, press Esc then f
Ctrl-s Freezes Terminal
Problem: Pressing Ctrl-s freezes the terminal.
Solution:
# Disable XON/XOFF flow control
stty -ixon
# Add to ~/.bashrc to make permanent
echo "stty -ixon" >> ~/.bashrc
Vi Mode Confusing
Problem: Accidentally entered Vi mode, can't type normally.
Solution:
# Press Esc to enter command mode
# Press 'i' to return to insert mode
# Or switch back to Emacs mode permanently:
set -o emacs
# Add to ~/.bashrc:
echo "set -o emacs" >> ~/.bashrc
History Not Saving
Problem: Command history not persisted between sessions.
Solution:
# Check HISTFILE is set
echo $HISTFILE
# Check history is enabled
set -o | grep history
# Enable history:
set -o history
# Add to ~/.bashrc:
export HISTFILE=~/.bash_history
export HISTSIZE=10000
export HISTFILESIZE=20000
Completion Not Working
Problem: Tab completion doesn't work or incomplete.
Solution:
# Install bash-completion (Debian/Ubuntu)
sudo apt-get install bash-completion
# Install bash-completion (macOS)
brew install bash-completion@2
# Source in ~/.bashrc:
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
# Check programmable completion is enabled:
shopt -p progcomp
Inputrc Changes Not Applied
Problem: Changes to ~/.inputrc don't take effect.
Solution:
# Reload inputrc without restarting shell
bind -f ~/.inputrc
# Or restart shell:
exec bash
# Check if changes were applied:
bind -v | grep setting-name
Special Characters Not Inserting
Problem: Need to insert literal control characters.
Solution:
# Use quoted-insert (Ctrl-v)
Ctrl-v Tab # Insert literal tab
Ctrl-v Ctrl-a # Insert literal ^A
# In Vi mode (command mode):
# Press Ctrl-v then the character
Configuration Examples
Minimal ~/.inputrc
# Basic configuration
set editing-mode emacs
set bell-style none
set completion-ignore-case on
set show-all-if-ambiguous on
# Better history search
"\e[A": history-search-backward
"\e[B": history-search-forward
Advanced ~/.inputrc
# Editing mode
set editing-mode emacs
set bell-style none
# Completion
set completion-ignore-case on
set show-all-if-ambiguous on
set visible-stats on
set mark-symlinked-directories on
set colored-stats on
set colored-completion-prefix on
set completion-map-case on
set skip-completed-text on
# History
set history-preserve-point on
set revert-all-at-newline on
# Key bindings
"\e[A": history-search-backward
"\e[B": history-search-forward
"\C-p": history-search-backward
"\C-n": history-search-forward
# Macros
"\C-xg": "git status\n"
"\C-xl": "ls -lah\n"
"\C-xh": "cd ~\n"
# Application-specific
$if Bash
Space: magic-space
"\C-x\C-e": edit-and-execute-command
$endif
$if Python
"\C-l": clear-screen
$endif
Vi Mode Configuration
# ~/.inputrc
set editing-mode vi
set keymap vi-command
# Show mode indicator
set show-mode-in-prompt on
set vi-ins-mode-string "\1\e[6 q\2"
set vi-cmd-mode-string "\1\e[2 q\2"
# Use Emacs-style completion in insert mode
set keymap vi-insert
"\C-p": history-search-backward
"\C-n": history-search-forward
"\C-a": beginning-of-line
"\C-e": end-of-line
Integration Examples
Python REPL
# ~/.inputrc
$if Python
set editing-mode emacs
set completion-ignore-case on
"\C-p": history-search-backward
"\C-n": history-search-forward
$endif
MySQL Client
# ~/.inputrc
$if mysql
set completion-ignore-case on
set show-all-if-ambiguous on
"\C-p": history-search-backward
"\C-n": history-search-forward
$endif
GDB Debugger
# ~/.inputrc
$if gdb
set editing-mode emacs
"\C-p": history-search-backward
"\C-n": history-search-forward
$endif
Also see
- GNU Readline Manual - Official documentation
- Bash Reference Manual - Readline init file syntax
- Readline Init File Syntax - Detailed configuration guide
- Bash History Facilities - History expansion
- Readline Vi Mode Cheatsheet - PDF cheatsheet
- Bash Emacs Editing Mode Cheatsheet - PDF cheatsheet