aboutsummaryrefslogtreecommitdiff
path: root/common/config/zsh/user/bindings.zsh
blob: 52cab064c37b70132e4d83c318ac92fc181c303e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
##########    Vi mode    ##########
bindkey -v

local WORDCHARS='*?_-.[]~=&;!#$%^(){}<>'
backward-kill-dir () {
    local WORDCHARS=${WORDCHARS/\/}
    zle backward-kill-word
    zle -f kill
}

zle -N backward-kill-dir
bindkey '^[^?' backward-kill-dir
bindkey "^W" backward-kill-dir

bindkey -M viins '^[[3~'  delete-char
bindkey -M vicmd '^[[3~'  delete-char
bindkey -v '^?' backward-delete-char
bindkey -r '\e/'
bindkey -s jk '\e'
#bindkey "^W" backward-kill-word
bindkey "^H" backward-delete-char      # Control-h also deletes the previous char
bindkey "^U" backward-kill-line
bindkey "^[j" history-search-forward # or you can bind it to the down key "^[[B"
bindkey "^[k" history-search-backward # or you can bind it to Up key "^[[A"

bindkey '^[[D' backward-char   # Left arrow
bindkey '^[[C' forward-char    # Right arrow
bindkey '^[D' backward-char   # Left arrow
bindkey '^[C' forward-char    # Right arrow
bindkey '[C' forward-word
bindkey '[D' backward-word
bindkey -M viins '^[[D' backward-char   # Left arrow
bindkey -M viins '^[[C' forward-char    # Right arrow

bindkey -M vicmd '^[[D' backward-char   # Left arrow
bindkey -M vicmd '^[[C' forward-char    # Right arrow

# Define the 'autosuggest-execute' and 'autosuggest-accept' ZLE widgets
autoload -Uz autosuggest-execute autosuggest-accept
zle -N autosuggest-execute
zle -N autosuggest-accept
bindkey '^X' autosuggest-execute
bindkey '^Y' autosuggest-accept
bindkey '\M-l' accept-and-complete-next-history

# Accept completion with <tab> or Ctrl+i and go to next/previous suggestions with Vi like keys: Ctrl+n/p
zmodload -i zsh/complist
accept-and-complete-next-history() {
    zle expand-or-complete-prefix
}
zle -N accept-and-complete-next-history
#bindkey -M menuselect '^i' accept-and-complete-next-history
bindkey '^n' expand-or-complete
bindkey '^p' reverse-menu-complete
#bindkey '^I' expand-or-complete
#bindkey '^[[Z]]' reverse-menu-complete
bindkey -M menuselect '^[' undo

# Edit line in vim with alt-e
autoload edit-command-line; zle -N edit-command-line
bindkey '^e' edit-command-line
bindkey '^[e' edit-command-line # alt + e

# Allow CTRL+D to exit zsh with partial command line (non empty line)
exit_zsh() { exit }
zle -N exit_zsh
bindkey '^D' exit_zsh

# Copy/Paste
# Safe clipboard copy
smart_copy() {
    local text="${LBUFFER}${RBUFFER}"

    # Prefer Wayland, fallback to X11, then others
    if command -v wl-copy >/dev/null 2>&1 && [[ "$WAYLAND_DISPLAY" || "$XDG_SESSION_TYPE" == "wayland" ]]; then
        echo -n "$text" | wl-copy --foreground --type text/plain 2>/dev/null || true
    elif command -v xclip >/dev/null 2>&1 && [[ "$DISPLAY" || "$XDG_SESSION_TYPE" == "x11" || "$XDG_SESSION_TYPE" == "x11-xwayland" ]]; then
        echo -n "$text" | xclip -selection clipboard 2>/dev/null || true
    elif [[ "$(uname -s)" == "Darwin" ]] && command -v pbcopy >/dev/null 2>&1; then
        echo -n "$text" | pbcopy 2>/dev/null || true
    elif [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
        echo -n "$text" | clip.exe 2>/dev/null || true
    else
        echo "smart_copy: No supported clipboard utility found." >&2
    fi
}

# Safe clipboard paste
smart_paste() {
    local clip=""
    if command -v wl-paste >/dev/null 2>&1 && [[ "$WAYLAND_DISPLAY" || "$XDG_SESSION_TYPE" == "wayland" ]]; then
        clip=$(wl-paste --no-newline 2>/dev/null)
    elif command -v xclip >/dev/null 2>&1 && [[ "$DISPLAY" || "$XDG_SESSION_TYPE" == "x11" || "$XDG_SESSION_TYPE" == "x11-xwayland" ]]; then
        clip=$(xclip -selection clipboard -o 2>/dev/null)
    elif [[ "$(uname -s)" == "Darwin" ]] && command -v pbpaste >/dev/null 2>&1; then
        clip=$(pbpaste 2>/dev/null)
    elif [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
        clip=$(powershell.exe -Command 'Get-Clipboard -Raw' 2>/dev/null | tr -d '\r')
    else
        echo "smart_paste: No supported clipboard utility found." >&2
    fi

    LBUFFER+="$clip"
    zle reset-prompt
}

# Register widgets
zle -N smart_copy
zle -N smart_paste

# Bind keys (optional: choose your preferred)
bindkey '^V' smart_paste
bindkey -M viins '^V' smart_paste
bindkey -M vicmd '^V' smart_paste
bindkey -M vicmd 'p' smart_paste

bindkey '^Y' smart_copy
bindkey -M viins '^Y' smart_copy
bindkey -M vicmd '^Y' smart_copy
bindkey -M vicmd 'y' smart_copy

# In vi mode, map Alt-H and Alt-L
#bindkey -M viins "^[u" go_up   # Alt-H to go up
#bindkey -M viins "^[o" go_into  # Alt-L to go into a directory


# Newline and clear
function newline_clear() {
    printf "\n"
    command clear
}

zle -N newline_clear

no_tmux_clear() {
    zle clear-screen
}
zle -N no_tmux_clear

# Newline before clear
if [[ -n "$TMUX" ]]; then
    # Bind Ctrl-L to send newline and clear screen
    bindkey '^L' newline_clear
else
    bindkey '^L' no_tmux_clear
fi

# use ctrl-z to toggle in and out of bg
function toggle_fg_bg() {
    if [[ $#BUFFER -eq 0 ]]; then
        BUFFER="fg"
        zle accept-line
    else
        BUFFER=""
        zle clear-screen
    fi
}
zle -N toggle_fg_bg
bindkey '^Z' toggle_fg_bg




## Custom key bindings to control history behavior
#bindkey -M vicmd '^[[C' vi-forward-char      # Right arrow in normal mode - just move cursor
#bindkey -M vicmd '^[[D' vi-backward-char     # Left arrow in normal mode - just move cursor
#bindkey -M vicmd '^A' beginning-of-line      # Ctrl-A - go to beginning of line
#bindkey -M vicmd '^E' end-of-line            # Ctrl-E - go to end of line

# Disable automatic suggestion accept on right arrow in normal mode

## Additional vi-mode key bindings to prevent unwanted history completion
## Disable automatic history completion in normal mode
#bindkey -M vicmd '^[[C' vi-forward-char      # Right arrow - just move right, don't complete
#bindkey -M vicmd '^[[D' vi-backward-char     # Left arrow - just move left