diff --git a/nvim/autoload/dotfiles/indent_motion.vim b/nvim/autoload/dotfiles/indent_motion.vim new file mode 100644 index 0000000..780d351 --- /dev/null +++ b/nvim/autoload/dotfiles/indent_motion.vim @@ -0,0 +1,63 @@ +" Based on +" A motion for moving over enclosing indentation blocks. Primarily intended +" for reverse-engineering CrossCode. + +function dotfiles#indent_motion#run(direction) + let l:cursor_linenr = line(".") + let l:max_linenr = line("$") + + let l:retry = 0 + while l:retry <# 2 + let l:retry += 1 + + let l:base_linenr = l:cursor_linenr + let l:base_indent = 0 + while 1 <=# l:base_linenr && l:base_linenr <=# l:max_linenr + let l:base_indent = dotfiles#indent_motion#indent_level_of(l:base_linenr) + if l:base_indent >=# 0 + break + endif + let l:base_linenr += a:direction + endwhile + + let l:target_linenr = l:base_linenr + + let l:curr_linenr = l:base_linenr + a:direction + let l:prev_indent = l:base_indent + while 1 <=# l:curr_linenr && l:curr_linenr <=# l:max_linenr + let l:indent = dotfiles#indent_motion#indent_level_of(l:curr_linenr) + + if l:indent >=# 0 + if l:indent <# l:base_indent + break + else + let l:target_linenr = l:curr_linenr + endif + elseif l:base_indent ==# 0 && l:prev_indent ==# 0 + break + endif + + let l:prev_indent = l:indent + let l:curr_linenr += a:direction + endwhile + + if l:target_linenr ==# l:cursor_linenr + let l:cursor_linenr += a:direction + if 1 <=# l:cursor_linenr && l:cursor_linenr <=# l:max_linenr + continue + endif + endif + + break + endwhile + + execute "normal! " . l:target_linenr . "G^" +endfunction + +" +function dotfiles#indent_motion#indent_level_of(linenr) + if getline(a:linenr) ==# "" + return -1 + endif + return indent(a:linenr) +endfunction diff --git a/nvim/autoload/dotfiles/utils.vim b/nvim/autoload/dotfiles/utils.vim new file mode 100644 index 0000000..d3cd2b2 --- /dev/null +++ b/nvim/autoload/dotfiles/utils.vim @@ -0,0 +1,6 @@ +function dotfiles#utils#array_remove_element(array, element) + let l:index = index(a:array, a:element) + if l:index >= 0 + call remove(a:array, l:index) + endif +endfunction diff --git a/nvim/plugin/dotfiles/indent_motion.vim b/nvim/plugin/dotfiles/indent_motion.vim new file mode 100644 index 0000000..32c4525 --- /dev/null +++ b/nvim/plugin/dotfiles/indent_motion.vim @@ -0,0 +1,9 @@ +for [s:plug_mapping, s:direction, s:user_mapping] in [["prev", -1, "("], ["next", 1, ")"]] + let s:plug_mapping = "dotfiles_indent_motion_".s:plug_mapping + for s:mode in ["n", "v", "o"] + execute s:mode."noremap" "" s:plug_mapping "call dotfiles#indent_motion#run(".s:direction.")" + if !empty(s:user_mapping) + execute s:mode."map" s:user_mapping s:plug_mapping + endif + endfor +endfor diff --git a/nvim/plugin/editing.vim b/nvim/plugin/editing.vim index ec77a41..3fb2af5 100644 --- a/nvim/plugin/editing.vim +++ b/nvim/plugin/editing.vim @@ -106,10 +106,6 @@ set commentstring=//%s nnoremap nnoremap - nnoremap kk set keymap& - nnoremap kr set keymap=russian-jcuken-custom - nnoremap ku set keymap=ukrainian-jcuken-custom - nnoremap Q " normal mode @@ -138,6 +134,19 @@ set commentstring=//%s " }}} +" Keymap switcher {{{ + + nnoremap kk set keymap& + nnoremap kr set keymap=russian-jcuken-custom + nnoremap ku set keymap=ukrainian-jcuken-custom + + nnoremap DotfilesSwapKeymaps + let g:dotfiles_prev_keymap = &keymap + command! -nargs=0 DotfilesSwapKeymaps let [g:dotfiles_prev_keymap, &keymap] = [&keymap, g:dotfiles_prev_keymap] + +" }}} + + " Search {{{ " ignore case if the pattern doesn't contain uppercase characters (use '\C' diff --git a/nvim/plugin/files.vim b/nvim/plugin/files.vim index b9266d5..8b3d347 100644 --- a/nvim/plugin/files.vim +++ b/nvim/plugin/files.vim @@ -36,6 +36,10 @@ nnoremap empty(&buftype) ? ":writewall\" : "\" " Ranger {{{ let g:ranger_replace_netrw = 1 let g:ranger_map_keys = 0 + " The default path (/tmp/chosenfile) is inaccessible at least on + " Android/Termux, so the tempname() function was chosen because it respects + " $TMPDIR. + let g:ranger_choice_file = tempname() nnoremap o Ranger " ranger.vim relies on the Bclose.vim plugin, but I use Bbye.vim, so this " command is here just for compatitabilty diff --git a/nvim/plugin/git.vim b/nvim/plugin/git.vim index c986e7b..cb154da 100644 --- a/nvim/plugin/git.vim +++ b/nvim/plugin/git.vim @@ -8,6 +8,7 @@ nnoremap gw :GBrowse nnoremap gW :.GBrowse nnoremap gc :Git commit % + nnoremap gC :Git commit --amend nnoremap gl :Gclog nnoremap gp :Git push " }}} diff --git a/zsh/path.zsh b/zsh/path.zsh index 02da266..47fdf6d 100644 --- a/zsh/path.zsh +++ b/zsh/path.zsh @@ -70,7 +70,8 @@ export GOPATH=~/go path_prepend path "$GOPATH/bin" # Rust -if [[ -f ~/.rustup/settings.toml ]]; then +rustup_home="${RUSTUP_HOME:-$HOME/.rustup}" +if [[ -f "$rustup_home"/settings.toml ]]; then # Make a low-effort attempt at quickly extracting the selected Rust toolchain # from rustup's settings. The TOML file is obviously assumed to be well-formed # and syntactically correct because virtually always it's manipulated with the @@ -78,7 +79,7 @@ if [[ -f ~/.rustup/settings.toml ]]; then # because Rust toolchain names don't need escaping in strings. # See also . rust_toolchain="" - < ~/.rustup/settings.toml while IFS= read -r line; do + < "$rustup_home"/settings.toml while IFS= read -r line; do if [[ "$line" =~ '^default_toolchain = "(.+)"$' ]]; then rust_toolchain="${match[1]}" break @@ -88,16 +89,20 @@ if [[ -f ~/.rustup/settings.toml ]]; then done; unset line if [[ -n "$rust_toolchain" ]]; then - rust_sysroot=~/.rustup/toolchains/"$rust_toolchain" + rust_sysroot="$rustup_home"/toolchains/"$rust_toolchain" # path_append path "$rust_sysroot"/bin path_prepend fpath "$rust_sysroot"/zsh/site-functions path_prepend manpath "$rust_sysroot"/share/man - path_prepend ld_library_path "$rust_sysroot"/lib - unset rust_sysroot fi - unset rust_toolchain + for rust_sysroot in "$rustup_home"/toolchains/*(/); do + # The filenames of all libraries in toolchain dirs are suffixed with their + # build hashes or the compiler identifier, so in practice conflicts are + # insanely unlikely. + path_prepend ld_library_path "$rust_sysroot"/lib + done fi +unset rustup_home rust_toolchain rust_sysroot path_prepend path ~/.cargo/bin diff --git a/zsh/plugins.zsh b/zsh/plugins.zsh index 0687e21..f207b1c 100644 --- a/zsh/plugins.zsh +++ b/zsh/plugins.zsh @@ -49,7 +49,7 @@ _plugin completions 'zsh-users/zsh-completions' "$_checkout_latest_version" # Oh My Zsh {{{ omz_features=(key-bindings termsupport) - omz_plugins=(git extract fasd) + omz_plugins=(git) _plugin ohmyzsh 'ohmyzsh/ohmyzsh' \ load='lib/'${^omz_features}'.zsh' \ @@ -64,22 +64,35 @@ _plugin completions 'zsh-users/zsh-completions' "$_checkout_latest_version" # fasd {{{ -#unalias j -#j() { -# local _fasd_ret -# _fasd_ret="$( -# # -l: list all paths in the database (without scores) -# # -d: list only directories -# # -R: in the reverse order -# fasd -l -d -R | -# fzf --height=40% --layout=reverse --tiebreak=index --query="$*" -# )" -# if [[ -d "$_fasd_ret" ]]; then -# cd -- "$_fasd_ret" -# elif [[ -n "$_fasd_ret" ]]; then -# print -- "$_fasd_ret" -# fi -#} + if command_exists fasd; then + # Initialization taken from + fasd_cache="${ZSH_CACHE_DIR}/fasd-init-cache" + if [[ "${commands[fasd]}" -nt "$fasd_cache" || ! -s "$fasd_cache" ]]; then + fasd --init posix-alias zsh-hook zsh-ccomp zsh-ccomp-install zsh-wcomp zsh-wcomp-install >| "$fasd_cache" + fi + source "$fasd_cache" + unset fasd_cache + + alias v='f -e "$EDITOR"' + alias o='a -e xdg-open' + + # alias j='zz' + j() { + local _fasd_ret + _fasd_ret="$( + # -l: list all paths in the database (without scores) + # -d: list only directories + # -R: in the reverse order + fasd -l -d -R | + fzf --height=40% --layout=reverse --tiebreak=index --query="$*" + )" + if [[ -d "$_fasd_ret" ]]; then + cd -- "$_fasd_ret" + elif [[ -n "$_fasd_ret" ]]; then + print -- "$_fasd_ret" + fi + } + fi # }}}