shellzshechotuitput

Inline Printing For Zsh Autosuggestions adding extra space when deleting


I am working to create a zsh script that gives auto completions and I am trying to do inline suggestions using tput and echoing the expected rest of the input. It works fine for when adding a character but when deleting there is an extra space where the character deleted was.

Here is an image of the issue. The top line is after adding a character, as you can see there is no extra space. When deleting the character the extra space appears.

enter image description here

I think what is happening is that after deleting a character that row and column can't immediately be printed to for some reason. Here is the minimum code to reproduce.

Here is the minimum code to reproduce:

function __keypress() {
  zle .$WIDGET
  __get_cur_pos
  tput cup $__fut_row $((__fut_col + 1))
  echo "works\033[K" 
  tput cup $__fut_row $__fut_col
}

function __delete() {
  # remove the last character from buffer
  BUFFER=${BUFFER%?}
  __get_cur_pos
  echo "fail\033[K" 
  tput cup $__fut_row $__fut_col
}

function __get_cur_pos(){
  echo -ne "\033[6n"
  read -t 1 -s -d 'R' line < /dev/tty
  line="${line##*\[}"
  __fut_row=$((${line%%;*}-1)) # extract the row number
  __fut_col=$((${line##*;}-1)) # extract the column number 
  unset line
}

zle -N self-insert __keypress 
zle -N __del __delete # change the action of delete key to deleting most recent and updating __current_input
bindkey "^?" __del

Put the code in a file and source it, at that point the script will print "works" when adding characters and "fail" when deleting. If anyone knows what is happening here or a possible fix please tell me. Thanks!


Solution

  • Here is code I eventually got that prints out in the correct area and customizes the styling that is to the right of BUFFER.

    #! /bin/zsh
    
    function __keypress() {
      zle .$WIDGET
      POSTDISPLAY="add"
      __apply_highlighting
    }
    
    function __delete() {
      # remove the last character from buffer
      # echo -n "fail\033[K"
      BUFFER=${BUFFER%?}
      POSTDISPLAY="del" 
      __apply_highlighting
    }
    
    zle -N self-insert __keypress 
    zle -N __del __delete # change the action of delete key to deleting most recent and updating __current_input
    bindkey "^?" __del  
    
    function __apply_highlighting() {
        if [ $#POSTDISPLAY -gt 0 ]; then
        region_highlight=("$#BUFFER $(($#BUFFER + $#POSTDISPLAY)) fg=4")
      fi
    }