Discussion:
[Help-bash] Storing cursor positions using tput into an array.
Sinbad
2017-09-11 12:54:16 UTC
Permalink
Hi,

I want to extract the cursor positions using tput into an array and recover
to the stored cursor positions accordingly at later point in time. The
following function is able to extract the position
but i'm not able to figure out how to store each extraction in to an array.

save_pos () {
export $1
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
echo -en "\033[6n" > /dev/tty
IFS=';' read -r -d R -a pos
stty $oldstty
eval "$1[0]=$((${pos[0]:2} - 2))"
eval "$1[1]=$((${pos[1]} - 1))"}

save_pos pos works, But i want something like save_pos pos[$index];
but this is resulting into
an error. how to achieve this ?

Thanks
João Eiras
2017-09-11 13:20:14 UTC
Permalink
Post by Sinbad
eval "$1[0]=$((${pos[0]:2} - 2))"
eval "$1[1]=$((${pos[1]} - 1))"}
save_pos pos works, But i want something like save_pos pos[$index];
You're trying to create an array of arrays which is not supported in
bash. I'd change your function to store both coordinates as "x,y".
Sinbad
2017-09-12 05:40:49 UTC
Permalink
Post by João Eiras
I'd change your function to store both coordinates as "x,y".
you mean like in a dictionary. can you please give an example ?
Post by João Eiras
Post by Sinbad
eval "$1[0]=$((${pos[0]:2} - 2))"
eval "$1[1]=$((${pos[1]} - 1))"}
save_pos pos works, But i want something like save_pos pos[$index];
You're trying to create an array of arrays which is not supported in
bash. I'd change your function to store both coordinates as "x,y".
Greg Wooledge
2017-09-11 14:08:47 UTC
Permalink
Post by Sinbad
I want to extract the cursor positions using tput into an array and recover
to the stored cursor positions accordingly at later point in time.
Have you looked at terminfo(5) or your operating system's equivalent?

restore_cursor rc rc restore cursor to
position of last
save_cursor

save_cursor sc sc save current cursor
position (P)
Sinbad
2017-09-12 05:42:12 UTC
Permalink
Post by Greg Wooledge
Have you looked at terminfo(5) or your operating system's equivalent?
with, 'tput sc' and 'tput rc' I will be able to store only one cursor
position.
I want to be able to store multiple locations and return to those positions
accordingly.
Post by Greg Wooledge
Post by Sinbad
I want to extract the cursor positions using tput into an array and
recover
Post by Sinbad
to the stored cursor positions accordingly at later point in time.
Have you looked at terminfo(5) or your operating system's equivalent?
restore_cursor rc rc restore cursor to
position of last
save_cursor
save_cursor sc sc save current cursor
position (P)
Dennis Williamson
2017-09-12 21:53:47 UTC
Permalink
Post by Sinbad
Post by Greg Wooledge
Have you looked at terminfo(5) or your operating system's equivalent?
with, 'tput sc' and 'tput rc' I will be able to store only one cursor
position.
I want to be able to store multiple locations and return to those positions
accordingly.
Post by Greg Wooledge
Post by Sinbad
I want to extract the cursor positions using tput into an array and
recover
Post by Sinbad
to the stored cursor positions accordingly at later point in time.
Have you looked at terminfo(5) or your operating system's equivalent?
restore_cursor rc rc restore cursor
to
Post by Greg Wooledge
position of
last
Post by Greg Wooledge
save_cursor
save_cursor sc sc save current cursor
position (P)
http://mywiki.wooledge.org/BashFAQ/006#Assigning_indirect.2Freference_variables
--
Visit serverfault.com to get your system administration questions answered.
Greg Wooledge
2017-09-13 12:40:58 UTC
Permalink
Post by Dennis Williamson
Post by Sinbad
with, 'tput sc' and 'tput rc' I will be able to store only one cursor
position.
I want to be able to store multiple locations and return to those positions
accordingly.
http://mywiki.wooledge.org/BashFAQ/006#Assigning_indirect.2Freference_variables
I don't see the need for that. If he wants to store 10 cursor positions,
indexed by integers, then he only needs two arrays: x and y.

tput cup "${y[i]}" "${x[i]}"

Or call them "row" and "col" if you prefer.

The real voodoo is how to GET the cursor position into the coordinate
arrays in the first place. Starting from

https://unix.stackexchange.com/questions/88296/get-vertical-cursor-position/183121#183121

I ended up with:

wooledg:~$ IFS=$'\e[;' read -sdR -p $'\e[6n' _ _ 'y[1]' 'x[1]'
wooledg:~$ declare -p x y
declare -a x=([1]="1")
declare -a y=([1]="45")

Not tested on anything but my own system in one terminal emulator.
Use at your own risk, etc.
Bob Proulx
2017-09-14 18:26:35 UTC
Permalink
Post by Greg Wooledge
The real voodoo is how to GET the cursor position into the coordinate
arrays in the first place. Starting from
https://unix.stackexchange.com/questions/88296/get-vertical-cursor-position/183121#183121
wooledg:~$ IFS=$'\e[;' read -sdR -p $'\e[6n' _ _ 'y[1]' 'x[1]'
wooledg:~$ declare -p x y
declare -a x=([1]="1")
declare -a y=([1]="45")
Not tested on anything but my own system in one terminal emulator.
Use at your own risk, etc.
Yes. Getting the cursor position seems to be voodoo. Unfortunately
using \e escape hard codes for one terminal type. The above is the
popular one today but it won't work for other types such as say
hpterm. (I didn't test hpterm but I assume not.) But I haven't found
a better way to ge tthis info either.

I think the original plan was that if some application wanted to
position the cursor then that application must position and track the
position itself completely. Like the way the curses library does it.
Then it will know where the cursor is later because it placed the
cursor there, obviating the need to ask the terminal where the cursor
happens to be at the moment.

Bob
Dennis Williamson
2017-09-14 20:46:50 UTC
Permalink
Post by Greg Wooledge
Post by Greg Wooledge
The real voodoo is how to GET the cursor position into the coordinate
arrays in the first place. Starting from
https://unix.stackexchange.com/questions/88296/get-
vertical-cursor-position/183121#183121
Post by Greg Wooledge
wooledg:~$ IFS=$'\e[;' read -sdR -p $'\e[6n' _ _ 'y[1]' 'x[1]'
wooledg:~$ declare -p x y
declare -a x=([1]="1")
declare -a y=([1]="45")
Not tested on anything but my own system in one terminal emulator.
Use at your own risk, etc.
Yes. Getting the cursor position seems to be voodoo. Unfortunately
using \e escape hard codes for one terminal type. The above is the
popular one today but it won't work for other types such as say
hpterm. (I didn't test hpterm but I assume not.) But I haven't found
a better way to ge tthis info either.
I think the original plan was that if some application wanted to
position the cursor then that application must position and track the
position itself completely. Like the way the curses library does it.
Then it will know where the cursor is later because it placed the
cursor there, obviating the need to ask the terminal where the cursor
happens to be at the moment.
Bob
One issue might be knowing where the cursor is after output which uses
${***@E} or ${***@P} (and possibly others) unless you know of a way to do
that.
--
Visit serverfault.com to get your system administration questions answered.
Dennis Williamson
2017-09-14 20:34:48 UTC
Permalink
Post by Dennis Williamson
http://mywiki.wooledge.org/BashFAQ/006#Assigning_indirect.
2Freference_variables

I don't see the need for that. If he wants to store 10 cursor positions,
indexed by integers, then he only needs two arrays: x and y.

tput cup "${y[i]}" "${x[i]}"

Or call them "row" and "col" if you prefer.



I agree but it's part of what the OP asked for.
Greg Wooledge
2017-09-14 20:44:05 UTC
Permalink
Post by Dennis Williamson
I agree but it's part of what the OP asked for.
The trick is to look past the exact wording of the first question and
figure out what the actual underlying goal is. Often this doesn't become
clear until the second or third iteration.

Bash *cannot* store an array of n-tuples (n-element lists), so a single
array of (X,Y) coordinate pairs simply doesn't make sense in bash.
But once you know that you just want to store a bunch of (X,Y) coords,
you can use something bash *can* do, like two separate arrays that
share a common set of indices.
Dan Douglas
2017-09-15 08:16:29 UTC
Permalink
On 09/14/2017 03:44 PM, Greg Wooledge wrote> Bash *cannot* store an array of n-tuples (n-element lists), so a single
Post by Greg Wooledge
array of (X,Y) coordinate pairs simply doesn't make sense in bash.
But once you know that you just want to store a bunch of (X,Y) coords,
you can use something bash *can* do, like two separate arrays that
share a common set of indices.
I'd probably use one array of n-tuples in this situation. Its
particularly useful in loops. You just refer to an offset + n args on
each iteration. Two arrays works fine too, of course.

Loading...