Skip to content

Commit b835aa9

Browse files
Update bash and zsh to use vi mode (#8)
* Update bash and zsh to use vi mode * Update keymaps and add better around/inside textobjects for tmux
1 parent c234656 commit b835aa9

File tree

10 files changed

+209
-5
lines changed

10 files changed

+209
-5
lines changed

.bashrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ done
2727
# Set variable identifying the chroot you work in
2828
[ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ] && debian_chroot=$(cat /etc/debian_chroot)
2929
# Color prompt
30-
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
30+
PS1='\n${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\$ '
3131
# If this is an xterm set the title to user@host:dir
3232
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
3333

@@ -45,4 +45,4 @@ fi
4545
# zoxide
4646
if command -v zoxide >/dev/null; then
4747
eval "$(zoxide init --cmd cd bash)"
48-
fi
48+
fi

.commonrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export XDG_RUNTIME_DIR="$XDG_CONFIG_HOME/local/runtime-dir"
1313
[ -d "$XDG_RUNTIME_DIR" ] || mkdir -p "$XDG_RUNTIME_DIR"
1414
[ "$(stat -c "%a" "$XDG_RUNTIME_DIR")" = "700" ] || chmod 700 "$XDG_RUNTIME_DIR"
1515

16+
# NOTE: Ctrl-X + Ctrl-E : Edits the current line in the $EDITOR program
17+
export VISUAL=vim
18+
export EDITOR=vim
19+
1620
# Set system locale
1721
export LANG=C.UTF-8
1822
export LANGUAGE=C.UTF-8
@@ -22,6 +26,9 @@ export PAGER=less
2226
# Enable 256 colors with xterm
2327
export TERM=xterm-256color
2428

29+
# Disable the freeze/unfreeze behavior for Ctrl-S/Q
30+
stty -ixon
31+
2532
addToPath () { [[ "$PATH" != *"$1"* ]] && export PATH="$PATH:$1"; }
2633
addToPathFront () { [[ "$PATH" != *"$1"* ]] && export PATH="$1:$PATH"; }
2734

.config/alias/.alias

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ if command -v nvim >/dev/null; then
22
# Don't connect to the X server.
33
# Shortens startup time in a terminal, but the window title and clipboard will not be used.
44
alias vi="nvim -X"
5+
export VISUAL=nvim
56
export EDITOR=nvim
67
export MANPAGER='nvim +Man!'
78
fi
@@ -22,6 +23,10 @@ else
2223
fi
2324

2425
if command -v lazygit &> /dev/null; then alias lg="lazygit"; fi
26+
# Copy and pasting from Windows to Linux
27+
# ^M is the keyboard equivalent to \r or Ctrl-V + Ctrl-M in Vim
28+
# dos2unix convert or translate the ^M characters
29+
if command -v dos2unix &> /dev/null; then alias d2u="dos2unix"; fi
2530

2631
alias cl="clear"
2732

.config/nvim/lua/config/keymaps.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ vim.keymap.set('n', 'x', 'charcol(".") == charcol("$") ? "J" : "x"', { expr = tr
104104

105105
-- Save file
106106
vim.keymap.set({ 'i', 'x', 'n', 's' }, '<C-s>', '<cmd>w<cr><Esc>', { desc = 'Save file' })
107+
-- `:cq` to quit, without saving, with a nonzero exit code to indicate failure - bash will not execute the command
108+
vim.keymap.set('n', 'ZC', '<cmd>cq<CR>', { desc = 'Quit without saving with a nonzero exit code' })
107109
-- New file
108110
vim.keymap.set('n', '<Leader>nf', '<cmd>enew<CR>', { desc = '[N]ew [F]ile' })
109111
-- Disable go to sleep keymap
@@ -146,7 +148,9 @@ vim.keymap.set('n', 'cA', 'ggdGi', { desc = '[C]hange [A]ll lines' })
146148
vim.keymap.set('n', 'yA', '<cmd>%y<CR>', { desc = '[Y]ank [A]ll lines', silent = true })
147149
-- Select to end of line: similar to `C`, `D` and `Y`
148150
vim.keymap.set('n', 'L', 'v$h', { desc = 'Select to end of line' })
151+
vim.keymap.set('v', 'L', '$h', { desc = 'Select to end of line' })
149152
vim.keymap.set('n', 'H', 'v^', { desc = 'Select to start of line' })
153+
vim.keymap.set('v', 'H', '^', { desc = 'Select to start of line' })
150154
-- Select pasted text: similar to `gv`
151155
vim.keymap.set('n', 'gp', [['`[' . strpart(getregtype(), 0, 1) . '`]']], { expr = true, desc = 'Select previous pasted text' })
152156

.config/nvim/lua/plugins/mini.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ return { -- Collection of various small independent plugins/modules
122122
-- Add/delete/replace surroundings (brackets, quotes, etc.)
123123
-- Supports dot-repeat
124124
--
125+
-- Examples:
125126
-- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren
126127
-- - sd' - [S]urround [D]elete [']quotes
127128
-- - sr)' - [S]urround [R]eplace [)] [']

.config/tmux/tmux.conf

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,17 @@ bind-key C-Space last-window
3939
# Don't exit copy mode when dragging with mouse
4040
# Does not work if tmux-yank is enabled
4141
# unbind -T copy-mode-vi MouseDragEnd1Pane
42-
bind-key k copy-mode
42+
43+
# NOTE: Use `tmux list-key` to see the key bindings
44+
# Enter copy-mode and move one line up/down
45+
bind-key k copy-mode \; send-key k
46+
bind-key j copy-mode \; send-key j
47+
# Enter copy-mode and search upwards
48+
# bind-key / copy-mode \; send-key ?
49+
# `n` to always search forward and `N` backward
50+
bind-key / copy-mode \; bind-key -T copy-mode-vi n send-keys -X search-reverse \; bind-key -T copy-mode-vi N send-keys -X search-again \; command-prompt -i -p "(search up)" "send -X search-backward-incremental \"%%%\""
51+
bind-key -T copy-mode-vi / \; bind-key -T copy-mode-vi N send-keys -X search-reverse \; bind-key -T copy-mode-vi n send-keys -X search-again \; command-prompt -i -p "(search down)" "send -X search-forward-incremental \"%%%\""
52+
bind-key -T copy-mode-vi ? \; bind-key -T copy-mode-vi n send-keys -X search-reverse \; bind-key -T copy-mode-vi N send-keys -X search-again \; command-prompt -i -p "(search up)" "send -X search-backward-incremental \"%%%\""
4353

4454
# vim mode
4555
bind-key -T copy-mode-vi v {
@@ -54,6 +64,18 @@ bind-key -T copy-mode-vi v {
5464
}
5565
}
5666
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
67+
bind-key -T copy-mode-vi L {
68+
if-shell -F "#{selection_present}" {} { send-key v }
69+
send-key $
70+
send-key h
71+
}
72+
bind-key -T copy-mode-vi H {
73+
if-shell -F "#{selection_present}" {} { send-key v }
74+
send-key ^
75+
}
76+
77+
# Better Around/Inside textobjects
78+
source-file $XDG_CONFIG_HOME/tmux/tmux.textobjects.conf
5779

5880
# Start numbering at 1 instead of 0
5981
set -g base-index 1
@@ -88,4 +110,4 @@ if "test ! -d $XDG_CONFIG_HOME/tmux/plugins/tpm" \
88110
"run 'git clone -q --depth=1 https://github.com/tmux-plugins/tpm $XDG_CONFIG_HOME/tmux/plugins/tpm && $XDG_CONFIG_HOME/tmux/plugins/tpm/bin/install_plugins'"
89111

90112
# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
91-
run "$XDG_CONFIG_HOME/tmux/plugins/tpm/tpm"
113+
run "$XDG_CONFIG_HOME/tmux/plugins/tpm/tpm"

.config/tmux/tmux.textobjects.conf

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Better Around/Inside textobjects
2+
# Adapted from https://github.com/kite12580/.vim/blob/main/config/.tmux.conf
3+
bind -T copy-mode-vi i switch-client -T copyModeMultiKey_i
4+
bind -T copyModeMultiKey_i w send-keys -X select-word
5+
bind -T copyModeMultiKey_i W send-keys -X clear-selection \; send-keys -X previous-space \; send-keys -X begin-selection \; send-keys -X next-space-end
6+
bind -T copyModeMultiKey_i ( send-keys -X clear-selection \; send-keys -X jump-to-forward ')' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '('
7+
bind -T copyModeMultiKey_i ) send-keys -X clear-selection \; send-keys -X jump-to-forward ')' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '('
8+
bind -T copyModeMultiKey_i \{ send-keys -X clear-selection \; send-keys -X jump-to-forward '}' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '{'
9+
bind -T copyModeMultiKey_i \} send-keys -X clear-selection \; send-keys -X jump-to-forward '}' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '{'
10+
bind -T copyModeMultiKey_i [ send-keys -X clear-selection \; send-keys -X jump-to-forward ']' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '['
11+
bind -T copyModeMultiKey_i ] send-keys -X clear-selection \; send-keys -X jump-to-forward ']' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '['
12+
bind -T copyModeMultiKey_i < send-keys -X clear-selection \; send-keys -X jump-to-forward '>' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '<'
13+
bind -T copyModeMultiKey_i > send-keys -X clear-selection \; send-keys -X jump-to-forward '>' \; send-keys -X begin-selection \; send-keys -X jump-to-backward '<'
14+
bind -T copyModeMultiKey_i ` send-keys -X clear-selection \; send-keys -X jump-to-backward '`' \; send-keys -X begin-selection \; send-keys -X jump-to-forward '`'
15+
bind -T copyModeMultiKey_i \' send-keys -X clear-selection \; send-keys -X jump-to-backward "'" \; send-keys -X begin-selection \; send-keys -X jump-to-forward "'"
16+
bind -T copyModeMultiKey_i \" send-keys -X clear-selection \; send-keys -X jump-to-backward '"' \; send-keys -X begin-selection \; send-keys -X jump-to-forward '"'
17+
bind -T copyModeMultiKey_i l send-keys -X clear-selection \; send-keys -X back-to-indentation \; send-keys -X begin-selection \; send-keys -X end-of-line \; send-keys -X cursor-left \; send-keys -X other-end
18+
bind -T copyModeMultiKey_i b {
19+
send-keys -X clear-selection
20+
send -X search-forward '[])}>]'
21+
send-keys -X begin-selection
22+
send -X search-backward '[[({<]'
23+
send-key o
24+
send-key h
25+
send-key o
26+
send-key l
27+
}
28+
# cursor has to be inside [q]uotes
29+
bind -T copyModeMultiKey_i q {
30+
send-keys -X clear-selection
31+
send -X search-forward "[`'\"]"
32+
send-keys -X begin-selection
33+
send -X search-backward "[`'\"]"
34+
send-key o
35+
send-key h
36+
send-key o
37+
send-key l
38+
}
39+
bind -T copy-mode-vi a switch-client -T copyModeMultiKey_a
40+
bind -T copyModeMultiKey_a ( send-keys -X clear-selection \; send-keys -X jump-forward ')' \; send-keys -X begin-selection \; send-keys -X jump-backward '('
41+
bind -T copyModeMultiKey_a ) send-keys -X clear-selection \; send-keys -X jump-forward ')' \; send-keys -X begin-selection \; send-keys -X jump-backward '('
42+
bind -T copyModeMultiKey_a \{ send-keys -X clear-selection \; send-keys -X jump-forward '}' \; send-keys -X begin-selection \; send-keys -X jump-backward '{'
43+
bind -T copyModeMultiKey_a \} send-keys -X clear-selection \; send-keys -X jump-forward '}' \; send-keys -X begin-selection \; send-keys -X jump-backward '{'
44+
bind -T copyModeMultiKey_a [ send-keys -X clear-selection \; send-keys -X jump-forward ']' \; send-keys -X begin-selection \; send-keys -X jump-backward '['
45+
bind -T copyModeMultiKey_a ] send-keys -X clear-selection \; send-keys -X jump-forward ']' \; send-keys -X begin-selection \; send-keys -X jump-backward '['
46+
bind -T copyModeMultiKey_a < send-keys -X clear-selection \; send-keys -X jump-forward '>' \; send-keys -X begin-selection \; send-keys -X jump-backward '<'
47+
bind -T copyModeMultiKey_a > send-keys -X clear-selection \; send-keys -X jump-forward '>' \; send-keys -X begin-selection \; send-keys -X jump-backward '<'
48+
bind -T copyModeMultiKey_a ` send-keys -X clear-selection \; send-keys -X jump-backward '`' \; send-keys -X begin-selection \; send-keys -X jump-forward '`'
49+
bind -T copyModeMultiKey_a \' send-keys -X clear-selection \; send-keys -X jump-backward "'" \; send-keys -X begin-selection \; send-keys -X jump-forward "'"
50+
bind -T copyModeMultiKey_a \" send-keys -X clear-selection \; send-keys -X jump-backward '"' \; send-keys -X begin-selection \; send-keys -X jump-forward '"'
51+
bind -T copyModeMultiKey_a b {
52+
send-keys -X clear-selection
53+
send -X search-forward '[])}>]'
54+
send-keys -X begin-selection
55+
send -X search-backward '[[({<]'
56+
}
57+
# cursor has to be inside [q]uotes
58+
bind -T copyModeMultiKey_a q {
59+
send-keys -X clear-selection
60+
send -X search-forward "[`'\"]"
61+
send-keys -X begin-selection
62+
send -X search-backward "[`'\"]"
63+
}

.config/zsh/bindkey-vi.zsh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Retrieve emacs bindings in the form of bindkey commands
2+
local emacs_binding=$(bindkey -L)
3+
4+
# https://thevaluable.dev/zsh-install-configure-mouseless - Zsh With Vim Flavors
5+
# Use vi mode
6+
bindkey -v
7+
# Makes the switch between modes quicker
8+
export KEYTIMEOUT=10
9+
# Apply emacs bindings to vi
10+
eval $emacs_binding
11+
12+
# Exit insert mode with `kj`
13+
bindkey -M viins 'kj' vi-cmd-mode
14+
15+
# Change cursor shape when switching between modes
16+
cursor_mode() {
17+
cursor_block='\e[2 q'
18+
cursor_beam='\e[6 q'
19+
function zle-keymap-select {
20+
if [[ ${KEYMAP} == vicmd ]] ||
21+
[[ $1 = 'block' ]]; then
22+
echo -ne $cursor_block
23+
elif [[ ${KEYMAP} == main ]] ||
24+
[[ ${KEYMAP} == viins ]] ||
25+
[[ ${KEYMAP} = '' ]] ||
26+
[[ $1 = 'beam' ]]; then
27+
echo -ne $cursor_beam
28+
fi
29+
}
30+
zle-line-init() {
31+
echo -ne $cursor_beam
32+
}
33+
zle -N zle-keymap-select
34+
zle -N zle-line-init
35+
}
36+
cursor_mode
37+
38+
# Adding Text Objects
39+
# Examples:
40+
# - va) - [V]isually select [A]round [)]paren
41+
# - ci' - [C]hange [I]nside [']quote
42+
autoload -Uz select-bracketed select-quoted
43+
zle -N select-quoted
44+
zle -N select-bracketed
45+
for km in viopp visual; do
46+
bindkey -M $km -- '-' vi-up-line-or-history
47+
for c in {a,i}${(s..)^:-\'\"\`\|,./:;=+@}; do
48+
bindkey -M $km $c select-quoted
49+
done
50+
for c in {a,i}${(s..)^:-'()[]{}<>bB'}; do
51+
bindkey -M $km $c select-bracketed
52+
done
53+
done
54+
55+
# Add/delete/replace surroundings (brackets, quotes, etc.)
56+
# Examples:
57+
# - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren
58+
# - sd' - [S]urround [D]elete [']quotes
59+
# - sr)' - [S]urround [R]eplace [)] [']
60+
autoload -Uz surround
61+
zle -N delete-surround surround
62+
zle -N add-surround surround
63+
zle -N change-surround surround
64+
bindkey -M vicmd sr change-surround
65+
bindkey -M vicmd sd delete-surround
66+
bindkey -M vicmd sa add-surround
67+
bindkey -M visual sa add-surround

.config/zsh/bindkey.zsh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44
# Use emacs keybindings even if our EDITOR is set to vi
55
bindkey -e
66

7+
# Use vi mode
8+
[ -f $ZDOTDIR/bindkey-vi.zsh ] && source $ZDOTDIR/bindkey-vi.zsh
9+
710
# Load widgets that are not loaded by default.
811
autoload -U up-line-or-beginning-search
912
zle -N up-line-or-beginning-search
1013

1114
autoload -U down-line-or-beginning-search
1215
zle -N down-line-or-beginning-search
1316

17+
autoload edit-command-line
18+
zle -N edit-command-line
19+
1420
function () {
1521
emulate -L zsh -o no_aliases
1622

@@ -51,6 +57,9 @@ function () {
5157
kLFT5 '^[[1;5D' backward-word # Ctrl + LeftArrow
5258
x '^U' backward-kill-line # Ctrl + U
5359
x '^U^U' kill-whole-line # Ctrl + UU
60+
# vi mode
61+
x '^Q' edit-command-line # Ctrl + Q - edit command line in vim buffer
62+
x '^?' backward-delete-char # Fix backspace bug when switching between modes
5463
); do
5564
bindkey -M emacs ${terminfo[$kcap]:-$seq} $widget
5665
bindkey -M viins ${terminfo[$kcap]:-$seq} $widget
@@ -72,4 +81,3 @@ FZF_CTRL_F_COMMAND () {
7281
}
7382
zle -N FZF_CTRL_F_COMMAND
7483
bindkey '^f' FZF_CTRL_F_COMMAND
75-

.inputrc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
set editing-mode vi
2+
# NOTE: bash 4.3 and readline 6.3 and above
3+
set show-mode-in-prompt on
4+
set vi-ins-mode-string \1\e[6 q\2\e[106;30mI\e[0m
5+
set vi-cmd-mode-string \1\e[2 q\2\e[102;30mN\e[0m
6+
7+
set keymap vi-insert
8+
"kj": vi-movement-mode
9+
"\ee": emacs-editing-mode
10+
"\C-n": next-history
11+
"\C-p": previous-history
12+
"\C-a": beginning-of-line
13+
"\C-e": end-of-line
14+
15+
set keymap vi-command
16+
"\ee": emacs-editing-mode
17+
"\C-n": next-history
18+
"\C-p": previous-history
19+
"\C-a": beginning-of-line
20+
"\C-e": end-of-line
21+
22+
set keymap emacs
23+
"\ee": vi-editing-mode
24+
25+
# v goes vi-editing-mode in cmd mode
26+
# `:cq` to quit, without saving, with a nonzero exit code to indicate failure - bash will not execute the command
27+
# - `ZC` custom nvim keymap

0 commit comments

Comments
 (0)