comp.lang.ada
 help / color / mirror / Atom feed
* Cursor control question - ncurses and alternatives
@ 2006-10-13 16:32 Dr. Adrian Wrigley
  2006-10-13 18:16 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Dr. Adrian Wrigley @ 2006-10-13 16:32 UTC (permalink / raw)


Hi!

This should be a fairly simple Ada problem to solve...

I'm trying to build a small, text-based, real-time application,
to run in an xterm under Linux.

I want the user to be prompted to type in a command with a
prompt which shows the time, along with some other dynamic
information.

As the user types in a command, the prompt should continue
updating, until return is pressed.  Then the updating stops,
an action is performed, and the prompt appears on another line.

What Ada library is likely to be easiest to use for cursor
control?  I hear there is an ncurses binding, but this seems
to have hundreds of calls.

At the most basic level, I want to move the cursor to the start
of the line, update the prompt, and move the cursor back to
where it was.  How can I do this?

I have some test code, shown below, to illustrate the problem.
Currently, the cursor moves to the end of the prompt
spontaneously, when it should be at the end of the user's command.
I don't want to take over the xterm with a "full-screen" application,
I just want to enter a series of commands in a scrolling terminal.

Is this a job for ncurses?  What function is needed?
Or is there a better way?

Thanks for your suggestions!
--
Adrian


with Text_IO;
with Ada.Characters.Latin_1;

procedure TimDat is

   Count : Integer := 1000;
   function A return Integer is
   begin
      Count := Count + 1;
      return Count;
   end A;

   Message : String := "Hello";
   CR : constant Character := Ada.Characters.Latin_1.CR;

   task ShowClock;

   task body ShowClock is
   begin
      loop
         declare
            S : String := Integer'Image (A);
         begin
            Text_IO.Put (CR & S & " - " & Message & " > ");
         end;
         delay 1.0;
      end loop;
   end ShowClock;

