This is my dotfiles repository - collection of the most convenient configurations for me, as far as I could make, for programs and Unix-like environments.

- Delete word on Ctrl + delete / backspace
- Convenient and beautiful
biratheme - Command completion via
zsh-autosuggestions - Alias completion
- Zoxide & uv setup
dotfiles=git --git-dir="$HOME/.dotfiles/" --work-tree="$HOME"
Adds $HOME/bin & $HOME/.local/bin to $PATH if exist.
Setup spicetify, jdtls, kotlin-lsp, Android SDK, Vulkan SDK and many other programs if they exist.
See .zshenv
A modern Neovim configuration with powerful language tooling and visual polish:
| Keybind | Action |
|---|---|
| Ctrl + arrows | Change split size (mini.basics) |
| Ctrl + h/j/k/l | Split navigation (mini.basics) |
| leader + bd | Close buffer (mini.bufremove) |
| leader + sv | Split window vertically (grinlex) |
| leader + sh | Split window horizontally (grinlex) |
| leader + se | Autosize split (grinlex) |
| leader + e | Toggle file explorer (neo-tree.nvim) |
| leader + q | Toggle quickfix (grinlex) |
| Alt + i | Open terminal (snacks.nvim) |
| Shift + l/h | Navigate opened buffers (bufferline.nvim) |
| Alt + l/h | Move opened buffers (bufferline.nvim) |
| leader + bp | Pin current buffer (bufferline.nvim) |
| leader + bo | Close all buffers except current (bufferline.nvim) |
| leader + bd | Close current buffer (mini.nvim) |
| leader + nm | Notifications (snacks.nvim) |
| leader + ff | Find files (telescope.nvim) |
| leader + fr | Find recent files (telescope.nvim) |
| leader + fs | Find string (Telescope.nvim) |
| Ctrl + h/j/k/l | Navigate search results (telescope.nvim) |
| Alt + h/j/k/l | Navigate search preview (telescope.nvim) |
| Ctrl + e | Quote text in search (telescope.nvim) |
| n | Next search (improved-search.nvim) |
| N | Previous search (improved-search.nvim) |
| ! | Search selected/word under cursor (improved-search.nvim) |
| \h | Clear highlights (mini.basics) |
| Alt + h/j/k/l | Move selection / current line (mini.move) |
| Tab | Indent line(s) in visual mode (grinlex) |
| Shift + Tab | Unindent line(s) in visual mode (grinlex) |
| Ctrl + s | Save file (mini.basics) |
| s | Substitute (substitute.nvim) |
| ss | Substitute line (substitute.nvim) |
| S | Substitute to end of line (substitute.nvim) |
| zA | Toggle folding under cursor (region-folding.nvim) |
| z + j/k | Navigate foldings (region-folding.nvim) |
| zR | Open all folds (region-folding.nvim) |
| zM | Close all folds (region-folding.nvim) |
| Ctrl + Space | Show autocomplete (blink.cmp) |
| Ctrl + e | Hide autocomplete (blink.cmp) |
| Ctrl + j/k | Navigate autocomplete (blink.cmp) |
| Alt + j/k | Scroll autocomplete docs (blink.cmp) |
| Alt + s | Toggle function signature (lsp_signature.nvim) |
| K | Show hover info (vim) |
| leader + d | Line diagnostics (vim) |
| leader + fd | Buffer diagnostics (telescope.nvim) |
| leader + fD | Workspace diagnostics (trouble.nvim) |
| leader + gD | Go to declaration (vim) |
| leader + gd | Show definitions (telescope.nvim) |
| leader + gi | Show implementations (telescope.nvim) |
| leader + gR | Show references (telescope.nvim) |
| leader + ga | Code actions (vim) |
| leader + gr | Smart rename (vim) |
| leader + gf | Format file or range (conform.nvim) |
| leader + gl | Lint current file (nvim-lint) |
| leader + rs | Restart lsp (vim) |
| gc[c] | Linewise comment (Comment) |
| gb[c] | Blockwise comment (Comment) |
| leader + gsa | Add surround (mini.surround) |
| leader + gsd | Delete surround (mini.surround) |
| leader + gsr | Replace surround (mini.surround) |
| leader + gsr | Replace surround (mini.surround) |
| leader + hs | Stage hunk (gitsigns.nvim) |
| leader + hr | Reset hunk (gitsigns.nvim) |
| leader + hS | Stage buffer (gitsigns.nvim) |
| leader + hR | Reset buffer (gitsigns.nvim) |
| leader + hu | Undo stage hunk (gitsigns.nvim) |
| leader + hp | Preview hunk (gitsigns.nvim) |
| leader + lg | Open lazy git (lazygit.nvim) |
| leader + cv | Select CMake preset (cmake-tools.nvim) |
| leader + cg | CMake generate (cmake-tools.nvim) |
| leader + ct | Select CMake build target (cmake-tools.nvim) |
| leader + cb | Build CMake target (cmake-tools.nvim) |
| leader + ci | CMake install (cmake-tools.nvim) |
| leader + cT | Select CMake launch target (cmake-tools.nvim) |
| leader + cd | Debug CMake target (cmake-tools.nvim) |
| leader + cc | CMake clean (cmake-tools.nvim) |
| leader + cx | Stop CMake executor (cmake-tools.nvim) |
| F5 | Continue / Start (nvim-dap) |
| F7 | Stop session (nvim-dap) |
| F9 | Toggle Breakpoint (nvim-dap) |
| F10 | Step Over (nvim-dap) |
| F11 | Step Into (nvim-dap) |
| F12 | Step Out (nvim-dap) |
| leader + ? | Buffer local keymaps (which-key.nvim) |
Install with:
sudo pacman -S cmake make ninja clang unzip rust python3 tree-sitter-cli fzf ripgrep wl-clipboard zsh zoxide lazygit uv fastfetch neovim kitty# For the latest version of nvim
sudo snap install nvim --classic
sudo apt install zsh zoxide cargo tree-sitter-cli cmake ninja-build unzip xclipscoop install rustup tree-sitter cmake ninja lazygit ripgrepUsing Arch Wiki's dotfile method:
git clone --bare https://github.com/GrinlexGH/.dotfiles.git $HOME/.dotfiles
alias dotfiles='/usr/bin/git --git-dir="$HOME/.dotfiles/" --work-tree="$HOME"'
dotfiles checkout
dotfiles config --local status.showUntrackedFiles noIf you get error like:
error: The following untracked working tree files would be overwritten by checkout:
.bashrc
.gitignore
Please move or remove them before you can switch branches.
AbortingYou can backup these files and try again:
mkdir -p .dotfiles-backup && \
dotfiles checkout 2>&1 | grep -E "^\s" | awk '{print $1}' | \
while read file; do
mkdir -p ".dotfiles-backup/$(dirname "$file")"
mv "$file" ".dotfiles-backup/$file"
done
dotfiles checkout
dotfiles config --local status.showUntrackedFiles noTo update the dotfiles later:
dotfiles pullNerd fonts:
https://www.nerdfonts.com/font-downloads
Zsh plugins:
https://github.com/zsh-users/zsh-autosuggestions
Android SDK for termux:
https://github.com/lzhiyong/termux-ndk
https://github.com/lzhiyong/android-sdk-tools
or
https://github.com/HomuHomu833/android-sdk-custom
https://github.com/HomuHomu833/android-ndk-custom
Fix self-hosted servers when VPN is on:
sudo tee /etc/NetworkManager/dispatcher.d/99-vpn-fix << 'EOF'
#!/bin/bash
INTERFACE=$1
ACTION=$2
TABLE_ID=200
RULE_PRIOS=(1500 2000 2001 2002 2003 2004 2005)
MARK_INBOUND=0x64 # 100 decimal
MARK_MASK=0xff
SVC_TCP_PORTS="80,443,25565"
SVC_UDP_PORTS="25565"
[[ "$INTERFACE" =~ ^(Meta|amn0|tun|wg|utun|ppp) ]] || exit 0
cleanup() {
ip rule del table $TABLE_ID 2>/dev/null
for p in "${RULE_PRIOS[@]}"; do
ip rule del priority "$p" 2>/dev/null
done
ip route flush table $TABLE_ID 2>/dev/null
if ip link show docker0 &>/dev/null; then
iptables -D FORWARD -i docker0 -j ACCEPT 2>/dev/null
iptables -D FORWARD -o docker0 -j ACCEPT 2>/dev/null
iptables -D FORWARD -i br-+ -j ACCEPT 2>/dev/null
iptables -D FORWARD -o br-+ -j ACCEPT 2>/dev/null
fi
iptables -t mangle -D PREROUTING -i "$PHYS_INT" -p tcp -m multiport --dports "$SVC_TCP_PORTS" \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $MARK_INBOUND 2>/dev/null
iptables -t mangle -D PREROUTING -i "$PHYS_INT" -p udp -m multiport --dports "$SVC_UDP_PORTS" \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $MARK_INBOUND 2>/dev/null
iptables -t mangle -D PREROUTING -j CONNMARK --restore-mark --mask $MARK_MASK 2>/dev/null
iptables -t mangle -D OUTPUT -j CONNMARK --restore-mark --mask $MARK_MASK 2>/dev/null
for OLD_PHYS in $(nmcli -t -f DEVICE,TYPE device 2>/dev/null | grep -E ':wifi|:ethernet|:wireless' | cut -d: -f1); do
iptables -t mangle -D PREROUTING -i "$OLD_PHYS" -p tcp -m multiport --dports "$SVC_TCP_PORTS" \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $MARK_INBOUND 2>/dev/null
iptables -t mangle -D PREROUTING -i "$OLD_PHYS" -p udp -m multiport --dports "$SVC_UDP_PORTS" \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $MARK_INBOUND 2>/dev/null
done
}
case "$ACTION" in
up)
if [ "$INTERFACE" = "amn0" ]; then
VPN_READY=true
else
for ((i=1; i<=15; i++)); do
if ip rule list | grep -qE "32764|16383|9000"; then
VPN_READY=true
break
fi
sleep 1
done
fi
if [ "$VPN_READY" != true ]; then
exit 0
fi
PHYS_INT=$(nmcli -t -f DEVICE,TYPE device | grep -E ':wifi|:ethernet|:wireless' | cut -d: -f1 | head -n1)
[ -n "$PHYS_INT" ] || exit 0
LAN_IP=$(ip -4 addr show "$PHYS_INT" | awk '/inet / {print $2}' | cut -d/ -f1)
LAN_NET=$(ip route show dev "$PHYS_INT" | grep -v default | grep "scope link" | awk '{print $1}' | head -n1)
GATEWAY=$(nmcli -g ip4.gateway device show "$PHYS_INT")
[ -n "$LAN_IP" ] && [ -n "$GATEWAY" ] || exit 0
cleanup
ip route add "$LAN_NET" dev "$PHYS_INT" scope link table $TABLE_ID 2>/dev/null
ip route add default via "$GATEWAY" dev "$PHYS_INT" table $TABLE_ID 2>/dev/null
ip rule add to 172.17.0.0/16 lookup main priority 2000 2>/dev/null
ip rule add to 172.18.0.0/16 lookup main priority 2001 2>/dev/null
ip rule add to "$LAN_NET" lookup main priority 2002 2>/dev/null
ip rule add from 172.17.0.0/16 table $TABLE_ID priority 2003 2>/dev/null
ip rule add from 172.18.0.0/16 table $TABLE_ID priority 2004 2>/dev/null
ip rule add from "$LAN_IP" table $TABLE_ID priority 2005 2>/dev/null
ip rule add fwmark $MARK_INBOUND lookup main priority 1500 2>/dev/null
iptables -t mangle -A PREROUTING -i "$PHYS_INT" -p tcp -m multiport --dports "$SVC_TCP_PORTS" \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $MARK_INBOUND
iptables -t mangle -A PREROUTING -i "$PHYS_INT" -p udp -m multiport --dports "$SVC_UDP_PORTS" \
-m conntrack --ctstate NEW -j CONNMARK --set-mark $MARK_INBOUND
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark --mask $MARK_MASK
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark --mask $MARK_MASK
if ip link show docker0 &>/dev/null; then
iptables -I FORWARD -i docker0 -j ACCEPT 2>/dev/null
iptables -I FORWARD -o docker0 -j ACCEPT 2>/dev/null
iptables -I FORWARD -i br-+ -j ACCEPT 2>/dev/null
iptables -I FORWARD -o br-+ -j ACCEPT 2>/dev/null
fi
;;
down)
PHYS_INT=$(nmcli -t -f DEVICE,TYPE device 2>/dev/null | grep -E ':wifi|:ethernet|:wireless' | cut -d: -f1 | head -n1)
cleanup
;;
esac
EOF
sudo chmod +x /etc/NetworkManager/dispatcher.d/99-vpn-fix
