aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-08-19 20:37:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2023-08-19 20:37:31 -0700
commit1bc984704ce4452ff85e68cfa2223a932fa67f4f (patch)
tree28f359599ccf52b9009cfd5409a73e9a7b3dfb2e
parentc14034e97868b274dd14b4d7672deb32644d9f62 (diff)
downloadbasta-1bc984704ce4452ff85e68cfa2223a932fa67f4f.tar.gz
basta-1bc984704ce4452ff85e68cfa2223a932fa67f4f.tar.bz2
basta-1bc984704ce4452ff85e68cfa2223a932fa67f4f.zip
hack: do cursor check only if no input pending
I'm addressing the following problem. Sometimes the user types a new command while a previous command is still running. This typed-ahead input is buffered in the TTY. When we execute our check to query the terminal "is the cursor out of bounds?" there is a conflict between that buffered input and the query. An imperfect fix is to check for the presence of unread input and skip doing the cursor check. This means that if the user runs some program that puts the cursor out of bounds, and impatiently types ahead before that command has completed, the cursor will go out of bounds. - We break the basta.before_prompt function into two: basta.check_cursor and basta.do_exit_status. - In basta.check_cursor, we now temporarily put the TTY into raw mode, so that the file descriptor can be polled for the presence of any bytes whatsoever. If we don't do this, read -t 0 will only report true (input is present) if the user has typed Enter, due to canonical input processing.
-rw-r--r--basta.sh33
1 files changed, 24 insertions, 9 deletions
diff --git a/basta.sh b/basta.sh
index 1b52c07..1c8fe93 100644
--- a/basta.sh
+++ b/basta.sh
@@ -68,18 +68,30 @@ basta.update_status()
printf "${esc}7$esc[%s;1H$esc[K%s$esc[1;%sr${esc}8" $((LINES + 1)) "$status" $LINES
}
-basta.before_prompt()
+basta.check_cursor()
{
- local exit=$?
- local esc=$(printf "\033")
- local curln=$(basta.get_cur_line)
- local getcmdno='\#'
- local cmdno=${getcmdno@P}
+ local saved_tty=$(stty -g)
+ stty raw
- if [ $curln -gt $LINES ]; then
- printf "$esc[%s;1H" $LINES
+ if ! read -t 0; then
+ local exit=$?
+ local esc=$(printf "\033")
+ local curln=$(basta.get_cur_line)
+
+ if [ $curln -gt $LINES ]; then
+ printf "$esc[%s;1H" $LINES
+ fi
fi
+ stty "$saved_tty"
+}
+
+basta.do_exit_status()
+{
+ local exit=$1
+ local getcmdno='\#'
+ local cmdno=${getcmdno@P}
+
if [ $exit -ne 0 -a $cmdno -ne $basta_old_cmdno ] ; then
printf "!%s!\n" $exit
fi
@@ -87,9 +99,12 @@ basta.before_prompt()
basta_old_cmdno=$cmdno
}
+
basta.prompt_hook()
{
- basta.before_prompt
+ local exit=$?
+ basta.check_cursor
+ basta.do_exit_status $exit
basta.update_status
}