Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ZLE / ZLE-Widgets

Der Zsh Line Editor (ZLE) ist das Herzstück der Kommandozeilen-Bearbeitung in zsh. Er ermöglicht umfangreiche Anpassungen der Eingabe, eigene Tastenkürzel und mächtige Widgets.

1 Grundlagen & Architektur

1.1 Was ist ZLE?

ZLE ist der eingebaute Zeileneditor von zsh, vergleichbar mit readline in bash. Er verarbeitet alle Tastatureingaben und stellt Funktionen bereit für:

  • Cursor-Bewegung und Textbearbeitung
  • History-Navigation
  • Tab-Completion
  • Vi- und Emacs-Modus
  • Benutzerdefinierte Widgets

1.2 Keymaps

ZLE organisiert Tastenbelegungen in Keymaps:

KeymapBeschreibung
emacsEmacs-Modus (Standard)
viinsVi-Insert-Modus
vicmdVi-Command-Modus
visualVi-Visual-Modus
isearchInkrementelle Suche
commandBefehlseingabe (nach M-x)
mainAlias für aktive Keymap

Aktuelle Keymap anzeigen:

bindkey -l          # Alle Keymaps auflisten
bindkey -M emacs    # Bindungen der emacs-Keymap
bindkey -M viins    # Bindungen des vi-Insert-Modus

Keymap wechseln:

# Emacs-Modus (Standard)
bindkey -e

# Vi-Modus
bindkey -v

1.3 Widgets

Ein Widget ist eine Funktion, die an eine Taste gebunden werden kann. ZLE stellt über 150 eingebaute Widgets bereit.

Eingebaute Widgets anzeigen:

zle -la             # Alle Widgets auflisten
zle -la | wc -l     # Anzahl
zle -la | grep hist # Widgets mit "hist" im Namen

Wichtige eingebaute Widgets:

WidgetBeschreibung
accept-lineZeile ausführen (Enter)
backward-charCursor links
forward-charCursor rechts
backward-wordWort zurück
forward-wordWort vor
beginning-of-lineZeilenanfang
end-of-lineZeilenende
backward-delete-charBackspace
delete-charDelete
kill-lineBis Zeilenende löschen
backward-kill-lineBis Zeilenanfang löschen
kill-wordWort löschen
yankEinfügen (aus Kill-Ring)
undoRückgängig
redoWiederholen
clear-screenBildschirm löschen
history-search-backwardHistory rückwärts suchen
history-search-forwardHistory vorwärts suchen
expand-or-completeTab-Completion
self-insertZeichen einfügen

1.4 Aktuelle Bindungen anzeigen

# Alle Bindungen
bindkey

# Bestimmte Taste
bindkey "^A"        # Was macht Ctrl+A?
bindkey "^[[A"      # Was macht Pfeil-Hoch?

# Widget suchen
bindkey | grep kill

1.5 Escape-Sequenzen

Tasten werden als Escape-Sequenzen dargestellt:

