├── Downloads ├── .config ├── fd │ └── ignore ├── dunst │ └── dunstrc ├── rofi │ └── config.rasi ├── nvim │ ├── init.lua │ └── coc-settings.json ├── pulse │ └── default.pa ├── surfingkeys.js ├── sublime-text-3 │ └── Packages │ │ └── User │ │ ├── Default (Linux).sublime-keymap │ │ └── Preferences.sublime-settings ├── gcal-notifier-kotlin-gtk │ └── settings.yml ├── xfce4 │ └── xfconf │ │ └── xfce-perchannel-xml │ │ ├── keyboards.xml │ │ ├── xfwm4.xml │ │ └── xfce4-keyboard-shortcuts.xml ├── micro │ ├── settings.json │ └── bindings.json ├── paru │ └── paru.conf ├── Code - OSS │ └── User │ │ ├── settings.json │ │ └── keybindings.json ├── user-dirs.dirs ├── gtk-3.0 │ └── settings.ini ├── karabiner │ └── assets │ │ └── complex_modifications │ │ ├── capsLockToCtrlAndEsc.json │ │ ├── ctrlBackspace.json │ │ └── ctrlArrows.json ├── i3blocks │ └── config ├── picom.conf ├── Crow Translate │ └── Crow Translate.conf ├── kitty │ └── kitty.conf ├── mimeapps.list ├── nnn │ └── plugins │ │ ├── preview-tabbed │ │ └── preview-tui ├── trizen │ └── trizen.conf ├── alacritty │ └── alacritty.yml ├── vim │ └── common.vim └── i3 │ └── config ├── .haskeline ├── .vnc └── config ├── .zshrc ├── .tor-browser └── app │ └── Browser │ └── Downloads ├── .vim ├── spell │ └── en.utf-8.add └── .gitconfig ├── .gnupg └── gpg-agent.conf ├── .v ├── ripgrep-without-flags.vim ├── vim-sh.vim ├── ripgrep-sensible.vim ├── long-lines.vim ├── markdown-preview-disable-sync-scroll.vim └── markdown-preview-enable-sync-scroll.vim ├── .inputrc ├── .bin ├── remove-all-pdf-metadata ├── mi ├── v ├── xpid ├── toggle-micro.bash ├── g ├── kill-process-on-port ├── bobko-screenlocker ├── upgrade ├── t ├── mv-strict ├── git-status.bash ├── pid-on-port ├── print-column ├── detach ├── isMacOs ├── prepend-each-line ├── macos-trust ├── echo-on-each-line ├── d ├── xargs-prepend-each-line ├── pass-gen ├── git-chi ├── o ├── stopwatch ├── interactive-cd ├── git-pull-smart-if-no-args ├── git-fetch-smart-if-no-args ├── git-cht ├── gp ├── rm-trash ├── spotlight ├── timer ├── git-fast-forward.bash ├── fix-spotify-on-mac ├── dnd ├── git-log-head ├── unshare-gradle ├── spotlight-cli ├── git-base ├── cb ├── async-profiler ├── mkscript ├── google-image-download-interactive.sh ├── fix-keyboard.sh ├── git-smart-cherry ├── pw ├── fix-name ├── idea-bobko └── git-jump ├── .vimrc ├── .Xresources.template ├── .bin-macos ├── alacritty └── google-chrome ├── .script ├── typeOnVirtualKeyboard.sh ├── todo-base ├── getActiveWindowTitle.sh └── macOsDefaults.sh ├── .gtkrc-2.0 ├── .xinitrc ├── .a └── Bobko.SC2Hotkeys ├── .ideavimrc ├── .github └── README.md ├── .aerospace.toml ├── .gitconfig ├── .shell.sh └── .tmux.conf /Downloads: -------------------------------------------------------------------------------- 1 | . -------------------------------------------------------------------------------- /.config/fd/ignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /.haskeline: -------------------------------------------------------------------------------- 1 | editMode: Vi 2 | -------------------------------------------------------------------------------- /.vnc/config: -------------------------------------------------------------------------------- 1 | session=i3 2 | -------------------------------------------------------------------------------- /.zshrc: -------------------------------------------------------------------------------- 1 | source ~/.shell.sh zsh 2 | -------------------------------------------------------------------------------- /.tor-browser/app/Browser/Downloads: -------------------------------------------------------------------------------- 1 | ../../.. -------------------------------------------------------------------------------- /.vim/spell/en.utf-8.add: -------------------------------------------------------------------------------- 1 | bobko 2 | JetBrains 3 | -------------------------------------------------------------------------------- /.gnupg/gpg-agent.conf: -------------------------------------------------------------------------------- 1 | no-allow-external-cache 2 | -------------------------------------------------------------------------------- /.v/ripgrep-without-flags.vim: -------------------------------------------------------------------------------- 1 | set grepprg=rg\ --vimgrep 2 | -------------------------------------------------------------------------------- /.vim/.gitconfig: -------------------------------------------------------------------------------- 1 | [clone] 2 | defaultRemoteName = origin 3 | -------------------------------------------------------------------------------- /.v/vim-sh.vim: -------------------------------------------------------------------------------- 1 | nnoremap :.!sh 2 | xnoremap :'<,'>!sh 3 | -------------------------------------------------------------------------------- /.config/dunst/dunstrc: -------------------------------------------------------------------------------- 1 | [skip-rule] 2 | appname=Spotify 3 | skip_display=true 4 | -------------------------------------------------------------------------------- /.inputrc: -------------------------------------------------------------------------------- 1 | # Ignore pasted enter at the end in bash 2 | set enable-bracketed-paste on 3 | -------------------------------------------------------------------------------- /.bin/remove-all-pdf-metadata: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | exiftool -overwrite_original -all= $@ 4 | -------------------------------------------------------------------------------- /.v/ripgrep-sensible.vim: -------------------------------------------------------------------------------- 1 | set grepprg=rg\ --vimgrep\ --ignore-case\ --fixed-strings\ --hidden\ --glob\ '!.git' 2 | -------------------------------------------------------------------------------- /.vimrc: -------------------------------------------------------------------------------- 1 | execute "set =\eJ" 2 | execute "set =\eK" 3 | 4 | source ~/.config/vim/common.vim 5 | 6 | -------------------------------------------------------------------------------- /.v/long-lines.vim: -------------------------------------------------------------------------------- 1 | set textwidth=0 2 | 3 | map j gj 4 | map k gk 5 | map H g^ 6 | map L g$ 7 | 8 | map g 9 | map g 10 | -------------------------------------------------------------------------------- /.config/rofi/config.rasi: -------------------------------------------------------------------------------- 1 | /*Dracula theme based on the Purple official rofi theme*/ 2 | configuration { 3 | show-icons: true; 4 | } 5 | 6 | element-icon { size: 3ch; } 7 | -------------------------------------------------------------------------------- /.v/markdown-preview-disable-sync-scroll.vim: -------------------------------------------------------------------------------- 1 | " https://github.com/iamcco/markdown-preview.nvim 2 | let g:mkdp_preview_options = { 3 | \ 'disable_sync_scroll': 1, 4 | \ } 5 | -------------------------------------------------------------------------------- /.v/markdown-preview-enable-sync-scroll.vim: -------------------------------------------------------------------------------- 1 | " https://github.com/iamcco/markdown-preview.nvim 2 | let g:mkdp_preview_options = { 3 | \ 'disable_sync_scroll': 0, 4 | \ } 5 | -------------------------------------------------------------------------------- /.Xresources.template: -------------------------------------------------------------------------------- 1 | ! Fonts {{{ 2 | Xft.antialias: true 3 | Xft.hinting: true 4 | Xft.rgba: rgb 5 | Xft.hintstyle: hintfull 6 | Xcursor.size: 30 7 | Xft.dpi: 190 8 | ! }}} 9 | -------------------------------------------------------------------------------- /.config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | -- Init NeoVim with Vim config 2 | vim.cmd([[ 3 | set runtimepath^=~/.vim runtimepath+=~/.vim/after 4 | let &packpath = &runtimepath 5 | source ~/.config/vim/common.vim 6 | ]]) 7 | -------------------------------------------------------------------------------- /.bin/mi: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | micro $@ 6 | -------------------------------------------------------------------------------- /.bin/v: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | exec nvim "$@" 6 | -------------------------------------------------------------------------------- /.bin/xpid: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | xprop _NET_WM_PID 6 | -------------------------------------------------------------------------------- /.bin/toggle-micro.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | amixer set Capture toggle 6 | -------------------------------------------------------------------------------- /.bin/g: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | # Disable slow git completion 6 | exec git "$@" 7 | -------------------------------------------------------------------------------- /.bin/kill-process-on-port: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | kill -9 $(lsof -t -i tcp:$1) 6 | 7 | -------------------------------------------------------------------------------- /.config/pulse/default.pa: -------------------------------------------------------------------------------- 1 | .include /etc/pulse/default.pa 2 | 3 | # Should be commented in /etc/pulse/default.pa 4 | # load-module module-switch-on-port-available 5 | 6 | .ifexists module-switch-on-connect.so 7 | load-module module-switch-on-connect 8 | .endif 9 | -------------------------------------------------------------------------------- /.bin/bobko-screenlocker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | xkb-switch -s us 6 | exec i3lock -c 000000 7 | -------------------------------------------------------------------------------- /.bin/upgrade: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | sudo pacman -S archlinux-keyring # update gpg keys 6 | gpg --refresh-keys 7 | sudo pacman -Syu 8 | trizen -Su --noconfirm --aur 9 | -------------------------------------------------------------------------------- /.bin/t: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | # Email myself. "t" stands for "todo" 6 | 7 | ~/.script/todo-base my-email@gmail.com "pass show google.com/my-email@gmail.com-app-password" my-email+todo@gmail.com 8 | -------------------------------------------------------------------------------- /.bin/mv-strict: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | if [ $# -ne 2 ]; then 6 | echo "Usage: mv-strict src dst" 7 | exit 1 8 | fi 9 | 10 | rm -rf "$2" || true 11 | mkdir -p "$2" 12 | rm -rf "$2" 13 | cp -r "$1" "$2" 14 | -------------------------------------------------------------------------------- /.config/surfingkeys.js: -------------------------------------------------------------------------------- 1 | // The config file for https://github.com/brookhong/Surfingkeys 2 | 3 | // Enter 'pass through' mode with 'p' 4 | api.map('p', '') 5 | 6 | // Whether to focus first candidate of matched result in Omnibar. 7 | // settings.focusFirstCandidate = false 8 | 9 | // Always use omnibox for picking tabs (don't use weird mnemonics) 10 | settings.tabsThreshold = 0; 11 | -------------------------------------------------------------------------------- /.bin/git-status.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | git status $@ 6 | 7 | if git rev-parse --quiet --verify CHERRY_PICK_HEAD > /dev/null; then 8 | echo "--- Cherry-pick HEAD:" 9 | git --no-pager log -1 CHERRY_PICK_HEAD 10 | fi 11 | -------------------------------------------------------------------------------- /.bin/pid-on-port: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | sudo lsof -n -i :$1 8 | -------------------------------------------------------------------------------- /.bin/print-column: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | awk "{print \$$1}" 8 | -------------------------------------------------------------------------------- /.bin/detach: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | exec nohup "$@" &> /dev/null & 8 | -------------------------------------------------------------------------------- /.bin/isMacOs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | [[ "$OSTYPE" == "darwin"* ]] 8 | -------------------------------------------------------------------------------- /.config/sublime-text-3/Packages/User/Default (Linux).sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | { "keys": ["ctrl+alt+right"], "command": "jump_forward" }, 3 | { "keys": ["ctrl+alt+left"], "command": "jump_back" }, 4 | { "keys": ["ctrl+tab"], "command": "next_view" }, 5 | { "keys": ["ctrl+shift+tab"], "command": "prev_view" }, 6 | { "keys": ["ctrl+shift+a"], "command": "show_overlay", "args": {"overlay": "command_palette"} }, 7 | ] 8 | -------------------------------------------------------------------------------- /.bin/prepend-each-line: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | awk "{print \"$1: \" \$0}" 8 | -------------------------------------------------------------------------------- /.bin/macos-trust: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | xattr -d com.apple.quarantine "$@" 8 | -------------------------------------------------------------------------------- /.bin/echo-on-each-line: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | for arg in "$@"; do echo "$arg"; done 8 | 9 | -------------------------------------------------------------------------------- /.bin-macos/alacritty: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | /Applications/Alacritty.app/Contents/MacOS/alacritty "$@" 8 | -------------------------------------------------------------------------------- /.config/gcal-notifier-kotlin-gtk/settings.yml: -------------------------------------------------------------------------------- 1 | # For date format documentation refer to: 2 | # https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/text/SimpleDateFormat.html 3 | dateFormat: dd MMM yyyy 4 | maxNumberOfEventsToShowInPopupMenu: 20 5 | # For time format documentation refer to: 6 | # https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/text/SimpleDateFormat.html 7 | timeFormat: HH:mm 8 | refreshFrequencyInMinutes: 5 -------------------------------------------------------------------------------- /.bin-macos/google-chrome: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome "$@" 8 | -------------------------------------------------------------------------------- /.bin/d: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | git -c status.showUntrackedFiles=no --git-dir=$HOME/.dotfiles --work-tree=$HOME "$@" 8 | -------------------------------------------------------------------------------- /.config/xfce4/xfconf/xfce-perchannel-xml/keyboards.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.bin/xargs-prepend-each-line: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | while read it; do 8 | eval "$@" "$it" | prepend-each-line "$it" 9 | done 10 | -------------------------------------------------------------------------------- /.bin/pass-gen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | username=$1 8 | 9 | file=$(mktemp) 10 | pwgen 23 > $file 11 | v $file 12 | pass insert -e "$username" < $file 13 | /bin/rm -rf $file 14 | -------------------------------------------------------------------------------- /.bin/git-chi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | # git checkout interactive 8 | 9 | head=${1:-HEAD} 10 | base=$(git base $head) 11 | git checkout --detach $head 12 | git rebase --interactive $base 13 | 14 | -------------------------------------------------------------------------------- /.bin/o: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | # "o" stands for "open" 6 | 7 | if [ ! -d "$1" ] && [ -x "$1" ]; then 8 | # The `if` is a replacement for `./executable`. It's not engornomic to type './' 9 | 10 | command="$1" 11 | shift 12 | 13 | exec ./"$command" "$@" 14 | fi 15 | 16 | if isMacOs; then 17 | open "$@" 18 | else 19 | detach xdg-open "$@" 20 | fi 21 | -------------------------------------------------------------------------------- /.bin/stopwatch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | echo "Press Enter to stop" 8 | now=$(date +%s)sec 9 | while true; do 10 | printf "%s\r" $(TZ=UTC date --date now-$now +%H:%M:%S.%N) 11 | sleep 0.1 12 | done 13 | -------------------------------------------------------------------------------- /.config/micro/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "autosu": true, 3 | "colorcolumn": 100, 4 | "colorscheme": "bubblegum", 5 | "cursorline": false, 6 | "eofnewline": false, 7 | "fastdirty": true, 8 | "hidehelp": false, 9 | "matchbrace": false, 10 | "matchbraceleft": false, 11 | "mkparents": true, 12 | "parsecursor": true, 13 | "pluginchannels": [ 14 | "https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json" 15 | ], 16 | "pluginrepos": [], 17 | "tabstospaces": true, 18 | "termtitle": false 19 | } 20 | -------------------------------------------------------------------------------- /.bin/interactive-cd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | cd "${1:-.}" 8 | while true; do 9 | selected="$(ls -aF | grep -v "^./$" | fzf --preview 'pwd' --height 60% --layout=reverse --preview-window up,1)" || break 10 | cd "$selected" 11 | done 12 | 13 | pwd 14 | -------------------------------------------------------------------------------- /.config/paru/paru.conf: -------------------------------------------------------------------------------- 1 | # 2 | # $PARU_CONF 3 | # /etc/paru.conf 4 | # ~/.config/paru/paru.conf 5 | # 6 | # See the paru.conf(5) manpage for options 7 | 8 | # 9 | # GENERAL OPTIONS 10 | # 11 | [options] 12 | PgpFetch 13 | Devel 14 | Provides 15 | DevelSuffixes = -git -cvs -svn -bzr -darcs -always 16 | BottomUp 17 | #RemoveMake 18 | SudoLoop 19 | #UseAsk 20 | #CombinedUpgrade 21 | #CleanAfter 22 | #UpgradeMenu 23 | #NewsOnUpgrade 24 | SkipReview 25 | 26 | #LocalRepo 27 | #Chroot 28 | #MovePkgs 29 | 30 | # 31 | # Binary OPTIONS 32 | # 33 | #[bin] 34 | #FileManager = vifm 35 | #MFlags = --skippgpcheck 36 | #Sudo = doas 37 | -------------------------------------------------------------------------------- /.config/Code - OSS/User/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.suggestSelection": "first", 3 | "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue", 4 | "editor.fontFamily": "JetBrains Mono", 5 | "workbench.activityBar.visible": false, 6 | "editor.renderWhitespace": "all", 7 | "editor.rulers": [ 8 | 120 9 | ], 10 | "workbench.startupEditor": "none", 11 | "cSpell.userWords": [ 12 | "commited" 13 | ], 14 | "workbench.colorTheme": "Visual Studio Light", 15 | "security.workspace.trust.untrustedFiles": "open", 16 | "security.workspace.trust.enabled": false 17 | } -------------------------------------------------------------------------------- /.config/user-dirs.dirs: -------------------------------------------------------------------------------- 1 | # This file is written by xdg-user-dirs-update 2 | # If you want to change or add directories, just edit the line you're 3 | # interested in. All local changes will be retained on the next run. 4 | # Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped 5 | # homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an 6 | # absolute path. No other format is supported. 7 | # 8 | XDG_DESKTOP_DIR="$HOME/" 9 | XDG_DOWNLOAD_DIR="$HOME/" 10 | XDG_DOCUMENTS_DIR="$HOME/" 11 | XDG_PICTURES_DIR="$HOME/" 12 | XDG_VIDEOS_DIR="$HOME/" 13 | XDG_TEMPLATES_DIR="$HOME/" 14 | XDG_PUBLICSHARE_DIR="$HOME/" 15 | XDG_MUSIC_DIR="$HOME/" 16 | -------------------------------------------------------------------------------- /.bin/git-pull-smart-if-no-args: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | if [ $# -eq 0 ]; then 8 | branch="$(git rev-parse --abbrev-ref HEAD)" 9 | if [ "$branch" = "HEAD" ]; then 10 | git pull o master || git pull o main 11 | else 12 | git pull o "$branch" 13 | fi 14 | else 15 | git pull "$@" 16 | fi 17 | -------------------------------------------------------------------------------- /.config/sublime-text-3/Packages/User/Preferences.sublime-settings: -------------------------------------------------------------------------------- 1 | { 2 | "color_scheme": "auto", 3 | "detect_indentation": false, 4 | "font_face": "JetBrains Mono Regular", 5 | "font_options": 6 | [ 7 | "no_liga", 8 | "no_clig", 9 | "no_calt" 10 | ], 11 | "font_size": 20, 12 | "ignored_packages": 13 | [ 14 | "Vintage", 15 | ], 16 | "rulers": 17 | [ 18 | 100 19 | ], 20 | "tab_size": 4, 21 | "theme": "Default.sublime-theme", 22 | "word_wrap": true, 23 | "save_on_focus_lost": true, 24 | "draw_white_space": ["all"], 25 | "dark_color_scheme": "Monokai.sublime-color-scheme", 26 | "light_color_scheme": "Breakers.sublime-color-scheme", 27 | } 28 | -------------------------------------------------------------------------------- /.bin/git-fetch-smart-if-no-args: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | if [ $# -eq 0 ]; then 8 | branch="$(git rev-parse --abbrev-ref HEAD)" 9 | if [ "$branch" = "HEAD" ]; then 10 | git fetch o master || git fetch o main 11 | else 12 | git fetch o "$branch" 13 | fi 14 | else 15 | git fetch "$@" 16 | fi 17 | -------------------------------------------------------------------------------- /.script/typeOnVirtualKeyboard.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | typeOnMacOs() { 8 | cat < [path]" 15 | exit 1 16 | fi 17 | 18 | git checkout "$commit" -- "$path" 19 | git reset "$commit" -- "$path" 20 | git clean -fd 21 | -------------------------------------------------------------------------------- /.bin/gp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | if [ ! -t 0 ]; then # If stdin descriptor isn't opened on tty (it can be interpreted as "something is piped into the stdin") 8 | grep --color=auto --fixed-string --ignore-case -n "$*" 9 | else # Otherwise grep current dir 10 | grep --color=auto --fixed-string --ignore-case --binary-files=without-match -n -r "$*" 11 | fi 12 | -------------------------------------------------------------------------------- /.bin/rm-trash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | mkdir -p ${HOME}/.trashBobko 8 | for file in "$@"; do 9 | if ! [[ "$file" == -* ]]; then # If path doesn't start with "-". E.g. -rf 10 | to="${HOME}/.trashBobko/$(readlink -f "$file")-REMOVED-$(date +%Y-%m-%d-%H:%M:%S)" 11 | mkdir -p "$(dirname "$to")" 12 | mv -- "$file" "$to" 13 | fi 14 | done 15 | -------------------------------------------------------------------------------- /.bin/spotlight: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | if isMacOs; then 6 | /Applications/Alacritty.app/Contents/MacOS/alacritty -t "mylauncher" \ 7 | -o window.position.x="100" \ 8 | -o window.position.y="200" \ 9 | -o window.dimensions.lines=35 \ 10 | -o window.dimensions.columns=80 \ 11 | -o window.decorations=none \ 12 | -e "spotlight-cli" 13 | # --working-directory "$(pwd)" \ 14 | else 15 | xkb-switch -s us 16 | detach rofi -modi combi -combi-modi drun,run -show combi -dpi 1 17 | fi 18 | -------------------------------------------------------------------------------- /.bin/timer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | if [ $# -ne 1 ]; then 6 | echo "Usage: timer [SUFFIX}" 7 | echo "SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days. NUMBER need not be an integer." 8 | exit 1 9 | fi 10 | 11 | echo "The timer started at:" 12 | date 13 | sleep $1 || true 14 | 15 | (ffplay -f lavfi -i "sine=frequency=1000" -nodisp &) || true 16 | 17 | while true; do 18 | notify-send "TIMER: $1 is/are expired" 19 | echo "Expired at:" 20 | date 21 | sleep 10 22 | done 23 | -------------------------------------------------------------------------------- /.bin/git-fast-forward.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ $# -ne 1 ]; then 5 | echo 'One argument expected' 6 | exit 1 7 | fi 8 | 9 | if ! git rev-parse --verify --quiet $1 >> /dev/null; then 10 | echo "$1 isn't git object" 11 | exit 1 12 | fi 13 | 14 | if git merge-base --is-ancestor HEAD $1; then 15 | git merge --ff-only $1 16 | exit 0 17 | fi 18 | 19 | if git merge-base --is-ancestor $1 HEAD; then 20 | if ! (git branch | grep -w $1 >> /dev/null); then 21 | echo "$1 isn't a branch" 22 | exit 1 23 | fi 24 | git branch -f $1 HEAD 25 | git checkout $1 26 | exit 0 27 | fi 28 | 29 | echo "Neither HEAD is ancestor of $1 nor $1 is ancestor of HEAD" 30 | exit 1 31 | -------------------------------------------------------------------------------- /.bin/fix-spotify-on-mac: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | # For some reason media buttons takes ages to respond in Spotify on mac. This script solves the problem for some time. After that 8 | # you may need to rerun the scipt (Fuck Spotify). 9 | # https://www.reddit.com/r/mac/comments/x1ifq9/does_anyone_elses_media_buttons_take_ages_to/ 10 | 11 | rm -rf ~/Library/Application\ Support/Spotify 12 | -------------------------------------------------------------------------------- /.bin/dnd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | 5 | # Drag and drop from CLI to GUI apps 6 | 7 | if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then 8 | dragon-drop "$@" 9 | exit 0 10 | fi 11 | 12 | if isMacOs; then 13 | open -R "$@" 14 | exit 0 15 | fi 16 | 17 | make_dnd_window_sticky_once_it_appear() { 18 | while [ "$(xdotool getwindowfocus getwindowname)" != "dragon" ]; do 19 | true # just wait 20 | done 21 | wmctrl -i -r "$(xdotool getwindowfocus)" -b add,sticky 22 | } 23 | 24 | make_dnd_window_sticky_once_it_appear & 25 | dragon-drop --all --and-exit "$@" 26 | -------------------------------------------------------------------------------- /.bin/git-log-head: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | branch_name=$(git branch --show-current) 8 | if git show-ref -q o/${branch_name}; then 9 | git l o/${branch_name}~..HEAD "$@" 10 | exit 0 11 | fi 12 | 13 | first_not_my_commit=$(git log --perl-regexp --author='^((?!Nikita Bobko).*)$' -1 --pretty='%H') 14 | if ! [ -z "$first_not_my_commit" ]; then 15 | git l $first_not_my_commit~..HEAD "$@" 16 | exit 0 17 | fi 18 | 19 | # fallback strategy 20 | git l -10 "$@" 21 | -------------------------------------------------------------------------------- /.bin/unshare-gradle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | tmp_gradle=~/.unshare/.gradle 8 | tmp_m2=~/.unshare/.m2 9 | tmp_cache=~/.unshare/.cache 10 | mkdir -p $tmp_gradle 11 | mkdir -p $tmp_m2 12 | mkdir -p $tmp_cache 13 | 14 | sudo unshare --mount --fork --pid bash -c " 15 | mount --bind $tmp_gradle /home/bobko/.gradle; 16 | mount --bind $tmp_m2 /home/bobko/.m2; 17 | mount --bind $tmp_cache /home/bobko/.cache; 18 | su -c \"PROMPT_LABEL='unshare-gradle ' zsh\" - bobko" 19 | -------------------------------------------------------------------------------- /.script/todo-base: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail 5 | set -x 6 | 7 | from="$1" 8 | pass="$2" 9 | to="$3" 10 | 11 | echo_red() { 12 | echo -e "\e[1;31m$@\e[0m" 13 | } 14 | 15 | echo_green() { 16 | echo -e "\033[0;32m$@\e[0m" 17 | } 18 | 19 | file=$(mktemp) 20 | echo "TMP FILE: $file" 21 | 22 | cat << EOF > $file 23 | To: $to 24 | Subject: 25 | EOF 26 | 27 | v '+norm G$' +startinsert! "$file" 28 | 29 | # sendmail $1 30 | 31 | curl --url 'smtp://smtp.gmail.com:587' \ 32 | --mail-from $from \ 33 | --mail-rcpt $1 \ 34 | --ssl-reqd \ 35 | --upload-file $file \ 36 | --user "${from}:$($pass)" 37 | 38 | echo_green 'Sent successfully!' 39 | -------------------------------------------------------------------------------- /.bin/spotlight-cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | buildList() { 8 | find \ 9 | /Applications \ 10 | ~/Applications/JetBrains\ Toolbox \ 11 | /System/Applications \ 12 | /System/Library/CoreServices \ 13 | /System/Applications/Utilities \ 14 | -maxdepth 1 -name "*.app" | sed -E "s/^(.*)$/open '\1'/" 15 | find ~/.password-store -name '*.gpg' | sed 's/\.gpg$//' | sed 's/.*password-store\///' | sed 's/^/pass show /' 16 | } 17 | 18 | eval "$(buildList | fzf)" 19 | -------------------------------------------------------------------------------- /.bin/git-base: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | head=${1:-HEAD} 8 | branch_name=$(git rev-parse --abbrev-ref $head) 9 | if git show-ref -q o/${branch_name}; then 10 | git merge-base $head o/${branch_name} 11 | exit 0 12 | fi 13 | 14 | echo "Can't find base for $head" > /dev/stderr 15 | exit 1 16 | 17 | first_not_my_commit=$(git log --perl-regexp --author='^((?!Nikita Bobko).*)$' -1 --pretty='%H' $head) 18 | if ! [ -z "$first_not_my_commit" ]; then 19 | echo $first_not_my_commit 20 | exit 0 21 | fi 22 | 23 | -------------------------------------------------------------------------------- /.config/karabiner/assets/complex_modifications/capsLockToCtrlAndEsc.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Change caps_lock to Esc and Control", 3 | "rules": [ 4 | { 5 | "description": "Post Esc if Caps is tapped, Control if held.", 6 | "manipulators": [ 7 | { 8 | "type": "basic", 9 | "from": { 10 | "key_code": "caps_lock", 11 | "modifiers": { 12 | "optional": [ 13 | "any" 14 | ] 15 | } 16 | }, 17 | "to": [ 18 | { 19 | "key_code": "left_control", 20 | "lazy": true 21 | } 22 | ], 23 | "to_if_alone": [ 24 | { 25 | "key_code": "escape" 26 | } 27 | ] 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /.config/i3blocks/config: -------------------------------------------------------------------------------- 1 | # i3blocks configuration file 2 | # 3 | # The i3blocks man page describes the usage of the binary, 4 | # and its website describes the configuration: 5 | # 6 | # https://vivien.github.io/i3blocks 7 | 8 | # Global properties 9 | separator=true 10 | separator_block_width=15 11 | 12 | [time] 13 | command=echo "📅 $(date '+%a %d %b, %H:%M')" 14 | interval=30 15 | 16 | [hostname] 17 | command=hostname 18 | interval=once 19 | 20 | [battery2] 21 | command=/usr/lib/i3blocks/battery2/battery2 22 | markup=pango 23 | interval=30 24 | 25 | [volume-pulseaudio] 26 | LONG_FORMAT="🔊 ${VOL}% [${INDEX}:${NAME}]" 27 | command=/usr/lib/i3blocks/volume-pulseaudio/volume-pulseaudio 28 | interval=persist 29 | SUBSCRIBE=1 30 | signal=1 31 | 32 | [xkb_layout] 33 | command=/usr/lib/i3blocks/xkb_layout/xkb_layout 34 | font=monospace 35 | font_weight=bold 36 | interval=persist 37 | markup=pango 38 | -------------------------------------------------------------------------------- /.config/karabiner/assets/complex_modifications/ctrlBackspace.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Map Ctrl+Backward-Delete.", 3 | "rules": [ 4 | { 5 | "description": "Add Ctrl+Backward-Delete to Option+Delete (delete current word).", 6 | "type": "basic", 7 | "manipulators": [ 8 | { 9 | "type": "basic", 10 | "from": { 11 | "key_code": "delete_or_backspace", 12 | "modifiers": { 13 | "mandatory": [ 14 | "control" 15 | ], 16 | "optional": [ 17 | "any" 18 | ] 19 | } 20 | }, 21 | "to": [ 22 | { 23 | "key_code": "delete_or_backspace", 24 | "modifiers": [ 25 | "option" 26 | ] 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /.bin/cb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | # cb is a shorthand for "ClipBoard" 8 | 9 | paste() { 10 | if isMacOs; then 11 | pbpaste 12 | else 13 | xsel -ob; 14 | fi 15 | } 16 | 17 | copy() { 18 | if isMacOs; then 19 | pbcopy 20 | else 21 | xclip -selection clipboard 22 | fi 23 | } 24 | 25 | if [ $# -eq 1 ]; then 26 | readlink -f "$1" | xargs echo -n | copy 27 | elif [ ! -t 0 ]; then # If stdin descriptor isn't opened on tty (it can be interpreted as "something is piped into the stdin") 28 | copy 29 | else 30 | paste 31 | fi 32 | -------------------------------------------------------------------------------- /.bin/async-profiler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 5 | 6 | if [ $# -ne 2 ]; then 7 | echo "Usage: async-profiler " 8 | echo " This is wrapper script for https://github.com/jvm-profiling-tools/async-profiler." 9 | echo " Because default UX of async-profiler desperately sucks!" 10 | exit 1 11 | fi 12 | 13 | profiler_sh=$1 14 | pid=$2 15 | snapshot_file="async-profiler-snapshot-$(date | tr ' ' '-')-pid-$pid.jfr" 16 | 17 | eval "$profiler_sh" start -f $snapshot_file $pid 18 | echo "Press Any Key to stop profiling" 19 | read 20 | 21 | eval "$profiler_sh" stop -f $snapshot_file $pid 22 | echo "snapshot is saved to $snapshot_file" 23 | -------------------------------------------------------------------------------- /.bin/mkscript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | if [ $# -ne 1 ]; then 8 | echo "One argument expected" 9 | return 1 10 | fi 11 | 12 | cat << EOF > "$1" 13 | #!/usr/bin/env bash 14 | set -e # Exit if one of commands exit with non-zero exit code 15 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 16 | set -o pipefail # Any command failed in the pipe fails the whole pipe 17 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 18 | 19 | cd "\$(dirname "\$0")" 20 | EOF 21 | 22 | chmod +x "$1" 23 | 24 | $EDITOR "$1" 25 | -------------------------------------------------------------------------------- /.bin/google-image-download-interactive.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | # set -v # Print shell input lines as they are read (You may also try -x which is more verbose) 5 | 6 | read input 7 | 8 | session="google-image-download-interactive" 9 | 10 | mkdir -p fucking-downloads 11 | 12 | tmux new-session -d -s $session 13 | tmux send-keys -t $session:1 "googleimagesdownload -o fucking-downloads -la Dutch -k '$input'" ENTER 14 | tmux split-window -v -t $session 15 | tmux send-keys -t $session:1 "nnn fucking-downloads -p /tmp/nnn-fucking-choice && tmux kill-session -t $session" ENTER 16 | tmux send-keys -t $session:1 ";t" ENTER # Enable nnn preview 17 | alacritty -e tmux attach -t "$session" 18 | 19 | input_without_spaces=$(echo "$input" | tr ' ' '-') 20 | filename=$(cat /tmp/nnn-fucking-choice) 21 | ext=$(echo "$filename" | sed -E 's/.*\.(.*)/\1/') 22 | mv "$filename" "$input_without_spaces.$ext" 23 | rm -rf fucking-downloads 24 | echo "./$input_without_spaces.$ext" 25 | 26 | -------------------------------------------------------------------------------- /.bin/fix-keyboard.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This is a separate script because it allows me to hit alt+space (invoke spotlight) and type "fix-keyboard" to fix every new 4 | # keyboard I connect to the computer. Those are primary bluetooth keyboards, so it happens that they disconnect pretty often 5 | # (typically on timeout) 6 | 7 | set -e # Exit if one of commands exit with non-zero exit code 8 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 9 | #set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 10 | 11 | xset r rate 160 90 # Key repeat first number is delay second is repeat speed 12 | xset s off # Turn off screensaver 13 | 14 | # setxkbmap. See /usr/share/X11/xkb/rules/base 15 | # setxkbmap -option altwin:swap_alt_win # swap alt and super keys 16 | # setxkbmap -option caps:escape # remap caps lock to esc 17 | 18 | setxkbmap -option ctrl:nocaps # remap caps lock to ctrl 19 | killall xcape &> /dev/null || true 20 | xcape -e 'Control_L=Escape' # make left ctrl (and caps lock too) behave as escape when pressed on it's own 21 | 22 | setxkbmap -layout us,ru -option grp:win_space_toggle 23 | 24 | -------------------------------------------------------------------------------- /.script/getActiveWindowTitle.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | getWindowTitleOnMacOs() { 8 | # taken from user Albert's answer on StackOverflow 9 | # http://stackoverflow.com/questions/5292204/macosx-get-foremost-window-title 10 | # tested on Mac OS X 10.7.5 11 | cat < []" 7 | echo "see 'git-cherry' command. 'git-smart-cherry' command have same semantic" 8 | exit 1 9 | fi 10 | 11 | upstream=$1 12 | head=$2 13 | limit="" 14 | if [ $# -eq 3 ]; then 15 | limit=$3 16 | fi 17 | 18 | git cherry $upstream $head $limit | while read it; do 19 | if [[ $it == "+"* ]]; then 20 | candidate=$(echo $it | awk '{print $2}') 21 | title=$(git log -1 --pretty="%B" $candidate | head -1) 22 | date=$(git log -1 --pretty="%at" $candidate) 23 | author="$(git log -1 --pretty="%an" $candidate) <$(git log -1 --pretty="%ae" $candidate)>" 24 | # What a shame, git doesn't allow to find by author date :facepalm: https://stackoverflow.com/questions/37311494/how-to-get-git-to-show-commits-in-a-specified-date-range-for-author-date 25 | cherry_pick_duplicate=$(git log --pretty="%at" --author="$author" -F --grep="$title" $upstream | grep "$date" | head -1) 26 | 27 | if [ -z $cherry_pick_duplicate ]; then 28 | echo "+ $candidate" 29 | else 30 | echo "- $candidate" 31 | fi 32 | else 33 | echo $it 34 | fi 35 | done 36 | -------------------------------------------------------------------------------- /.config/picom.conf: -------------------------------------------------------------------------------- 1 | shadow = false; 2 | shadow-radius = 7; 3 | shadow-offset-x = -7; 4 | shadow-offset-y = -7; 5 | shadow-exclude = [ "name = 'Notification'", "class_g = 'Conky'", "class_g ?= 'Notify-osd'", "class_g = 'Cairo-clock'", "_GTK_FRAME_EXTENTS@:c" ]; 6 | fading = false; 7 | fade-in-step = 0.0; 8 | fade-out-step = 0.0; 9 | inactive-opacity = 1.0; 10 | frame-opacity = 1.0; 11 | inactive-opacity-override = false; 12 | focus-exclude = [ "class_g = 'Cairo-clock'" ]; 13 | corner-radius = 0; 14 | rounded-corners-exclude = [ "window_type = 'dock'", "window_type = 'desktop'" ]; 15 | blur-kern = "3x3box"; 16 | blur-background-exclude = [ "window_type = 'dock'", "window_type = 'desktop'", "_GTK_FRAME_EXTENTS@:c" ]; 17 | backend = "glx"; 18 | vsync = true; 19 | mark-wmwin-focused = true; 20 | mark-ovredir-focused = true; 21 | detect-rounded-corners = true; 22 | detect-client-opacity = true; 23 | detect-transient = true; 24 | use-damage = true; 25 | log-level = "warn"; 26 | wintypes : 27 | { 28 | tooltip : 29 | { 30 | fade = true; 31 | shadow = true; 32 | opacity = 1.0; 33 | focus = true; 34 | full-shadow = false; 35 | }; 36 | dock : 37 | { 38 | shadow = false; 39 | clip-shadow-above = true; 40 | }; 41 | dnd : 42 | { 43 | shadow = false; 44 | }; 45 | popup_menu : 46 | { 47 | opacity = 1.0; 48 | }; 49 | dropdown_menu : 50 | { 51 | opacity = 1.0; 52 | }; 53 | }; 54 | no-fading-openclose = true; 55 | -------------------------------------------------------------------------------- /.bin/pw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | export FZF_DEFAULT_OPTS="--height 60% --layout=reverse" 8 | 9 | account=$(find ~/.password-store -name '*.gpg' | sed 's/\.gpg$//' | sed 's/.*password-store\///' | fzf) || exit 0 10 | decrypted="$(pass show "$account")" 11 | password="$(head -1 <<< "$decrypted")" 12 | meta="$(sed 1d <<< "$decrypted")" 13 | 14 | printAcc() { sed -E 's/.*\/(.*)$/\1/' <<< "$account"; } 15 | 16 | printAcc 17 | echo "(copied to clipboard)" 18 | printAcc | cb 19 | 20 | PASS_ITEM="_PASS" 21 | FILENAME_ITEM="_FILENAME" 22 | 23 | while true; do 24 | picked="$(echo -e "$PASS_ITEM\n$FILENAME_ITEM\ntype\n$meta" | cut -d ':' -f 1 | fzf)" || break 25 | if [ "$picked" = "type" ]; then 26 | onStart="$(~/.script/getActiveWindowTitle.sh)" 27 | while [ "$(~/.script/getActiveWindowTitle.sh)" = "$onStart" ]; do true; done 28 | ~/.script/typeOnVirtualKeyboard.sh "$(printAcc)\t$(pass show "$account" | head -1)" 29 | elif [ "$picked" = "$FILENAME_ITEM" ]; then 30 | printAcc | cb 31 | echo "filename is copied to clipboard" 32 | elif [ "$picked" = "$PASS_ITEM" ]; then 33 | pass show --clip "$account" 34 | elif [ "$picked" = "otpauth" ]; then 35 | pass otp "$account" | cb 36 | echo "OTP is copied to clipboard" 37 | else 38 | grep "$picked" <<< "$meta" | head -1 | cut -d ':' -f 2 | pbcopy 39 | echo "$picked is copied to clipboard" 40 | fi 41 | done 42 | -------------------------------------------------------------------------------- /.config/Crow Translate/Crow Translate.conf: -------------------------------------------------------------------------------- 1 | [General] 2 | StartMinimized=true 3 | TrayIconVisible=true 4 | WindowMode=0 5 | 6 | [Buttons] 7 | CheckedSource=-2 8 | CheckedTranslation=-2 9 | Source=en 10 | Translation=ru 11 | 12 | [Connection] 13 | ProxyAuthEnabled=false 14 | ProxyHost= 15 | ProxyPassword= 16 | ProxyPort=8080 17 | ProxyType=0 18 | ProxyUsername= 19 | 20 | [Interface] 21 | CustomIconPath=crow-translate-tray 22 | Font=@Variant(\0\0\0@\0\0\0\f\0R\0o\0\x62\0o\0t\0o@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10) 23 | MainWindowLanguageFormat=0 24 | PopupHeight=300 25 | PopupLanguageFormat=1 26 | PopupOpacity=1 27 | PopupWidth=350 28 | TranslationNotificationTimeout=3 29 | TrayIconName=0 30 | 31 | [MainWindow] 32 | AutoTranslate=false 33 | CurrentEngine=0 34 | WindowGeometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x2\x89\0\0\0\xcd\0\0\0\0\0\0\0\0\0\0\x2\x89\0\0\0\xcd\0\0\0\0\0\0\0\0\a\x80\0\0\0\0\0\0\0\0\0\0\x2\x89\0\0\0\xcd) 35 | 36 | [OCR] 37 | ApplyLightMask=true 38 | CaptureOnRelease=false 39 | Languages=@ByteArray() 40 | LanguagesPath=@ByteArray() 41 | RegionRememberType=0 42 | ShowMagnifier=false 43 | 44 | [Shortcuts] 45 | CloseWindow= 46 | CopyTranslatedSelection= 47 | CopyTranslation= 48 | GlobalShortcutsEnabled=true 49 | ShowMainWindow= 50 | SpeakSelection= 51 | SpeakSource= 52 | SpeakTranslatedSelection= 53 | SpeakTranslation= 54 | StopSelection= 55 | Swap= 56 | Translate= 57 | TranslateScreenAreaShortcut= 58 | TranslateSelection=Ctrl+Alt+E 59 | 60 | [Translation] 61 | ExamplesEnabled=true 62 | ForceSourceAutodetect=true 63 | ForceTranslationAutodetect=true 64 | PrimaryLanguage=22 65 | SecondaryLanguage=86 66 | SimplifySource=false 67 | SourceTranscriptionEnabled=true 68 | SourceTranslitEnabled=true 69 | TranslationOptionsEnabled=true 70 | TranslationTranslitEnabled=true 71 | YandexEmotion=0 72 | YandexVoice=0 73 | -------------------------------------------------------------------------------- /.a/Bobko.SC2Hotkeys: -------------------------------------------------------------------------------- 1 | [Settings] 2 | Grid=1 3 | Suffix=_GLS 4 | 5 | [Hotkeys] 6 | PTT=F4 7 | MenuGame=M 8 | AlertRecall= 9 | ArmySelect= 10 | CommanderAbility0= 11 | ControlGroupAppend0= 12 | ControlGroupAppend1= 13 | ControlGroupAppend2= 14 | ControlGroupAppend3= 15 | ControlGroupAppend4= 16 | ControlGroupAppend5= 17 | ControlGroupAppend6= 18 | ControlGroupAppend7= 19 | ControlGroupAppend8= 20 | ControlGroupAppend9= 21 | ControlGroupAppendAndSteal0=Shift+0,Shift+Grave 22 | ControlGroupAppendAndSteal1=Shift+1 23 | ControlGroupAppendAndSteal2=Shift+2 24 | ControlGroupAppendAndSteal3=Shift+3 25 | ControlGroupAppendAndSteal4=Shift+4 26 | ControlGroupAppendAndSteal5=Shift+5 27 | ControlGroupAppendAndSteal6=Shift+6 28 | ControlGroupAppendAndSteal7=Shift+7,Shift+Q 29 | ControlGroupAppendAndSteal8=Shift+8,Shift+A 30 | ControlGroupAssign0= 31 | ControlGroupAssign1= 32 | ControlGroupAssign2= 33 | ControlGroupAssign3= 34 | ControlGroupAssign4= 35 | ControlGroupAssign5= 36 | ControlGroupAssign6= 37 | ControlGroupAssign7= 38 | ControlGroupAssign8= 39 | ControlGroupAssign9= 40 | ControlGroupAssignAndSteal0=Control+Grave 41 | ControlGroupAssignAndSteal1=Control+1 42 | ControlGroupAssignAndSteal2=Control+2 43 | ControlGroupAssignAndSteal3=Control+3 44 | ControlGroupAssignAndSteal4=Control+4 45 | ControlGroupAssignAndSteal5=Control+5 46 | ControlGroupAssignAndSteal6=Control+6 47 | ControlGroupAssignAndSteal7=Control+CapsLock,Control+Q 48 | ControlGroupAssignAndSteal8=Control+A 49 | ControlGroupRecall0=0,Grave 50 | ControlGroupRecall7=CapsLock,Q 51 | ControlGroupRecall8=8,A 52 | GameTooltipsOn= 53 | PauseGame=P 54 | QuickPing= 55 | QuickSave= 56 | StatusOwner= 57 | TargetChoose=LeftMouseButton,W,E,R,T,Y,S,D,F,G,H,X,C,V,B,N,Space 58 | TownCamera=Z,Option 59 | CommandButtonAlt04= 60 | CommandButtonAlt08= 61 | CommandButtonAlt09= 62 | CommandButton00=W 63 | CommandButton01=E 64 | CommandButton02=R 65 | CommandButton03=T 66 | CommandButton04=Y,Space 67 | CommandButton05=S 68 | CommandButton06=D 69 | CommandButton07=F 70 | CommandButton08=G 71 | CommandButton09=H 72 | CommandButton10=X 73 | CommandButton11=C 74 | CommandButton12=V 75 | CommandButton13=B 76 | CommandButton14=N,Escape 77 | 78 | [Commands] 79 | 80 | -------------------------------------------------------------------------------- /.bin/fix-name: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -x # Print shell commands as they are executed (or you can try -v which is less verbose) 6 | 7 | fixer() { 8 | echo "$1" | 9 | sed 's/ /_/g' | 10 | sed 's/(/_/g' | 11 | sed 's/)/_/g' | 12 | sed 's/а/a/g' | sed 's/А/A/g' | 13 | sed 's/б/b/g' | sed 's/Б/B/g' | 14 | sed 's/в/v/g' | sed 's/В/V/g' | 15 | sed 's/г/g/g' | sed 's/Г/G/g' | 16 | sed 's/д/d/g' | sed 's/Д/D/g' | 17 | sed 's/е/e/g' | sed 's/Е/E/g' | 18 | sed 's/ё/e/g' | sed 's/Ё/E/g' | 19 | sed 's/ж/zh/g' | sed 's/Ж/ZH/g' | 20 | sed 's/з/z/g' | sed 's/З/Z/g' | 21 | sed 's/и/i/g' | sed 's/И/I/g' | 22 | sed 's/й/y/g' | sed 's/Й/Y/g' | 23 | sed 's/к/k/g' | sed 's/К/K/g' | 24 | sed 's/л/l/g' | sed 's/Л/L/g' | 25 | sed 's/м/m/g' | sed 's/М/M/g' | 26 | sed 's/н/n/g' | sed 's/Н/N/g' | 27 | sed 's/о/o/g' | sed 's/О/O/g' | 28 | sed 's/п/p/g' | sed 's/П/P/g' | 29 | sed 's/р/r/g' | sed 's/Р/R/g' | 30 | sed 's/с/s/g' | sed 's/С/S/g' | 31 | sed 's/т/t/g' | sed 's/Т/T/g' | 32 | sed 's/у/u/g' | sed 's/У/U/g' | 33 | sed 's/ф/f/g' | sed 's/Ф/F/g' | 34 | sed 's/к/k/g' | sed 's/К/K/g' | 35 | sed 's/ц/ts/g' | sed 's/Ц/TS/g' | 36 | sed 's/ч/ch/g' | sed 's/Ч/CH/g' | 37 | sed 's/ш/sh/g' | sed 's/Ш/SH/g' | 38 | sed 's/щ/sh/g' | sed 's/Щ/SH/g' | 39 | sed 's/ъ//g' | sed 's/Ъ//g' | 40 | sed 's/ы/y/g' | sed 's/Ы/Y/g' | 41 | sed 's/ь//g' | sed 's/Ь//g' | 42 | sed 's/э/e/g' | sed 's/Э/E/g' | 43 | sed 's/ю/u/g' | sed 's/Ю/U/g' | 44 | sed 's/я/ya/g' | sed 's/Я/YA/g' 45 | } 46 | 47 | for it in "$@"; do 48 | new_name="$(fixer "$it")" 49 | if ! [ -e "$new_name" ]; then 50 | mv "$it" "$new_name" 51 | else 52 | echo "can't move '$it' to '$new_name' (already exist)" 53 | fi 54 | done 55 | -------------------------------------------------------------------------------- /.ideavimrc: -------------------------------------------------------------------------------- 1 | source ~/.vimrc 2 | set ideajoin 3 | set argtextobj| " Add argument text objects. Same what 'set argtextobj' does for me in real vim 4 | set quickscope 5 | 6 | " TODO hotkey to open current file in a real vim 7 | 8 | " map fb :Buffers " TODO 9 | nmap :action SelectNextOccurrence| " vim-visual-multi 10 | map f :action GotoFile 11 | " map gr :action FindInPath 12 | map h :action RecentFiles| " Like ":History" in vim 13 | map ]d :action GotoNextError 14 | map [d :action GotoPreviousError 15 | map ]q :action NextOccurence 16 | map [q :action PreviousOccurence 17 | " map gr :Rg 18 | " map gs :action GotoSymbol 19 | map p :action ParameterInfo 20 | " nmap :action EditorCloneCaretBelow| " vim-visual-multi TODO drop? 21 | " nmap :action EditorCloneCaretAbove| " vim-visual-multi 22 | nmap Q (Exit) 23 | map u :action FindUsages 24 | " map r :action SearchEverywhere| " Mnemonics gRep 25 | map e :action ShowNavBar| " I have the same mapping vim 26 | map r :action RenameElement 27 | map b :action Annotate 28 | map l :action Vcs.ShowTabbedFileHistory| " Git log for current file 29 | map d :action ShowErrorDescription 30 | map a :action ShowIntentionActions 31 | map s :action FileStructurePopup 32 | 33 | " CopyReferencePopupGroup 34 | " map c :action CopyPathFromRepositoryRootProvider 35 | 36 | " map gy :action GotoTypeDeclaration 37 | map gy :action GotoTypeDeclaration 38 | 39 | " Because it's like suspend in terminal. Defined in IdeaVIM (not in bobko-keymap) because I want to preserve ctr+z original 40 | " behaviour in other toolwindows just in case 41 | map (Terminal.OpenInTerminal) 42 | 43 | " Tip: use :actionlist 44 | 45 | " Fix behaviour of IdeaVIM 46 | " imap p 47 | " map cc "_Ojddka| " Fix ideavim bug that it doesn't support 'cc' as "insert with correct indent" 48 | nmap (Forward)| " https://youtrack.jetbrains.com/issue/VIM-44 49 | nmap (Back)| " https://youtrack.jetbrains.com/issue/VIM-44 `nmap :action Back|` doesn't work for some reason 50 | nnoremap g; :action JumpToLastChange| " https://youtrack.jetbrains.com/issue/VIM-519 51 | nnoremap g, :action JumpToNextChange| " https://youtrack.jetbrains.com/issue/VIM-519 52 | 53 | "command ol :action RecentFiles 54 | -------------------------------------------------------------------------------- /.config/micro/bindings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Alt,": "PreviousTab", 3 | "Alt-/": "lua:comment.comment", 4 | "Alt-CtrlH": "DeleteWordLeft", 5 | "Alt-a": "StartOfLine", 6 | "Alt-b": "WordLeft", 7 | "Alt-c": "RemoveAllMultiCursors", 8 | "Alt-e": "EndOfLine", 9 | "Alt-f": "WordRight", 10 | "Alt-m": "SpawnMultiCursorSelect", 11 | "Alt-n": "SpawnMultiCursor", 12 | "Alt-p": "RemoveMultiCursor", 13 | "Alt-x": "SkipMultiCursor", 14 | "Alt-{": "ParagraphPrevious", 15 | "Alt-}": "ParagraphNext", 16 | "Alt.": "NextTab", 17 | "Backspace": "Backspace", 18 | "Backtab": "OutdentSelection,OutdentLine", 19 | "Ctrl-MouseLeft": "MouseMultiCursor", 20 | "CtrlA": "SelectAll", 21 | "CtrlB": "ShellMode", 22 | "CtrlC": "Copy", 23 | "CtrlD": "DuplicateLine", 24 | "CtrlE": "CommandMode", 25 | "CtrlEnd": "CursorEnd", 26 | "CtrlF": "Find", 27 | "CtrlG": "command-edit:goto ", 28 | "CtrlH": "DeleteWordLeft", 29 | "CtrlShiftH": "ToggleHelp", 30 | "CtrlHome": "CursorStart", 31 | "CtrlJ": "PlayMacro", 32 | "CtrlK": "CutLine", 33 | "CtrlLeft": "WordLeft", 34 | "CtrlN": "FindNext", 35 | "CtrlO": "OpenFile", 36 | "CtrlP": "FindPrevious", 37 | "CtrlQ": "Quit", 38 | "CtrlR": "ToggleRuler", 39 | "CtrlRight": "WordRight", 40 | "CtrlS": "Save", 41 | "CtrlShiftDown": "MoveLinesDown", 42 | "CtrlShiftEnd": "SelectToEnd", 43 | "CtrlShiftHome": "SelectToStart", 44 | "CtrlShiftLeft": "SelectWordLeft", 45 | "CtrlShiftRight": "SelectWordRight", 46 | "CtrlShiftUp": "MoveLinesUp", 47 | "CtrlT": "AddTab", 48 | "CtrlU": "ToggleMacro", 49 | "CtrlUnderscore": "lua:comment.comment", 50 | "CtrlV": "Paste", 51 | "CtrlW": "NextSplit", 52 | "CtrlX": "Cut", 53 | "CtrlY": "Redo", 54 | "CtrlZ": "Undo", 55 | "Delete": "Delete", 56 | "Down": "CursorDown", 57 | "End": "EndOfLine", 58 | "Enter": "InsertNewline", 59 | "Esc": "Escape,RemoveAllMultiCursors", 60 | "Home": "StartOfLine", 61 | "Left": "CursorLeft", 62 | "MouseLeft": "MousePress", 63 | "MouseMiddle": "PastePrimary", 64 | "MouseWheelDown": "ScrollDown", 65 | "MouseWheelUp": "ScrollUp", 66 | "PageDown": "CursorPageDown", 67 | "PageUp": "CursorPageUp", 68 | "Right": "CursorRight", 69 | "ShiftDown": "SelectDown", 70 | "ShiftEnd": "SelectToEndOfLine", 71 | "ShiftHome": "SelectToStartOfLine", 72 | "ShiftLeft": "SelectLeft", 73 | "ShiftRight": "SelectRight", 74 | "ShiftUp": "SelectUp", 75 | "Tab": "IndentSelection,InsertTab", 76 | "Up": "CursorUp" 77 | } 78 | -------------------------------------------------------------------------------- /.bin/idea-bobko: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e # Exit if one of commands exit with non-zero exit code 3 | set -u # Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error 4 | set -o pipefail # Any command failed in the pipe fails the whole pipe 5 | # set -v # Print shell input lines as they are read (You may also try -x which is more verbose) 6 | 7 | VERSION=232 8 | 9 | # if [ $# -lt 1 ]; then 10 | # echo "Usage: idea xxx [other args]" 11 | # exit 1 12 | # fi 13 | 14 | cat < /dev/null 15 | idea.is.internal=true 16 | EOF 17 | 18 | # https://youtrack.jetbrains.com/issue/IDEA-299903 19 | path="" 20 | if [ $# -gt 0 ]; then 21 | path=$(realpath "$1") 22 | test -e "$path" || { echo "'$path' doesn't exist" && exit 1; } 23 | shift # Drop second argument 24 | fi 25 | 26 | candidates="$(find ~/.local/share/JetBrains/Toolbox/apps/IDEA-U -name idea.sh | grep $VERSION | sort -Vr)" 27 | idea_sh=$(head -1 <<< "$candidates") 28 | 29 | echo "Candidates:" 30 | echo "$candidates" 31 | echo "---" 32 | echo "Selected: $idea_sh" 33 | 34 | if [ -z "$path" ]; then 35 | detach "$idea_sh" "$@" 36 | else 37 | detach "$idea_sh" "$path" "$@" 38 | fi 39 | 40 | # version="$1" 41 | # shift # Drop first argument 42 | 43 | # # https://youtrack.jetbrains.com/issue/IDEA-299903 44 | # path="" 45 | # if [ $# -gt 0 ]; then 46 | # path=$(realpath "$1") 47 | # test -e "$path" || { echo "'$path' doesn't exist" && exit 1; } 48 | # shift # Drop second argument 49 | # fi 50 | 51 | # if [ $# -gt 0 ]; then 52 | # echo "Usage: i [OPTIONAL-FILE]" 53 | # exit 1 54 | # fi 55 | 56 | # find_installed_idea_sh() { 57 | # find ~/.local/share/JetBrains/Toolbox/apps/IDEA-U -name idea.sh 58 | # find ~/.local/share/JetBrains/Toolbox/apps/IDEA-C -name idea.sh 59 | # find ~/.app -name idea.sh 60 | # } 61 | 62 | # installed_ideas_sorted_descending_with_versions() { 63 | # find_installed_idea_sh | xargs dirname | xargs dirname \ 64 | # | while read it; do echo "$(cat $it/build.txt) $it/bin/idea.sh"; done \ 65 | # | sort -Vr 66 | # } 67 | 68 | # matching=$(installed_ideas_sorted_descending_with_versions | grep "$version") 69 | # echo "Matching versions:" 70 | # echo "$matching" 71 | # echo "----------------" 72 | 73 | # picked=$(echo "$matching" | head -1 | awk '{print $2}') 74 | # echo "Picked:" 75 | # echo "$picked" 76 | # echo "----------------" 77 | 78 | # test -z "$path" && 79 | # { nohup "$picked" "$@" &> /dev/null & } || 80 | # { nohup "$picked" "$path" "$@" &> /dev/null & } 81 | -------------------------------------------------------------------------------- /.bin/git-jump: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # https://github.com/git/git/tree/master/contrib/git-jump 4 | 5 | usage() { 6 | cat <<\EOF 7 | usage: git jump [--stdout] [] 8 | 9 | Jump to interesting elements in an editor. 10 | The parameter is one of: 11 | 12 | diff: elements are diff hunks. Arguments are given to diff. 13 | 14 | merge: elements are merge conflicts. Arguments are ignored. 15 | 16 | grep: elements are grep hits. Arguments are given to git grep or, if 17 | configured, to the command in `jump.grepCmd`. 18 | 19 | ws: elements are whitespace errors. Arguments are given to diff --check. 20 | 21 | If the optional argument `--stdout` is given, print the quickfix 22 | lines to standard output instead of feeding it to the editor. 23 | EOF 24 | } 25 | 26 | open_editor() { 27 | editor=`git var GIT_EDITOR` 28 | case "$editor" in 29 | *emacs*) 30 | # Supported editor values are: 31 | # - emacs 32 | # - emacsclient 33 | # - emacsclient -t 34 | # 35 | # Wait for completion of the asynchronously executed process 36 | # to avoid race conditions in case of "emacsclient". 37 | eval "$editor --eval \"(let ((buf (grep \\\"cat \$1\\\"))) (pop-to-buffer buf) (select-frame-set-input-focus (selected-frame)) (while (get-buffer-process buf) (sleep-for 0.1)))\"" 38 | ;; 39 | *) 40 | # assume anything else is vi-compatible 41 | eval "$editor -q \$1" 42 | ;; 43 | esac 44 | } 45 | 46 | mode_diff() { 47 | git diff --no-prefix --relative "$@" | 48 | perl -ne ' 49 | if (m{^\+\+\+ (.*)}) { $file = $1; next } 50 | defined($file) or next; 51 | if (m/^@@ .*?\+(\d+)/) { $line = $1; next } 52 | defined($line) or next; 53 | if (/^ /) { $line++; next } 54 | if (/^[-+]\s*(.*)/) { 55 | print "$file:$line: $1\n"; 56 | $line = undef; 57 | } 58 | ' 59 | } 60 | 61 | mode_merge() { 62 | git ls-files -u "$@" | 63 | perl -pe 's/^.*?\t//' | 64 | sort -u | 65 | while IFS= read fn; do 66 | grep -Hn '^<<<<<<<' "$fn" 67 | done 68 | } 69 | 70 | # Grep -n generates nice quickfix-looking lines by itself, 71 | # but let's clean up extra whitespace, so they look better if the 72 | # editor shows them to us in the status bar. 73 | mode_grep() { 74 | cmd=$(git config jump.grepCmd) 75 | test -n "$cmd" || cmd="git grep -n --column" 76 | $cmd "$@" | 77 | perl -pe ' 78 | s/[ \t]+/ /g; 79 | s/^ *//; 80 | ' 81 | } 82 | 83 | mode_ws() { 84 | git diff --check "$@" 85 | } 86 | 87 | use_stdout= 88 | while test $# -gt 0; do 89 | case "$1" in 90 | --stdout) 91 | use_stdout=t 92 | ;; 93 | --*) 94 | usage >&2 95 | exit 1 96 | ;; 97 | *) 98 | break 99 | ;; 100 | esac 101 | shift 102 | done 103 | if test $# -lt 1; then 104 | usage >&2 105 | exit 1 106 | fi 107 | mode=$1; shift 108 | type "mode_$mode" >/dev/null 2>&1 || { usage >&2; exit 1; } 109 | 110 | if test "$use_stdout" = "t"; then 111 | "mode_$mode" "$@" 112 | exit 0 113 | fi 114 | 115 | trap 'rm -f "$tmp"' 0 1 2 3 15 116 | tmp=`mktemp -t git-jump.XXXXXX` || exit 1 117 | "mode_$mode" "$@" >"$tmp" 118 | test -s "$tmp" || exit 0 119 | open_editor "$tmp" 120 | -------------------------------------------------------------------------------- /.config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | # https://sw.kovidgoyal.net/kitty/ 2 | # https://sw.kovidgoyal.net/kitty/conf.html 3 | 4 | # remove all shortcut definition seen up to this point 5 | clear_all_shortcuts yes 6 | 7 | font_family JetBrains Mono 8 | bold_font JetBrains Mono Bold 9 | italic_font JetBrains Mono Italic 10 | bold_italic_font JetBrains Mono Bold Italic 11 | 12 | font_size 11.0 13 | 14 | disable_ligatures always 15 | 16 | # infinite scrollback 17 | scrollback_lines -1 18 | 19 | tab_bar_edge top 20 | tab_bar_style separator 21 | tab_separator │ 22 | 23 | cursor #4e9a06 24 | 25 | #cursor_shape beam 26 | 27 | cursor_beam_thickness 1.5 28 | 29 | enable_audio_bell no 30 | 31 | wheel_scroll_multiplier 3.0 32 | 33 | rectangle_select_modifiers alt+shift 34 | mouse_map ctrl+left release grabbed,ungrabbed mouse_click_url 35 | 36 | # No blinking 37 | cursor_blink_interval 0 38 | 39 | # Arc dark theme 40 | background #2f343f 41 | 42 | # Dark theme 43 | #background #000000 44 | 45 | # white theme 46 | # foreground #000000 47 | # background #ffffff 48 | # selection_foreground #ffffff 49 | # selection_background #2f5bed 50 | # active_tab_background #ffffff 51 | 52 | # Arc light theme 53 | #background #e7e8eb 54 | 55 | 56 | allow_remote_control yes 57 | 58 | enabled_layouts splits 59 | map alt+- launch --cwd=current --location=hsplit 60 | map alt+\ launch --cwd=current --location=vsplit 61 | map alt+shift+up move_window up 62 | map alt+shift+left move_window left 63 | map alt+shift+down move_window down 64 | map alt+shift+right move_window right 65 | map alt+up neighboring_window up 66 | map alt+left neighboring_window left 67 | map alt+down neighboring_window down 68 | map alt+right neighboring_window right 69 | # map alt+shift+i move_window up 70 | # map alt+shift+j move_window left 71 | # map alt+shift+k move_window down 72 | # map alt+shift+l move_window right 73 | # map alt+i neighboring_window up 74 | # map alt+j neighboring_window left 75 | # map alt+k neighboring_window down 76 | # map alt+l neighboring_window right 77 | 78 | map ctrl+t new_tab 79 | map ctrl+shift+w close_tab 80 | map ctrl+shift+q close_window 81 | map ctrl+tab next_tab 82 | map ctrl+shift+tab previous_tab 83 | 84 | map ctrl+alt+left resize_window narrower 85 | map ctrl+alt+right resize_window wider 86 | map ctrl+alt+up resize_window shorter 87 | map ctrl+alt+down resize_window taller 88 | 89 | map ctrl+shift+n new_os_window 90 | 91 | # \x03 is `ctrl + c` See `kitty +kitten show_key` - https://sw.kovidgoyal.net/kitty/faq.html 92 | map ctrl+c combine : copy_to_clipboard : send_text all \x03 93 | map ctrl+v paste_from_clipboard 94 | 95 | #map ctrl+up scroll_line_up 96 | #map ctrl+i scroll_line_up 97 | #map ctrl+down scroll_line_down 98 | #map ctrl+k scroll_line_down 99 | 100 | map ctrl+alt+h kitten hints --type hash --program - --alphabet fjasdklgh --hints-text-color black 101 | map ctrl+alt+p kitten hints --type path --program - --alphabet fjasdklgh --hints-text-color black 102 | 103 | #map f1 launch --stdin-source=@screen_scrollback 'head -1 | kitty @ send-text --stdin' 104 | #map f1 launch '/usr/bin/kitty @ send-text foo' 105 | map ctrl+f1 launch --stdin-source=@screen_scrollback 'v' 106 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | # Bobko Linux & macOS .dotfiles 2 | 3 | The repo contains my configs for the CLI and some GUI apps. It's mostly CLI oriented environment 4 | 5 | ## Highlights 6 | 7 | ### ⭐ VIM as a default $EDITOR 8 | 9 | I always thought that VIM is some sort of ancient software that people still use for some reason, but one day I read "Practical 10 | VIM", and it changed everything. VIM is awesome. IMO, the best way to explore VIM by reading "Practical Vim" by Drew Neil. 11 | 12 | - VIM isn't just a editor, it's entirely different paradigm. It's a concept that allows a more efficient text manipulations. If 13 | you do programming or a lot of writing, then VIM is a must learn 14 | - VIM is so popular that its "hotkeys" are the only hotkeys you find supported in majority of software. You can stop learning a 15 | set of hotkeys for each software, and apply your knowledge of VIM hotkeys for: 16 | - [browsers](https://github.com/philc/vimium) 17 | - Other text editors and IDEs [IntelliJ IDEA](https://github.com/JetBrains/ideavim), 18 | [VS Code](https://github.com/vscode-neovim/vscode-neovim), [Xcode](https://developer.apple.com/forums/thread/681968) (Though 19 | XCode supports a limited set of keys), [Obsidian](https://obsidian.md/), etc 20 | - VIM mode for macOS - https://kindavim.app/ (Though I didn't try it) 21 | - VIM "hotkeys" are OS independent. The only modifier that VIM uses is CTRL, which is hopefully is on the same place on the 22 | keyboard (bottom left corner) on all computer OS'es. All other operations are performed using only QWERTY, which is obviously 23 | the same on all OS'es. (Yes, macOS, I'm looking at you with your custom CMD and OPT modifiers) 24 | 25 | ### ⭐ grep shortcut for 90% of use cases 26 | 27 | [`gp`](../.bin/gp) - Basically, it's a `grep --fixed-string --ignore-case` alias. But there are small tweaks. 28 | 29 | - If you pipe something into `gp`, then it searched in stdin. Otherwise, it searches in text files in current dir recursively 30 | - Searches for the plain text match, not regex (because it's what's needed in 90%) 31 | - Ignores case by default (because it's what's needed in 90%) 32 | - No need to put quotes around the search query. `gp search query` and `gp "search query"` are equivalent 33 | - Uses `-n` to print line number by default. It's needed to make it possible to use `gp` in vim quickfix list 34 | 35 | `gp` isn't a replacement for `grep` or [`rg`](https://github.com/BurntSushi/ripgrep). `gp` is a shortcut for `grep` functionality 36 | which is needed in 90% you use `grep`. For more complicated search queries I still use plain old `grep`. 37 | 38 | **Name explanation:** Original `grep` stands for vim `:global/regex/print` command. If you drop the middle "**RE**gex" part and 39 | use plain text match then you will get `gp`. 40 | 41 | ### ⭐ Better clipboard CLI tool 42 | 43 | [`cb`](../.bin/cb) - Stands for "**C**lip**B**oard" 44 | 45 | - If you pipe something into `cb`, then it copies stdin into clipboard. If it's used without args and without stdin, it prints 46 | the current clipboard content. 47 | - If the argument is passed then `cb` interprets it as a relative path, and copies its normalized path to the clipboard (because 48 | CLI is my main environment, and I often need to copy path from CLI into some GUI app) 49 | - Linux and macOS are supported 50 | 51 | ### ⭐ dotfiles version control with pure git. No symlinks involved 52 | 53 | [`d`](../.bin/d) - "d" because "**D**otfiles". `d` is just an alias for `git -c status.showUntrackedFiles=no 54 | --git-dir=$HOME/.dotfiles --work-tree=$HOME "$@"` 55 | 56 | -------------------------------------------------------------------------------- /.config/mimeapps.list: -------------------------------------------------------------------------------- 1 | [Added Associations] 2 | application/json=sublime_text_3.desktop;code-oss.desktop; 3 | application/octet-stream=yourkit.desktop; 4 | application/pdf=okularApplication_pdf.desktop;org.gnome.Evince.desktop; 5 | application/x-java-archive=org.gnome.FileRoller.desktop; 6 | application/xml=sublime_text_3.desktop;code-oss.desktop; 7 | image/gif=xviewer.desktop; 8 | image/jpeg=xviewer.desktop; 9 | image/png=xviewer.desktop;org.gnome.gThumb.desktop;org.gnome.eog.desktop; 10 | image/svg+xml=xviewer.desktop; 11 | inode/directory=file-manager.desktop;xfce4-file-manager.desktop; 12 | text/csv=sublime_text_3.desktop;code-oss.desktop; 13 | text/html=google-chrome-fixed.desktop; 14 | text/markdown=userapp-micro-XHH0M0.desktop;sublime_text_3.desktop; 15 | text/plain=sublime_text_3.desktop; 16 | text/x-c++src=sublime_text_3.desktop;code-oss.desktop; 17 | text/x-csrc=code-oss.desktop; 18 | text/x-log=sublime_text_3.desktop; 19 | text/x-makefile=sublime_text_3.desktop; 20 | video/mp4=vlc.desktop; 21 | video/quicktime=vlc.desktop; 22 | video/x-matroska=vlc.desktop; 23 | video/x-msvideo=vlc.desktop; 24 | x-scheme-handler/http=web-browser.desktop;opera.desktop;exo-web-browser.desktop; 25 | x-scheme-handler/https=web-browser.desktop;opera.desktop;exo-web-browser.desktop; 26 | x-scheme-handler/tg=userapp-Telegram Desktop-5671V0.desktop;userapp-Telegram Desktop-SKXMS1.desktop;org.telegram.desktop.desktop; 27 | x-scheme-handler/trash=xfce4-file-manager.desktop; 28 | audio/x-matroska=vlc.desktop; 29 | x-scheme-handler/mid=userapp-Thunderbird-6SKIB1.desktop;userapp-Thunderbird-JK43Z1.desktop; 30 | x-scheme-handler/webcal=userapp-Thunderbird-7QTGB1.desktop;userapp-Thunderbird-2QU7Z1.desktop; 31 | x-scheme-handler/webcals=userapp-Thunderbird-7QTGB1.desktop;userapp-Thunderbird-2QU7Z1.desktop; 32 | x-scheme-handler/mailto=userapp-Thunderbird-JK43Z1.desktop; 33 | 34 | [Default Applications] 35 | application/json=code-oss.desktop 36 | application/octet-stream=yourkit.desktop 37 | application/pdf=org.gnome.Evince.desktop 38 | application/x-java-archive=org.gnome.FileRoller.desktop 39 | application/xml=code-oss.desktop 40 | image/gif=xviewer.desktop 41 | image/jpeg=xviewer.desktop 42 | image/png=org.gnome.eog.desktop 43 | image/svg+xml=xviewer.desktop 44 | inode/directory=file-manager.desktop; 45 | text/csv=code-oss.desktop 46 | text/html=google-chrome.desktop 47 | text/markdown=sublime_text_3.desktop 48 | text/plain=sublime_text_3.desktop 49 | text/x-c++src=sublime_text_3.desktop 50 | text/x-csrc=code-oss.desktop 51 | text/x-log=sublime_text_3.desktop 52 | text/x-makefile=sublime_text_3.desktop 53 | video/mp4=vlc.desktop 54 | video/quicktime=vlc.desktop 55 | video/x-matroska=vlc.desktop 56 | video/x-msvideo=vlc.desktop 57 | x-scheme-handler/about=google-chrome.desktop 58 | x-scheme-handler/discord-402572971681644545=discord-402572971681644545.desktop 59 | x-scheme-handler/http=google-chrome.desktop 60 | x-scheme-handler/https=google-chrome.desktop 61 | x-scheme-handler/jetbrains=jetbrains-toolbox.desktop 62 | x-scheme-handler/tg=org.telegram.desktop.desktop 63 | x-scheme-handler/trash=xfce4-file-manager.desktop 64 | x-scheme-handler/unknown=google-chrome.desktop 65 | x-scheme-handler/slack=slack.desktop 66 | audio/x-matroska=vlc.desktop 67 | message/rfc822=userapp-Thunderbird-JK43Z1.desktop 68 | x-scheme-handler/mid=userapp-Thunderbird-JK43Z1.desktop 69 | x-scheme-handler/webcal=userapp-Thunderbird-2QU7Z1.desktop 70 | text/calendar=userapp-Thunderbird-2QU7Z1.desktop 71 | application/x-extension-ics=userapp-Thunderbird-2QU7Z1.desktop 72 | x-scheme-handler/webcals=userapp-Thunderbird-2QU7Z1.desktop 73 | x-scheme-handler/franz=franz.desktop 74 | x-scheme-handler/fleet=Fleet.desktop 75 | x-scheme-handler/mailto=userapp-Thunderbird-JK43Z1.desktop 76 | -------------------------------------------------------------------------------- /.aerospace.toml: -------------------------------------------------------------------------------- 1 | start-at-login = true 2 | 3 | [mode.main.binding] 4 | alt-enter = 'exec-and-forget open -n /Applications/Alacritty.app' 5 | # alt-enter = 'exec-and-forget /Applications/Alacritty.app/Contents/MacOS/alacritty -e /Users/bobko/.bin/pw' 6 | 7 | alt-slash = 'layout tiles horizontal vertical' 8 | alt-comma = 'layout accordion horizontal vertical' 9 | 10 | # Focus window 11 | alt-h = 'focus left' 12 | alt-j = 'focus down' 13 | alt-k = 'focus up' 14 | alt-l = 'focus right' 15 | 16 | alt-shift-k = 'move-through up' 17 | alt-shift-h = 'move-through left' 18 | alt-shift-j = 'move-through down' 19 | alt-shift-l = 'move-through right' 20 | 21 | alt-shift-minus = 'resize smart -50' 22 | alt-shift-equal = 'resize smart +50' 23 | 24 | alt-0 = 'workspace 0' 25 | alt-1 = 'workspace 1' 26 | alt-2 = 'workspace 2' 27 | alt-3 = 'workspace 3' 28 | alt-4 = 'workspace 4' 29 | alt-5 = 'workspace 5' 30 | alt-6 = 'workspace 6' 31 | alt-7 = 'workspace 7' 32 | alt-8 = 'workspace 8' 33 | alt-9 = 'workspace 9' 34 | alt-a = 'workspace A' 35 | alt-b = 'workspace B' 36 | alt-c = 'workspace C' 37 | alt-d = 'workspace D' 38 | alt-e = 'workspace E' 39 | alt-f = 'workspace F' 40 | alt-g = 'workspace G' 41 | alt-i = 'workspace I' 42 | alt-m = 'workspace M' 43 | alt-n = 'workspace N' 44 | alt-o = 'workspace O' 45 | alt-p = 'workspace P' 46 | alt-q = 'workspace Q' 47 | alt-r = 'workspace R' 48 | alt-s = 'workspace S' 49 | alt-t = 'workspace T' 50 | alt-u = 'workspace U' 51 | alt-v = 'workspace V' 52 | alt-w = 'workspace W' 53 | alt-x = 'workspace X' 54 | alt-y = 'workspace Y' 55 | alt-z = 'workspace Z' 56 | 57 | alt-shift-0 = 'move-node-to-workspace 0' 58 | alt-shift-1 = 'move-node-to-workspace 1' 59 | alt-shift-2 = 'move-node-to-workspace 2' 60 | alt-shift-3 = 'move-node-to-workspace 3' 61 | alt-shift-4 = 'move-node-to-workspace 4' 62 | alt-shift-5 = 'move-node-to-workspace 5' 63 | alt-shift-6 = 'move-node-to-workspace 6' 64 | alt-shift-7 = 'move-node-to-workspace 7' 65 | alt-shift-8 = 'move-node-to-workspace 8' 66 | alt-shift-9 = 'move-node-to-workspace 9' 67 | alt-shift-a = 'move-node-to-workspace A' 68 | alt-shift-b = 'move-node-to-workspace B' 69 | alt-shift-c = 'move-node-to-workspace C' 70 | alt-shift-d = 'move-node-to-workspace D' 71 | alt-shift-e = 'move-node-to-workspace E' 72 | alt-shift-f = 'move-node-to-workspace F' 73 | alt-shift-g = 'move-node-to-workspace G' 74 | alt-shift-i = 'move-node-to-workspace I' 75 | alt-shift-m = 'move-node-to-workspace M' 76 | alt-shift-n = 'move-node-to-workspace N' 77 | alt-shift-o = 'move-node-to-workspace O' 78 | alt-shift-p = 'move-node-to-workspace P' 79 | alt-shift-q = 'move-node-to-workspace Q' 80 | alt-shift-r = 'move-node-to-workspace R' 81 | alt-shift-s = 'move-node-to-workspace S' 82 | alt-shift-t = 'move-node-to-workspace T' 83 | alt-shift-u = 'move-node-to-workspace U' 84 | alt-shift-v = 'move-node-to-workspace V' 85 | alt-shift-w = 'move-node-to-workspace W' 86 | alt-shift-x = 'move-node-to-workspace X' 87 | alt-shift-y = 'move-node-to-workspace Y' 88 | alt-shift-z = 'move-node-to-workspace Z' 89 | 90 | alt-tab = 'workspace-back-and-forth' 91 | alt-shift-tab = 'move-workspace-to-display next' 92 | 93 | alt-shift-semicolon = 'mode service' 94 | alt-shift-slash = 'mode join' 95 | 96 | [mode.service.binding] 97 | r = ['flatten-workspace-tree', 'mode main'] # Mnemonics: R - reset 98 | # p = ['exec-and-forget /Applications/Alacritty.app/Contents/MacOS/alacritty -e /Users/bobko/.bin/pw', 'mode main'] 99 | # s = ['layout sticky', 'mode main'] 100 | f = ['layout floating tiling', 'mode main'] 101 | backspace = ['close-all-windows-but-current', 'mode main'] 102 | esc = ['mode main', 'reload-config'] 103 | 104 | [mode.join.binding] 105 | alt-shift-h = ['join-with left', 'mode main'] 106 | alt-shift-j = ['join-with down', 'mode main'] 107 | alt-shift-k = ['join-with up', 'mode main'] 108 | alt-shift-l = ['join-with right', 'mode main'] 109 | esc = 'mode main' 110 | -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | [alias] 2 | a = add -p 3 | aa = add --all 4 | an = add -N . 5 | b = branch 6 | c = -c diff.noprefix=true commit 7 | ca = commit --amend --allow-empty 8 | cae = commit --allow-empty 9 | can = commit --amend --no-edit --allow-empty 10 | cem = commit -m 'EMPTY MESSAGE' # mnemonic Empty Message 11 | cf = commit --fixup 12 | ch = checkout 13 | chd = checkout --detach 14 | cln = "!f() { local hash=$(git rev-parse HEAD) && git add --all && git commit --no-verify -m \"GIT CLEAN $(date)\" && git reset --hard $hash; }; f" 15 | cp = cherry-pick --allow-empty 16 | cpa = cherry-pick --abort 17 | cps = cherry-pick --skip 18 | cpc = cherry-pick --continue 19 | cps = cherry-pick --skip 20 | cpx = cherry-pick -x --allow-empty 21 | crm = commit --reuse-message 22 | cup = "!f() { git cem && git u && git p; }; f" # commit && pull && push 23 | cs = commit --squash 24 | d = diff --no-prefix 25 | dt = "!f() { git --paginate difftool --tool=difftastic --no-prompt \"$@\"; }; f" 26 | ds = diff --staged --no-prefix 27 | f = !git-fetch-smart-if-no-args 28 | ff = !git-fast-forward.bash 29 | fpr = "!f() { git fetch o pull/"$1"/head:pr-"$1"; }; f" # fetch-pull-request 30 | g = l --graph 31 | ga = g --all 32 | jm = jump merge 33 | l = log --no-prefix --pretty='%C(auto)%h %Cgreen%as %Cblue%an/%cn%C(auto)%d %Creset%s' 34 | lh = log-head 35 | ls-assumed-unchanged = "!f() { git ls-files -v | grep '^h'; }; f" 36 | ls-repo = ls-tree --full-tree -r --name-only HEAD 37 | ls-untracked = ls-files --others --exclude-standard 38 | p = push 39 | pb = "!f() { git push o @:refs/heads/"$1"; }; f" # mnemonic: git push branch 40 | pbf = "!f() { git push --force-with-lease o @:refs/heads/"$1"; }; f" # mnemonic: git push branch 41 | pf = push --force-with-lease 42 | p-tmp = "!f() { git push o "${1:-HEAD}":refs/heads/bobko/tmp/$(git rev-parse --short "${1:-HEAD}"); }; f" 43 | rb = rebase -i 44 | rba = rebase --abort 45 | rbas = rebase -i --autosquash 46 | rbc = rebase --continue 47 | rbs = rebase --skip 48 | rv = revise -i 49 | rvc = revise -c 50 | rve = revise -e 51 | rvas = revise -i --autosquash 52 | rs = reset 53 | rsh = reset --hard 54 | rss = reset --soft 55 | s = !git-status.bash 56 | scp = "!f() { git rev-list --no-walk --reverse $@ | while read it; do git cherry @ ${it} ${it}~; done | grep + | awk '{print $2}' | xargs git cherry-pick; }; f" 57 | sh = show --no-prefix 58 | sht = "!f() { git --paginate difftool --tool=difftastic --no-prompt ${1:-@}^..${1:-@}; }; f" 59 | tmp = branch -f tmp 60 | u = !git-pull-smart-if-no-args 61 | up = "!f() { g u && g p; }; f" 62 | wip = "!f() { git add --all && git commit --no-verify -m \"WIP! $(date) $*\"; }; f" 63 | wa = worktree add --detach 64 | wl = worktree list 65 | [user] 66 | name = Nikita Bobko 67 | email = email@example.com 68 | [core] 69 | editor = "v '+set colorcolumn=73'" 70 | quotePath = false 71 | commitGraph = true 72 | [push] 73 | default = current 74 | [commit] 75 | verbose = true 76 | cleanup = scissors 77 | [rebase] 78 | instructionFormat = "%as %an/%cn%d %s" 79 | autoStash = on 80 | missingCommitsCheck = error 81 | [pull] 82 | rebase = true 83 | [filter "lfs"] 84 | clean = git-lfs clean -- %f 85 | smudge = git-lfs smudge -- %f 86 | process = git-lfs filter-process 87 | required = true 88 | [receive] 89 | denyCurrentBranch = updateInstead 90 | [merge] 91 | conflictstyle = diff3 92 | [format] 93 | pretty = fuller 94 | [status] 95 | showStash = true 96 | [init] 97 | defaultBranch = main 98 | [advice] 99 | detachedHead = false 100 | [diff] 101 | colorMoved = default 102 | [difftool "difftastic"] 103 | cmd = difft "$LOCAL" "$REMOTE" 104 | [branch] 105 | autosetupmerge = off 106 | [clone] 107 | defaultRemoteName = o 108 | [remote] 109 | pushDefault = o 110 | [includeIf "gitdir:~/jb/"] 111 | path = ~/jb/.gitconfig 112 | [includeIf "gitdir:~/.vim/"] 113 | path = ~/.vim/.gitconfig # Hack because vim-plug doesn't ignore my custom git configs. This PR https://github.com/junegunn/vim-plug/pull/1117 doens't fix the problem 114 | [gc] 115 | writeCommitGraph = true 116 | [fetch] 117 | prune = true # Because people like to push branches with incompatible names that lead to 'cannot lock ref' errors 118 | -------------------------------------------------------------------------------- /.config/karabiner/assets/complex_modifications/ctrlArrows.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Exchange control + arrows keys with option + arrows keys", 3 | "rules": [ 4 | { 5 | "description": "Exchange control + arrow keys with option + arrow keys", 6 | "manipulators": [ 7 | { 8 | "type": "basic", 9 | "from": { 10 | "key_code": "right_arrow", 11 | "modifiers": { 12 | "mandatory": [ 13 | "control" 14 | ], 15 | "optional": [ 16 | "any" 17 | ] 18 | } 19 | }, 20 | "to": [ 21 | { 22 | "key_code": "right_arrow", 23 | "modifiers": [ 24 | "option" 25 | ] 26 | } 27 | ] 28 | }, 29 | { 30 | "type": "basic", 31 | "from": { 32 | "key_code": "left_arrow", 33 | "modifiers": { 34 | "mandatory": [ 35 | "control" 36 | ], 37 | "optional": [ 38 | "any" 39 | ] 40 | } 41 | }, 42 | "to": [ 43 | { 44 | "key_code": "left_arrow", 45 | "modifiers": [ 46 | "option" 47 | ] 48 | } 49 | ] 50 | }, 51 | { 52 | "type": "basic", 53 | "from": { 54 | "key_code": "up_arrow", 55 | "modifiers": { 56 | "mandatory": [ 57 | "control" 58 | ], 59 | "optional": [ 60 | "any" 61 | ] 62 | } 63 | }, 64 | "to": [ 65 | { 66 | "key_code": "up_arrow", 67 | "modifiers": [ 68 | "option" 69 | ] 70 | } 71 | ] 72 | }, 73 | { 74 | "type": "basic", 75 | "from": { 76 | "key_code": "down_arrow", 77 | "modifiers": { 78 | "mandatory": [ 79 | "control" 80 | ], 81 | "optional": [ 82 | "any" 83 | ] 84 | } 85 | }, 86 | "to": [ 87 | { 88 | "key_code": "down_arrow", 89 | "modifiers": [ 90 | "option" 91 | ] 92 | } 93 | ] 94 | }, 95 | { 96 | "type": "basic", 97 | "from": { 98 | "key_code": "right_arrow", 99 | "modifiers": { 100 | "mandatory": [ 101 | "control" 102 | ], 103 | "optional": [ 104 | "any" 105 | ] 106 | } 107 | }, 108 | "to": [ 109 | { 110 | "key_code": "right_arrow", 111 | "modifiers": [ 112 | "command" 113 | ] 114 | } 115 | ] 116 | }, 117 | { 118 | "type": "basic", 119 | "from": { 120 | "key_code": "left_arrow", 121 | "modifiers": { 122 | "mandatory": [ 123 | "control" 124 | ], 125 | "optional": [ 126 | "any" 127 | ] 128 | } 129 | }, 130 | "to": [ 131 | { 132 | "key_code": "left_arrow", 133 | "modifiers": [ 134 | "command" 135 | ] 136 | } 137 | ] 138 | }, 139 | { 140 | "type": "basic", 141 | "from": { 142 | "key_code": "up_arrow", 143 | "modifiers": { 144 | "mandatory": [ 145 | "control" 146 | ], 147 | "optional": [ 148 | "any" 149 | ] 150 | } 151 | }, 152 | "to": [ 153 | { 154 | "key_code": "up_arrow", 155 | "modifiers": [ 156 | "command" 157 | ] 158 | } 159 | ] 160 | }, 161 | { 162 | "type": "basic", 163 | "from": { 164 | "key_code": "down_arrow", 165 | "modifiers": { 166 | "mandatory": [ 167 | "control" 168 | ], 169 | "optional": [ 170 | "any" 171 | ] 172 | } 173 | }, 174 | "to": [ 175 | { 176 | "key_code": "down_arrow", 177 | "modifiers": [ 178 | "command" 179 | ] 180 | } 181 | ] 182 | } 183 | ] 184 | } 185 | ] 186 | } 187 | -------------------------------------------------------------------------------- /.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /.config/nnn/plugins/preview-tabbed: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Description: tabbed/xembed based file previewer 4 | # 5 | # Dependencies: 6 | # - tabbed (https://tools.suckless.org/tabbed): xembed host 7 | # - xterm (or urxvt or st) : xembed client for text-based preview 8 | # - mpv (https://mpv.io): xembed client for video/audio 9 | # - sxiv (https://github.com/muennich/sxiv) or, 10 | # - nsxiv (https://github.com/nsxiv/nsxiv) : xembed client for images 11 | # - zathura (https://pwmt.org/projects/zathura): xembed client for PDF 12 | # - nnn's nuke plugin for text preview and fallback 13 | # nuke is a fallback for 'mpv', 'sxiv'/'nsxiv', and 'zathura', but has its 14 | # own dependencies, see the script for more information 15 | # - vim (or any editor/pager really) 16 | # - file 17 | # - mktemp 18 | # - xdotool (optional, to keep main window focused) 19 | # 20 | # Usage: 21 | # - Install the dependencies. Then set a NNN_FIFO 22 | # and set a key for the plugin, then start `nnn`: 23 | # $ NNN_FIFO=/tmp/nnn.fifo nnn 24 | # - Launch the plugin with the designated key from nnn 25 | # 26 | # Notes: 27 | # 1. This plugin needs a "NNN_FIFO" to work. See man. 28 | # 2. If the same NNN_FIFO is used in multiple nnn instances, there will be one 29 | # common preview window. With different FIFO paths, they will be independent. 30 | # 31 | # How it works: 32 | # We use `tabbed` [1] as a xembed [2] host, to have a single window 33 | # owning each previewer window. So each previewer must be a xembed client. 34 | # For text previewers, this is not an issue, as there are a lot of 35 | # xembed-able terminal emulator (we default to `xterm`, but examples are 36 | # provided for `urxvt` and `st`). For graphic preview this can be trickier, 37 | # but a few popular viewers are xembed-able, we use: 38 | # - `mpv`: multimedia player, for video/audio preview 39 | # - `sxiv`/`nsxiv`: image viewer 40 | # - `zathura`: PDF viewer 41 | # - but we always fallback to `nuke` plugin 42 | # 43 | # [1]: https://tools.suckless.org/tabbed/ 44 | # [2]: https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html 45 | # 46 | # Shell: Bash (job control is weakly specified in POSIX) 47 | # Author: Léo Villeveygoux 48 | 49 | 50 | XDOTOOL_TIMEOUT=2 51 | PAGER=${PAGER:-"vim -R"} 52 | NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke" 53 | 54 | 55 | if type xterm >/dev/null 2>&1 ; then 56 | TERMINAL="xterm -into" 57 | elif type urxvt >/dev/null 2>&1 ; then 58 | TERMINAL="urxvt -embed" 59 | elif type st >/dev/null 2>&1 ; then 60 | TERMINAL="st -w" 61 | else 62 | echo "No xembed term found" >&2 63 | fi 64 | 65 | 66 | term_nuke () { 67 | # $1 -> $XID, $2 -> $FILE 68 | $TERMINAL "$1" -e "$NUKE" "$2" & 69 | } 70 | 71 | start_tabbed () { 72 | FIFO="$(mktemp -u)" 73 | mkfifo "$FIFO" 74 | 75 | tabbed > "$FIFO" & 76 | 77 | jobs # Get rid of the "Completed" entries 78 | 79 | TABBEDPID="$(jobs -p %%)" 80 | 81 | if [ -z "$TABBEDPID" ] ; then 82 | echo "Can't start tabbed" 83 | exit 1 84 | fi 85 | 86 | read -r XID < "$FIFO" 87 | 88 | rm "$FIFO" 89 | } 90 | 91 | get_viewer_pid () { 92 | VIEWERPID="$(jobs -p %%)" 93 | } 94 | 95 | kill_viewer () { 96 | if [ -n "$VIEWERPID" ] && jobs -p | grep "$VIEWERPID" ; then 97 | kill "$VIEWERPID" 98 | fi 99 | } 100 | 101 | sigint_kill () { 102 | kill_viewer 103 | kill "$TABBEDPID" 104 | exit 0 105 | } 106 | 107 | previewer_loop () { 108 | unset -v NNN_FIFO 109 | # mute from now 110 | exec >/dev/null 2>&1 111 | 112 | MAINWINDOW="$(xdotool getactivewindow)" 113 | 114 | start_tabbed 115 | trap sigint_kill SIGINT 116 | 117 | xdotool windowactivate "$MAINWINDOW" 118 | 119 | # Bruteforce focus stealing prevention method, 120 | # works well in floating window managers like XFCE 121 | # but make interaction with the preview window harder 122 | # (uncomment to use): 123 | #xdotool behave "$XID" focus windowactivate "$MAINWINDOW" & 124 | 125 | while read -r FILE ; do 126 | 127 | jobs # Get rid of the "Completed" entries 128 | 129 | if ! jobs | grep tabbed ; then 130 | break 131 | fi 132 | 133 | if [ ! -e "$FILE" ] ; then 134 | continue 135 | fi 136 | 137 | kill_viewer 138 | 139 | MIME="$(file -bL --mime-type "$FILE")" 140 | 141 | case "$MIME" in 142 | video/*) 143 | if type mpv >/dev/null 2>&1 ; then 144 | mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" & 145 | else 146 | term_nuke "$XID" "$FILE" 147 | fi 148 | ;; 149 | audio/*) 150 | if type mpv >/dev/null 2>&1 ; then 151 | mpv --force-window=immediate --loop-file --wid="$XID" "$FILE" & 152 | else 153 | term_nuke "$XID" "$FILE" 154 | fi 155 | ;; 156 | image/*) 157 | if type sxiv >/dev/null 2>&1 ; then 158 | sxiv -ae "$XID" "$FILE" & 159 | elif type nsxiv >/dev/null 2>&1 ; then 160 | nsxiv -ae "$XID" "$FILE" & 161 | else 162 | term_nuke "$XID" "$FILE" 163 | fi 164 | ;; 165 | application/pdf) 166 | if type zathura >/dev/null 2>&1 ; then 167 | zathura -e "$XID" "$FILE" & 168 | else 169 | term_nuke "$XID" "$FILE" 170 | fi 171 | ;; 172 | inode/directory) 173 | $TERMINAL "$XID" -e nnn "$FILE" & 174 | ;; 175 | text/*) 176 | if [ -x "$NUKE" ] ; then 177 | term_nuke "$XID" "$FILE" 178 | else 179 | # shellcheck disable=SC2086 180 | $TERMINAL "$XID" -e $PAGER "$FILE" & 181 | fi 182 | ;; 183 | *) 184 | if [ -x "$NUKE" ] ; then 185 | term_nuke "$XID" "$FILE" 186 | else 187 | $TERMINAL "$XID" -e sh -c "file '$FILE' | $PAGER -" & 188 | fi 189 | ;; 190 | esac 191 | get_viewer_pid 192 | 193 | # following lines are not needed with the bruteforce xdotool method 194 | ACTIVE_XID="$(xdotool getactivewindow)" 195 | if [ $((ACTIVE_XID == XID)) -ne 0 ] ; then 196 | xdotool windowactivate "$MAINWINDOW" 197 | else 198 | timeout "$XDOTOOL_TIMEOUT" xdotool behave "$XID" focus windowactivate "$MAINWINDOW" & 199 | fi 200 | done 201 | kill "$TABBEDPID" 202 | kill_viewer 203 | } 204 | 205 | if [ ! -r "$NNN_FIFO" ] ; then 206 | echo "Can't read \$NNN_FIFO ('$NNN_FIFO')" 207 | exit 1 208 | fi 209 | 210 | previewer_loop < "$NNN_FIFO" & 211 | disown 212 | -------------------------------------------------------------------------------- /.config/trizen/trizen.conf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # trizen configuration file 4 | 5 | our $CONFIG = { 6 | ask_for_retry => 1, # bool -- When `makepkg` fails to build a package, offer the option for trying again. 7 | aur_results_last_modified => 1, # bool -- Show the date when the packages were last updated in AUR results. 8 | aur_results_popularity => 1, # bool -- Show the popularity score in AUR results. 9 | aur_results_show_installed => 1, # bool -- Show when a package is installed in AUR results. 10 | aur_results_sort_by => "votes", # str -- Sort the AUR results by "name", "votes", "popularity" or "date". 11 | aur_results_sort_order => "descending", # str -- Sort the AUR results in "ascending" or "descending" order. 12 | aur_results_votes => 1, # bool -- Show the number of votes in AUR results. 13 | clone_dir => "$ENV{HOME}/.cache/trizen", # str -- Absolute path to the directory where to clone and build packages. 14 | color_code_dependencies => 1, # bool -- Display the dependencies of a package in specific colors (green = installed; cyan = in repo; purple = in AUR). 15 | debug => 0, # bool -- Verbose mode. 16 | flip_indices => 1, # bool -- In search+install mode, show the indices of packages in reverse order. 17 | flip_results => 1, # bool -- Show the search results in reverse order. 18 | forcecolors => 0, # bool -- Force output colors even when not writing to STDOUT. 19 | git_clone_depth => 0, # int -- Pass the `--depth int` flag to `git clone`. (0 means no limit) 20 | lwp_env_proxy => 1, # bool -- Use proxy settings defined in `env` (if any). 21 | lwp_show_progress => 0, # bool -- Show the HTTPS requests made by LWP::UserAgent to the AUR servers. 22 | lwp_timeout => 60, # int -- Seconds after which an HTTPS connection is aborted. 23 | makepkg_command => "/usr/bin/makepkg -scf", # str -- The `makepkg` command that is used internally in building a package. 24 | movepkg => 1, # bool -- Move built packages in the directory `movepkg_dir`. 25 | movepkg_dir => "/var/cache/pacman/pkg", # str -- Absolute path to the directory where to move built packages (with `movepkg`). 26 | nocolors => 0, # bool -- Disable output colors for `trizen`. 27 | noedit => 0, # bool -- Do not prompt to edit files when installing an AUR package. 28 | noinfo => 0, # bool -- Do not display package information when installing an AUR package. 29 | noinstall => 0, # bool -- Do not install built packages -- builds only. 30 | nopull => 0, # bool -- Do not `git pull` new changes from the AUR git server. 31 | one_line_edit => 0, # bool -- Select one or more build files to view/edit with one-line prompt. 32 | packages_in_stats => 5, # int -- The number of packages to display in `--stats` 33 | pacman_command => "/usr/bin/pacman", # str -- The `pacman` command that is used internally for pacman operations. 34 | pacman_local_dir => "/var/lib/pacman/local", # str -- Absolute path to the pacman's local directory. 35 | pager_mode => 0, # bool -- Show the build files in pager mode using pager. 36 | recompute_deps => 1, # bool -- Recompute the dependencies of a package (after its build files are inspected / edited). 37 | show_build_files_content => 1, # bool -- Show the content of the build files of a package before building it. 38 | show_comments => 0, # int -- Show the `n` most recent AUR comments for a package before building it. (max: 10) 39 | show_diff_only => 0, # bool -- When the build files of a package already exist locally, show the diff only. 40 | show_inexistent => 1, # bool -- Warn about packages that do not exist in AUR, during -Su. 41 | show_ood => 1, # bool -- Warn about out-of-date marked packages, during -Su. 42 | show_unmaintained => 1, # bool -- Warn about unmaintained packages, during -Su. 43 | skipinteg => 0, # bool -- Pass the `--skipinteg` argument to `makepkg`. 44 | split_packages => 1, # bool -- Ask about installing the other parts of a split package. 45 | ssl_verify_hostname => 1, # bool -- Ensure LWP::UserAgent connects to servers that have a valid certificate. 46 | su_command => "/usr/bin/su -c", # str -- Command used when special permissions are required and `use_sudo` is set to 0. 47 | sudo_autorepeat => 0, # bool -- Automatically repeat `sudo -v` in the background after a `sudo` command was first executed. 48 | sudo_autorepeat_at_runtime => 0, # bool -- Execute `sudo -v` when `trizen` is first executed and apply the behavior of `sudo_autorepeat`. 49 | sudo_autorepeat_interval => 180, # int -- Interval, in seconds, after which `sudo -v` is executed in background (with `sudo_autorepeat`). 50 | sudo_command => "/usr/bin/sudo", # str -- Command used when special permissions are required and `use_sudo` is set to 1. 51 | sudo_remove_timestamp => 1, # bool -- Remove the cached sudo credentials before `makepkg` is executed (`sudo --remove-timestamp`). 52 | syntax_highlighting => 0, # bool -- Syntax highlighting of the build files, using the `highlight` tool from [community]. 53 | syntax_highlighting_cmd => "/usr/bin/highlight -O ansi", # str -- The `highlight` command used in highlighting the syntax of the build files (with `syntax_highlighting`). 54 | use_github_api => 1, # bool -- Check GitHub sources for updates using GitHub's API. (during `--devel --needed`) 55 | use_gitlab_api => 1, # bool -- Check GitLab sources for updates using GitLab's API. (during `--devel --needed`) 56 | use_sudo => 1, # bool -- Use the `sudo` command when special permissions are required. 57 | } 58 | -------------------------------------------------------------------------------- /.config/Code - OSS/User/keybindings.json: -------------------------------------------------------------------------------- 1 | // Place your key bindings in this file to override the defaultsauto[] 2 | [ 3 | { 4 | "key": "ctrl+tab", 5 | "command": "workbench.action.nextEditor" 6 | }, 7 | { 8 | "key": "ctrl+pagedown", 9 | "command": "-workbench.action.nextEditor" 10 | }, 11 | { 12 | "key": "ctrl+shift+tab", 13 | "command": "-workbench.action.openPreviousRecentlyUsedEditorInGroup" 14 | }, 15 | { 16 | "key": "ctrl+shift+tab", 17 | "command": "-workbench.action.quickOpenNavigatePreviousInEditorPicker", 18 | "when": "inEditorsPicker && inQuickOpen" 19 | }, 20 | { 21 | "key": "ctrl+shift+tab", 22 | "command": "workbench.action.previousEditor" 23 | }, 24 | { 25 | "key": "ctrl+pageup", 26 | "command": "-workbench.action.previousEditor" 27 | }, 28 | { 29 | "key": "ctrl+tab", 30 | "command": "-workbench.action.openNextRecentlyUsedEditorInGroup" 31 | }, 32 | { 33 | "key": "f12", 34 | "command": "-editor.action.revealDefinition", 35 | "when": "editorHasDefinitionProvider && editorTextFocus && !isInEmbeddedEditor" 36 | }, 37 | { 38 | "key": "ctrl+b", 39 | "command": "-editor.action.goToDeclaration", 40 | "when": "editorHasDefinitionProvider && editorTextFocus" 41 | }, 42 | { 43 | "key": "ctrl+b", 44 | "command": "editor.action.revealDefinition" 45 | }, 46 | { 47 | "key": "ctrl+alt+left", 48 | "command": "workbench.action.quickInputBack", 49 | "when": "inQuickOpen" 50 | }, 51 | { 52 | "key": "ctrl+alt+-", 53 | "command": "-workbench.action.quickInputBack", 54 | "when": "inQuickOpen" 55 | }, 56 | { 57 | "key": "ctrl+alt+left", 58 | "command": "workbench.action.navigateBack" 59 | }, 60 | { 61 | "key": "ctrl+alt+-", 62 | "command": "-workbench.action.navigateBack" 63 | }, 64 | { 65 | "key": "ctrl+p", 66 | "command": "-workbench.action.quickOpen" 67 | }, 68 | { 69 | "key": "ctrl+p", 70 | "command": "editor.action.triggerParameterHints", 71 | "when": "editorHasSignatureHelpProvider && editorTextFocus" 72 | }, 73 | { 74 | "key": "ctrl+shift+space", 75 | "command": "-editor.action.triggerParameterHints", 76 | "when": "editorHasSignatureHelpProvider && editorTextFocus" 77 | }, 78 | { 79 | "key": "ctrl+d", 80 | "command": "-editor.action.addSelectionToNextFindMatch", 81 | "when": "editorFocus" 82 | }, 83 | { 84 | "key": "ctrl+j", 85 | "command": "-workbench.action.togglePanel" 86 | }, 87 | { 88 | "key": "shift+alt+f7", 89 | "command": "references-view.find", 90 | "when": "editorHasReferenceProvider" 91 | }, 92 | { 93 | "key": "shift+alt+f12", 94 | "command": "-references-view.find", 95 | "when": "editorHasReferenceProvider" 96 | }, 97 | { 98 | "key": "shift+f6", 99 | "command": "editor.action.rename", 100 | "when": "editorHasRenameProvider && editorTextFocus && !editorReadonly" 101 | }, 102 | { 103 | "key": "f2", 104 | "command": "-editor.action.rename", 105 | "when": "editorHasRenameProvider && editorTextFocus && !editorReadonly" 106 | }, 107 | { 108 | "key": "ctrl+shift+down", 109 | "command": "editor.action.moveLinesDownAction", 110 | "when": "editorTextFocus && !editorReadonly" 111 | }, 112 | { 113 | "key": "alt+down", 114 | "command": "-editor.action.moveLinesDownAction", 115 | "when": "editorTextFocus && !editorReadonly" 116 | }, 117 | { 118 | "key": "ctrl+shift+up", 119 | "command": "editor.action.moveLinesUpAction", 120 | "when": "editorTextFocus && !editorReadonly" 121 | }, 122 | { 123 | "key": "alt+up", 124 | "command": "-editor.action.moveLinesUpAction", 125 | "when": "editorTextFocus && !editorReadonly" 126 | }, 127 | { 128 | "key": "ctrl+shift+alt+up", 129 | "command": "-editor.action.copyLinesUpAction", 130 | "when": "editorTextFocus && !editorReadonly" 131 | }, 132 | { 133 | "key": "ctrl+shift+d", 134 | "command": "editor.action.copyLinesDownAction", 135 | "when": "editorTextFocus && !editorReadonly" 136 | }, 137 | { 138 | "key": "ctrl+shift+alt+down", 139 | "command": "-editor.action.copyLinesDownAction", 140 | "when": "editorTextFocus && !editorReadonly" 141 | }, 142 | { 143 | "key": "ctrl+shift+a", 144 | "command": "workbench.action.showCommands" 145 | }, 146 | { 147 | "key": "ctrl+shift+p", 148 | "command": "-workbench.action.showCommands" 149 | }, 150 | { 151 | "key": "ctrl+alt+right", 152 | "command": "-workbench.action.moveEditorToNextGroup" 153 | }, 154 | { 155 | "key": "shift+escape", 156 | "command": "workbench.action.toggleSidebarVisibility" 157 | }, 158 | { 159 | "key": "ctrl+b", 160 | "command": "-workbench.action.toggleSidebarVisibility" 161 | }, 162 | { 163 | "key": "ctrl+alt+right", 164 | "command": "workbench.action.navigateForward" 165 | }, 166 | { 167 | "key": "ctrl+shift+-", 168 | "command": "-workbench.action.navigateForward" 169 | }, 170 | { 171 | "key": "ctrl+f12", 172 | "command": "workbench.action.gotoSymbol" 173 | }, 174 | { 175 | "key": "ctrl+shift+o", 176 | "command": "-workbench.action.gotoSymbol" 177 | }, 178 | { 179 | "key": "ctrl+d", 180 | "command": "editor.action.addSelectionToNextFindMatch" 181 | }, 182 | { 183 | "key": "ctrl+shift+e", 184 | "command": "-workbench.action.quickOpenNavigatePreviousInFilePicker", 185 | "when": "inFilesPicker && inQuickOpen" 186 | }, 187 | { 188 | "key": "ctrl+shift+e", 189 | "command": "-workbench.view.explorer" 190 | }, 191 | { 192 | "key": "ctrl+shift+b", 193 | "command": "editor.action.goToTypeDefinition" 194 | }, 195 | { 196 | "key": "alt+f7", 197 | "command": "editor.action.goToReferences", 198 | "when": "editorHasReferenceProvider && editorTextFocus && !inReferenceSearchEditor && !isInEmbeddedEditor" 199 | }, 200 | { 201 | "key": "shift+f12", 202 | "command": "-editor.action.goToReferences", 203 | "when": "editorHasReferenceProvider && editorTextFocus && !inReferenceSearchEditor && !isInEmbeddedEditor" 204 | }, 205 | { 206 | "key": "alt+enter", 207 | "command": "problems.action.showQuickFixes", 208 | "when": "problemFocus" 209 | }, 210 | { 211 | "key": "ctrl+.", 212 | "command": "-problems.action.showQuickFixes", 213 | "when": "problemFocus" 214 | }, 215 | { 216 | "key": "alt+enter", 217 | "command": "editor.action.quickFix", 218 | "when": "editorHasCodeActionsProvider && editorTextFocus && !editorReadonly" 219 | }, 220 | { 221 | "key": "ctrl+.", 222 | "command": "-editor.action.quickFix", 223 | "when": "editorHasCodeActionsProvider && editorTextFocus && !editorReadonly" 224 | } 225 | ] -------------------------------------------------------------------------------- /.config/alacritty/alacritty.yml: -------------------------------------------------------------------------------- 1 | font: 2 | normal: 3 | family: JetBrains Mono 4 | size: 10 5 | 6 | window: 7 | decorations: None 8 | 9 | colors: 10 | hints: 11 | start: 12 | foreground: '#1d1f21' 13 | background: '#e9ff5e' 14 | 15 | end: 16 | foreground: '#1d1f21' 17 | background: '#e9ff5e' 18 | cursor: 19 | background: '#008000' # green. Avoid problems like that https://github.com/alacritty/alacritty/issues/4576 20 | 21 | 22 | hints: 23 | enabled: 24 | # sha-1 hashes (git) 25 | - regex: '[0-9a-f]{5,40}' 26 | action: Copy 27 | post_processing: false 28 | binding: 29 | key: H 30 | mods: Control|Alt 31 | # Linux path 32 | - regex: '\~?[\w/.\-]*[/.][\w/.\-]*' 33 | action: Copy 34 | post_processing: false 35 | binding: 36 | key: P 37 | mods: Control|Alt 38 | - regex: "(ipfs:|ipns:|magnet:|mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)\ 39 | [^\u0000-\u001F\u007F-\u009F<>\"\\s{-}\\^⟨⟩`]+" 40 | command: xdg-open 41 | post_processing: true 42 | mouse: 43 | enabled: true 44 | mods: None 45 | binding: 46 | key: U 47 | mods: Control|Alt 48 | 49 | key_bindings: 50 | # win + shift + enter starts new terminal in the same directory 51 | - { key: V, mods: Control, action: Paste } 52 | - { key: C, mods: Control, action: Copy } 53 | - { key: Back, mods: Control, chars: "\x08" } # ctrl backspace (for macOS) to drop the word in vim 54 | - { key: Back, mods: Alt, chars: "\x08" } # option backspace (for macOS) to drop the word in vim 55 | # Ctrl+Period to siginit because Ctrl+C is Copy (Ctrl+period because it's not escape sequence thus can't produce binding 56 | # conflict with cli) 57 | - { key: Period, mods: Control, chars: "\x03" } 58 | # Remap ctrl+; to ctrl+b for tmux usage (Use `showkey -a` not inside tmux) 59 | - { key: Semicolon, mods: Control, chars: "\x02" } 60 | # macOs HACK. make ctrl+6 behave like ctrl+^ (like it behaves on Linux). Needed for vim 61 | - { key: Key6, mods: Control, chars: "\x1e" } 62 | # Hack for macOs https://github.com/alacritty/alacritty/issues/62 63 | - { key: A, mods: Command, chars: "\x1ba" } 64 | - { key: B, mods: Command, chars: "\x1bb" } 65 | # - { key: C, mods: Command, chars: "\x1bc" } 66 | - { key: D, mods: Command, chars: "\x1bd" } 67 | - { key: E, mods: Command, chars: "\x1be" } 68 | - { key: F, mods: Command, chars: "\x1bf" } 69 | - { key: G, mods: Command, chars: "\x1bg" } 70 | - { key: H, mods: Command, chars: "\x1bh" } 71 | - { key: I, mods: Command, chars: "\x1bi" } 72 | - { key: J, mods: Command, chars: "\x1bj" } 73 | - { key: K, mods: Command, chars: "\x1bk" } 74 | - { key: L, mods: Command, chars: "\x1bl" } 75 | - { key: M, mods: Command, chars: "\x1bm" } 76 | - { key: N, mods: Command, chars: "\x1bn" } 77 | - { key: O, mods: Command, chars: "\x1bo" } 78 | - { key: P, mods: Command, chars: "\x1bp" } 79 | - { key: R, mods: Command, chars: "\x1br" } 80 | - { key: S, mods: Command, chars: "\x1bs" } 81 | - { key: T, mods: Command, chars: "\x1bt" } 82 | - { key: U, mods: Command, chars: "\x1bu" } 83 | # - { key: V, mods: Command, chars: "\x1bv" } 84 | - { key: W, mods: Command, chars: "\x1bw" } 85 | - { key: X, mods: Command, chars: "\x1bx" } 86 | - { key: Y, mods: Command, chars: "\x1by" } 87 | - { key: Z, mods: Command, chars: "\x1bz" } 88 | - { key: A, mods: Command|Shift, chars: "\x1bA" } 89 | - { key: B, mods: Command|Shift, chars: "\x1bB" } 90 | # - { key: C, mods: Command|Shift, chars: "\x1bC" } 91 | - { key: D, mods: Command|Shift, chars: "\x1bD" } 92 | - { key: E, mods: Command|Shift, chars: "\x1bE" } 93 | - { key: F, mods: Command|Shift, chars: "\x1bF" } 94 | - { key: G, mods: Command|Shift, chars: "\x1bG" } 95 | - { key: H, mods: Command|Shift, chars: "\x1bH" } 96 | - { key: I, mods: Command|Shift, chars: "\x1bI" } 97 | - { key: J, mods: Command|Shift, chars: "\x1bJ" } 98 | - { key: K, mods: Command|Shift, chars: "\x1bK" } 99 | - { key: L, mods: Command|Shift, chars: "\x1bL" } 100 | - { key: M, mods: Command|Shift, chars: "\x1bM" } 101 | - { key: N, mods: Command|Shift, chars: "\x1bN" } 102 | - { key: O, mods: Command|Shift, chars: "\x1bO" } 103 | - { key: P, mods: Command|Shift, chars: "\x1bP" } 104 | - { key: R, mods: Command|Shift, chars: "\x1bR" } 105 | - { key: S, mods: Command|Shift, chars: "\x1bS" } 106 | - { key: T, mods: Command|Shift, chars: "\x1bT" } 107 | - { key: U, mods: Command|Shift, chars: "\x1bU" } 108 | # - { key: V, mods: Command|Shift, chars: "\x1bV" } 109 | - { key: W, mods: Command|Shift, chars: "\x1bW" } 110 | - { key: X, mods: Command|Shift, chars: "\x1bX" } 111 | - { key: Y, mods: Command|Shift, chars: "\x1bY" } 112 | - { key: Z, mods: Command|Shift, chars: "\x1bZ" } 113 | - { key: Key1, mods: Command, chars: "\x1b1" } 114 | - { key: Key2, mods: Command, chars: "\x1b2" } 115 | - { key: Key3, mods: Command, chars: "\x1b3" } 116 | - { key: Key4, mods: Command, chars: "\x1b4" } 117 | - { key: Key5, mods: Command, chars: "\x1b5" } 118 | - { key: Key6, mods: Command, chars: "\x1b6" } 119 | - { key: Key7, mods: Command, chars: "\x1b7" } 120 | - { key: Key8, mods: Command, chars: "\x1b8" } 121 | - { key: Key9, mods: Command, chars: "\x1b9" } 122 | - { key: Key0, mods: Command, chars: "\x1b0" } 123 | - { key: Space, mods: Control, chars: "\x00" } # Ctrl + Space 124 | - { key: Grave, mods: Command, chars: "\x1b`" } # Command + ` 125 | - { key: Grave, mods: Command|Shift, chars: "\x1b~" } # Command + ~ 126 | - { key: Period, mods: Command, chars: "\x1b." } # Command + . 127 | - { key: Key8, mods: Command|Shift, chars: "\x1b*" } # Command + * 128 | - { key: Key3, mods: Command|Shift, chars: "\x1b#" } # Command + # 129 | - { key: Period, mods: Command|Shift, chars: "\x1b>" } # Command + > 130 | - { key: Comma, mods: Command|Shift, chars: "\x1b<" } # Command + < 131 | - { key: Minus, mods: Command|Shift, chars: "\x1b_" } # Command + _ 132 | - { key: Key5, mods: Command|Shift, chars: "\x1b%" } # Command + % 133 | - { key: Key6, mods: Command|Shift, chars: "\x1b^" } # Command + ^ 134 | - { key: Backslash, mods: Command, chars: "\x1b\\" } # Command + \ 135 | - { key: Backslash, mods: Command|Shift, chars: "\x1b|" } # Command + | 136 | -------------------------------------------------------------------------------- /.config/vim/common.vim: -------------------------------------------------------------------------------- 1 | set langmap=ё`йqцwуeкrеtнyгuшiщoзpх[ъ]фaыsвdаfпgрhоjлkдlж\\;э'яzчxсcмvиbтnьmб\\,ю.Ё~№#ЙQЦWУEКRЕTНYГUШIЩOЗPХ{Ъ}ФAЫSВDАFПGРHОJЛKДLЖ:Э\"ЯZЧXСCМVИBТNЬMБ<Ю> 2 | set keymap=russian-jcukenwin " Switch with ctrl-6 while in insert mode 3 | call plug#begin() 4 | " Plug 'RRethy/vim-hexokinase'| " Colors in the editor. The plugin requires fucking manual `make` 5 | " Plug 'easymotion/vim-easymotion' 6 | " Plug 'godlygeek/tabular'| Plug 'preservim/vim-markdown' 7 | " Plug 'powerman/vim-plugin-ruscmd' 8 | " Plug 'sheerun/vim-polyglot' 9 | " Plug 'tomasr/molokai' 10 | " TODO: autosave 11 | "Plug 'AndrewRadev/switch.vim' 12 | " Plug 'preservim/nerdtree' 13 | " Plug 'Yggdroot/indentLine'| " Indentation vertical line. Disable because it override conceallevel 14 | Plug 'chrisbra/Recover.vim'| " Prompt to show diff when recovering vim swap file 15 | Plug 'AndrewRadev/linediff.vim'| " Simple plugin to show diff between marked lines 16 | Plug 'jeffkreeftmeijer/vim-numbertoggle'| " Use relative numbers only when terminal window is focused & in normal mode 17 | Plug 'junegunn/fzf.vim' 18 | Plug 'kana/vim-textobj-user' | 19 | Plug 'kana/vim-textobj-entire'| " text object = entire document 20 | Plug 'kana/vim-textobj-line'| " line text object 21 | Plug 'pianohacker/vim-textobj-indented-paragraph' 22 | Plug 'saihoooooooo/vim-textobj-space'| " continious whitespaces text object 23 | Plug 'glts/vim-textobj-comment'| " ic/ac comment text object 24 | 25 | Plug 'AndrewRadev/linediff.vim'| " :Linediff 26 | Plug 'unblevable/quick-scope'| " Highlight unique letters on the line 27 | " Plug 'mg979/vim-visual-multi'| " Multi carret 28 | Plug 'michaeljsmith/vim-indent-object' 29 | Plug 'morhetz/gruvbox'| " Color theme 30 | Plug 'psliwka/vim-smoothie'| " Smooth scrolling 31 | Plug 'tpope/vim-commentary'| " 'gc' to comment 32 | Plug 'tpope/vim-fugitive' 33 | Plug 'tpope/vim-repeat'| " Extend dot behaviour to repeat custom actions from plugins 34 | Plug 'tpope/vim-sleuth'| " automatic indent 35 | Plug 'tpope/vim-surround' 36 | Plug 'udalov/kotlin-vim' 37 | Plug 'wellle/targets.vim'| " Additional text objects (arguments inside paired chars like /) 38 | Plug 'haya14busa/vim-asterisk'| " z start motion + star in visual mode 39 | Plug 'tpope/vim-unimpaired'| " Pairs of handy bracket mappings ]q, [q (for quick fix list), ]a, [a (for argument list), ], [ 40 | Plug 'neoclide/coc.nvim', {'branch': 'release'}| " The plugin enables autocompletion 41 | 42 | Plug 'iamcco/markdown-preview.nvim', { 'do': 'cd app && yarn install' } 43 | 44 | Plug 'MrcJkb/haskell-tools.nvim' 45 | Plug 'neovim/nvim-lspconfig' 46 | Plug 'nvim-lua/plenary.nvim' 47 | call plug#end() 48 | 49 | set termguicolors 50 | colorscheme gruvbox 51 | set bg=dark 52 | let &t_ut=''| " Fix background issue in kitty terminal https://github.com/kovidgoyal/kitty/issues/108 53 | 54 | " HACK https://github.com/junegunn/fzf.vim/issues/439 55 | set rtp+=/opt/homebrew/opt/fzf 56 | 57 | " dash in completion 58 | autocmd FileType * let b:coc_additional_keywords = ["-"] 59 | 60 | let g:indentLine_char = '▏' 61 | "set spell spelllang=en_us 62 | au BufRead,BufNewFile git-revise-todo setfiletype gitrebase 63 | set smartcase 64 | set autoindent| " Auto indent 65 | set wildmenu| " Better tab completion in command mode 66 | set wildmode=longest:full,lastused:full 67 | set wildignorecase| " Ignore case in wildmenu 68 | filetype plugin on 69 | 70 | "autocmd FileType gitcommit set textwidth=72 71 | set colorcolumn=+1| " Ruler 72 | set textwidth=130| " automatically insert line breaks at specified length 73 | 74 | set expandtab shiftwidth=4| " OVERRIDE SLEUTH DEFAUL: Tn pressing tab, insert 4 spaces 75 | set conceallevel=0| " Never ever hide quotes in json 76 | set hlsearch| " Search highlighting 77 | set ignorecase| " ignore case in search 78 | " set foldmethod=syntax 79 | " set nofoldenable| " Don't fold everything by default 80 | set incsearch| " Show matches while search 81 | set list listchars=space:·,tab:╶─ 82 | set mouse=a| " Mouse support 83 | set number relativenumber| " Show line numbers 84 | set tabstop=4| " show existing tab with 4 spaces width 85 | set timeoutlen=1000 ttimeoutlen=0 " Avoid delay on ESC 86 | set hidden| " Don't require to save buffer in order to switch to another buffer 87 | set nofixendofline| " Don't add new lines at the end of every file 88 | set iminsert=0 89 | set imsearch=-1 90 | syntax on| " Enable or disable syntax 91 | set nowrapscan| " Don't cycle search results 92 | set cursorline| " Highlight line where the cursor is 93 | 94 | if executable('rg') 95 | source ~/.v/ripgrep-sensible.vim 96 | endif 97 | 98 | set undodir=$HOME/.vim/undo| " directory where the undo files will be stored 99 | set undofile 100 | 101 | " Different cursor style (beam/block) in different modes 102 | let &t_SI.="\e[5 q" "SI = INSERT mode 103 | let &t_SR.="\e[4 q" "SR = REPLACE mode 104 | let &t_EI.="\e[1 q" "EI = NORMAL mode (ELSE) 105 | 106 | " Paste yanked line without line breaks before/after cursor position 107 | nnoremap gP i"+PkJxJx 108 | nnoremap gp a"+PkJxJx 109 | 110 | """""""""""""""" 111 | """ BINDINGS """ 112 | """""""""""""""" 113 | ":map :noremap :unmap Normal, Visual, Select, Operator-pending 114 | ":nmap :nnoremap :nunmap Normal 115 | ":vmap :vnoremap :vunmap Visual and Select 116 | ":smap :snoremap :sunmap Select 117 | ":xmap :xnoremap :xunmap Visual 118 | ":omap :onoremap :ounmap Operator-pending 119 | ":map! :noremap! :unmap! Insert and Command-line 120 | ":imap :inoremap :iunmap Insert 121 | ":lmap :lnoremap :lunmap Insert, Command-line, Lang-Arg 122 | ":cmap :cnoremap :cunmap Command-line 123 | ":tmap :tnoremap :tunmap Terminal-Job 124 | " Insert modes key mappings 125 | imap | " ctrl-backspace to drop a word (CLI) 126 | imap | " ctrl-backspace to drop a word (GUI) 127 | imap "+pa 128 | vmap "+y 129 | cmap + 130 | map b :Buffers! 131 | map f :Files! 132 | map s :GFiles!?| " git status files 133 | map h :History! 134 | map r :Rg! 135 | map b :G blame 136 | map l :G log -p -- % 137 | " 138 | " https://vi.stackexchange.com/questions/20307/find-and-highlight-current-file-in-netrw 139 | " map e :Ex :sil! /=expand("%:t") 140 | map e :e =expand("%:h")/ 141 | 142 | map Q :cq!| map Й :cq! 143 | map q :wqa| map й :wqa 144 | map w :wa| map ц :wa 145 | " Whenever I do line-wise operations (like prepend something with `I`) then 146 | " I want to be able to repeat it with dot in visual mode 147 | xnoremap . :normal . 148 | xnoremap @ :normal @ 149 | 150 | " Switch keyboard layout in vim using ctrl+space 151 | " inoremap 152 | 153 | " Swap ^$ pair with HL because ^$ are used much more often than HL but HL is home-row friendly 154 | noremap H ^| noremap Р ^ 155 | noremap L $| noremap Д $ 156 | noremap ^ H 157 | noremap $ L 158 | 159 | map :noh 160 | " nmap | " Extend vim-visual-multi functionality 161 | " nmap | " Extend vim-visual-multi functionality 162 | 163 | nnoremap 164 | nnoremap 165 | nnoremap 166 | nnoremap 167 | 168 | " Record big relative jumps into jumplist 169 | nnoremap k (v:count > 5 ? "m'" . v:count : "") . 'k' 170 | nnoremap j (v:count > 5 ? "m'" . v:count : "") . 'j' 171 | 172 | if has('ide') 173 | else 174 | " haya14busa/vim-asterisk plugin 175 | map * (asterisk-*) 176 | map # (asterisk-#) 177 | map g* (asterisk-g*) 178 | map g# (asterisk-g#) 179 | map z* (asterisk-z*) 180 | map gz* (asterisk-gz*) 181 | map z# (asterisk-z#) 182 | map gz# (asterisk-gz#) 183 | endif 184 | 185 | " Clipboard 186 | " set clipboard=unnamedplus| " Use OS system clipboard 187 | noremap Y "+y$| " Make Y consistent with D and C 188 | noremap y "+y 189 | nnoremap yy "+yy 190 | noremap y y| " Make original y functionality accessible 191 | nnoremap yy yy| " Make original y functionality accessible 192 | noremap p "+p| noremap p p 193 | noremap P "+P| noremap P P 194 | noremap s "+d 195 | nnoremap ss "+dd 196 | noremap S "+D 197 | 198 | " Clipboard for Russian layout 199 | noremap Н "+y$| " Make Y consistent with D and C 200 | noremap н "+y 201 | nnoremap нн "+yy 202 | noremap н y| " Make original y functionality accessible 203 | nnoremap нн yy| " Make original y functionality accessible 204 | noremap з "+p| noremap p p 205 | noremap З "+P| noremap P P 206 | noremap ы "+d 207 | nnoremap ыы "+dd 208 | noremap Ы "+D 209 | " tnoremap 210 | 211 | " Rarely used keys: 212 | " Q (gQ can be used as a replacement) 213 | " R 214 | " s 215 | " S (remap only not in visual mode (because visual mode is taken by vim-surrond) 216 | " H 217 | " L 218 | " Tab (in normal mode) 219 | " also see: https://www.reddit.com/r/vim/comments/shtto/what_are_the_main_single_keys_that_you_remap_in/ 220 | 221 | let g:fzf_preview_window = ['down:50%', 'ctrl-/']| " Usually I have long paths in projects so I move preview to the down to give 222 | 223 | " Some magic to automatically create parent directories https://stackoverflow.com/a/4294176/4359679 224 | augroup BWCCreateDir 225 | autocmd! 226 | autocmd BufWritePre * if expand("")!~#'^\w\+:/' && !isdirectory(expand("%:h")) | execute "silent! !mkdir -p ".shellescape(expand('%:h'), 1) | redraw! | endif 227 | augroup END 228 | 229 | " Make it possible to send fzf results into quickfix list https://github.com/junegunn/fzf.vim/issues/185 230 | function! s:build_quickfix_list(lines) 231 | call setqflist(map(copy(a:lines), '{ "filename": v:val }')) 232 | copen 233 | cc 234 | endfunction 235 | let g:fzf_action = { 236 | \ 'ctrl-q': function('s:build_quickfix_list'), 237 | \ 'ctrl-t': 'tab split', 238 | \ 'ctrl-x': 'split', 239 | \ 'ctrl-v': 'vsplit' } 240 | 241 | " Automatically sync plugins on startup https://github.com/junegunn/vim-plug/wiki/extra#automatically-install-missing-plugins-on-startup 242 | autocmd VimEnter * 243 | \ if len(filter(values(g:plugs), '!isdirectory(v:val.dir)')) 244 | \| PlugInstall --sync | q 245 | \| endif 246 | 247 | -------------------------------------------------------------------------------- /.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /.shell.sh: -------------------------------------------------------------------------------- 1 | ############################# 2 | ### Environment variables ### 3 | ############################# 4 | 5 | export JAVA_HOME="/usr/lib/jvm/java-8-openjdk" 6 | export VISUAL="v" 7 | export EDITOR="v" 8 | # export PAGER="vimpager" 9 | export CP="CHERRY_PICK_HEAD" 10 | # respect gitignore by default (and I am not sure but probably fd is faster than find then this export also speed ups the fzf) 11 | export FZF_DEFAULT_COMMAND='fd --type f --hidden' 12 | export PATH="$HOME/.bin:$PATH" 13 | export ANDROID_HOME="$HOME/.android/sdk" 14 | # export FZF_DEFAULT_OPTS="\ 15 | # --height 60% --layout=reverse --multi \ 16 | # --bind 'ctrl-y:execute-silent(echo {} | xclip -selection clipboard)' \ 17 | # --bind 'ctrl-o:execute-silent(o {})'" 18 | export NNN_PLUG='p:preview-tui' 19 | export NNN_FIFO=/tmp/nnn.fifo # reuiqred for nnn-preview plugin 20 | #export LESS="-i" 21 | 22 | if isMacOs; then 23 | # https://gist.github.com/skyzyx/3438280b18e4f7c490db8a2a2ca0b9da 24 | BREW_BIN="/usr/local/bin/brew" 25 | if [ -f "/opt/homebrew/bin/brew" ]; then 26 | BREW_BIN="/opt/homebrew/bin/brew" 27 | fi 28 | 29 | if type "${BREW_BIN}" &> /dev/null; then 30 | export BREW_PREFIX="$("${BREW_BIN}" --prefix)" 31 | for bindir in "${BREW_PREFIX}/opt/"*"/libexec/gnubin"; do export PATH=$bindir:$PATH; done 32 | for bindir in "${BREW_PREFIX}/opt/"*"/bin"; do export PATH=$bindir:$PATH; done 33 | for mandir in "${BREW_PREFIX}/opt/"*"/libexec/gnuman"; do export MANPATH=$mandir:$MANPATH; done 34 | for mandir in "${BREW_PREFIX}/opt/"*"/share/man/man1"; do export MANPATH=$mandir:$MANPATH; done 35 | fi 36 | 37 | export PATH="$HOME/.bin-macos:$PATH" 38 | fi 39 | 40 | if [ -d $ANDROID_HOME ]; then 41 | export PATH="$PATH:$ANDROID_HOME/platform-tools" 42 | fi 43 | 44 | # If not running interactively, don't do anything 45 | [[ $- != *i* ]] && return 46 | 47 | simplified_mode() { 48 | test -z "$DISPLAY" && ! isMacOs 49 | } 50 | 51 | CURRENT_SHELL=$1 52 | if [ -z $CURRENT_SHELL ]; then 53 | echo_red "Current shell is unknown. Pass it parameter to ~/.shell.sh" 54 | fi 55 | is_zsh() { 56 | test $CURRENT_SHELL = "zsh" 57 | return $? 58 | } 59 | 60 | echo_red() { 61 | echo -e "\e[1;31m$@\e[0m" 62 | } 63 | 64 | xdotool_available() { 65 | if simplified_mode; then 66 | return 1 67 | fi 68 | return $(command -v xdotool > /dev/null) 69 | } 70 | 71 | join_to_string() { local IFS="$1"; shift; echo "$*"; } 72 | 73 | ######################## 74 | ### General settings ### 75 | ######################## 76 | 77 | if ! isMacOs && [[ "$(sysctl kernel.sysrq)" != *"= 1" ]]; then 78 | echo_red "sysrq kernel option is off. Enter the sudo password to turn it on" 79 | sudo sysctl kernel.sysrq=1 80 | fi 81 | 82 | if ! simplified_mode; then 83 | if ! xdotool_available; then 84 | echo_red "xdotool isn't available. GUI notifications won't work" 85 | fi 86 | 87 | if ! command -v notify-send > /dev/null; then 88 | echo_red "notify-send isn't installed. GUI notifications won't work" 89 | fi 90 | fi 91 | 92 | if is_zsh; then 93 | # Lines configured by ZSH setup wizard 94 | HISTFILE=~/.zsh_history 95 | HISTSIZE=5000 96 | SAVEHIST=1000 97 | 98 | # 0ms for key sequences (I did it for removing delay for ESC key) 99 | export KEYTIMEOUT=0 100 | 101 | source_package() { 102 | for it in $@; do 103 | if [ -f $it ]; then 104 | source $it 105 | else 106 | echo_red "Cannot find $it" 107 | fi 108 | done 109 | } 110 | 111 | if isMacOs; then 112 | source $(brew --prefix)/Cellar/antigen/*/share/antigen/antigen.zsh 113 | else 114 | source /usr/share/zsh/share/antigen.zsh 115 | fi 116 | 117 | # vim mode 118 | # bindkey -v 119 | antigen bundle jeffreytse/zsh-vi-mode 120 | antigen bundle zsh-users/zsh-autosuggestions 121 | 122 | antigen apply 123 | 124 | zvm_after_init() { 125 | if isMacOs; then 126 | source_package $(brew --prefix)/Cellar/fzf/*/shell/key-bindings.zsh 127 | source_package $(brew --prefix)/Cellar/fzf/*/shell/completion.zsh 128 | # source_package $(brew --prefix)/Cellar/fzf/*/shell/fzf-extras.zsh 129 | else 130 | source_package /usr/share/fzf/key-bindings.zsh 131 | source_package /usr/share/fzf/completion.zsh 132 | source_package /usr/share/fzf/fzf-extras.zsh 133 | fi 134 | zvm_bindkey viins '^H' backward-kill-word 135 | zvm_bindkey vicmd 'H' zle vi-first-non-blank 136 | zvm_bindkey vicmd 'L' zle vi-end-of-line 137 | 138 | # Disable because I used to press tab when I know that the first match 139 | # will be ok. fzf-tab prompts unnecessary fuzzy search in such case 140 | # source_package ~/.app/fzf-tab/fzf-tab.plugin.zsh 141 | } 142 | zvm_after_init 143 | 144 | zvm_vi_yank() { # Hack from https://github.com/jeffreytse/zsh-vi-mode/issues/19 145 | zvm_yank 146 | printf %s "${CUTBUFFER}" | cl 147 | zvm_exit_visual_mode 148 | } 149 | 150 | # source_package ~/.app/zsh-syntax-highlighting/zsh-syntax-highlighting.plugin.zsh # Disable because comments are not visible 151 | 152 | # Starts the completion system 153 | if type brew &>/dev/null; then 154 | FPATH="$(brew --prefix)/share/zsh-completions:$FPATH" 155 | FPATH="$(brew --prefix)/share/zsh/site-functions:$FPATH" 156 | fi 157 | autoload -Uz compinit 158 | compinit 159 | # Initialize colors 160 | autoload -U colors 161 | colors 162 | 163 | # Use run-help for help for builtin commands like `zle`, `setopt` 164 | unalias run-help 165 | autoload run-help 166 | 167 | # If globbing expression don't match anything then 168 | # ZSH will pass it "as it is". (e.g. asterisk expansion) 169 | setopt +o nomatch 170 | 171 | # Enable comments in interactive shell 172 | setopt INTERACTIVE_COMMENTS 173 | 174 | # File completion after '=' character in args 175 | setopt MAGIC_EQUAL_SUBST 176 | 177 | # setopt MENU_COMPLETE 178 | # Turn off additional zsh verification for rm smt/* 179 | setopt rm_star_silent 180 | 181 | # Share history between different instances of zsh 182 | # setopt share_history 183 | 184 | # Turn on case insensetive in completion 185 | zstyle ':completion:*' matcher-list 'm:{[:lower:]}={[:upper:]}' 186 | 187 | # Discard autosuggest with Escape 188 | # bindkey '\e' autosuggest-clear # why do I need it? 189 | fi 190 | 191 | ############### 192 | ### aliases ### 193 | ############### 194 | 195 | # bookmarks 196 | alias bk='cd ~/jb/kotlin' 197 | alias bi='cd ~/jb/intellij' 198 | alias bn='cd ~/a/notes' 199 | alias jb='cd ~/jb' 200 | alias a='cd ~/a' 201 | alias sb='subl' 202 | 203 | alias xdot='detach xdot' 204 | alias vlc='detach vlc' 205 | 206 | v-sh() { nvim "+source ~/.v/vim-sh.vim" "$@"; } 207 | alias mount='udisksctl mount -b' 208 | alias umount='udisksctl unmount -b' 209 | alias gw='./gradlew' 210 | alias gwDebug='./gradlew --stop && ./gradlew -Dkotlin.daemon.jvm.options="-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=y\\,address=5005" ' 211 | alias ls='ls -F --color=auto' 212 | alias diff='diff -us --color=auto' 213 | alias grep='grep --color=auto' 214 | alias fgrep='fgrep --color=auto' 215 | zd() { cd "$(interactive-cd)"; } 216 | alias egrep='egrep --color=auto' 217 | alias ll='ls -alFh' 218 | alias cp='cp -r' 219 | alias scp='scp -r' 220 | alias mkdir='mkdir -p' 221 | alias gs='echo fucking ghostscript' 222 | alias fd='fd --hidden' 223 | alias vanila-vim='vim -u NONE' 224 | vanila-tmux() { tmux -L "$RANDOM" -f /dev/null "$@"; } 225 | alias lf='ls | fzf' 226 | alias cal='cal -y' 227 | alias i='idea-bobko' 228 | alias help='run-help' # For shell built-ins 229 | tmp() { cd $(mktemp -d); } 230 | killvlc() { 231 | # It freezes so often that it deserves a separate alias 232 | ps -A | grep vlc | awk '{print$1}' | while read it; do kill -9 $it; done 233 | } 234 | alias n='nnn -p /tmp/nnn-select && ! test -s /tmp/nnn-select || v /tmp/nnn-select' 235 | alias ta='tmux attach || tmux new-session -s MMM' 236 | alias tmux-source='tmux source ~/.tmux.conf' 237 | alias rm='rm-trash' 238 | alias cg='cd "$(git rev-parse --show-toplevel)"' 239 | 240 | if is_zsh; then 241 | true # empty then cannot be parsed in bash 242 | # compdef git d 243 | # compadd d _path_files 244 | # compdef '_dispatch git git' d 245 | 246 | else 247 | # complete -o bashdefault -o default -o nospace -F __git_wrap__git_main dotfiles 248 | _completion_loader git 249 | fi 250 | 251 | if ! isMacOs && [[ "$(tty)" == "/dev/tty"* ]]; then 252 | alias x='startx' 253 | alias p='poweroff' 254 | alias r='reboot' 255 | fi 256 | 257 | ############## 258 | ### Prompt ### 259 | ############## 260 | 261 | if is_zsh; then 262 | # Enable $(cmd) in $PS1 etc. 263 | setopt prompt_subst 264 | fi 265 | 266 | displaytime() { 267 | local T=$1 268 | local D=$((T/60/60/24)) 269 | local H=$((T/60/60%24)) 270 | local M=$((T/60%60)) 271 | local S=$((T%60)) 272 | (( $D > 0 )) && printf '%d days ' $D 273 | (( $H > 0 )) && printf '%d hours ' $H 274 | (( $M > 0 )) && printf '%d minutes ' $M 275 | (( $D > 0 || $H > 0 || $M > 0 )) && printf 'and ' 276 | printf '%d seconds\n' $S 277 | } 278 | 279 | LAST_CMD_START_SECONDS=0 280 | LAST_EXECUTED_CMD="" 281 | CURRENT_SESSION_WINDOW_ID="" 282 | 283 | update_terminal_title() { 284 | echo -ne "\033]0;${PWD} 🚀 ${LAST_EXECUTED_CMD}\007" 285 | # In tmux window too (see allow-rename in `man tmux`) 286 | if ! [ -z "$TMUX" ]; then 287 | # echo -ne "\ek${PWD} 🚀 ${LAST_EXECUTED_CMD}\e\\" 288 | true 289 | fi 290 | } 291 | 292 | # Before executig command (ZSH only) 293 | preexec() { 294 | LAST_CMD_START_SECONDS="$SECONDS" 295 | LAST_EXECUTED_CMD="$1" 296 | update_terminal_title 297 | if [ -z "$CURRENT_SESSION_WINDOW_ID" ] && xdotool_available; then 298 | CURRENT_SESSION_WINDOW_ID=$(xdotool getwindowfocus) 299 | fi 300 | } 301 | 302 | prompt_green() { 303 | if is_zsh; then 304 | echo "%F{green}$@%f" 305 | else 306 | echo -e "\e[1;32m$@\e[0m" 307 | fi 308 | } 309 | 310 | prompt_red() { 311 | if is_zsh; then 312 | echo "%F{red}$@%f" 313 | else 314 | echo -e "\e[1;31m$@\e[0m" 315 | fi 316 | } 317 | 318 | prompt_blue() { 319 | if is_zsh; then 320 | echo "%F{blue}$@%f" 321 | else 322 | echo -e "\e[1;34m$@\e[0m" 323 | fi 324 | } 325 | 326 | # Before showing PROMPT 327 | precmd() { 328 | # Capture exit code of last command 329 | local ex=$? 330 | update_terminal_title 331 | 332 | local spent_time_in_seconds=$(expr $SECONDS - $LAST_CMD_START_SECONDS) 333 | local spent_time_if_too_long="" 334 | if is_zsh && [ $spent_time_in_seconds -gt 5 ] && ! [ -z $LAST_EXECUTED_CMD ]; then 335 | spent_time_if_too_long="\"${LAST_EXECUTED_CMD}\" took $(displaytime $spent_time_in_seconds)" 336 | fi 337 | if is_zsh && 338 | xdotool_available && 339 | ! [ -z "$LAST_EXECUTED_CMD" ] && 340 | [ "$(xdotool getwindowfocus)" -ne "$CURRENT_SESSION_WINDOW_ID" ] && 341 | command -v notify-send > /dev/null; then 342 | local notif_body="Finished successfully" 343 | if [ "$ex" -ne 0 ]; then 344 | local notif_body="Exited with exit code: $ex" 345 | fi 346 | # notify-send "$LAST_EXECUTED_CMD" "$notif_body" 347 | fi 348 | LAST_EXECUTED_CMD="" 349 | 350 | local prev_exit_command="" 351 | if [ "$ex" -ne 0 ]; then 352 | prev_exit_command=$(prompt_red "Exit Code: $ex ") 353 | fi 354 | 355 | if is_zsh; then 356 | local current_path="%~" 357 | local spent_time_prompt=$(prompt_green $spent_time_if_too_long) 358 | if [ "$ex" -ne 0 ]; then 359 | local spent_time_prompt=$(prompt_red $spent_time_if_too_long) 360 | fi 361 | RPROMPT=$(join_to_string " " $spent_time_prompt) 362 | else 363 | local current_path="\w" 364 | fi 365 | if [ ! -z "$VIRTUAL_ENV" ]; then 366 | local python_env="($(realpath --relative-to=$PWD $VIRTUAL_ENV)) " 367 | fi 368 | tmux_status=$([ -z "$TMUX" ] && prompt_red "NOT A TMUX SESSION " || prompt_blue "$(tmux display-message -p '#S') ") 369 | PS1="${PROMPT_LABEL}${python_env}${prev_exit_command}$(prompt_green "${current_path} \$") " 370 | } 371 | if ! is_zsh; then 372 | export PROMPT_COMMAND=precmd 373 | fi 374 | 375 | -------------------------------------------------------------------------------- /.config/i3/config: -------------------------------------------------------------------------------- 1 | ################# 2 | ### Variables ### 3 | ################# 4 | set $win Mod4 5 | set $alt Mod1 6 | set $middle_mouse_button button2 7 | set $left_mouse_button button1 8 | set $right_mouse_button button3 9 | set $scroll_up button4 10 | set $scroll_down button5 11 | set $scroll_right button6 12 | set $scroll_left button7 13 | # Use xev to check keys names 14 | set $backtick grave 15 | # set $refresh_i3status killall -SIGUSR1 i3status 16 | 17 | ##################### 18 | ### Configuration ### 19 | ##################### 20 | font pango:Roboto Regular 8 21 | floating_modifier $win 22 | focus_follows_mouse no 23 | 24 | # Get rid of title bars 25 | # default_border pixel 2 # TODO remove because it's redundant? 26 | # default_floating_border normal 2 # TODO remove because it's redundant? 27 | for_window [all] border pixel 2 28 | 29 | hide_edge_borders smart 30 | for_window [all] title_window_icon on 31 | # https://github.com/i3/i3/issues/5389 32 | # workspace_layout tabbed 33 | focus_wrapping workspace 34 | 35 | #################### 36 | ### Exec Hotkeys ### 37 | #################### 38 | bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +5% && $refresh_i3status 39 | bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -5% && $refresh_i3status 40 | bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status 41 | bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status 42 | # bindsym XF86AudioRaiseVolume exec amixer -q -D pulse sset Master 5%+ 43 | # bindsym XF86AudioLowerVolume exec amixer -q -D pulse sset Master 5%- 44 | # bindsym XF86AudioMute exec amixer -q -D pulse sset Master toggle 45 | 46 | bindsym XF86MonBrightnessDown exec --no-startup-id xbacklight -dec 15 47 | bindsym XF86MonBrightnessUp exec --no-startup-id xbacklight -inc 15 48 | 49 | bindsym $alt+space exec spotlight 50 | bindsym $alt+Shift+space exec "rofi -modi window -show window -dpi 1" 51 | bindsym $alt+Shift+Tab move workspace to output right; move workspace to output up; focus output right; focus output up 52 | # bindsym $win+Tab focus output right; focus output up 53 | bindsym $win+Print exec "flameshot screen -c" 54 | 55 | # macOS like screenshot hotkeys 56 | bindsym $alt+Shift+2 exec "gnome-screenshot --window --interactive" 57 | bindsym $alt+Shift+3 exec "gnome-screenshot --interactive" 58 | bindsym $alt+Shift+4 exec "gnome-screenshot --area --interactive" 59 | 60 | ########################### 61 | ### i3 specific hotkeys ### 62 | ########################### 63 | # it's not possible to use win because win+space (keybr layout toggle) shadows win+shfit+space 64 | # mode_toggle is floating vs tailing toggle 65 | # bindsym $win+Shift+slash focus mode_toggle 66 | bindsym $win+Shift+apostrophe focus child 67 | bindsym $win+apostrophe focus parent 68 | bindsym Control+$alt+q exec bobko-screenlocker 69 | bindsym Control+$win+f bar mode toggle 70 | 71 | # Avoid memozing latest split layout with explicit "toggle splith splitv" instead of "toggle split". 72 | # I prefer predictability to memoization 73 | bindsym $win+slash layout toggle splith splitv 74 | 75 | # bindsym $win+q kill 76 | # bindsym $win+period kill 77 | # Like in macOS 78 | bindsym $alt+q kill 79 | bindsym $alt+w kill 80 | # Create new container (do I use it?) 81 | # bindsym $win+Shift+slash split toggle 82 | bindsym $win+comma layout toggle tabbed stacking 83 | 84 | bindsym --whole-window $win+Shift+$left_mouse_button floating toggle; sticky disable 85 | bindsym --whole-window $win+Shift+$right_mouse_button floating enable; sticky toggle 86 | # bindsym --whole-window $win+$scroll_up resize grow height 5 px or 5 ppt 87 | # bindsym --whole-window $win+$scroll_down resize shrink height 5 px or 5 ppt 88 | # bindsym --whole-window $win+Shift+$scroll_up resize grow width 5 px or 5 ppt 89 | # bindsym --whole-window $win+Shift+$scroll_down resize shrink width 5 px or 5 ppt 90 | 91 | # Focus window 92 | bindsym $win+k focus tiling; focus up 93 | bindsym $win+h focus tiling; focus left 94 | bindsym $win+j focus tiling; focus down 95 | bindsym $win+l focus tiling; focus right 96 | 97 | bindsym $win+Left focus tiling; focus left 98 | bindsym $win+Down focus tiling; focus down 99 | bindsym $win+Up focus tiling; focus up 100 | bindsym $win+Right focus tiling; focus right 101 | 102 | # Move window 103 | bindsym $win+Shift+k focus tiling; move up 104 | bindsym $win+Shift+h focus tiling; move left 105 | bindsym $win+Shift+j focus tiling; move down 106 | bindsym $win+Shift+l focus tiling; move right 107 | 108 | bindsym $win+Shift+Left focus tiling; move left 109 | bindsym $win+Shift+Down focus tiling; move down 110 | bindsym $win+Shift+Up focus tiling; move up 111 | bindsym $win+Shift+Right focus tiling; move right 112 | 113 | # "Move in" window 114 | bindsym $win+Control+Shift+k focus tiling; focus up; split toggle; focus down; move up 115 | bindsym $win+Control+Shift+h focus tiling; focus left; split toggle; focus right; move left 116 | bindsym $win+Control+Shift+j focus tiling; focus down; split toggle; focus up; move down 117 | bindsym $win+Control+Shift+l focus tiling; focus right; split toggle; focus left; move right 118 | 119 | # "Move in" mode 120 | set $move_in_mode "'Move in' window" 121 | bindsym $win+Shift+slash mode $move_in_mode 122 | mode $move_in_mode { 123 | bindsym $win+Shift+k focus tiling; focus up; split toggle; focus down; move up; mode "default" 124 | bindsym $win+Shift+h focus tiling; focus left; split toggle; focus right; move left; mode "default" 125 | bindsym $win+Shift+j focus tiling; focus down; split toggle; focus up; move down; mode "default" 126 | bindsym $win+Shift+l focus tiling; focus right; split toggle; focus left; move right; mode "default" 127 | 128 | bindsym Escape mode "default" 129 | } 130 | 131 | # Swap windows 132 | bindsym $win+Control+k focus tiling; focus up; mark --add swapee; focus down; swap container with mark swapee; unmark swapee 133 | bindsym $win+Control+h focus tiling; focus left; mark --add swapee; focus right; swap container with mark swapee; unmark swapee 134 | bindsym $win+Control+j focus tiling; focus down; mark --add swapee; focus up; swap container with mark swapee; unmark swapee 135 | bindsym $win+Control+l focus tiling; focus right; mark --add swapee; focus left; swap container with mark swapee; unmark swapee 136 | 137 | # Resize window 138 | bindsym $win+Shift+minus resize shrink height 2 px or 2 ppt 139 | bindsym $win+Shift+equal resize grow height 2 px or 2 ppt 140 | bindsym $win+Shift+comma resize shrink width 2 px or 2 ppt 141 | bindsym $win+Shift+period resize grow width 2 px or 2 ppt 142 | 143 | set $0 "000" 144 | set $1 "111" 145 | set $2 "222" 146 | set $3 "333" 147 | set $4 "444" 148 | set $5 "555" 149 | set $6 "666" 150 | set $7 "777" 151 | set $8 "888" 152 | set $9 "999" 153 | set $a "AAA" 154 | set $b "BBB" 155 | set $c "CCC" 156 | set $d "DDD" 157 | set $e "EEE" 158 | set $f "FFF" 159 | set $g "GGG" 160 | set $i "III" 161 | set $m "MMM" 162 | set $n "NNN" 163 | set $o "OOO" 164 | set $p "PPP" 165 | set $q "QQQ" 166 | set $r "RRR" 167 | set $s "SSS" 168 | set $t "TTT" 169 | set $u "UUU" 170 | set $v "VVV" 171 | set $w "WWW" 172 | set $x "XXX" 173 | set $y "YYY" 174 | set $z "ZZZ" 175 | 176 | bindsym $alt+Tab workspace back_and_forth 177 | bindsym $win+Tab workspace back_and_forth 178 | bindsym $win+0 workspace $0 179 | bindsym $win+1 workspace $1 180 | bindsym $win+2 workspace $2 181 | bindsym $win+3 workspace $3 182 | bindsym $win+4 workspace $4 183 | bindsym $win+5 workspace $5 184 | bindsym $win+6 workspace $6 185 | bindsym $win+7 workspace $7 186 | bindsym $win+8 workspace $8 187 | bindsym $win+9 workspace $9 188 | bindsym $win+a workspace $a 189 | bindsym $win+b workspace $b 190 | bindsym $win+c workspace $c 191 | bindsym $win+d workspace $d 192 | bindsym $win+e workspace $e 193 | bindsym $win+f workspace $f 194 | bindsym $win+g workspace $g 195 | bindsym $win+i workspace $i 196 | bindsym $win+m workspace $m 197 | bindsym $win+n workspace $n 198 | bindsym $win+o workspace $o 199 | bindsym $win+p workspace $p 200 | bindsym $win+q workspace $q 201 | bindsym $win+r workspace $r 202 | bindsym $win+s workspace $s 203 | bindsym $win+t workspace $t 204 | bindsym $win+u workspace $u 205 | bindsym $win+v workspace $v 206 | bindsym $win+w workspace $w 207 | bindsym $win+x workspace $x 208 | bindsym $win+y workspace $y 209 | bindsym $win+z workspace $z 210 | 211 | bindsym $win+Shift+0 move container to workspace $0 212 | bindsym $win+Shift+1 move container to workspace $1 213 | bindsym $win+Shift+2 move container to workspace $2 214 | bindsym $win+Shift+3 move container to workspace $3 215 | bindsym $win+Shift+4 move container to workspace $4 216 | bindsym $win+Shift+5 move container to workspace $5 217 | bindsym $win+Shift+6 move container to workspace $6 218 | bindsym $win+Shift+7 move container to workspace $7 219 | bindsym $win+Shift+8 move container to workspace $8 220 | bindsym $win+Shift+9 move container to workspace $9 221 | bindsym $win+Shift+a move container to workspace $a 222 | bindsym $win+Shift+b move container to workspace $b 223 | bindsym $win+Shift+c move container to workspace $c 224 | bindsym $win+Shift+d move container to workspace $d 225 | bindsym $win+Shift+e move container to workspace $e 226 | bindsym $win+Shift+f move container to workspace $f 227 | bindsym $win+Shift+g move container to workspace $g 228 | bindsym $win+Shift+i move container to workspace $i 229 | bindsym $win+Shift+m move container to workspace $m 230 | bindsym $win+Shift+n move container to workspace $n 231 | bindsym $win+Shift+o move container to workspace $o 232 | bindsym $win+Shift+p move container to workspace $p 233 | bindsym $win+Shift+q move container to workspace $q 234 | bindsym $win+Shift+r move container to workspace $r 235 | bindsym $win+Shift+s move container to workspace $s 236 | bindsym $win+Shift+t move container to workspace $t 237 | bindsym $win+Shift+u move container to workspace $u 238 | bindsym $win+Shift+v move container to workspace $v 239 | bindsym $win+Shift+w move container to workspace $w 240 | bindsym $win+Shift+x move container to workspace $x 241 | bindsym $win+Shift+y move container to workspace $y 242 | bindsym $win+Shift+z move container to workspace $z 243 | 244 | # TODO Replace with command mode like vim/tmux with fzf and scripting help 245 | set $wm_mode "WINDOW MANAGER MODE rel[O]ad, [E]xit, [P]oweroff, re[B]oot, [F]loating, [S]ticky, [R]eset" 246 | bindsym $win+Shift+semicolon mode $wm_mode 247 | mode $wm_mode { 248 | bindsym o reload 249 | bindsym e exit 250 | bindsym p exec poweroff 251 | bindsym b exec reboot 252 | bindsym s floating enable; sticky toggle; mode "default" 253 | bindsym f sticky disable; floating toggle; mode "default" 254 | # https://www.reddit.com/r/i3wm/comments/8c6yfy/how_to_reset_a_workspace_move_all_nodes_to_root/ 255 | bindsym r [tiling workspace="__focused__"] move workspace "_reorder_"; [workspace="_reorder_"] move workspace current; mode "default" 256 | bindsym --release x exec xkill; mode "default" 257 | 258 | bindsym Escape mode "default" 259 | } 260 | 261 | bindsym $win+Return exec alacritty 262 | 263 | # set $run_mode "RUN MODE" 264 | # bindsym $win+semicolon mode "RUN MODE" 265 | # mode "RUN MODE" { 266 | # bindsym $win+semicolon exec alacritty; mode "default" 267 | # bindsym semicolon exec alacritty; mode "default" 268 | # bindsym c exec google-chrome-stable; mode "default" 269 | # bindsym --release x exec xkill; mode "default" 270 | # # TODO drop because now I use `p` in CLI? 271 | # # bindsym p exec rofi-pass; mode "default" 272 | # bindsym Escape mode "default" 273 | # } 274 | 275 | # # Jump into VNC session back and worth with one hotkey. Make sure to disable "Pass system keys directly to server" in VNC 276 | # bindsym $win+Shift+Return move container to workspace "REMOTE" 277 | # bindsym $win+Return mode "REMOTE"; workspace "REMOTE" 278 | # mode "REMOTE" { 279 | # bindsym $win+Return mode "default"; workspace back_and_forth 280 | # } 281 | 282 | # class border backgr. text indicator child_border 283 | client.focused #4c7899 #285577 #ffffff #2e9ef4 #32CD32 284 | 285 | bar { 286 | status_command i3blocks 287 | position top 288 | tray_output primary 289 | modifier none 290 | 291 | # Disable switching workspaces with scrolling 292 | bindsym $scroll_up nop 293 | bindsym $scroll_down nop 294 | bindsym $scroll_left nop 295 | bindsym $scroll_right nop 296 | } 297 | -------------------------------------------------------------------------------- /.tmux.conf: -------------------------------------------------------------------------------- 1 | ############################# 2 | ### PLUGINS CONFIGURATION ### 3 | ############################# 4 | # Don't exit copy mode after copy 5 | set -g @yank_action 'copy-pipe' # or 'copy-pipe-and-cancel' for the default 6 | 7 | ############### 8 | ### PLUGINS ### 9 | ############### 10 | set -g @plugin 'tmux-plugins/tpm' 11 | set -g @plugin 'tmux-plugins/tmux-yank' 12 | 13 | # Init TMUX plugin manager (https://github.com/tmux-plugins/tpm) 14 | run '~/.tmux/plugins/tpm/tpm' 15 | 16 | ##################### 17 | ### CONFIGURATION ### 18 | ##################### 19 | set -g mouse on # Enable mouse support 20 | set -g history-limit 50000 # increase scrollback buffer size 21 | setw -g mode-keys vi # vim keys in "copy mode" 22 | set -g base-index 1 # Set the base index for windows to 1 instead of 0 (because this is the way numbers are placed on qwerty) 23 | setw -g pane-base-index 1 # Set the base index for panes to 1 instead of 0 (because this is the way numbers are placed on qwerty) 24 | set -g default-terminal "xterm-256color" # Colorized bash prompt 25 | set -sg escape-time 0 # No delay for escape key press 26 | set -g status-position top # I don't really have reasons for it. Just why not 27 | set -g detach-on-destroy off # Attach to another session on shell exit 28 | set -g renumber-windows on # Automatically reorder windows 29 | setw -g aggressive-resize on # Resize window to the smallest client in case when both clients observer the same window 30 | 31 | # Show status bar only if there are several windows 32 | # if -F '#{==:#{session_windows},1}' { set -g status off } { set -g status on } 33 | # set-hook -g window-linked "if -F '#{==:#{session_windows},1}' { set -g status off } { set -g status on }" 34 | # set-hook -g window-unlinked "if -F '#{==:#{session_windows},1}' { set -g status off } { set -g status on }" 35 | # set-hook -g client-session-changed "if -F '#{==:#{session_windows},1}' { set -g status off } { set -g status on }" 36 | 37 | # window tabs in status bar 38 | set -g window-status-current-style "bg=default,reverse" 39 | set -g window-status-separator '│' 40 | set -g allow-rename on # Allow shell escape sequence to control tmux window title 41 | 42 | # enable activity alerts (changes window items in status bar when any activity happens on that window) 43 | # TODO Fix monitor activity across sessions 44 | # setw -g monitor-activity on 45 | # set -g visual-activity on 46 | 47 | # Send sigint to all panels TODO do I need it? 48 | # bind X run-shell "tmux list-panes -s -F '##{pane_pid} ##{pane_current_command}' | grep -v tmux | awk '{print $1}' | xargs kill -INT" 49 | 50 | ################ 51 | ### BINDINGS ### 52 | ################ 53 | unbind -a # Unbind all awful default keys 54 | 55 | bind -n M-h if -F '#{pane_at_left}' 'previous-window' 'select-pane -L' 56 | bind -n M-l if -F '#{pane_at_right}' 'next-window' 'select-pane -R' 57 | bind -n M-k if -F '#{pane_at_top}' '' 'select-pane -U' # Disable wrapping 58 | bind -n M-j if -F '#{pane_at_bottom}' '' 'select-pane -D' # Disable wrapping 59 | 60 | # bind / split-window -h -c "#{pane_current_path}" 61 | # bind - split-window -v -c "#{pane_current_path}" 62 | 63 | # Cycle between even-horizontal/even-vertical 64 | bind -r / if "[ $(echo '#{window_layout}' | sed s/[^\[\{]//g) = '[' ]" \ 65 | { select-layout even-horizontal } { select-layout even-vertical } 66 | # Cycle between main-vertical/main-horizontal 67 | # bind -n , if "[ $(echo '#{window_layout}' | sed s/[^\[\{]//g) = '[{' ]" \ 68 | # { 69 | # select-layout main-vertical 70 | # # Hack to make main-vertical spread evenly horizontally 71 | # select-layout -E main-vertical 72 | # } \ 73 | # { select-layout main-horizontal } 74 | # Split window and normalize layout 75 | bind -n M-. run " 76 | tmux split-window -c '#{pane_current_path}' -v 77 | # you can use 'tmux display-message -p' instead of 'echo' 78 | layout=$(echo '#{window_layout}' | sed s/[^\[\{]//g) 79 | { [ \$layout = '{' ] && tmux select-layout even-horizontal; } || 80 | { [ \$layout = '[{' ] && tmux select-layout main-horizontal; } || 81 | # Hack to make main-vertical spread evenly horizontally 82 | { [ \$layout = '{[' ] && tmux select-layout main-vertical && tmux select-layout -E main-vertical; } || 83 | tmux select-layout even-vertical" 84 | 85 | # TODO drop? 86 | # bind , display-menu \ 87 | # even-Horizontal 'h' 'select-layout even-horizontal' \ 88 | # even-Vertical 'v' 'select-layout even-vertical' \ 89 | # main-hOrizontal 'o' 'select-layout main-horizontal' \ 90 | # main-vErtical 'e' 'select-layout main-vertical' \ 91 | # Tiled 't' 'select-layout tiled' 92 | 93 | bind Enter new-window -c "#{pane_current_path}" -a 94 | 95 | bind -n M-H if -F '#{pane_at_left}' \ 96 | { 97 | if '[ #{pane_at_right} = 1 ] && [ #{pane_at_top} = 1 ] && [ #{pane_at_bottom} = 1 ]' \ 98 | { join-pane -t :-1 } \ 99 | { break-pane -b } 100 | } \ 101 | { select-pane -L; swap-pane -t ! } # ! is a previously active pane 102 | bind -n M-L if -F '#{pane_at_right}' \ 103 | { 104 | if '[ #{pane_at_left} = 1 ] && [ #{pane_at_top} = 1 ] && [ #{pane_at_bottom} = 1 ]' \ 105 | { join-pane -t :+1 } \ 106 | { break-pane -a } 107 | } \ 108 | { select-pane -R; swap-pane -t ! } # ! is a previously active pane 109 | bind -n M-K if -F '#{pane_at_top}' '' { select-pane -U; swap-pane -t ! } 110 | bind -n M-J if -F '#{pane_at_bottom}' '' { select-pane -D; swap-pane -t ! } 111 | 112 | # Pane resizing (repetitive) panes with Prefix h,j,k,l 113 | bind -r h resize-pane -L 1 114 | bind -r j resize-pane -D 1 115 | bind -r k resize-pane -U 1 116 | bind -r l resize-pane -R 1 117 | 118 | bind v copy-mode 119 | bind -T copy-mode-vi v send -X begin-selection 120 | bind -T copy-mode-vi i send -X cancel 121 | bind -T copy-mode-vi 'C-q' send -X begin-selection\; send -X rectangle-toggle 122 | bind -T copy-mode-vi p paste-buffer -p\; send -X cancel 123 | # TODO fix Y 124 | bind -r Tab switch -l 125 | 126 | # Swap HL pair with ^$ pair (the same is done in my vim config) 127 | bind -T copy-mode-vi H send -X back-to-indentation 128 | bind -T copy-mode-vi L send -X end-of-line 129 | bind -T copy-mode-vi ^ send -X top-line 130 | bind -T copy-mode-vi \$ send -X bottom-line 131 | 132 | bind -r < { swap-window -t -1; previous-window } 133 | bind -r > { swap-window -t +1; next-window } 134 | 135 | # Disable auto copy on mouse release https://github.com/tmux/tmux/issues/140 136 | unbind -T copy-mode-vi MouseDragEnd1Pane 137 | # since MouseDragEnd1Pane neither exit copy-mode nor clear selection now, 138 | # let single click do selection clearing for us. https://github.com/tmux/tmux/issues/140 139 | bind -T copy-mode-vi MouseDown1Pane select-pane\; send-keys -X clear-selection 140 | # Just visually select word/line and DON'T copy (by default tmux also copies which is not what I want) 141 | # With help of https://www.seanh.cc/2020/12/27/copy-and-paste-in-tmux/ also related https://github.com/tmux/tmux/issues/140 142 | bind -T copy-mode-vi DoubleClick1Pane select-pane\; send -X select-word 143 | bind -n DoubleClick1Pane select-pane\; copy-mode -M\; send -X select-word 144 | bind -n TripleClick1Pane select-pane\; copy-mode -M\; send -X select-line 145 | bind -T copy-mode-vi TripleClick1Pane select-pane\; send -X select-line 146 | 147 | # Incremental search 148 | bind -T copy-mode-vi / command-prompt -i -p "(search down)" "send -X search-forward-incremental \"%%%\"" 149 | bind -T copy-mode-vi ? command-prompt -i -p "(search up)" "send -X search-backward-incremental \"%%%\"" 150 | 151 | # Switch or create new session 152 | bind -n M-q if 'tmux switch -t QQQ' '' 'new-session -s QQQ' 153 | bind -n M-w if 'tmux switch -t WWW' '' 'new-session -s WWW' 154 | bind -n M-e if 'tmux switch -t EEE' '' 'new-session -s EEE' 155 | bind -n M-r if 'tmux switch -t RRR' '' 'new-session -s RRR' 156 | bind -n M-t if 'tmux switch -t TTT' '' 'new-session -s TTT' 157 | bind -n M-y if 'tmux switch -t YYY' '' 'new-session -s YYY' 158 | bind -n M-u if 'tmux switch -t UUU' '' 'new-session -s UUU' 159 | bind -n M-i if 'tmux switch -t III' '' 'new-session -s III' 160 | bind -n M-o if 'tmux switch -t OOO' '' 'new-session -s OOO' 161 | bind -n M-p if 'tmux switch -t PPP' '' 'new-session -s PPP' 162 | bind -n M-a if 'tmux switch -t AAA' '' 'new-session -s AAA' 163 | bind -n M-s if 'tmux switch -t SSS' '' 'new-session -s SSS' 164 | bind -n M-d if 'tmux switch -t DDD' '' 'new-session -s DDD' 165 | bind -n M-f if 'tmux switch -t FFF' '' 'new-session -s FFF' 166 | bind -n M-g if 'tmux switch -t GGG' '' 'new-session -s GGG' 167 | bind -n M-z if 'tmux switch -t ZZZ' '' 'new-session -s ZZZ' 168 | bind -n M-x if 'tmux switch -t XXX' '' 'new-session -s XXX' 169 | bind -n M-c if 'tmux switch -t CCC' '' 'new-session -s CCC' 170 | bind -n M-v if 'tmux switch -t VVV' '' 'new-session -s VVV' 171 | bind -n M-b if 'tmux switch -t BBB' '' 'new-session -s BBB' 172 | bind -n M-n if 'tmux switch -t NNN' '' 'new-session -s NNN' 173 | bind -n M-m if 'tmux switch -t MMM' '' 'new-session -s MMM' 174 | bind -n M-1 if 'tmux switch -t 111' '' 'new-session -s 111' 175 | bind -n M-2 if 'tmux switch -t 222' '' 'new-session -s 222' 176 | bind -n M-3 if 'tmux switch -t 333' '' 'new-session -s 333' 177 | bind -n M-4 if 'tmux switch -t 444' '' 'new-session -s 444' 178 | bind -n M-5 if 'tmux switch -t 555' '' 'new-session -s 555' 179 | bind -n M-6 if 'tmux switch -t 666' '' 'new-session -s 666' 180 | bind -n M-7 if 'tmux switch -t 777' '' 'new-session -s 777' 181 | bind -n M-8 if 'tmux switch -t 888' '' 'new-session -s 888' 182 | bind -n M-9 if 'tmux switch -t 999' '' 'new-session -s 999' 183 | bind -n M-0 if 'tmux switch -t 000' '' 'new-session -s 000' 184 | 185 | # Switch or create new session 186 | bind -n M-'Q' if 'tmux break-pane -t QQQ:' '' { new-session -d -s QQQ exit; break-pane -t QQQ: } 187 | bind -n M-'W' if 'tmux break-pane -t WWW:' '' { new-session -d -s WWW exit; break-pane -t WWW: } 188 | bind -n M-'E' if 'tmux break-pane -t EEE:' '' { new-session -d -s EEE exit; break-pane -t EEE: } 189 | bind -n M-'R' if 'tmux break-pane -t RRR:' '' { new-session -d -s RRR exit; break-pane -t RRR: } 190 | bind -n M-'T' if 'tmux break-pane -t TTT:' '' { new-session -d -s TTT exit; break-pane -t TTT: } 191 | bind -n M-'Y' if 'tmux break-pane -t YYY:' '' { new-session -d -s YYY exit; break-pane -t YYY: } 192 | bind -n M-'U' if 'tmux break-pane -t UUU:' '' { new-session -d -s UUU exit; break-pane -t UUU: } 193 | bind -n M-'I' if 'tmux break-pane -t III:' '' { new-session -d -s III exit; break-pane -t III: } 194 | bind -n M-'O' if 'tmux break-pane -t OOO:' '' { new-session -d -s OOO exit; break-pane -t OOO: } 195 | bind -n M-'P' if 'tmux break-pane -t PPP:' '' { new-session -d -s PPP exit; break-pane -t PPP: } 196 | bind -n M-'A' if 'tmux break-pane -t AAA:' '' { new-session -d -s AAA exit; break-pane -t AAA: } 197 | bind -n M-'S' if 'tmux break-pane -t SSS:' '' { new-session -d -s SSS exit; break-pane -t SSS: } 198 | bind -n M-'D' if 'tmux break-pane -t DDD:' '' { new-session -d -s DDD exit; break-pane -t DDD: } 199 | bind -n M-'F' if 'tmux break-pane -t FFF:' '' { new-session -d -s FFF exit; break-pane -t FFF: } 200 | bind -n M-'G' if 'tmux break-pane -t GGG:' '' { new-session -d -s GGG exit; break-pane -t GGG: } 201 | bind -n M-'Z' if 'tmux break-pane -t ZZZ:' '' { new-session -d -s ZZZ exit; break-pane -t ZZZ: } 202 | bind -n M-'X' if 'tmux break-pane -t XXX:' '' { new-session -d -s XXX exit; break-pane -t XXX: } 203 | bind -n M-'C' if 'tmux break-pane -t CCC:' '' { new-session -d -s CCC exit; break-pane -t CCC: } 204 | bind -n M-'V' if 'tmux break-pane -t VVV:' '' { new-session -d -s VVV exit; break-pane -t VVV: } 205 | bind -n M-'B' if 'tmux break-pane -t BBB:' '' { new-session -d -s BBB exit; break-pane -t BBB: } 206 | bind -n M-'N' if 'tmux break-pane -t NNN:' '' { new-session -d -s NNN exit; break-pane -t NNN: } 207 | bind -n M-'M' if 'tmux break-pane -t MMM:' '' { new-session -d -s MMM exit; break-pane -t MMM: } 208 | bind -n M-'!' if 'tmux break-pane -t 111:' '' { new-session -d -s 111 exit; break-pane -t 111: } 209 | bind -n M-'@' if 'tmux break-pane -t 222:' '' { new-session -d -s 222 exit; break-pane -t 222: } 210 | bind -n M-'#' if 'tmux break-pane -t 333:' '' { new-session -d -s 333 exit; break-pane -t 333: } 211 | bind -n M-'$' if 'tmux break-pane -t 444:' '' { new-session -d -s 444 exit; break-pane -t 444: } 212 | bind -n M-'%' if 'tmux break-pane -t 555:' '' { new-session -d -s 555 exit; break-pane -t 555: } 213 | bind -n M-'^' if 'tmux break-pane -t 666:' '' { new-session -d -s 666 exit; break-pane -t 666: } 214 | bind -n M-'&' if 'tmux break-pane -t 777:' '' { new-session -d -s 777 exit; break-pane -t 777: } 215 | bind -n M-'*' if 'tmux break-pane -t 888:' '' { new-session -d -s 888 exit; break-pane -t 888: } 216 | bind -n M-'(' if 'tmux break-pane -t 999:' '' { new-session -d -s 999 exit; break-pane -t 999: } 217 | bind -n M-')' if 'tmux break-pane -t 000:' '' { new-session -d -s 000 exit; break-pane -t 000: } 218 | 219 | bind Space choose-tree -Z 220 | bind : command-prompt 221 | -------------------------------------------------------------------------------- /.config/nnn/plugins/preview-tui: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Description: Terminal based file previewer 4 | # 5 | # Note: This plugin needs a "NNN_FIFO" to work. See man. 6 | # 7 | # Dependencies: 8 | # - Supports 4 independent methods to preview with: 9 | # - tmux (>=3.0), or 10 | # - kitty with allow_remote_control and listen_on set in kitty.conf, or 11 | # - QuickLook on WSL (https://github.com/QL-Win/QuickLook) 12 | # - $TERMINAL set to a terminal (it's xterm by default). 13 | # - less or $PAGER 14 | # - tree or exa or ls 15 | # - mediainfo or file 16 | # - mktemp 17 | # - unzip 18 | # - tar 19 | # - man 20 | # - optional: bsdtar or atool for additional archive preview 21 | # - optional: bat for code syntax highlighting 22 | # - optional: ueberzug, kitty terminal, viu or catimg for images 23 | # - optional: convert(ImageMagick) for playing gif preview 24 | # - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer) 25 | # - optional: ffmpeg for audio thumbnails 26 | # - optional: libreoffce for opendocument/officedocument preview 27 | # - optional: pdftoppm(poppler) for pdf thumbnails 28 | # - optional: gnome-epub-thumbnailer for epub thumbnails (https://gitlab.gnome.org/GNOME/gnome-epub-thumbnailer) 29 | # - optional: fontpreview for font preview (https://github.com/sdushantha/fontpreview) 30 | # - optional: glow or lowdown for markdown 31 | # - optional: w3m or lynx or elinks for html 32 | # - optional: set/export ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup 33 | # Icons and colors are configureable in .iconlookup 34 | # - optional: scope.sh file viewer from ranger. 35 | # 1. drop scope.sh executable in $PATH 36 | # 2. set/export $USE_SCOPE as 1 37 | # - optional: pistol file viewer (https://github.com/doronbehar/pistol). 38 | # 1. install pistol 39 | # 2. set/export $USE_PISTOL as 1 40 | # 41 | # Usage: 42 | # You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG, 43 | # then start `nnn`: 44 | # 45 | # $ nnn -a 46 | # 47 | # or 48 | # 49 | # $ NNN_FIFO=/tmp/nnn.fifo nnn 50 | # 51 | # Then launch the `preview-tui` plugin in `nnn`. 52 | # 53 | # If you provide the same NNN_FIFO to all nnn instances, there will be a 54 | # single common preview window. If you provide different FIFO path (e.g. 55 | # with -a), they will be independent. 56 | # 57 | # The previews will be shown in a tmux split. If that isn't possible, it 58 | # will try to use a kitty terminal split. And as a final fallback, a 59 | # different terminal window will be used ($TERMINAL). 60 | # 61 | # Tmux and kitty users can configure $SPLIT to either "h" or "v" to set a 62 | # 'h'orizontal split or a 'v'ertical split (as in, the line that splits the 63 | # windows will be horizontal or vertical). 64 | # 65 | # Kitty users need `allow_remote_control` set to `yes`, and `listen_on` set 66 | # to e.g. "unix:$TMPDIR/kitty". To customize the window split, `enabled_layouts` 67 | # has to be set to `all` or `splits` (the former is the default value). 68 | # This terminal is also able to show images without extra dependencies. 69 | # 70 | # Iterm2 users are recommended to use viu to view images without getting pixelated. 71 | # 72 | # Shell: POSIX compliant 73 | # Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal 74 | 75 | #SPLIT="$SPLIT" # you can set a permanent split here 76 | #TERMINAL="$TERMINAL" # same goes for the terminal 77 | USE_SCOPE="${USE_SCOPE:-0}" 78 | USE_PISTOL="${USE_PISTOL:-0}" 79 | ICONLOOKUP="${ICONLOOKUP:-0}" 80 | PAGER="${PAGER:-less -P?n -R}" 81 | TMPDIR="${TMPDIR:-/tmp}" 82 | BAT_STYLE="${BAT_STYLE:-numbers}" 83 | BAT_THEME="${BAT_THEME:-ansi}" 84 | # Consider setting NNN_PREVIEWDIR to $XDG_CACHE_HOME/nnn/previews if you want to keep previews on disk between reboots 85 | NNN_PREVIEWDIR="${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}" 86 | NNN_PREVIEWWIDTH="${NNN_PREVIEWWIDTH:-1920}" 87 | NNN_PREVIEWHEIGHT="${NNN_PREVIEWHEIGHT:-1080}" 88 | NNN_PARENT="${NNN_FIFO#*.}" 89 | [ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT="" 90 | FIFOPID="$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT" 91 | PREVIEWPID="$TMPDIR/nnn-preview-tui-pagerpid.$NNN_PARENT" 92 | CURSEL="$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT" 93 | FIFO_UEBERZUG="$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT" 94 | 95 | start_preview() { 96 | [ "$PAGER" = "most" ] && PAGER="less -R" 97 | 98 | if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then 99 | TERMINAL=tmux 100 | elif [ -n "$KITTY_LISTEN_ON" ]; then 101 | TERMINAL=kitty 102 | elif [ -z "$TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then 103 | TERMINAL=iterm 104 | else 105 | TERMINAL="${TERMINAL:-xterm}" 106 | fi 107 | 108 | if [ -z "$SPLIT" ] && [ $(($(tput lines <"$TTY") * 2)) -gt "$(tput cols <"$TTY")" ]; then 109 | SPLIT='h' 110 | elif [ "$SPLIT" != 'h' ]; then 111 | SPLIT='v' 112 | fi 113 | 114 | case "$TERMINAL" in 115 | tmux) # tmux splits are inverted 116 | if [ "$SPLIT" = "v" ]; then DSPLIT="h"; else DSPLIT="v"; fi 117 | tmux split-window -e "NNN_FIFO=$NNN_FIFO" -e "PREVIEW_MODE=1" -e TTY="$TTY" \ 118 | -e "CURSEL=$CURSEL" -e "TMPDIR=$TMPDIR" -e "FIFOPID=$FIFOPID" \ 119 | -e "BAT_STYLE=$BAT_STYLE" -e "BAT_THEME=$BAT_THEME" -e "PREVIEWPID=$PREVIEWPID" \ 120 | -e "PAGER=$PAGER" -e "ICONLOOKUP=$ICONLOOKUP" -e "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" \ 121 | -e "USE_SCOPE=$USE_SCOPE" -e "SPLIT=$SPLIT" -e "USE_PISTOL=$USE_PISTOL" \ 122 | -e "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" -e "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \ 123 | -e "FIFO_UEBERZUG=$FIFO_UEBERZUG" -e "QLPATH=$2" -d"$DSPLIT" "$0" "$1" ;; 124 | kitty) # Setting the layout for the new window. It will be restored after the script ends. 125 | kitty @ goto-layout splits 126 | # Trying to use kitty's integrated window management as the split window. All 127 | # environmental variables that will be used in the new window must be explicitly passed. 128 | kitty @ launch --no-response --title "nnn preview" --keep-focus \ 129 | --cwd "$PWD" --env "PATH=$PATH" --env "NNN_FIFO=$NNN_FIFO" \ 130 | --env "PREVIEW_MODE=1" --env "PAGER=$PAGER" --env "TMPDIR=$TMPDIR" \ 131 | --env "USE_SCOPE=$USE_SCOPE" --env "SPLIT=$SPLIT" --env "TERMINAL=$TERMINAL"\ 132 | --env "PREVIEWPID=$PREVIEWPID" --env "FIFO_UEBERZUG=$FIFO_UEBERZUG" \ 133 | --env "ICONLOOKUP=$ICONLOOKUP" --env "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \ 134 | --env "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" --env "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" \ 135 | --env "USE_PISTOL=$USE_PISTOL" --env "BAT_STYLE=$BAT_STYLE" \ 136 | --env "BAT_THEME=$BAT_THEME" --env "FIFOPID=$FIFOPID" --env TTY="$TTY" \ 137 | --env "CURSEL=$CURSEL" --location "${SPLIT}split" "$0" "$1" ;; 138 | iterm) 139 | command="$SHELL -c 'cd $PWD; \ 140 | PATH=\\\"$PATH\\\" NNN_FIFO=\\\"$NNN_FIFO\\\" PREVIEW_MODE=1 PAGER=\\\"$PAGER\\\" \ 141 | USE_SCOPE=\\\"$USE_SCOPE\\\" SPLIT=\\\"$SPLIT\\\" TERMINAL=\\\"$TERMINAL\\\" \ 142 | PREVIEWPID=\\\"$PREVIEWPID\\\" CURSEL=\\\"$CURSEL\\\" TMPDIR=\\\"$TMPDIR\\\" \ 143 | ICONLOOKUP=\\\"$ICONLOOKUP\\\" NNN_PREVIEWHEIGHT=\\\"$NNN_PREVIEWHEIGHT\\\" \ 144 | NNN_PREVIEWWIDTH=\\\"$NNN_PREVIEWWIDTH\\\" NNN_PREVIEWDIR=\\\"$NNN_PREVIEWDIR\\\" \ 145 | USE_PISTOL=\\\"$USE_PISTOL\\\" BAT_STYLE=\\\"$BAT_STYLE\\\" TTY=\\\"$TTY\\\" \ 146 | BAT_THEME=\\\"$BAT_THEME\\\" FIFOPID=\\\"$FIFOPID\\\" \\\"$0\\\" \\\"$1\\\"'" 147 | if [ "$SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi 148 | osascript <<-EOF 149 | tell application "iTerm" 150 | tell current session of current window 151 | split $split with default profile command "$command" 152 | end tell 153 | end tell 154 | EOF 155 | ;; 156 | *) if [ -n "$2" ]; then 157 | QUICKLOOK=1 QLPATH="$2" PREVIEW_MODE=1 "$0" "$1" & 158 | else 159 | PREVIEWPID="$PREVIEWPID" CURSEL="$CURSEL" PREVIEW_MODE=1 TTY="$TTY" \ 160 | FIFOPID="$FIFOPID" FIFO_UEBERZUG="$FIFO_UEBERZUG" $TERMINAL -e "$0" "$1" & 161 | fi ;; 162 | esac 163 | } >/dev/null 2>&1 164 | 165 | toggle_preview() { 166 | if exists QuickLook.exe; then 167 | QLPATH="QuickLook.exe" 168 | elif exists Bridge.exe; then 169 | QLPATH="Bridge.exe" 170 | fi 171 | if kill "$(cat "$FIFOPID")"; then 172 | [ -p "$NNN_PPIPE" ] && printf "0" > "$NNN_PPIPE" 173 | kill "$(cat "$PREVIEWPID")" 174 | pkill -f "tail --follow $FIFO_UEBERZUG" 175 | if [ -n "$QLPATH" ] && stat "$1"; then 176 | f="$(wslpath -w "$1")" && "$QLPATH" "$f" & 177 | fi 178 | else 179 | [ -p "$NNN_PPIPE" ] && printf "1" > "$NNN_PPIPE" 180 | start_preview "$1" "$QLPATH" 181 | fi 182 | } >/dev/null 2>&1 183 | 184 | exists() { 185 | type "$1" >/dev/null 186 | } 187 | 188 | fifo_pager() { 189 | cmd="$1" 190 | shift 191 | 192 | # We use a FIFO to access $PAGER PID in jobs control 193 | tmpfifopath="$TMPDIR/nnn-preview-tui-fifo.$$" 194 | mkfifo "$tmpfifopath" || return 195 | 196 | $PAGER < "$tmpfifopath" & 197 | printf "%s" "$!" > "$PREVIEWPID" 198 | 199 | ( 200 | exec > "$tmpfifopath" 201 | if [ "$cmd" = "pager" ]; then 202 | if exists bat; then 203 | bat --terminal-width="$(tput cols <"$TTY")" --decorations=always --color=always \ 204 | --paging=never --style="$BAT_STYLE" --theme="$BAT_THEME" "$@" & 205 | else 206 | $PAGER "$@" & 207 | fi 208 | else 209 | "$cmd" "$@" & 210 | fi 211 | ) 212 | 213 | rm "$tmpfifopath" 214 | } 2>/dev/null 215 | 216 | # Binary file: show file info inside the pager 217 | print_bin_info() { 218 | printf -- "-------- \033[1;31mBinary file\033[0m --------\n" 219 | if exists mediainfo; then 220 | mediainfo "$1" 221 | else 222 | file -b "$1" 223 | fi 224 | } 2>/dev/null 225 | 226 | handle_mime() { 227 | case "$2" in 228 | image/jpeg) image_preview "$cols" "$lines" "$1" ;; 229 | image/gif) generate_preview "$cols" "$lines" "$1" "gif" ;; 230 | image/*) generate_preview "$cols" "$lines" "$1" "image" ;; 231 | video/*) generate_preview "$cols" "$lines" "$1" "video" ;; 232 | audio/*) generate_preview "$cols" "$lines" "$1" "audio" ;; 233 | application/font*|application/*opentype|font/*) generate_preview "$cols" "$lines" "$1" "font" ;; 234 | */*office*|*/*document*) generate_preview "$cols" "$lines" "$1" "office" ;; 235 | application/zip) fifo_pager unzip -l "$1" ;; 236 | text/troff) 237 | if exists man; then 238 | fifo_pager man -Pcat -l "$1" 239 | else 240 | fifo_pager pager "$1" 241 | fi ;; 242 | *) handle_ext "$1" "$3" "$4" ;; 243 | esac 244 | } 245 | 246 | handle_ext() { 247 | case "$2" in 248 | epub) generate_preview "$cols" "$lines" "$1" "epub" ;; 249 | pdf) generate_preview "$cols" "$lines" "$1" "pdf" ;; 250 | gz|bz2) fifo_pager tar -tvf "$1" ;; 251 | md) if exists glow; then 252 | fifo_pager glow -s dark "$1" 253 | elif exists lowdown; then 254 | fifo_pager lowdown -Tterm "$1" 255 | else 256 | fifo_pager pager "$1" 257 | fi ;; 258 | htm|html|xhtml) 259 | if exists w3m; then 260 | fifo_pager w3m "$1" 261 | elif exists lynx; then 262 | fifo_pager lynx "$1" 263 | elif exists elinks; then 264 | fifo_pager elinks "$1" 265 | else 266 | fifo_pager pager "$1" 267 | fi ;; 268 | 7z|a|ace|alz|arc|arj|bz|cab|cpio|deb|jar|lha|lz|lzh|lzma|lzo\ 269 | |rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z) 270 | if exists atool; then 271 | fifo_pager atool -l "$1" 272 | elif exists bsdtar; then 273 | fifo_pager bsdtar -tvf "$1" 274 | fi ;; 275 | *) if [ "$3" = "bin" ]; then 276 | fifo_pager print_bin_info "$1" 277 | else 278 | fifo_pager pager "$1" 279 | fi ;; 280 | esac 281 | } 282 | 283 | preview_file() { 284 | clear 285 | # Trying to use pistol if it's available. 286 | if [ "$USE_PISTOL" -ne 0 ] && exists pistol; then 287 | fifo_pager pistol "$1" 288 | return 289 | fi 290 | 291 | # Trying to use scope.sh if it's available. 292 | if [ "$USE_SCOPE" -ne 0 ] && exists scope.sh; then 293 | fifo_pager scope.sh "$1" "$cols" "$lines" "$(mktemp -d)" "True" 294 | return 295 | fi 296 | 297 | # Use QuickLook if it's available. 298 | if [ -n "$QUICKLOOK" ]; then 299 | stat "$1" && f="$(wslpath -w "$1")" && "$QLPATH" "$f" & 300 | return 301 | fi 302 | 303 | # Detecting the exact type of the file: the encoding, mime type, and extension in lowercase. 304 | encoding="$(file -bL --mime-encoding -- "$1")" 305 | mimetype="$(file -bL --mime-type -- "$1")" 306 | ext="${1##*.}" 307 | [ -n "$ext" ] && ext="$(printf "%s" "${ext}" | tr '[:upper:]' '[:lower:]')" 308 | lines=$(tput lines <"$TTY") 309 | cols=$(tput cols <"$TTY") 310 | 311 | # Otherwise, falling back to the defaults. 312 | if [ -d "$1" ]; then 313 | cd "$1" || return 314 | if [ "$ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then 315 | [ "$SPLIT" = v ] && BSTR="\n" 316 | # shellcheck disable=SC2012 317 | ls -F --group-directories-first | head -n "$((lines - 3))" | "$(dirname "$0")"/.iconlookup -l "$cols" -B "$BSTR" -b " " 318 | elif exists tree; then 319 | fifo_pager tree --filelimit "$(find . -maxdepth 1 | wc -l)" -L 3 -C -F --dirsfirst --noreport 320 | elif exists exa; then 321 | exa -G --group-directories-first --colour=always 322 | else 323 | fifo_pager ls -F --group-directories-first --color=always 324 | fi 325 | elif [ "${encoding#*)}" = "binary" ]; then 326 | handle_mime "$1" "$mimetype" "$ext" "bin" 327 | else 328 | handle_mime "$1" "$mimetype" "$ext" 329 | fi 330 | } 2>/dev/null 331 | 332 | generate_preview() { 333 | if [ -n "$QLPATH" ] && stat "$3"; then 334 | f="$(wslpath -w "$3")" && "$QLPATH" "$f" & 335 | elif [ ! -f "$NNN_PREVIEWDIR/$3.jpg" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.jpg")" ]; then 336 | mkdir -p "$NNN_PREVIEWDIR/${3%/*}" 337 | case $4 in 338 | audio) ffmpeg -i "$3" -filter_complex "scale=iw*min(1\,min($NNN_PREVIEWWIDTH/iw\,ih)):-1" "$NNN_PREVIEWDIR/$3.jpg" -y ;; 339 | epub) gnome-epub-thumbnailer "$3" "$NNN_PREVIEWDIR/$3.jpg" ;; 340 | font) fontpreview -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" ;; 341 | gif) if [ -p "$FIFO_UEBERZUG" ] && exists convert; then 342 | if [ ! -d "$NNN_PREVIEWDIR/$3" ]; then 343 | mkdir -p "$NNN_PREVIEWDIR/$3" 344 | convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$NNN_PREVIEWDIR/$3/${3##*/}.jpg" 345 | fi 346 | while true; do 347 | for frame in $(find "$NNN_PREVIEWDIR/$3"/*.jpg | sort -V); do 348 | image_preview "$1" "$2" "$frame" 349 | sleep 0.1 350 | done 351 | done & 352 | printf "%s" "$!" > "$PREVIEWPID" 353 | return 354 | else 355 | exec >/dev/tty 356 | image_preview "$1" "$2" "$3" 357 | return 358 | fi ;; 359 | image) if exists convert; then 360 | convert "$3" -flatten -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$NNN_PREVIEWDIR/$3.jpg" 361 | else 362 | image_preview "$1" "$2" "$3" && return 363 | fi ;; 364 | office) libreoffice --convert-to jpg "$3" --outdir "$NNN_PREVIEWDIR/${3%/*}" 365 | filename="$(printf "%s" "${3##*/}" | cut -d. -f1)" 366 | mv "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;; 367 | pdf) pdftoppm -jpeg -f 1 -singlefile "$3" "$NNN_PREVIEWDIR/$3" ;; 368 | video) ffmpegthumbnailer -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm "$NNN_PREVIEWDIR/$3.jpg" ;; 369 | esac 370 | fi >/dev/null 371 | if [ -f "$NNN_PREVIEWDIR/$3.jpg" ]; then 372 | image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.jpg" 373 | else 374 | fifo_pager print_bin_info "$3" 375 | fi 376 | } 2>/dev/null 377 | 378 | image_preview() { 379 | clear 380 | if [ "$TERMINAL" = "kitty" ]; then 381 | # Kitty terminal users can use the native image preview method 382 | kitty +kitten icat --silent --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" & 383 | elif exists ueberzug; then 384 | ueberzug_layer "$1" "$2" "$3" && return 385 | elif exists catimg; then 386 | catimg "$3" & 387 | elif exists viu; then 388 | viu -t "$3" & 389 | else 390 | fifo_pager print_bin_info "$3" && return 391 | fi 392 | printf "%s" "$!" > "$PREVIEWPID" 393 | } 2>/dev/null 394 | 395 | ueberzug_layer() { 396 | printf '{"action": "add", "identifier": "nnn_ueberzug", "x": 0, "y": 0, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n' "$1" "$2" "$3" > "$FIFO_UEBERZUG" 397 | } 398 | 399 | ueberzug_remove() { 400 | printf '{"action": "remove", "identifier": "nnn_ueberzug"}\n' > "$FIFO_UEBERZUG" 401 | } 402 | 403 | winch_handler() { 404 | clear 405 | kill "$(cat "$PREVIEWPID")" 406 | if [ -p "$FIFO_UEBERZUG" ]; then 407 | pkill -f "tail --follow $FIFO_UEBERZUG" 408 | tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json & 409 | fi 410 | preview_file "$(cat "$CURSEL")" 411 | } 2>/dev/null 412 | 413 | preview_fifo() { 414 | while read -r selection; do 415 | if [ -n "$selection" ]; then 416 | kill "$(cat "$PREVIEWPID")" 417 | [ -p "$FIFO_UEBERZUG" ] && ueberzug_remove 418 | [ "$selection" = "close" ] && sleep 0.15 && pkill -P "$$" && exit 419 | preview_file "$selection" 420 | printf "%s" "$selection" > "$CURSEL" 421 | fi 422 | done < "$NNN_FIFO" 423 | sleep 0.1 # make sure potential preview by winch_handler is killed 424 | pkill -P "$$" 425 | } 2>/dev/null 426 | 427 | if [ "$PREVIEW_MODE" ]; then 428 | if [ "$TERMINAL" != "kitty" ] && exists ueberzug; then 429 | mkfifo "$FIFO_UEBERZUG" 430 | tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json & 431 | fi 432 | 433 | preview_file "$PWD/$1" 434 | preview_fifo & 435 | printf "%s" "$!" > "$FIFOPID" 436 | printf "%s" "$PWD/$1" > "$CURSEL" 437 | trap 'winch_handler; wait' WINCH 438 | trap 'rm "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" 2>/dev/null' INT HUP EXIT 439 | wait "$!" 2>/dev/null 440 | else 441 | if [ ! -r "$NNN_FIFO" ]; then 442 | clear 443 | printf "No FIFO available! (\$NNN_FIFO='%s')\nPlease read Usage in preview-tui." "$NNN_FIFO" 444 | cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" 445 | elif [ "$KITTY_WINDOW_ID" ] && [ -z "$TMUX" ] && [ -z "$KITTY_LISTEN_ON" ]; then 446 | clear 447 | printf "\$KITTY_LISTEN_ON not set!\nPlease read Usage in preview-tui." 448 | cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" 449 | else 450 | TTY="$(tty)" 451 | TTY="$TTY" toggle_preview "$1" & 452 | fi 453 | fi 454 | --------------------------------------------------------------------------------