diff --git a/dot_config/zsh/completion/_kcl b/dot_config/zsh/completion/_kcl new file mode 100644 index 0000000..2438ee9 --- /dev/null +++ b/dot_config/zsh/completion/_kcl @@ -0,0 +1,212 @@ +#compdef kcl +compdef _kcl kcl + +# zsh completion for kcl -*- shell-script -*- + +__kcl_debug() +{ + local file="$BASH_COMP_DEBUG_FILE" + if [[ -n ${file} ]]; then + echo "$*" >> "${file}" + fi +} + +_kcl() +{ + local shellCompDirectiveError=1 + local shellCompDirectiveNoSpace=2 + local shellCompDirectiveNoFileComp=4 + local shellCompDirectiveFilterFileExt=8 + local shellCompDirectiveFilterDirs=16 + local shellCompDirectiveKeepOrder=32 + + local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder + local -a completions + + __kcl_debug "\n========= starting completion logic ==========" + __kcl_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $CURRENT location, so we need + # to truncate the command-line ($words) up to the $CURRENT location. + # (We cannot use $CURSOR as its value does not work when a command is an alias.) + words=("${=words[1,CURRENT]}") + __kcl_debug "Truncated words[*]: ${words[*]}," + + lastParam=${words[-1]} + lastChar=${lastParam[-1]} + __kcl_debug "lastParam: ${lastParam}, lastChar: ${lastChar}" + + # For zsh, when completing a flag with an = (e.g., kcl -n=) + # completions must be prefixed with the flag + setopt local_options BASH_REMATCH + if [[ "${lastParam}" =~ '-.*=' ]]; then + # We are dealing with a flag with an = + flagPrefix="-P ${BASH_REMATCH}" + fi + + # Prepare the command to obtain completions + requestComp="${words[1]} __complete ${words[2,-1]}" + if [ "${lastChar}" = "" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go completion code. + __kcl_debug "Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi + + __kcl_debug "About to call: eval ${requestComp}" + + # Use eval to handle any environment variables and such + out=$(eval ${requestComp} 2>/dev/null) + __kcl_debug "completion output: ${out}" + + # Extract the directive integer following a : from the last line + local lastLine + while IFS='\n' read -r line; do + lastLine=${line} + done < <(printf "%s\n" "${out[@]}") + __kcl_debug "last line: ${lastLine}" + + if [ "${lastLine[1]}" = : ]; then + directive=${lastLine[2,-1]} + # Remove the directive including the : and the newline + local suffix + (( suffix=${#lastLine}+2)) + out=${out[1,-$suffix]} + else + # There is no directive specified. Leave $out as is. + __kcl_debug "No directive found. Setting do default" + directive=0 + fi + + __kcl_debug "directive: ${directive}" + __kcl_debug "completions: ${out}" + __kcl_debug "flagPrefix: ${flagPrefix}" + + if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then + __kcl_debug "Completion received error. Ignoring completions." + return + fi + + local activeHelpMarker="_activeHelp_ " + local endIndex=${#activeHelpMarker} + local startIndex=$((${#activeHelpMarker}+1)) + local hasActiveHelp=0 + while IFS='\n' read -r comp; do + # Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker) + if [ "${comp[1,$endIndex]}" = "$activeHelpMarker" ];then + __kcl_debug "ActiveHelp found: $comp" + comp="${comp[$startIndex,-1]}" + if [ -n "$comp" ]; then + compadd -x "${comp}" + __kcl_debug "ActiveHelp will need delimiter" + hasActiveHelp=1 + fi + + continue + fi + + if [ -n "$comp" ]; then + # If requested, completions are returned with a description. + # The description is preceded by a TAB character. + # For zsh's _describe, we need to use a : instead of a TAB. + # We first need to escape any : as part of the completion itself. + comp=${comp//:/\\:} + + local tab="$(printf '\t')" + comp=${comp//$tab/:} + + __kcl_debug "Adding completion: ${comp}" + completions+=${comp} + lastComp=$comp + fi + done < <(printf "%s\n" "${out[@]}") + + # Add a delimiter after the activeHelp statements, but only if: + # - there are completions following the activeHelp statements, or + # - file completion will be performed (so there will be choices after the activeHelp) + if [ $hasActiveHelp -eq 1 ]; then + if [ ${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then + __kcl_debug "Adding activeHelp delimiter" + compadd -x "--" + hasActiveHelp=0 + fi + fi + + if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then + __kcl_debug "Activating nospace." + noSpace="-S ''" + fi + + if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then + __kcl_debug "Activating keep order." + keepOrder="-V" + fi + + if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then + # File extension filtering + local filteringCmd + filteringCmd='_files' + for filter in ${completions[@]}; do + if [ ${filter[1]} != '*' ]; then + # zsh requires a glob pattern to do file filtering + filter="\*.$filter" + fi + filteringCmd+=" -g $filter" + done + filteringCmd+=" ${flagPrefix}" + + __kcl_debug "File filtering command: $filteringCmd" + _arguments '*:filename:'"$filteringCmd" + elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then + # File completion for directories only + local subdir + subdir="${completions[1]}" + if [ -n "$subdir" ]; then + __kcl_debug "Listing directories in $subdir" + pushd "${subdir}" >/dev/null 2>&1 + else + __kcl_debug "Listing directories in ." + fi + + local result + _arguments '*:dirname:_files -/'" ${flagPrefix}" + result=$? + if [ -n "$subdir" ]; then + popd >/dev/null 2>&1 + fi + return $result + else + __kcl_debug "Calling _describe" + if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then + __kcl_debug "_describe found some completions" + + # Return the success of having called _describe + return 0 + else + __kcl_debug "_describe did not find completions." + __kcl_debug "Checking if we should do file completion." + if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then + __kcl_debug "deactivating file completion" + + # We must return an error code here to let zsh know that there were no + # completions found by _describe; this is what will trigger other + # matching algorithms to attempt to find completions. + # For example zsh can match letters in the middle of words. + return 1 + else + # Perform file completion + __kcl_debug "Activating file completion" + + # We must return the result of this command, so it must be the + # last command, or else we must store its result to return it. + _arguments '*:filename:_files'" ${flagPrefix}" + fi + fi + fi +} + +# don't run the completion function when being source-ed or eval-ed +if [ "$funcstack[1]" = "_kcl" ]; then + _kcl +fi diff --git a/dot_config/zsh/include/env.zsh b/dot_config/zsh/env.zsh similarity index 57% rename from dot_config/zsh/include/env.zsh rename to dot_config/zsh/env.zsh index edc7b39..5550701 100644 --- a/dot_config/zsh/include/env.zsh +++ b/dot_config/zsh/env.zsh @@ -8,10 +8,11 @@ export KREW_NO_UPGRADE_CHECK=1 export KREW_ROOT=${XDG_DATA_HOME:-$HOME/.local/share/krew} export PATH=${KREW_ROOT:-$HOME/.krew}/bin:~/bin:~/.local/bin:$GOPATH/bin:~/.nix-profile/bin:$PATH + export EDITOR=nvim export MANPAGER="nvim +Man!" -export DOCKER_HOST=unix:///run/user/1000/podman/podman.sock +export DOCKER_HOST=unix://${XDG_RUNTIME_DIR}/podman/podman.sock # make locales work in nix shell export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive @@ -20,3 +21,6 @@ GPG_TTY=$(tty) export GPG_TTY export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) + +LS_COLORS='rs=0:di=01;38;2;131;165;152:ln=40;01;38;2;142;192;124:or=09;40;01;38;2;142;192;124:mh=00:pi=40;38;2;215;153;33:so=01;38;2;211;134;155:do=01;38;2;211;134;155:bd=40;01;38;2;215;153;33:cd=40;01;38;2;215;153;33:mi=00:su=48;2;204;36;29;38;2;254;128;25:sg=30;48;2;215;153;33:ca=00:tw=48;2;152;151;26;38;2;69;133;136:ow=30;48;2;152;151;26:st=30;48;2;69;133;136:ex=01;38;2;184;187;38:'; +export LS_COLORS diff --git a/dot_config/zsh/include/bashcompl.zsh b/dot_config/zsh/include/bashcompl.zsh new file mode 100644 index 0000000..5b030d1 --- /dev/null +++ b/dot_config/zsh/include/bashcompl.zsh @@ -0,0 +1,13 @@ +autoload -U +X bashcompinit && bashcompinit + +prgs=( + grr + mcli + vault + ) + +for p in $prgs; do + if whence $p > /dev/null; then + complete -o nospace -C $p $p + fi +done diff --git a/dot_config/zsh/include/colors.zsh b/dot_config/zsh/include/colors.zsh deleted file mode 100644 index b4d1c1f..0000000 --- a/dot_config/zsh/include/colors.zsh +++ /dev/null @@ -1,2 +0,0 @@ -LS_COLORS='rs=0:di=01;38;2;131;165;152:ln=40;01;38;2;142;192;124:or=09;40;01;38;2;142;192;124:mh=00:pi=40;38;2;215;153;33:so=01;38;2;211;134;155:do=01;38;2;211;134;155:bd=40;01;38;2;215;153;33:cd=40;01;38;2;215;153;33:mi=00:su=48;2;204;36;29;38;2;254;128;25:sg=30;48;2;215;153;33:ca=00:tw=48;2;152;151;26;38;2;69;133;136:ow=30;48;2;152;151;26:st=30;48;2;69;133;136:ex=01;38;2;184;187;38:'; -export LS_COLORS diff --git a/dot_config/zsh/include/extra.zsh b/dot_config/zsh/include/extra.zsh deleted file mode 100644 index 8eb8c0d..0000000 --- a/dot_config/zsh/include/extra.zsh +++ /dev/null @@ -1 +0,0 @@ -# source /usr/share/fzf/key-bindings.zsh diff --git a/dot_config/zsh/init.zsh b/dot_config/zsh/init.zsh index 851c5b2..451c289 100644 --- a/dot_config/zsh/init.zsh +++ b/dot_config/zsh/init.zsh @@ -1,9 +1,12 @@ cachedir=${XDG_CACHE_HOME:-$HOME/.cache}/zsh datadir=${XDG_DATA_HOME:-$HOME/.local/share}/zsh -confdir=$(dirname $(print -P %N)) test -d $cachedir || mkdir -p $cachedir test -d $datadir || mkdir -p $datadir +source $ZSH_CONFIG_DIR/env.zsh +source $ZSH_CONFIG_DIR/options.zsh +source $ZSH_CONFIG_DIR/input.zsh + # Enable Powerlevel10k instant prompt. Should stay close to the top of ${ZDOTDIR:-${HOME}}/.zshrc. # Initialization code that may require console input (password prompts, [y/n] # confirmations, etc.) must go above this block; everything else may go below. @@ -12,27 +15,27 @@ if [[ -r "${cachedir}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then fi ZIM_HOME=$datadir/zim +ZIM_CONFIG_FILE=$ZSH_CONFIG_DIR/zimrc test -d $ZIM_HOME || mkdir -p $ZIM_HOME if [[ ! -e ${ZIM_HOME}/zimfw.zsh ]]; then wget -O ${ZIM_HOME}/zimfw.zsh \ https://github.com/zimfw/zimfw/releases/latest/download/zimfw.zsh fi -for cf in ~/.config/zsh/include/*.zsh ; do - source $cf -done - -if [[ ! ${ZIM_HOME}/init.zsh -nt ${ZDOTDIR:-${HOME}}/.zimrc ]]; then +if [[ ! ${ZIM_HOME}/init.zsh -nt $ZIM_CONFIG_FILE ]]; then source ${ZIM_HOME}/zimfw.zsh init -v fi source ${ZIM_HOME}/init.zsh +for cf in $ZSH_CONFIG_DIR/include/*.zsh ; do + source $cf +done -if [[ $confdir/theme/gruvbox.ini -nt $(fast-theme -w && pwd )/current_theme.zsh ]] +if [[ $ZSH_CONFIG_DIR/theme/gruvbox.ini -nt $(fast-theme -w && pwd )/current_theme.zsh ]] then echo "Refreshing theme" - fast-theme $confdir/theme/gruvbox.ini + fast-theme $ZSH_CONFIG_DIR/theme/gruvbox.ini fi unset _fast_theme @@ -41,4 +44,4 @@ then zimfw update -v fi -unset cachedir datadir confdir +unset cachedir datadir diff --git a/dot_config/zsh/include/input.zsh b/dot_config/zsh/input.zsh similarity index 100% rename from dot_config/zsh/include/input.zsh rename to dot_config/zsh/input.zsh diff --git a/dot_config/zsh/include/options.zsh b/dot_config/zsh/options.zsh similarity index 100% rename from dot_config/zsh/include/options.zsh rename to dot_config/zsh/options.zsh diff --git a/dot_config/zsh/zimrc b/dot_config/zsh/zimrc new file mode 100644 index 0000000..f2bfa70 --- /dev/null +++ b/dot_config/zsh/zimrc @@ -0,0 +1,9 @@ +#zmodule input +zmodule romkatv/powerlevel10k --use degit +zmodule agkozak/zsh-z +zmodule $ZSH_CONFIG_DIR/completion --name custom-completion --fpath . +zmodule completion +zmodule zdharma-continuum/fast-syntax-highlighting +# zmodule zsh-users/zsh-syntax-highlighting + +# vim:ft=zsh diff --git a/dot_zshrc b/dot_zshrc index 5cba676..a7b19bb 100644 --- a/dot_zshrc +++ b/dot_zshrc @@ -1,7 +1,4 @@ _zprintlevel=1 -source ~/.config/zsh/init.zsh -autoload -U +X bashcompinit && bashcompinit -complete -o nospace -C /home/vladimir/bin/grr grr - -complete -o nospace -C /usr/bin/mcli mcli +ZSH_CONFIG_DIR="$HOME/.config/zsh" +source ${ZSH_CONFIG_DIR}/init.zsh