NotationBedeutungBeispiel
^XCtrl+X^A = Ctrl+A
^[Escape / Alt^[b = Alt+B
\eEscape (alternativ)\eb = Alt+B
`^[CSI (Terminal-Sequenz)^[[A = Pfeil hoch
^[OSS3 (Terminal-Sequenz)^[OA = Pfeil hoch (alt)

Terminal-Sequenzen ermitteln:

# Methode 1: cat
cat -v
# Dann Taste drücken, z.B. Pfeil hoch zeigt: ^[[A

# Methode 2: read
read -k
# Taste drücken

# Methode 3: Ctrl+V in zsh
# Ctrl+V drücken, dann Taste → zeigt Sequenz

Häufige Terminal-Sequenzen:

TasteSequenz
Pfeil hoch^[[A
Pfeil runter^[[B
Pfeil rechts^[[C
Pfeil links^[[D
Home^[[H oder ^[OH
End^[[F oder ^[OF
Delete^[[3~
Page Up^[[5~
Page Down^[[6~
F1–F12^[OP bis ^[[24~

1.6 ZLE-Variablen

Innerhalb eines Widgets verfügbare Variablen:

VariableBeschreibung
$BUFFERGesamte Eingabezeile
$LBUFFERText links vom Cursor
$RBUFFERText rechts vom Cursor
$CURSORCursor-Position (0-basiert)
$WIDGETName des aktuellen Widgets
$LASTWIDGETName des vorherigen Widgets
$KEYSGedrückte Tasten
$KEYMAPAktive Keymap
$PREBUFFERVorherige Zeilen (Multiline)
$REGION_ACTIVEIst Region aktiv?
$MARKPosition der Markierung

2 Eigene Widgets schreiben

2.1 Widget-Grundstruktur

# Widget-Funktion definieren
my-widget() {
    # Code hier
}

# Als Widget registrieren
zle -N my-widget

# An Taste binden
bindkey "^X^M" my-widget

2.2 Einfache Beispiele

Text einfügen:

# Aktuelles Datum einfügen
insert-date() {
    LBUFFER+=$(date +%Y-%m-%d)
}
zle -N insert-date
bindkey "^Xd" insert-date

# Timestamp einfügen
insert-timestamp() {
    LBUFFER+=$(date +"%Y-%m-%d %H:%M:%S")
}
zle -N insert-timestamp
bindkey "^Xt" insert-timestamp

Buffer manipulieren:

# Zeile in Großbuchstaben
uppercase-line() {
    BUFFER=${BUFFER:u}
}
zle -N uppercase-line
bindkey "^Xu" uppercase-line

# Zeile in Kleinbuchstaben
lowercase-line() {
    BUFFER=${BUFFER:l}
}
zle -N lowercase-line
bindkey "^Xl" lowercase-line

# Wort unter Cursor in Großbuchstaben
uppercase-word() {
    local word="${LBUFFER##* }"
    LBUFFER="${LBUFFER% *} ${word:u}"
}
zle -N uppercase-word

Sudo voranstellen:

prepend-sudo() {
    if [[ $BUFFER != sudo\ *](`.md); then
        BUFFER="sudo $BUFFER"
        CURSOR+=5
    fi
}
zle -N prepend-sudo
bindkey "^[s" prepend-sudo   # Alt+S

2.3 Mit History arbeiten

# Letzten Befehl mit sudo wiederholen
sudo-last-command() {
    BUFFER="sudo $(fc -ln -1)"
    zle accept-line
}
zle -N sudo-last-command
bindkey "^[!" sudo-last-command

# Letztes Argument des vorherigen Befehls
insert-last-arg() {
    zle insert-last-word
}
zle -N insert-last-arg
bindkey "^[." insert-last-arg   # Alt+. (oft schon belegt)

2.4 Externe Befehle einbinden

# fzf für History-Suche
fzf-history() {
    local selected
    selected=$(fc -ln 1 | fzf --tac --no-sort)
    if [-n "$selected"](-n%20"$selected".md); then
        BUFFER="$selected"
        CURSOR=$#BUFFER
    fi
    zle redisplay
}
zle -N fzf-history
bindkey "^R" fzf-history

# fzf für Dateiauswahl
fzf-file() {
    local file
    file=$(fzf)
    if [-n "$file"](-n%20"$file".md); then
        LBUFFER+="${(q)file}"  # Quoted einfügen
    fi
    zle redisplay
}
zle -N fzf-file
bindkey "^Xf" fzf-file

# fzf für Verzeichniswechsel
fzf-cd() {
    local dir
    dir=$(find . -type d 2>/dev/null | fzf)
    if [-n "$dir"](-n%20"$dir".md); then
        cd "$dir"
        zle reset-prompt
    fi
}
zle -N fzf-cd
bindkey "^Xc" fzf-cd

2.5 Clipboard-Integration

# Auswahl in Clipboard kopieren (macOS)
copy-to-clipboard() {
    echo -n "$BUFFER" | pbcopy
    zle -M "Copied to clipboard"
}
zle -N copy-to-clipboard
bindkey "^Xy" copy-to-clipboard

# Aus Clipboard einfügen
paste-from-clipboard() {
    LBUFFER+=$(pbpaste)
}
zle -N paste-from-clipboard
bindkey "^Xp" paste-from-clipboard

# Kill-Ring nach Clipboard
copy-kill-ring() {
    echo -n "$CUTBUFFER" | pbcopy
    zle -M "Kill buffer copied"
}
zle -N copy-kill-ring

2.6 Widgets mit Parametern

# Widget das andere Widgets aufruft
surround-with-quotes() {
    BUFFER="\"$BUFFER\""
    CURSOR=$#BUFFER
}
zle -N surround-with-quotes
bindkey "^X\"" surround-with-quotes

# Flexibler: Wrapper-Funktion
surround-with() {
    local open="$1" close="$2"
    BUFFER="${open}${BUFFER}${close}"
    CURSOR=$#BUFFER
}

