40 lines
944 B
Bash
40 lines
944 B
Bash
#!/usr/bin/env zsh
|
|
#
|
|
# Usage: -z4h-replace-buf START END REPLACEMENT
|
|
#
|
|
# Replaces BUFFER[START,END] with REPLACEMENT while keeping the cursor
|
|
# pointing to the same content as before.
|
|
|
|
emulate -L zsh
|
|
|
|
local -i start=$1 end=$2
|
|
local orig_word=$BUFFER[start,end] new_word=$3
|
|
|
|
local reply
|
|
if (( $#orig_word * $#new_word <= 10000 )); then
|
|
-z4h-string-diff "$orig_word" "$new_word"
|
|
else
|
|
reply=("$orig_word" "$new_word")
|
|
fi
|
|
|
|
local -i orig_cur='CURSOR - start + 1' cur new_cur
|
|
local src dst
|
|
for src dst in "${reply[@]}"; do
|
|
(( cur += $#src ))
|
|
if (( cur < orig_cur )); then
|
|
(( new_cur += $#dst - $#src ))
|
|
elif (( cur == orig_cur )); then
|
|
(( cur == $#orig_word )) && break
|
|
(( new_cur += $#dst - $#src ))
|
|
else
|
|
if (( orig_cur - (cur - $#src) > $#dst )); then
|
|
(( new_cur -= orig_cur - (cur - $#src) - $#dst ))
|
|
fi
|
|
break
|
|
fi
|
|
done
|
|
|
|
(( new_cur += CURSOR ))
|
|
BUFFER[start,end]=$new_word
|
|
(( CURSOR = new_cur ))
|
|
return 0
|