-
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.
Initial version of an idea – an on demand plugin-id completor and
verifier. One will be able to obtain, e.g.: zinit fzf<Alt>-a » zinit junegunn/fzf zinit cd rip<Alt>-a » zinit cd BurntSushi/ripgrep zinit cd tmux/tmux<Alt>-v » "tmux/tmux" highlighted eighter in blue » or red, depending on existence of » such plugin and so on. The <Alt>-a and <Alt>-v shortcuts work 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).
- Loading branch information
Showing
3 changed files
with
167 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# -*- mode: sh; sh-indentation: 4; indent-tabs-mode: nil; sh-basic-offset: 4; -*- | ||
# Copyright (c) 2016-2020 Sebastian Gniazdowski and contributors. | ||
|
||
ziactioncomplete() | ||
{ | ||
# 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 | ||
|
||
# Invoke the helper/worker function that does all needed $BUFFER processing | ||
ziprocessbuffer | ||
integer i j pos=$CURSOR size=${#ZINIT_PB_WORDS} newcursor | ||
local w=$ZINIT_PB_WORDS[ZINIT_PB_SELECTED_WORD] buf | ||
local -a matches=( $ZINIT[PLUGINS_DIR]/*${w//\//---}*(-onND[1,8]) ) | ||
REPLY=${${matches[1]:t}//---//} | ||
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 | ||
# Check if we're at the word itself, | ||
# or at some distance after it | ||
if [[ $WIDGET == ziactioncompleteinsert ]] && (( 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 )) | ||
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
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,96 @@ | ||
# 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]}" | ||
|
||
# vim:ft=zsh |