# # Replicate expandtab from vim. # declare-option -docstring "Expand to spaces based on tabstop." bool expandtab yes # # Replicate softtabstop from vim. # declare-option -docstring "Make tabstop number of spaces feel like a when pressing or in insert mode." int softtabstop 4 # # Helper function for inserting a # def softtabstop-insert-tab -hidden %{ # evaluate-commands -no-hooks -draft -itersel %{ # try %sh{ # tabstop=$kak_opt_softtabstop # if [ $tabstop -lt 0 ]; then # tabstop=$kak_opt_indentwidth # fi # # Determine if this is an append operation (end column > start column). If so, prefix with ';' # prefix=$(echo $kak_selections_display_column_desc | awk -F '[.,]' '{if($4 > $2) {print ";"}}') # if [ $tabstop -eq 0 ]; then # # if tabstop is 0 that means we are just inserting tabs # printf "execute-keys '${prefix}i'\n" # # expand tabs to spaces if needed # [ $kak_opt_expandtab = "true" ] && printf "%s\n" 'execute-keys h@' # else # # compute the number of spaces needed to reach the next softtabstop # display_column=$((kak_cursor_display_column - 1)) # adjust for 1-based indexing # end_column=$((display_column % tabstop)) # space_count=$((tabstop - end_column)) # # insert enough spaces to reach the next softtabstop # printf "execute-keys '${prefix}i%${space_count}s'\n" # # if not expanding tabs, convert *all* preceding whitespace to a mix of spaces and # # tabs, not just the spaces that were inserted (this is how vim behaves) # [ $kak_opt_expandtab = "false" ] && printf "execute-keys '\h+H'" # fi # } # } # } # # Helper function for deleting whitespace a # def softtabstop-insert-backspace -hidden %{ # evaluate-commands -no-hooks -draft -itersel -save-regs ^ %{ # # save off the current selection in case the try block fails # try %sh{ # tabstop=$kak_opt_softtabstop # if [ $tabstop -lt 0 ]; then # tabstop=$kak_opt_indentwidth # fi # if [ $tabstop -gt 0 ]; then # # compute the end display column based on tabstop and the number of # # number spaces needed to reach it # display_column=$((kak_cursor_display_column - 1)) # adjust for 1-based indexing # num_spaces=$((display_column % tabstop)) # [ $num_spaces -eq 0 ] && num_spaces=$tabstop # end_display_column=$((display_column - num_spaces)) # # extract any preceding whitespace # echo "evaluate-commands -draft %{ # execute-keys '\h+H' # echo -to-file $kak_response_fifo %val{selection} # }" > $kak_command_fifo # whitespace="$(cat $kak_response_fifo)" # # count the number of mixed tabs and spaces needed to reach the end display column # tab=$(printf "\t") # num_whitespaces=0 # adjust_cursor=";" # while [ -z "$non_ws" ] \ # && [ -n "$whitespace" ] \ # && [ $display_column -gt $end_display_column ]; # do # # iterate over the whitespace right-to-left, early out after reaching the # # first non whitespace # prefix=${whitespace%?}; # ws="${whitespace#$prefix}"; # case "$ws" in # $tab) display_column=$((display_column - $kak_opt_tabstop)); # # the first whitespace encountered is a tab. when '@' is pressed, the # # cursor moves (or extends) one char to the right. account for this here # [ $num_whitespaces -eq 0 ] && adjust_cursor="${adjust_cursor}h";; # " ") display_column=$((display_column - 1));; # *) non_ws="true";; # esac # whitespace=$prefix; # if [ -z "$non_ws" ]; then # num_whitespaces=$((num_whitespaces + 1)); # fi # done # if [ $num_whitespaces -gt 0 ]; then # # * select the number of mixed tabs and spaces computed above # # * convert to spaces and adjust the cursor position # # * select the number of spaces to reach the end column and delete them # echo "execute-keys ';h\h{$((num_whitespaces - 1))}@${adjust_cursor} {,$((num_spaces - 1))}d'" # else # echo "fail" # fi # else # echo "fail" # fi # } catch %{ # # in normal mode, delete previous character # execute-keys 'hd' # } # } # } # # Use a hook to enable/disable key mappings such that '\' properly allows disabling specialized behavior # # hook global ModeChange 'push:.+:insert' %{ # # map buffer insert ':softtabstop-insert-tab' # # map buffer insert ':softtabstop-insert-backspace' # # } # # hook global ModeChange 'pop:insert:normal' %{ # # unmap buffer insert ':softtabstop-insert-tab' # # unmap buffer insert ':softtabstop-insert-backspace' # # }