surround-parens()   { surround-with '(' ')'; }
surround-brackets() { surround-with '[' ']'; }
surround-braces()   { surround-with '{' '}'; }
surround-single()   { surround-with "'" "'"; }
surround-double()   { surround-with '"' '"'; }

zle -N surround-parens
zle -N surround-brackets
zle -N surround-braces
zle -N surround-single
zle -N surround-double

bindkey "^X(" surround-parens
bindkey "^X[" surround-brackets
bindkey "^X{" surround-braces
bindkey "^X'" surround-single
bindkey '^X"' surround-double

2.7 Rückgabewerte und Fehlerbehandlung

# Widget mit Fehlermeldung
safe-rm() {
    if [-z "$BUFFER"](-z%20"$BUFFER".md); then
        zle -M "Buffer ist leer"
        return 1
    fi

    if ["$BUFFER" == rm\ *]("$BUFFER"%20==%20rm\%20*.md); then
        BUFFER="${BUFFER/rm /rm -i }"
        zle -M "rm → rm -i (interaktiv)"
    fi
}
zle -N safe-rm
bindkey "^Xr" safe-rm

3 Erweiterte Shortcuts / ZLE-Bindings

3.1 bindkey Syntax

bindkey [optionen] "taste" widget
OptionBeschreibung
-eEmacs-Keymap aktivieren
-vVi-Keymap aktivieren
-M keymapBinding in bestimmter Keymap
-r "taste"Binding entfernen
-s "taste" "string"Makro (String einfügen)
-lKeymaps auflisten
-LBindungen als bindkey-Befehle

3.2 Tastenkombinationen definieren

# Einzelne Taste
bindkey "^A" beginning-of-line

# Tastensequenz
bindkey "^X^F" fzf-file

# Mit Escape/Alt
bindkey "^[b" backward-word     # Alt+B
bindkey "\eb" backward-word     # Alternative Notation

# Pfeiltasten
bindkey "^[[A" history-search-backward
bindkey "^[[B" history-search-forward

# Funktionstasten
bindkey "^[OP" my-f1-widget     # F1
bindkey "^[[15~" my-f5-widget   # F5

3.3 Makros (String-Bindungen)

Mit -s wird ein String eingefügt statt ein Widget aufgerufen:

# Pipe zu less
bindkey -s "^Xl" " | less"

# Pipe zu grep
bindkey -s "^Xg" " | grep "

# Redirect Stderr
bindkey -s "^Xe" " 2>&1"

# Redirect zu /dev/null
bindkey -s "^Xn" " > /dev/null 2>&1"

# Git Status
bindkey -s "^Gs" "git status\n"

# Git Diff
bindkey -s "^Gd" "git diff\n"

# Häufige Befehle
bindkey -s "^Ll" "ll\n"
bindkey -s "^Lc" "clear\n"

tip

\n führt den Befehl direkt aus.

3.4 Keymap-spezifische Bindungen

# Nur im Vi-Insert-Modus
bindkey -M viins "jk" vi-cmd-mode

# Nur im Vi-Command-Modus
bindkey -M vicmd "H" beginning-of-line
bindkey -M vicmd "L" end-of-line

# Nur im Emacs-Modus
bindkey -M emacs "^Xe" edit-command-line

3.5 Bindung entfernen

# Binding entfernen
bindkey -r "^X^K"

# In bestimmter Keymap
bindkey -M viins -r "^A"

3.6 Alle Bindungen exportieren/importieren

# Aktuelle Bindungen als Befehle ausgeben
bindkey -L > ~/bindkeys-backup.zsh

# Wiederherstellen
source ~/bindkeys-backup.zsh

4 Erweiterte Tastenkombinationen

4.1 Emacs-Modus Referenz

Navigation:

KürzelWidgetBeschreibung
Ctrl+Abeginning-of-lineZeilenanfang
Ctrl+Eend-of-lineZeilenende
Ctrl+Fforward-charZeichen vor
Ctrl+Bbackward-charZeichen zurück
Alt+Fforward-wordWort vor
Alt+Bbackward-wordWort zurück

Bearbeitung:

