added an example script for keymaps based on the nvim-surround plugin
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
_get_surround_target() {
|
_get_surround_target() {
|
||||||
|
# get the delimiters to surround our selection with
|
||||||
read_key -v _s_ch
|
read_key -v _s_ch
|
||||||
case "$_s_ch" in
|
case "$_s_ch" in
|
||||||
\(|\)) _sl='('; _sr=')' ;;
|
\(|\)) _sl='('; _sr=')' ;;
|
||||||
@@ -10,6 +11,8 @@ _get_surround_target() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
_read_obj() {
|
_read_obj() {
|
||||||
|
# use the 'read_key' builtin to have our keymap function take user input
|
||||||
|
# keep reading keys until we have something that looks like a text object
|
||||||
_obj=""
|
_obj=""
|
||||||
while read_key -v key; do
|
while read_key -v key; do
|
||||||
if [[ "${#_obj}" -ge 3 ]]; then return 1; fi
|
if [[ "${#_obj}" -ge 3 ]]; then return 1; fi
|
||||||
@@ -42,6 +45,7 @@ _read_obj() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
_scan_left() {
|
_scan_left() {
|
||||||
|
# search to the left for a pattern in a string
|
||||||
local needle="$1"
|
local needle="$1"
|
||||||
local haystack="$2"
|
local haystack="$2"
|
||||||
local i=$((${#haystack} - 1))
|
local i=$((${#haystack} - 1))
|
||||||
@@ -60,6 +64,7 @@ _scan_left() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
_scan_right() {
|
_scan_right() {
|
||||||
|
# search to the right for a pattern in a string
|
||||||
local needle="$1"
|
local needle="$1"
|
||||||
local haystack="$2"
|
local haystack="$2"
|
||||||
local i=0
|
local i=0
|
||||||
@@ -78,13 +83,21 @@ _scan_right() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
_surround_1() {
|
_surround_1() {
|
||||||
|
# here we get our text object and our delimiters
|
||||||
local _obj
|
local _obj
|
||||||
_read_obj
|
_read_obj
|
||||||
_get_surround_target
|
_get_surround_target
|
||||||
|
|
||||||
|
# the $_KEYS variable can be used to send a sequence of keys
|
||||||
|
# back to the editor. here, we prefix the text object with 'v'
|
||||||
|
# to make the line editor enter visual mode and select the text object.
|
||||||
_KEYS="v$_obj"
|
_KEYS="v$_obj"
|
||||||
|
|
||||||
}
|
}
|
||||||
_surround_2() {
|
_surround_2() {
|
||||||
|
# this is called after _surround_1. the editor received our visual
|
||||||
|
# selection command, so now we can operate on the range it has selected.
|
||||||
|
# $_ANCHOR and $_CURSOR can be used to find both sides of the selection
|
||||||
local start
|
local start
|
||||||
local end
|
local end
|
||||||
if [ "$_ANCHOR" -lt "$_CURSOR" ]; then
|
if [ "$_ANCHOR" -lt "$_CURSOR" ]; then
|
||||||
@@ -98,43 +111,68 @@ _surround_2() {
|
|||||||
|
|
||||||
delta=$((end - start))
|
delta=$((end - start))
|
||||||
|
|
||||||
|
# use parameter expansion to slice up the buffer into 3 parts
|
||||||
left="${_BUFFER:0:$start}"
|
left="${_BUFFER:0:$start}"
|
||||||
mid="${_BUFFER:$start:$delta}"
|
mid="${_BUFFER:$start:$delta}"
|
||||||
right="${_BUFFER:$end}"
|
right="${_BUFFER:$end}"
|
||||||
|
|
||||||
|
# slide our delimiters inbetween those parts
|
||||||
_BUFFER="$left$_sl$mid$_sr$right"
|
_BUFFER="$left$_sl$mid$_sr$right"
|
||||||
_CURSOR=$start
|
_CURSOR=$start
|
||||||
|
|
||||||
}
|
}
|
||||||
_surround_del() {
|
_surround_del() {
|
||||||
|
# this one is pretty weird
|
||||||
|
|
||||||
|
# get our delimiters
|
||||||
_get_surround_target
|
_get_surround_target
|
||||||
|
|
||||||
|
# slice the buffer in half at the cursor
|
||||||
local left_buf="${_BUFFER:0:$_CURSOR}"
|
local left_buf="${_BUFFER:0:$_CURSOR}"
|
||||||
local right_buf="${_BUFFER:$left}"
|
local right_buf="${_BUFFER:$left}"
|
||||||
local left=""
|
local left=""
|
||||||
local right=""
|
local right=""
|
||||||
|
|
||||||
|
# scan left to see if we find our left delimiter
|
||||||
_scan_left $_sl "$left_buf"
|
_scan_left $_sl "$left_buf"
|
||||||
|
|
||||||
if [ "$?" -ne 0 ]; then
|
if [ "$?" -ne 0 ]; then
|
||||||
|
# we didnt find $_sl to the left of the cursor
|
||||||
|
# so let's look for it to the right of the cursor
|
||||||
_scan_right $_sl "$right_buf"
|
_scan_right $_sl "$right_buf"
|
||||||
|
|
||||||
[ "$?" -ne 0 ] && return 1
|
[ "$?" -ne 0 ] && return 1 # did not find it
|
||||||
|
|
||||||
|
# we found the left delimiter to the right of the cursor.
|
||||||
|
# _scan_right set the value of $right so lets take that and put it in $left
|
||||||
left=$right
|
left=$right
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# this is the start of the middle part of the buffer
|
||||||
mid_start=$((left + 1))
|
mid_start=$((left + 1))
|
||||||
right=""
|
right=""
|
||||||
left_buf="${_BUFFER:0:$left}"
|
left_buf="${_BUFFER:0:$left}"
|
||||||
right_buf="${_BUFFER:$mid_start}"
|
right_buf="${_BUFFER:$mid_start}" # from mid_start to end of buffer
|
||||||
_scan_right $_sr "$right_buf"
|
_scan_right $_sr "$right_buf" # scan right
|
||||||
|
|
||||||
[ "$?" -ne 0 ] && return 1
|
[ "$?" -ne 0 ] && return 1
|
||||||
|
|
||||||
mid_end=$((mid_start + right))
|
# right now contains the distance we traveled to hit our right delimiter
|
||||||
right_start=$((mid_end + 1))
|
mid_end=$((mid_start + right)) # use that to calculate the end of the middle
|
||||||
|
right_start=$((mid_end + 1)) # and get the start of the last part
|
||||||
|
|
||||||
|
# and now we just slice it like we did in _surround_2
|
||||||
new_left_buf="${_BUFFER:0:$left}"
|
new_left_buf="${_BUFFER:0:$left}"
|
||||||
new_mid_buf="${_BUFFER:$mid_start:$right}"
|
new_mid_buf="${_BUFFER:$mid_start:$right}"
|
||||||
new_right_buf="${_BUFFER:$right_start}"
|
new_right_buf="${_BUFFER:$right_start}"
|
||||||
|
|
||||||
|
# put them back together. the end result is a buffer without those pesky delimiters
|
||||||
_BUFFER="$new_left_buf$new_mid_buf$new_right_buf"
|
_BUFFER="$new_left_buf$new_mid_buf$new_right_buf"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# map our functions to some keys
|
||||||
|
# our savvy readers will notice that these are the same
|
||||||
|
# default keybinds set by kylechui's 'nvim-surround' plugin
|
||||||
|
keymap -n 'ds' '<CMD>!_surround_del<CR>'
|
||||||
|
keymap -n 'ys' '<CMD>!_surround_1<CR><CMD>!_surround_2<CR>' # chain these two together
|
||||||
|
|||||||
Reference in New Issue
Block a user