Terminal in Unix/Linux OS, History of commands with cursor up/down

I’ve just ported Adventure Definition Language to Linux using WSL.

I’ve encountered a small problem with Terminal command history with ADLRun.

Instead of previous command some characters are displayed: ^[[A for cursor up.

I tried with TermCap and ANSI settings, without luck. I’m not quite sure what’s causing it. Windows and Amiga versions command-history work in Shell without problem.

P.S. If someone that works with Linux could test the ADLRun, I’ll be glad. Thanks.

I had also planned to make macOS version as well - on this basis. All this to spread the ADL games reachability.

1 Like

How are you reading a line of input?

Things like ^[[A are what Unix terminals (copying ye-olde hardware terminals) generate for special keys. So you need a library to handle that.

If you are controlling the whole screen, then the ncurses library is commonly used. If you just want to read a line of input, then readline is also commonly used. There are more light-weight equivalents to these libraries. e.g. my own one is called TweakLine.

1 Like

^[[A are the raw key codes for the up arrow key. It’s up to the running program to interpret them appropriately. Generally programs use a termcap or terminfo library, or something higher level like readline.

In the case of ADL, it looks like it’ll use termcap (or termlib, an even older library) as long as you compile it with TERMCAP set to 1 in include/adltypes.h. Per the porting file, you need to update the makefile to link in the appropriate library by adding -ltermcap or -ltermlib to the cc -o adlrun step.

2 Likes

The ADLRun is reading the line with gets() function.

I know there should be fgets(), but it makes no difference.

It turns out, that the curses, termcap and termlib are only used with the printing, not with the input.

So I checked:

  • I tried to use readline() function, but I have problem with copying the result string to other string buffer. Anyway, the cursor up/down keys don’t display anything in this case.
  • I checked the standard shell sh instead of bash and there’s no history at all and the ^[[A is displayed also outside ADLRun.

It’s strange, because history works in Windows CMD and AmigaShell without any problems with very same gets() function.

It might be WSL problem as well. Maybe under real Linux bash history works correctly.

Thank you for help so far. I’m still not sure how I could fix this, because I even couldn’t handle stdin cursor up/down keys.to manage history by myself.

readline() should help but it doesn’t work.

To get history with readline, you need to add the line to the history explicitly. For example:

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

//...

char * line = readline ("prompt> ");
if (line == NULL)
   handle EOF...
if (line[0] != 0)
   add_history (line);

Hope that helps.

3 Likes

Superb. Thank you very much. I missed the headers <readline/readline.h> which are essential for readline() to work. Otherwise I got segmentation fault errors during execution, because some restrict were not defined.

Now it works as expected. :slight_smile: Thanks also for the add_history().

So I just replace the gets() with readline() when there’s UNIX constant defined with #ifdef.

I probably need also to free() the memory allocated with readline().

Use rl_free() on it.

2 Likes