KürzelWidgetBeschreibung
Ctrl+Ddelete-charZeichen löschen
Ctrl+Hbackward-delete-charBackspace
Ctrl+Wbackward-kill-wordWort rückwärts löschen
Alt+Dkill-wordWort vorwärts löschen
Ctrl+Kkill-lineBis Zeilenende löschen
Ctrl+Ubackward-kill-lineBis Zeilenanfang löschen
Ctrl+YyankEinfügen
Alt+Yyank-popVorheriges aus Kill-Ring
Ctrl+Ttranspose-charsZeichen tauschen
Alt+Ttranspose-wordsWörter tauschen
Alt+Uup-case-wordWort GROSS
Alt+Ldown-case-wordWort klein
Alt+Ccapitalize-wordWort Kapitalisieren

History:

KürzelWidgetBeschreibung
Ctrl+Pup-line-or-historyVorheriger Befehl
Ctrl+Ndown-line-or-historyNächster Befehl
Ctrl+Rhistory-incremental-search-backwardHistory suchen rückwärts
Ctrl+Shistory-incremental-search-forwardHistory suchen vorwärts
Alt+<beginning-of-buffer-or-historyErste History
Alt+>end-of-buffer-or-historyLetzte History
Alt+.insert-last-wordLetztes Argument

Sonstiges:

KürzelWidgetBeschreibung
Ctrl+Lclear-screenBildschirm löschen
Ctrl+_undoRückgängig
Ctrl+X Ctrl+UundoRückgängig (alternativ)
Ctrl+X Ctrl+Eedit-command-lineIn Editor öffnen
Tabexpand-or-completeCompletion
Ctrl+Gsend-breakAbbrechen

4.2 Vi-Modus Referenz

Modus wechseln:

KürzelBeschreibung
EscapeInsert → Command
iInsert vor Cursor
aInsert nach Cursor
AInsert am Zeilenende
IInsert am Zeilenanfang
oNeue Zeile darunter
ONeue Zeile darüber

Navigation (Command-Modus):

KürzelBeschreibung
h / lLinks / Rechts
j / kHistory runter / hoch
w / bWort vor / zurück
eWortende
0 / $Zeilenanfang / -ende
^Erstes Nicht-Whitespace
f{char}Vorwärts zu Zeichen
F{char}Rückwärts zu Zeichen
t{char}Vor Zeichen
T{char}Nach Zeichen (rückwärts)

Bearbeitung (Command-Modus):

KürzelBeschreibung
xZeichen löschen
XZeichen davor löschen
ddGanze Zeile löschen
DBis Zeilenende löschen
dwWort löschen
cwWort ändern
ccZeile ändern
CBis Zeilenende ändern
r{char}Zeichen ersetzen
RReplace-Modus
yyZeile kopieren
ywWort kopieren
p / PEinfügen nach/vor
uUndo
Ctrl+RRedo

History (Command-Modus):

KürzelBeschreibung
/patternVorwärts suchen
?patternRückwärts suchen
n / NNächster / Vorheriger Treffer

4.3 Eigene Keymap erstellen

# Neue Keymap basierend auf emacs
bindkey -N mymap emacs

# Anpassungen
bindkey -M mymap "^Xd" insert-date
bindkey -M mymap "^Xs" prepend-sudo

# Keymap aktivieren
bindkey -A mymap main

4.4 Contextuelle Bindings

# Binding nur bei bestimmter Eingabe
# Beispiel: Tab verhält sich unterschiedlich

smart-tab() {
    if [-z "$LBUFFER"](-z%20"$LBUFFER".md); then
        # Leere Zeile: 4 Spaces einfügen
        LBUFFER+="    "
    elif ["$LBUFFER" =~ '^ +$']("$LBUFFER"%20=~%20'^%20+$'.md); then
        # Nur Whitespace: weitere Spaces
        LBUFFER+="    "
    else
        # Sonst: normale Completion
        zle expand-or-complete
    fi
}
zle -N smart-tab
bindkey "^I" smart-tab

5 Beispiele & Use-Cases

5.1 Produktivitäts-Widgets

Befehl in Editor öffnen:

# Bereits eingebaut, aber oft nicht gebunden
autoload -U edit-command-line
zle -N edit-command-line
bindkey "^Xe" edit-command-line
bindkey "^X^E" edit-command-line

Git-Integration:

