hanslub42 / rlwrap

A readline wrapper
GNU General Public License v2.0
2.59k stars 151 forks source link

rlwrap with minetest ncurses terminal #124

Closed vapniks closed 3 years ago

vapniks commented 3 years ago

It would be really convenient to have rlwrap working with the minetest terminal, since there are many commands, and no builtin completion. I tried the following:

rlwrap -a -i minetest --server --worldname XXX --terminal --name XXX --password XXX

Unfortunately minetest uses ncurses, and continually updates the time at the top of the screen. So although I am able to use rlwrap's line editing features, the cursor flicks between different positions on the screen taking the input text with it, which is really annoying. I notice that rlwrap prints certain escape codes to the screen whenever the cursor moves position, e.g. [1;45H3 so I wonder if it might be possible to intercept these codes with a filter and prevent the cursor movements. Do you have any suggestions?

hanslub42 commented 3 years ago

Usually programs that use ncurses for terminal handling are not rlwrapable. However, you could try using rlwrap -t dumb .... to make minetest think it runs on a dumb terminal (where ncurses wouldn't work).

Filtering out control codes is possible but usually results in unreadable output.

hanslub42 commented 3 years ago

If you want to try filtering, the easiest way would be to take a script that removes control characters, like the one I mentioned before:

#!/usr/bin/env perl
## uncolor — remove terminal escape sequences such as color changes
while (<>) {
   s/ \e[ #%()*+\-.\/]. |
       \e\[ [ -?]* [@-~] | # CSI ... Cmd
       \e\] .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       \e[P^_] .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e. //xg;
     print;
}

... then save it as e.g. uncolor, and use it like

rlwrap -a -z 'makefilter ./uncolor' .....
vapniks commented 3 years ago

Thankyou for the tips, but unfortunately neither of those methods helped. However after commented out a couple of lines from the minetest source code, the server terminal now works with rlwrap without cursor flickering: https://github.com/vapniks/minetest There are still problems; tab completion is very messy when there are multiple candidates, and doesn't work with macros. I have no experience with ncurses, but perhaps it's possible to fix those problems, or remove the ncurses dependency altogether. If anyone with more knowledge in this area is interested here's the relevant file, it probably just needs a tiny bit of tweaking (it's only 457 lines of code): https://github.com/vapniks/minetest/blob/master/src/terminal_chat_console.cpp

hanslub42 commented 3 years ago

Looking at the source, I see it even does TAB completion

All in all, it doesn't really look like a program where rlwrap can be of much use....

vapniks commented 3 years ago

It only TAB completes player names, not the 50 or so commands, and the line editing is really poor (only single character movements).

hanslub42 commented 3 years ago

It only TAB completes player names, not the 50 or so commands

Wouldn't that be easy to extend then?, But of course, TAB completing programs can be rlwraped (losing the original completion); it is the ncurses that is causing the problems.

vapniks commented 3 years ago

I'm not sure if needs ncurses, apart from the time & date printed at the top (which can easily be removed from the code), it behaves pretty much like an IRC client. Is rlwrap able to handle asynchronous terminal messages?