zsh-users
 help / color / mirror / code / Atom feed
* cursor position in a variable
@ 2015-09-05 18:36 david sowerby
  2015-09-05 19:05 ` Mikael Magnusson
  0 siblings, 1 reply; 4+ messages in thread
From: david sowerby @ 2015-09-05 18:36 UTC (permalink / raw)
  To: zsh-users

I can get the cursor position by doing:
print "\e[6n"
this gives me the row and column. Though oddly the output appears after the next prompt, not on its own line. This
may (or nor) be why when I do:
pos=$(print "\e[6n")
print $pos
I get an empty line - and the output after the next prompt.
I want to use the row the cursor is on in a script -- so how do I get that into a variable? If not this way is there a way using ZLE?
thanks for any help   --------------dave
====================================================
Never trust a person who can clear their conscience of any immoral
act by asking forgiveness from their imaginary friend.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: cursor position in a variable
  2015-09-05 18:36 cursor position in a variable david sowerby
@ 2015-09-05 19:05 ` Mikael Magnusson
  2015-09-06 10:50   ` ZyX
  0 siblings, 1 reply; 4+ messages in thread
From: Mikael Magnusson @ 2015-09-05 19:05 UTC (permalink / raw)
  To: david sowerby; +Cc: Zsh Users

On Sat, Sep 5, 2015 at 8:36 PM, david sowerby <d_sowerby@yahoo.com> wrote:
> I can get the cursor position by doing:
> print "\e[6n"
> this gives me the row and column. Though oddly the output appears after the next prompt, not on its own line. This
> may (or nor) be why when I do:
> pos=$(print "\e[6n")
> print $pos
> I get an empty line - and the output after the next prompt.
> I want to use the row the cursor is on in a script -- so how do I get that into a variable? If not this way is there a way using ZLE?
> thanks for any help   --------------dave

When you print a terminal control sequence, the terminal writes the
reply on standard input, so you need something like

print -n '\e[6n'
read pos

The problem here is that the terminal doesn't print a newline, so this
will hang until you press enter. You can dance around with a loop
reading one character at a time and checking if there is more pending
input, but I'm not 100% sure what the best way to handle this is. If
'read' had an option "read all pending input", it would be easy, but
it does not. :)

print -n '\e[6n'
pos=
while IFS= read -rs -t 0.1 -k1; do pos+=$REPLY; done
echo ${(V)pos}

this "works", but the 0.1 feels hacky. With 0, the whole loop might
abort before the terminal has time to write any characters back.

print -n '\e[6n'
until IFS= read -rs -k1 pos; do done
while IFS= read -rs -t 0 -k1; do pos+=$REPLY; done
echo ${(V)pos}

this variant will spin until it gets one character back, then read the
rest of the pending characters. You may also want to abort that loop
when you get the "R" back.
...; do pos+=$REPLY; [[ $REPLY == R ]] && break; done

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: cursor position in a variable
  2015-09-05 19:05 ` Mikael Magnusson
@ 2015-09-06 10:50   ` ZyX
  2015-09-06 11:54     ` Mikael Magnusson
  0 siblings, 1 reply; 4+ messages in thread
From: ZyX @ 2015-09-06 10:50 UTC (permalink / raw)
  To: Mikael Magnusson, david sowerby; +Cc: Zsh Users



05.09.2015, 22:07, "Mikael Magnusson" <mikachu@gmail.com>:
> On Sat, Sep 5, 2015 at 8:36 PM, david sowerby <d_sowerby@yahoo.com> wrote:
>>  I can get the cursor position by doing:
>>  print "\e[6n"
>>  this gives me the row and column. Though oddly the output appears after the next prompt, not on its own line. This
>>  may (or nor) be why when I do:
>>  pos=$(print "\e[6n")
>>  print $pos
>>  I get an empty line - and the output after the next prompt.
>>  I want to use the row the cursor is on in a script -- so how do I get that into a variable? If not this way is there a way using ZLE?
>>  thanks for any help --------------dave
>
> When you print a terminal control sequence, the terminal writes the
> reply on standard input, so you need something like
>
> print -n '\e[6n'
> read pos
>
> The problem here is that the terminal doesn't print a newline, so this
> will hang until you press enter. You can dance around with a loop
> reading one character at a time and checking if there is more pending
> input, but I'm not 100% sure what the best way to handle this is. If
> 'read' had an option "read all pending input", it would be easy, but
> it does not. :)
>
> print -n '\e[6n'
> pos=
> while IFS= read -rs -t 0.1 -k1; do pos+=$REPLY; done
> echo ${(V)pos}
>
> this "works", but the 0.1 feels hacky. With 0, the whole loop might
> abort before the terminal has time to write any characters back.
>
> print -n '\e[6n'
> until IFS= read -rs -k1 pos; do done
> while IFS= read -rs -t 0 -k1; do pos+=$REPLY; done
> echo ${(V)pos}
>
> this variant will spin until it gets one character back, then read the
> rest of the pending characters. You may also want to abort that loop
> when you get the "R" back.
> ...; do pos+=$REPLY; [[ $REPLY == R ]] && break; done
>
> --
> Mikael Magnusson

What’s the point of using IFS with read -k? If you know that terminal does print something the following works fine:

    print -n $'\e[6n' ; pos= ; while read -rs -k1 ; do pos+=$REPLY ; [[ $REPLY == R ]] && break ; done

. Timeout I removed will be needed if you don’t know that terminal will output anything though.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: cursor position in a variable
  2015-09-06 10:50   ` ZyX
@ 2015-09-06 11:54     ` Mikael Magnusson
  0 siblings, 0 replies; 4+ messages in thread
From: Mikael Magnusson @ 2015-09-06 11:54 UTC (permalink / raw)
  To: ZyX; +Cc: david sowerby, Zsh Users

On Sun, Sep 6, 2015 at 12:50 PM, ZyX <kp-pav@yandex.ru> wrote:
>
>
> 05.09.2015, 22:07, "Mikael Magnusson" <mikachu@gmail.com>:
>> On Sat, Sep 5, 2015 at 8:36 PM, david sowerby <d_sowerby@yahoo.com> wrote:
>>>  I can get the cursor position by doing:
>>>  print "\e[6n"
>>>  this gives me the row and column. Though oddly the output appears after the next prompt, not on its own line. This
>>>  may (or nor) be why when I do:
>>>  pos=$(print "\e[6n")
>>>  print $pos
>>>  I get an empty line - and the output after the next prompt.
>>>  I want to use the row the cursor is on in a script -- so how do I get that into a variable? If not this way is there a way using ZLE?
>>>  thanks for any help --------------dave
>>
>> When you print a terminal control sequence, the terminal writes the
>> reply on standard input, so you need something like
>>
>> print -n '\e[6n'
>> read pos
>>
>> The problem here is that the terminal doesn't print a newline, so this
>> will hang until you press enter. You can dance around with a loop
>> reading one character at a time and checking if there is more pending
>> input, but I'm not 100% sure what the best way to handle this is. If
>> 'read' had an option "read all pending input", it would be easy, but
>> it does not. :)
>>[snip kinda dumb code]
>
> What’s the point of using IFS with read -k? If you know that terminal does print something the following works fine:
>
>     print -n $'\e[6n' ; pos= ; while read -rs -k1 ; do pos+=$REPLY ; [[ $REPLY == R ]] && break ; done
>
> . Timeout I removed will be needed if you don’t know that terminal will output anything though.

You're right, I coded in a bit of a circle there. I had the timeout in
case the terminal didn't print anything, but then added the loop to
wait until it did, so uh, not sure what I intended with that :).

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-09-06 11:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-05 18:36 cursor position in a variable david sowerby
2015-09-05 19:05 ` Mikael Magnusson
2015-09-06 10:50   ` ZyX
2015-09-06 11:54     ` Mikael Magnusson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).