begin

   loop
      declare
         Command : String := Text_IO.Get_Line (Text_IO.Standard_Input);
      begin
         Text_IO.Put_Line ("Command was """ & Command & """");
      end;
   end loop;

end TimDat;
----------------------------------------------------------------




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

* Re: Cursor control question - ncurses and alternatives
  2006-10-13 16:32 Cursor control question - ncurses and alternatives Dr. Adrian Wrigley
@ 2006-10-13 18:16 ` Dmitry A. Kazakov
  2006-10-13 21:13 ` Jeffrey R. Carter
  2006-10-13 22:41 ` Björn Persson
  2 siblings, 0 replies; 6+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-13 18:16 UTC (permalink / raw)


On Fri, 13 Oct 2006 16:32:30 GMT, Dr. Adrian Wrigley wrote:

> At the most basic level, I want to move the cursor to the start
> of the line, update the prompt, and move the cursor back to
> where it was.  How can I do this?
> 
> I have some test code, shown below, to illustrate the problem.
> Currently, the cursor moves to the end of the prompt
> spontaneously, when it should be at the end of the user's command.
> I don't want to take over the xterm with a "full-screen" application,
> I just want to enter a series of commands in a scrolling terminal.
> 
> Is this a job for ncurses?  What function is needed?
> Or is there a better way?

You could try the ANSI escape sequences instead of ncurses:

http://en.wikipedia.org/wiki/ANSI_escape_code

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Cursor control question - ncurses and alternatives
  2006-10-13 16:32 Cursor control question - ncurses and alternatives Dr. Adrian Wrigley
  2006-10-13 18:16 ` Dmitry A. Kazakov
@ 2006-10-13 21:13 ` Jeffrey R. Carter
  2006-10-13 22:41 ` Björn Persson
  2 siblings, 0 replies; 6+ messages in thread
From: Jeffrey R. Carter @ 2006-10-13 21:13 UTC (permalink / raw)


Dr. Adrian Wrigley wrote:
> 
> What Ada library is likely to be easiest to use for cursor
> control?  I hear there is an ncurses binding, but this seems
> to have hundreds of calls.

For an X-term, I'd also suggest ANSI escape sequences, accessed through 
PragmARC.ANSI_TTY_Control, part of the PragmAda Reusable Components.

http://pragmada.home.mchsi.com/

-- 
Jeff Carter
"If a sperm is wasted, God gets quite irate."
Monty Python's the Meaning of Life
56



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

* Re: Cursor control question - ncurses and alternatives
  2006-10-13 16:32 Cursor control question - ncurses and alternatives Dr. Adrian Wrigley
  2006-10-13 18:16 ` Dmitry A. Kazakov
  2006-10-13 21:13 ` Jeffrey R. Carter
@ 2006-10-13 22:41 ` Björn Persson
  2006-10-14  2:38   ` Dr. Adrian Wrigley
  2 siblings, 1 reply; 6+ messages in thread
From: Björn Persson @ 2006-10-13 22:41 UTC (permalink / raw)


Dr. Adrian Wrigley wrote:
> At the most basic level, I want to move the cursor to the start
> of the line, update the prompt, and move the cursor back to
> where it was.  How can I do this?

While there are escape sequences for querying, saving and restoring the 
cursor position, I think you'll get the best result if you know what's 
in the command buffer so that you can update the entire command line. 
That means you'll have to do the line editing yourself. It could look 
something like this:

with Text_IO;
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

procedure TimDat is

    Count : Integer := 1000;

    Message : String := "Hello";

    Buffer : Unbounded_String;

    procedure Update is
    begin
       Text_IO.Put (ESC & "[2K" & CR & Integer'Image (Count) & " - " &
                    Message & " > " & To_String(Buffer));
    end Update;

    task ShowClock;

    task body ShowClock is
    begin
       loop
          Count := Count + 1;
          Update;
          delay 1.0;
       end loop;
    end ShowClock;

    Keypress : Character;

begin

    loop
       Text_IO.Get_Immediate (Keypress);
       case Keypress is
          when DEL =>
             if Length (Buffer) > 0 then
                -- Delete the last character.
                Head (Buffer, Length (Buffer) - 1);
                Update;
             end if;
          when ESC =>
             -- Handle arrow keys and stuff.
             null;
          when LF | CR =>
             Text_IO.New_Line;
             Text_IO.Put_Line ("Command was """ & To_String(Buffer) &
                               """.");
             Head (Buffer, 0);  -- reset
             Update;
          -- and so on for other special characters
          when others =>
             Append (Buffer, Keypress);
             Update;
       end case;
    end loop;

end TimDat;

There are most likely race conditions in that code, but I'm sure you can 
fix that. You'll also need to decide what to do when the command line 
gets so long that it wraps. To know whether it wraps you need to find 
out how wide the window is.

For advanced line editing you may want to look at the Readline library � 
at least for inspiration.

-- 
Bj�rn Persson                              PGP key A88682FD
                    omb jor ers @sv ge.
                    r o.b n.p son eri nu



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

* Re: Cursor control question - ncurses and alternatives
  2006-10-13 22:41 ` Björn Persson
@ 2006-10-14  2:38   ` Dr. Adrian Wrigley
  2006-10-14 12:53     ` Dr. Adrian Wrigley
  0 siblings, 1 reply; 6+ messages in thread
From: Dr. Adrian Wrigley @ 2006-10-14  2:38 UTC (permalink / raw)


On Fri, 13 Oct 2006 22:41:52 +0000, Bj�rn Persson wrote:

> Dr. Adrian Wrigley wrote:
>> At the most basic level, I want to move the cursor to the start
>> of the line, update the prompt, and move the cursor back to
>> where it was.  How can I do this?
> 
> While there are escape sequences for querying, saving and restoring the 
> cursor position, I think you'll get the best result if you know what's 
> in the command buffer so that you can update the entire command line. 
> That means you'll have to do the line editing yourself. It could look 
> something like this:

<code snipped>
 
> There are most likely race conditions in that code, but I'm sure you can 
> fix that. You'll also need to decide what to do when the command line 
> gets so long that it wraps. To know whether it wraps you need to find 
> out how wide the window is.
> 
> For advanced line editing you may want to look at the Readline library
> at least for inspiration.

Thank you for the outline code.  I was beginning to see that the
Text_IO.Get_Line might not work very well with concurrent screen
updates because of race hazards.

Readline is a good idea - it provides just the facilities a user
would want in this application.  Perhaps I can find a way of
combining it with real-time data.  If it can't do a real-time
prompt out of the box, hacking the source code sounds possible.

Building the string in memory like in your example might not give the
best return on programmer time if an existing library can be a
basis for a solution instead.  I'll have another go tomorrow!
--
Adrian




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

* Re: Cursor control question - ncurses and alternatives
  2006-10-14  2:38   ` Dr. Adrian Wrigley
@ 2006-10-14 12:53     ` Dr. Adrian Wrigley
  0 siblings, 0 replies; 6+ messages in thread
From: Dr. Adrian Wrigley @ 2006-10-14 12:53 UTC (permalink / raw)


On Sat, 14 Oct 2006 02:38:22 +0000, Dr. Adrian Wrigley wrote:

> On Fri, 13 Oct 2006 22:41:52 +0000, Bj�rn Persson wrote:
> 
>> Dr. Adrian Wrigley wrote:
>>> At the most basic level, I want to move the cursor to the start
>>> of the line, update the prompt, and move the cursor back to
>>> where it was.  How can I do this?
>> 
>> While there are escape sequences for querying, saving and restoring the 
>> cursor position, I think you'll get the best result if you know what's 
>> in the command buffer so that you can update the entire command line. 
>> That means you'll have to do the line editing yourself. It could look 
>> something like this:
> 
> <code snipped>
>  
>> There are most likely race conditions in that code, but I'm sure you can 
>> fix that. You'll also need to decide what to do when the command line 
>> gets so long that it wraps. To know whether it wraps you need to find 
>> out how wide the window is.
>> 
>> For advanced line editing you may want to look at the Readline library
>> at least for inspiration.
> 
> Thank you for the outline code.  I was beginning to see that the
> Text_IO.Get_Line might not work very well with concurrent screen
> updates because of race hazards.
> 
> Readline is a good idea - it provides just the facilities a user
> would want in this application.  Perhaps I can find a way of
> combining it with real-time data.  If it can't do a real-time
> prompt out of the box, hacking the source code sounds possible.
> 
> Building the string in memory like in your example might not give the
> best return on programmer time if an existing library can be a
> basis for a solution instead.  I'll have another go tomorrow!

OK.  Readline is exactly what I want.  I'd forgotten how cool is!
Code below is in C, but will integrate nicely (Samuel Tartieu
shows elementary use of readline in ada with areadline).
--
Adrian


#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>

// plenty of buffer overflow bugs, memory leaks etc.

float d=10000.0;

char myprompt[100];

int increment (void) {
   sprintf (myprompt, "%5.3f -   > ", d);
   rl_set_prompt (myprompt);
   rl_redisplay();
   d += 0.001;
}

int main () {

  char *x;

  rl_event_hook = &increment;

  x = readline (NULL);

  printf ("You typed : %s\n", x);

}




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

end of thread, other threads:[~2006-10-14 12:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-10-13 16:32 Cursor control question - ncurses and alternatives Dr. Adrian Wrigley
2006-10-13 18:16 ` Dmitry A. Kazakov
2006-10-13 21:13 ` Jeffrey R. Carter
2006-10-13 22:41 ` Björn Persson
2006-10-14  2:38   ` Dr. Adrian Wrigley
2006-10-14 12:53     ` Dr. Adrian Wrigley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox