-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
On demand plugin-id completor and ice name completor. One will be abl…
…e to obtain, e.g.: zinit fzf<Alt>-<Shift>-A » zinit junegunn/fzf zinit cd rip<Alt>-<Shift>-A » zinit cd BurntSushi/ripgrep and so on. The <Alt>-<Shift>-A shortcut works with ALL commands, regardless if it's zinit command or not. Two autoloaded functions added, ziactioncomplete (the proper imple- mentation of the main features) and ziprocessbuffer (a very useful library function that takes care of $BUFFFER/$CURSOR processing). Also Feature: Cycling and ice-completion (<Alt>-<Shift>-C). Cycling will allow to choose a particular match, say for, e.g.: zinit at<Alt>-<Shift>-C » zinit atclone<Alt><Shift>-C » zinit atinit<Alt>-<Shift>-C
- Loading branch information
Showing
4 changed files
with
248 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
#!/usr/bin/env zsh | ||
# | ||
# -*- mode: sh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- | ||
# | ||
# Copyright (c) 2022 zdharma-continuum and contributors | ||
# Copyright (c) 2016-2022 Sebastian Gniazdowski and contributors. | ||
|
||
zi-action-complete() | ||
{ | ||
# Emulate zsh and useful options | ||
emulate -L zsh -o extended_glob -o warn_create_global -o typeset_silent \ | ||
-o no_short_loops -o rc_quotes -o no_auto_pushd | ||
|
||
# The index of the match that's inserted in cmd line | ||
integer -g ziac_midx | ||
typeset -ga ziac_matches ziac_wids | ||
typeset -g ziac_prevw ziac_mt | ||
local -a match mbegin mend | ||
typeset -gA Times | ||
|
||
# Emulate real time if needed | ||
if (( !$+EPOCHREALTIME )); then | ||
(( !$+SECONDS )) && float -g SECONDS | ||
float EPOCHREALTIME=$SECONDS | ||
fi | ||
|
||
# | ||
# Invoke the helper/worker function that does all needed $BUFFER processing | ||
# | ||
|
||
zi-process-buffer || return 1 | ||
|
||
integer i j pos=$CURSOR size=${#ZINIT_PB_WORDS} newcursor | ||
local w PWIDGET buf | ||
(( Times[$WIDGET] = Times[$WIDGET] <= 0 ? | ||
EPOCHREALTIME-3 : Times[$WIDGET] )) | ||
# Detect series. | ||
if (( EPOCHREALTIME - Times[$WIDGET] < 1.5 )); then | ||
PWIDGET=$WIDGET | ||
else | ||
PWIDGET= ziac_prevw= | ||
fi | ||
Times[$WIDGET]=$EPOCHREALTIME | ||
|
||
# Cursor at empty space? Only if not use the word | ||
[[ $BUFFER[CURSOR] == [[:space:]] ]] || \ | ||
w=$ZINIT_PB_WORDS[ZINIT_PB_SELECTED_WORD] | ||
|
||
if [[ $WIDGET == zi-action-complete-ice && $WIDGET != $PWIDGET && \ | ||
( $ziac_prevw != $w || -z $w ) ]] | ||
then | ||
local -a ice_order=( | ||
${(Aons:|:)ZINIT[ice-list]} | ||
${(@)${(A@kons:|:)${ZINIT_EXTS[ice-mods]//\'\'/}}/(#s)<->-/} | ||
) | ||
ziac_prevw=$w | ||
match=() | ||
w=${w//(#b)(([=:]|)[\'\"]?#([\'\"]|(#e)))/} | ||
ziac_mt=$match[1] | ||
|
||
ziac_matches=( ${(onM)ice_order:#*$w*} ) | ||
elif (( ziac_midx )) && [[ $WIDGET == *-ice && $WIDGET == $PWIDGET ]]; then | ||
ziac_midx+=1 | ||
fi | ||
if [[ $WIDGET == zi-action-complete && $WIDGET != $PWIDGET && \ | ||
( $ziac_prevw != $w || -z $w ) ]]; then | ||
ziac_matches=( $ZINIT[PLUGINS_DIR]/*${w//\//---}*(-onND[1,18]) ) | ||
ziac_prevw=$w | ||
ziac_mt= | ||
elif (( ziac_midx )) && [[ $WIDGET == *-complete && $WIDGET == $PWIDGET ]]; then | ||
ziac_midx+=1 | ||
fi | ||
if (( !ziac_midx || ziac_midx > $#ziac_matches )); then | ||
ziac_midx=1 | ||
fi | ||
|
||
if [[ -z $ziac_matches ]]; then | ||
zle -M "No matches for $w found" | ||
return 1 | ||
fi | ||
zle -M "${(j: :)${ziac_matches[@]:t}//---//}" | ||
REPLY=${${ziac_matches[$ziac_midx]:t}//---//}$ziac_mt | ||
for (( i=1; i<=size; i++ )); do | ||
# Check if we're at (i.e. directly at or after, | ||
# when after are just spaces) current word | ||
if [[ $i = $ZINIT_PB_SELECTED_WORD ]]; then | ||
# INSERT MODE? I.e.: addition of a new token at the pointed free space? | ||
if (( pos > (ZINIT_PB_WORDS_BEGINNINGS[i] + ${#ZINIT_PB_WORDS[i]} - 1) )); then | ||
# We need to introduce new word | ||
# First move all words and spaces forward | ||
for (( j=size; j>=i+1; j-- )); do | ||
ZINIT_PB_WORDS[j+1]=${ZINIT_PB_WORDS[j]} | ||
ZINIT_PB_SPACES[j+1]=${ZINIT_PB_SPACES[j]} | ||
ZINIT_PB_WORDS_BEGINNINGS[j+1]=${ZINIT_PB_WORDS_BEGINNINGS[j]} | ||
done | ||
size+=1 | ||
# New word is introduced at position i+1, after current word | ||
# It doesn't have word beginnings and spaces assigned | ||
# It has to take spaces from word next to it, i+2 | ||
ZINIT_PB_WORDS[i+1]=$REPLY | ||
ZINIT_PB_WORDS_BEGINNINGS[i+1]="$(( pos + 1 ))" | ||
|
||
# Now split spaces | ||
# cursor_spaces: spaces from current word to the cursor | ||
integer cursor_spaces=$(( pos - ZINIT_PB_WORDS_BEGINNINGS[i] - ${#ZINIT_PB_WORDS[i]} + 1 )) | ||
# take that from spaces of word "next" in: current NEW next | ||
integer after_spaces=$(( ZINIT_PB_SPACES[i+2] - cursor_spaces )) | ||
local empty="" | ||
ZINIT_PB_SPACES[i+1]="${(l:cursor_spaces:: :)empty}" | ||
ZINIT_PB_SPACES[i+2]="${(l:after_spaces:: :)empty}" | ||
|
||
# Cursor will be at end of newly added word | ||
newcursor=$(( ZINIT_PB_WORDS_BEGINNINGS[i+1] + ${#ZINIT_PB_WORDS[i+1]} - 1 )) | ||
# OR REPLACE MODE – substitute the match for the input/needle token | ||
else | ||
ZINIT_PB_WORDS[i]=$REPLY | ||
|
||
# Cursor will be at end of newly substituted word | ||
newcursor=$(( ZINIT_PB_WORDS_BEGINNINGS[i] + ${#ZINIT_PB_WORDS[i]} - 1 )) | ||
|
||
# Update word beginnings of following words – skipped | ||
fi | ||
fi | ||
buf+=$ZINIT_PB_SPACES[i]$ZINIT_PB_WORDS[i] | ||
done | ||
|
||
buf+=$ZINIT_PB_SPACES[i] | ||
BUFFER=$buf | ||
CURSOR=$newcursor | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# Input: | ||
# $1 - optional buffer to process (default is $BUFFER) | ||
# $2 - optional parameter containing cursor (default is $CURSOR) | ||
# | ||
# Output: | ||
# ZINIT_PB_WORDS - split of $1 into shell words; array | ||
# ZINIT_PB_WORDS_BEGINNINGS - indexes of first letters of corresponding words in ZINIT_PB_WORDS | ||
# ZINIT_PB_SPACES - white spaces before corresponding words in ZINIT_PB_WORDS | ||
# ZINIT_PB_SELECTED_WORD - index in ZINIT_PB_WORDS pointing to word activated by cursor position | ||
# ZINIT_PB_LEFT - left part of active word | ||
# ZINIT_PB_RIGHT - right part of active word | ||
# | ||
|
||
emulate -LR zsh | ||
setopt typesetsilent extendedglob noshortloops | ||
|
||
local MBEGIN MEND MATCH mbegin mend match | ||
|
||
local buf="${1:-$BUFFER}" | ||
local cursor="${2:-$CURSOR}" | ||
|
||
ZINIT_PB_WORDS=( "${(Z+n+)buf}" ) | ||
ZINIT_PB_SPACES=( ) | ||
ZINIT_PB_WORDS_BEGINNINGS=( ) | ||
ZINIT_PB_SELECTED_WORD=-1 | ||
|
||
# (Z+n+) will return 1 element for buf that is empty or only whitespace | ||
if [[ $buf = ( |$'\t')# ]]; then | ||
ZINIT_PB_WORDS=( ) | ||
integer nwords=0 | ||
else | ||
integer nwords="${#ZINIT_PB_WORDS}" | ||
fi | ||
|
||
# Remove ZINIT_PB_WORDS one by one, counting characters, | ||
# computing beginning of each word, to find | ||
# place to break the word into 2 halves (for | ||
# complete_in_word option) | ||
|
||
local i word wordlen | ||
integer char_count=0 | ||
|
||
# (Z) handles spaces nicely, but we need them for the user | ||
# Also compute words beginnings and the selected word | ||
for (( i=1; i<=nwords; i++ )); do | ||
# Remove spurious space generated by Z-flag when | ||
# input is an unbound '$(' (happens with zsh < 5.1) | ||
# and also real spaces gathered by an unbound '$(', | ||
# to handle them in a way normal to this loop | ||
ZINIT_PB_WORDS[i]="${ZINIT_PB_WORDS[i]%% ##}" | ||
word="${ZINIT_PB_WORDS[i]}" | ||
|
||
# In general, $buf can start with white spaces | ||
# We will not search for them, but instead for | ||
# leading character of current shell word, | ||
# negated. This is an ambition to completely | ||
# avoid character classes | ||
|
||
# Remove white spaces | ||
buf="${buf##(#m)[^$word[1]]#}" | ||
# Count them | ||
char_count=char_count+"$#MATCH" | ||
# This is the beginning of current word | ||
ZINIT_PB_WORDS_BEGINNINGS[i]=$(( char_count + 1 )) | ||
# Remember the spaces | ||
ZINIT_PB_SPACES[i]=$MATCH | ||
|
||
# Remove the word | ||
wordlen="${#word}" | ||
[[ "${buf[1,wordlen]}" != $word ]] && return 1 # should not happen unless bug in (z) | ||
buf="${buf[wordlen+1,-1]}" | ||
|
||
# Spaces point to previous shell word | ||
# Visual cursor right after spaces (-ge) -> not enough to select previous word (-gt required) | ||
[[ $ZINIT_PB_SELECTED_WORD -eq -1 && $char_count -gt $cursor ]] && ZINIT_PB_SELECTED_WORD=$(( i-1 )) | ||
|
||
# Actual characters point to current shell word | ||
# Visual cursor right after letters (-ge) -> enough to select current word | ||
char_count=char_count+"$#word" | ||
[[ $ZINIT_PB_SELECTED_WORD -eq -1 && $char_count -ge $cursor ]] && ZINIT_PB_SELECTED_WORD=$i | ||
done | ||
|
||
# What's left in $buf can be only white spaces | ||
char_count=char_count+"$#buf" | ||
ZINIT_PB_SPACES[i]=$buf | ||
|
||
# Visual cursor right after spaces (-ge) -> enough to select last word | ||
[[ $ZINIT_PB_SELECTED_WORD -eq -1 && $char_count -ge $cursor ]] && ZINIT_PB_SELECTED_WORD=$(( i-1 )) | ||
|
||
# Divide active word into two halves | ||
integer diff=$(( cursor - ZINIT_PB_WORDS_BEGINNINGS[ZINIT_PB_SELECTED_WORD] + 1 )) | ||
word="${ZINIT_PB_WORDS[ZINIT_PB_SELECTED_WORD]}" | ||
ZINIT_PB_LEFT="${word[1,diff]}" | ||
ZINIT_PB_RIGHT="${word[diff+1,-1]}" | ||
|
||
[[ $ZINIT_PB_SELECTED_WORD -gt 0 ]] | ||
|
||
# vim:ft=zsh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters