[GTALUG] Finding current cursor position in the terminal

Giles Orr gilesorr at gmail.com
Wed Feb 19 08:38:45 EST 2020


On Tue, 18 Feb 2020 at 12:41, Lennart Sorensen via talk <talk at gtalug.org> wrote:
>
> On Mon, Feb 10, 2020 at 02:54:43PM -0500, Giles Orr via talk wrote:
> > I'd like to be able to get the current x,y (or row, column) position
> > of the cursor in a terminal.  This is for a Bash or ZSH prompt, and my
> > intention is to calculate how far across the terminal we've printed
> > and then decide if we should wrap the prompt from one to two lines.
> >
> > There's a terminal escape sequence to do this:
> >
> >     echo -e '\033[6n'
> >
> > or:
> >
> >     tput u7
> >
> > These output the desired information in some form of extremely
> > difficult-to-parse code (works on Mac or any Linux, I think).  The
> > output looks like this:
> >
> >     ^[[24;1R
> >
> > The numbers are line and column respectively.
> >
> > If you search the web, you can find various code (usually using the
> > builtin 'read' command) to parse this.  And some of the answers work
> > fine ... in this context, ie. running it as a stand-alone command.
> > But wrap it in a prompt and things go straight to hell.
> >
> >     export PS1="--\$(echo -en '\e[6n')-- "
> >
> > You'll find that some of the output appears after the prompt, as part
> > of the input line.  Any attempt to 'read' and parse the value within
> > the prompt hangs or returns empty, or does something else weird.  My
> > guess (uneducated and wild as it is) is that the escape sequence
> > doesn't complete until AFTER the prompt is displayed.  Because it's
> > waiting for some magical code the prompt provides?  I have no clue.
> > One or two of the pieces of code I've found do parse the result and
> > return properly ... but then they always return "1" for the column ...
> > (they usually get the row right).  And I'm primarily looking for the
> > column.
> >
> > I've spent a lot of time searching for a solution, and trying all
> > kinds of weird Bash coding tricks, with no particular luck.  Does
> > anyone have any idea how this might be handled?
> >
> > This is just one of many, many half-complete examples I've tracked
> > down.  The questioner eventually provided his own answer:
> >
> > https://stackoverflow.com/questions/43911175/get-current-cursor-position-while-drawing-zsh-prompt
> >
> > but what I found was that it always returns 1 for the column ...  The
> > author didn't care because they were only interested in the line
> > number.
> >
> > Any help appreciated.
>
> What would you like the prompt to look like?  Could you give an example?
>
> Since the command expansion of your echo command happens before PS1 is
> evaluated and printed, there is no way to do it by that method.  You would
> need to figure out the length of PS1 before it is printed and make the
> decision based on that.

And ... I think you just nailed my misunderstanding.  In my head, I
was thinking of the part of PS1 before the escape sequence as already
being printed ... except it isn't.  So yes, I'll always get the right
ROW and COLUMN=1 if I embed in an existing PS1.

Yeah, I've done the math calculations to figure out how big a prompt
will be.  This escape sequence seemed like a better way to do it.
I'll take a look at using the PROMPT_COMMAND in Bash (or precmd() in
ZSH) to print something before the prompt (the directory name, which
can vary significantly in length if you don't apply some form of
truncation), then run the escape sequence.  I'll see if that will
work.

Thanks!


--
Giles
https://www.gilesorr.com/
gilesorr at gmail.com


More information about the talk mailing list