# Git Branch wechseln mit fzf
fzf-git-branch() {
    local branch
    branch=$(git branch --all | grep -v HEAD | fzf --preview 'git log --oneline -20 {1}')
    branch=${branch#remotes/origin/}
    branch=${branch## }
    if [-n "$branch"](-n%20"$branch".md); then
        BUFFER="git checkout $branch"
        zle accept-line
    fi
}
zle -N fzf-git-branch
bindkey "^Gb" fzf-git-branch

# Git Status anzeigen (ohne Ausführung)
show-git-status() {
    zle -M "$(git status -s 2>/dev/null || echo 'Not a git repo')"
}
zle -N show-git-status
bindkey "^Gs" show-git-status

# Git Add mit fzf
fzf-git-add() {
    local files
    files=$(git status -s | fzf -m | awk '{print $2}')
    if [-n "$files"](-n%20"$files".md); then
        BUFFER="git add ${files//$'\n'/ }"
        CURSOR=$#BUFFER
    fi
    zle redisplay
}
zle -N fzf-git-add
bindkey "^Ga" fzf-git-add

Verzeichnis-Navigation:

# Schnell zu häufigen Verzeichnissen
goto-projects() {
    local dir
    dir=$(find ~/projects -maxdepth 1 -type d | fzf)
    if [-n "$dir"](-n%20"$dir".md); then
        cd "$dir"
        zle reset-prompt
    fi
}
zle -N goto-projects
bindkey "^Xp" goto-projects

# Parent Directory
goto-parent() {
    cd ..
    zle reset-prompt
}
zle -N goto-parent
bindkey "^X." goto-parent

# Zurück zum vorherigen Verzeichnis
goto-previous() {
    cd - > /dev/null
    zle reset-prompt
}
zle -N goto-previous
bindkey "^X-" goto-previous

5.2 Textmanipulation

Pipe-Operatoren schnell einfügen:

# Pipe-Menü
pipe-menu() {
    local pipes=(
        "| less"
        "| grep "
        "| head -20"
        "| tail -20"
        "| wc -l"
        "| sort"
        "| sort -u"
        "| xargs "
        "| awk '{print \$1}'"
        "| sed 's///g'"
        "> /dev/null 2>&1"
        "2>&1"
    )
    local selected
    selected=$(printf '%s\n' "${pipes[@]}" | fzf --prompt="Pipe: ")
    if [-n "$selected"](-n%20"$selected".md); then
        LBUFFER+=" $selected"
    fi
    zle redisplay
}
zle -N pipe-menu
bindkey "^X|" pipe-menu

Pfad expandieren:

# ~ und Variablen expandieren
expand-path() {
    BUFFER="${(e)BUFFER}"
}
zle -N expand-path
bindkey "^Xx" expand-path

# Aktuelles Wort zu absolutem Pfad
expand-to-absolute() {
    local word="${LBUFFER##* }"
    local rest="${LBUFFER% *}"
    local abs="${word:A}"
    if ["$rest" == "$LBUFFER"]("$rest"%20==%20"$LBUFFER".md); then
        LBUFFER="$abs"
    else
        LBUFFER="$rest $abs"
    fi
}
zle -N expand-to-absolute
bindkey "^Xa" expand-to-absolute

Wort-Operationen:

# Wort duplizieren
duplicate-word() {
    local word="${LBUFFER##* }"
    LBUFFER+=" $word"
}
zle -N duplicate-word
bindkey "^Xw" duplicate-word

# Wörter rückwärts
reverse-words() {
    local words=(${=BUFFER})
    BUFFER="${(j: :)${(Oa)words}}"
}
zle -N reverse-words

5.3 History-Erweiterungen

History mit Preview:

fzf-history-widget() {
    local selected
    selected=$(fc -rl 1 | fzf +s --tac \
        --preview 'echo {}' \
        --preview-window down:3:wrap)
    if [-n "$selected"](-n%20"$selected".md); then
        # Nummer entfernen
        BUFFER="${selected#*  }"
        CURSOR=$#BUFFER
    fi
    zle redisplay
}
zle -N fzf-history-widget
bindkey "^R" fzf-history-widget

Letzten Befehl modifizieren:

# Letzten Befehl holen und editierbar machen
recall-last-command() {
    BUFFER=$(fc -ln -1)
    CURSOR=$#BUFFER
}
zle -N recall-last-command
bindkey "^[r" recall-last-command

5.4 Prompt-Integration

# Prompt neu zeichnen nach Widget
update-prompt() {
    # Prompt-relevante Variablen aktualisieren
    zle reset-prompt
}

# Nach cd immer Prompt aktualisieren
cd-and-update() {
    if [-n "$BUFFER"](-n%20"$BUFFER".md); then
        zle accept-line
        zle reset-prompt
    fi
}

5.5 Debugging-Widgets

# Aktuellen Buffer anzeigen
debug-buffer() {
    zle -M "BUFFER: '$BUFFER' | LBUFFER: '$LBUFFER' | CURSOR: $CURSOR"
}
zle -N debug-buffer
bindkey "^Xb" debug-buffer

# Letzte Tasten anzeigen
debug-keys() {
    zle -M "KEYS: '$KEYS' | WIDGET: '$WIDGET' | LASTWIDGET: '$LASTWIDGET'"
}
zle -N debug-keys
bindkey "^Xk" debug-keys

# Widget-Liste durchsuchen
search-widgets() {
    local widget
    widget=$(zle -la | fzf --prompt="Widget: ")
    if [-n "$widget"](-n%20"$widget".md); then
        zle -M "Widget: $widget"
    fi
}
zle -N search-widgets
bindkey "^X?" search-widgets

5.6 Vollständige .zshrc-Integration

# ~/.zshrc - ZLE-Konfiguration

# === Grundeinstellungen ===
bindkey -e                              # Emacs-Modus

# === Standard-Verbesserungen ===
bindkey "^[[A" history-search-backward  # Pfeil hoch: History mit Prefix
bindkey "^[[B" history-search-forward   # Pfeil runter: History mit Prefix
bindkey "^[[H" beginning-of-line        # Home
bindkey "^[[F" end-of-line              # End
bindkey "^[[3~" delete-char             # Delete

# === Editor ===
autoload -U edit-command-line
zle -N edit-command-line
bindkey "^Xe" edit-command-line
bindkey "^X^E" edit-command-line

# === Eigene Widgets ===

# Sudo voranstellen
prepend-sudo() {
    [$BUFFER != sudo\ *]($BUFFER%20!=%20sudo\%20*.md) && BUFFER="sudo $BUFFER" && ((CURSOR+=5))
}
zle -N prepend-sudo
bindkey "^[s" prepend-sudo

# Datum einfügen
insert-date() { LBUFFER+=$(date +%Y-%m-%d); }
zle -N insert-date
bindkey "^Xd" insert-date

# Clipboard (macOS)
copy-buffer() { echo -n "$BUFFER" | pbcopy; zle -M "Copied"; }
paste-buffer() { LBUFFER+=$(pbpaste); }
zle -N copy-buffer
zle -N paste-buffer
bindkey "^Xy" copy-buffer
bindkey "^Xp" paste-buffer

# === Makros ===
bindkey -s "^Xl" " | less"
bindkey -s "^Xg" " | grep "
bindkey -s "^Xn" " > /dev/null 2>&1"

# === fzf-Integration (falls installiert) ===
if command -v fzf &> /dev/null; then
    # History
    fzf-history() {
        local cmd=$(fc -ln 1 | fzf --tac --no-sort)
        [-n "$cmd"](-n%20"$cmd".md) && BUFFER="$cmd" && CURSOR=$#BUFFER
        zle redisplay
    }
    zle -N fzf-history
    bindkey "^R" fzf-history

    # Dateien
    fzf-file() {
        local file=$(fzf)
        [-n "$file"](-n%20"$file".md) && LBUFFER+="${(q)file}"
        zle redisplay
    }
    zle -N fzf-file
    bindkey "^Xf" fzf-file

    # Verzeichnisse
    fzf-cd() {
        local dir=$(find . -type d 2>/dev/null | fzf)
        [-n "$dir"](-n%20"$dir".md) && cd "$dir" && zle reset-prompt
    }
    zle -N fzf-cd
    bindkey "^Xc" fzf-cd
fi

5.7 Cheatsheet

Widget erstellen:

widget-name() { ... }           # Funktion definieren
zle -N widget-name              # Als Widget registrieren
bindkey "^Xk" widget-name       # An Taste binden

Wichtige Variablen:

$BUFFER                         # Gesamte Zeile
$LBUFFER                        # Links vom Cursor
$RBUFFER                        # Rechts vom Cursor
$CURSOR                         # Cursor-Position

Bindkey:

bindkey                         # Alle Bindungen
bindkey "^X"                    # Was macht Ctrl+X?
bindkey "^Xk" widget            # Widget binden
bindkey -s "^Xk" "string"       # Makro binden
bindkey -r "^Xk"                # Binding entfernen
bindkey -M viins "jk" vi-cmd    # Keymap-spezifisch

Escape-Sequenzen:

^X   = Ctrl+X
^[   = Escape / Alt
^[[A = Pfeil hoch
^[[B = Pfeil runter
\n   = Enter (für Makros)