Control cursor position also at bottom of window


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Control cursor position also at bottom of window
# 1  
Old 02-03-2020
Control cursor position also at bottom of window

I have a slight problem controlling the cursor position in a Bash terminal window. I have a function ask a question and then wait for an answer which is either 'y' or 'n' or a carriage return. Whenever the user enters anything else it just erases the answer and waits for the next one. However, the script behaves differently when the cursor is on the bottom line of a window as compared to any other line.
Code:
#!/bin/bash

# -----
# function: askYesOrNo
# purpose : ask question passed as $1
# return  : 0 if answer was y or Y, 
#           1 otherwise
# -----
function askYesOrNo {
        printf "\e[1;31;47m$1 [Y|n]\e[0m "      # print $1 in color
        printf "\e[s"                           # save cursor x-pos

        while true ; do
                read answer
                if [ -z "$answer" ] ; then
                        return 0
                elif [ "$(tr -d "NnYy" <<< $answer)" != "$answer" ] ; then
                        break
                fi
                # restore cursor x-pos, erase rest of line
#               printf "\e[u\e[K"     
                # restore cursor x-pos, erase rest of line
                printf "\e[u\e[1A\e[K"      
        done
        if [ "${answer^}" == "Y" ]; then
                return 0
        fi
        return 1
}


for (( i = 100, max = 110; i <= max; i++ )) ; do
        printf " %d\n" $i
        if [ $i -eq $max ] ; then
                if askYesOrNo "Do you wish to continue?" ; then
                        (( max += 10 ))
                fi
        fi
done

The for-loop is the 'productive' part. It just puts out numbers in a column. Every 10 numbers it asks if the user wants to continue and uses the function askYesOrNo for that purpose.

The problem lies with the two lines in the function askYesOrNo (at the end of the while-loop) and when the user enters an answer that is not Y, y, N, n or Enter. The first line (now commented out) works fine when the cursor is not in the bottom line of the window. But if it is then the window scrolls up and the next answer appears in the next line.

The second version moves the cursor one line up and that's fine with the cursor at the bottom of the window but not if the question is asked elsewhere.

How can I get this to work in every situation?
# 2  
Old 02-03-2020
Hi Ralph...

Some terminals don't always follow terminal escape codes to the _letter_.
You could try and force the line prompt, force the cursor to the correct position and force clearing after the line prompt.
An example of the cursor forcing, it is just as easy to manipulate this to write the prompt and clear the line
Code:
printf "\033[12;36fSome prompt: \n"

# 3  
Old 02-03-2020
But how do I know the correct position? It keeps changing as the script proceeds.
# 4  
Old 02-03-2020
Would a (man console_codes)
Code:
ESC M     RI       Reverse linefeed.

help?
# 5  
Old 02-03-2020
An example clearing the screen/window:
Code:
while true
do
        printf "\033[2J\033[H\033[12;30fSome prompt: "
        read -r text
done

EDIT:

You can omit the \033[H if you wish but some terminals will not clear correctly without it...

Last edited by wisecracker; 02-03-2020 at 07:01 PM.. Reason: see EDIT:
# 6  
Old 02-03-2020
Quote:
Originally Posted by RudiC
Would a (man console_codes)
Code:
ESC M     RI       Reverse linefeed.

help?
Cool manual page but no... the page still scrolled up and I ended up in the next line, rather than restarting in the same line.

I think I have to check whether the cursor is in the last line of the window or not and do the reverse line feed only in that case. Together with an answer that I found elsewhere on this forum I came up with this version of the function which apparently works now:

Code:
function askYesOrNo {
        printf "\e[1;31;47m$1 [Y|n]\e[0m "      # print $1 in color
        printf "\e[s"                           # save cursor x-pos
    
        while true ; do
                read answer
                if [ -z "$answer" ] ; then
                        return 0
                elif [ "$(tr -d "NnYy" <<< $answer)" != "$answer" ] ; then
                        break
                fi

                # How many lines in this window?
                LINES=$(tput lines)

                # find cursor y-position ( line number )
                printf "\e[6n" ; read -sd R POS 
                CURPOS=${POS#*[}; CUR_Y=${CURPOS%;*}
 
                if [ "$CUR_Y" -eq "$LINES" ] ; then
#                       printf "\e[u\e[1A\e[K" 
                        printf "\e[u\eM\e[K"
                else
                        printf "\e[u\e[K" 
                fi                          
        done
        if [ "${answer^}" == "Y" ]; then 
                return 0
        fi  
        return 1
}

# 7  
Old 02-03-2020
Same idea here, but also using CSI sequence



Code:
      r   DECSTBM   Set scrolling region; parameters are top and bottom row.



to reduce that region to last line. Not yet the ultimate answer, but worth a try, mayhap.



Code:
function askYesOrNo     { read -sdR -p $'\e[6n' TMP
                          TMP="${TMP#??}"
                          [ "${TMP%;*}" -eq "$LINES" ] && printf "\e7\e[$LINES;120r\e8"
                          while true 
                            do  read -p$'\e[1;31;47m'"$1 [Y|n]"$'\e[0m \e[s' answer
                                answer=${answer:-Y}
                                answer=${answer^^}
                                [ "${answer//[YN]}" = "${answer}" ] || break 
                            done
                          printf "\e7\e[1;${LINES}r\e8"
                          [ "$answer" = "Y" ] && return 0
                          return 1
                        }

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Holding cursor position on one line

Hi there. It's easier to explain this with a pseudo code, I hope this makes sense: var1=hello echo $var1 some kind of loop echo loop counter done How do I hold the cursor position immediately behind the last output so I'd get something like: hello123456789 DOS used to use ","... (5 Replies)
Discussion started by: MuntyScrunt
5 Replies

2. Shell Programming and Scripting

Getting the cursor position

I need to get the cursor position, and put it inside a variable. Problem is, i don't have the tput command, or ncurses. Apparently I was supposed to try the following: echo -e '\E But I don't get a value or anything. Please help. (3 Replies)
Discussion started by: tinman47
3 Replies

3. Shell Programming and Scripting

ksh - moving cursor position

hi all, am trying to modify a ksh script to group server names together depending on the cluster they sit in. currently the script does a find . -name '*.pid' to find all running servers and prints out their pids and names. current output looks something like this : serverA ... (1 Reply)
Discussion started by: cesarNZ
1 Replies

4. UNIX for Dummies Questions & Answers

Cursor position

Is there a way of finding the current cursor position (line & column) within AIX (4 Replies)
Discussion started by: gefa
4 Replies

5. UNIX and Linux Applications

read position mouse cursor

Hi to all! I'm a teacher of maths and physics in an italian high school in Milan, Italy. I need a simple program that read the position of mouse cursor in function of time and write the coordinates in a text file. The time resolution have to be something like 1/10 sec or better (I have to know... (2 Replies)
Discussion started by: chris75
2 Replies

6. Shell Programming and Scripting

Changing cursor position using shell script

Hi, Pleae help me on this. Normally, when we say read username, the cursor will come in the first position of next line, but I want the output of the below Normal usage ------------- please enter username: _ I want like the below ---------------------- please enter username: ... (2 Replies)
Discussion started by: balamv
2 Replies

7. Programming

get terminal width and cursor position

I want to get the screen width and cursor positions. When I used curses, all the screen content was cleared. So Can I use curses to get the screen size without clearing anything in the window? Or is there any other alternative??? I can use only C or C++. (0 Replies)
Discussion started by: Sreejesh.S
0 Replies

8. HP-UX

Command to know the terminal cursor position

Dear all, How can i get the current cursor position..is thr any command to find the same? Thanks in Advance Aneesh (3 Replies)
Discussion started by: aneesha
3 Replies

9. Programming

Cursor Global Position

Hello all, How can i get the global position of the cursor? (i'm using c language, and suse 10.1 linux) Thanks. (3 Replies)
Discussion started by: boogy
3 Replies

10. Shell Programming and Scripting

Get the cursor position

Hello, Is there a way to get the current cursor position? I know "tput sc" saves it. Is there a way to find out the value saved? Thanks. (0 Replies)
Discussion started by: bestbuyernc
0 Replies
Login or Register to Ask a Question