Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use something other than ncurses by default #411

Open
Shnatsel opened this issue Dec 14, 2019 · 13 comments
Open

Use something other than ncurses by default #411

Shnatsel opened this issue Dec 14, 2019 · 13 comments

Comments

@Shnatsel
Copy link

README states that Cursive uses ncurses backend by default. Sadly Rust bindings for ncurses are very problematic from the safety point of view:

This presents issues from both security and reliability standpoints. Please consider switching to a backend other than ncurses by default. If Rust-only backends are not anticipated to reach parity with ncurses anytime soon, consider using ncursesw crate - I have not audited it, but it seems to be less of a lost cause than ncurses crate.

@gyscos
Copy link
Owner

gyscos commented Dec 14, 2019

Hi!

I agree that ncurses is far from an optimal solution. Especially for newcomers, requiring a separate installation for development is not great.
To be fair, most of the unsafety around ncurses itself can be worked around by being very careful about the API - basically treating all their functions as unsafe, even if they're not explicitly so. This means writing a ncurses backend is a bit more delicate, but should hopefully not reflect in unsafety for Cursive users. And because it links to ncurses dynamically, it really only needs maintenance when ncurses changes its ABI, which they have been pretty good at not doing.

One of the reasons it's still the default backend is the input it supports: things like Ctrl+F1, Ctrl+Insert are currently working on the ncurses backend. Last time I quickly surveyed the other backends, none of them were returning enough information to implement that (even if it's raw input code from the terminal to be parsed in cursive itself). It's not critical to support these modifiers, but I was a bit sad having to cut features.

@Shnatsel
Copy link
Author

@TimonPost is that something Crossterm could provide?

@gyscos is there a list of ncurses-only features? Perhaps Rust backends could implement the missing APIs once they're aware of them.

@TimonPost
Copy link
Contributor

Crossterm supports those key combinations. I'm sure of windows, though Linux I will have to check. If not, they probably will when the new input parsing library 'anes' is implemented. I will get back to you.

@TimonPost
Copy link
Contributor

TimonPost commented Dec 16, 2019

@Shnatsel, nope, those combinations are not yet supported for Linux. We do support those for windows. In order to make those work, we have to expand our input parser. With a rough estimation, this is going to be done in 2 months. One question though.... who in the world uses those modifiers haha. Like I have never had the urge to use CTRL + INSER for something. So it is the question of useability vs cutting edge (maybe useless) feature support.

@gyscos
Copy link
Owner

gyscos commented Dec 16, 2019

Exotic modifiers get more useful when building complex UIs like IDEs where users can register their own shortcuts, or in terminal games where you may also want a bunch of shortcuts. Though I agree that Ctrl+Ins is not the most common one; the modifier+Fn keys are more popular.

Terminal UIs in general are already quite a niche target, uncommon use-cases are ironically not that uncommon. Especially for a base, "foundational" library, treating these features as "useless" may be a bit harsh.

@TimonPost
Copy link
Contributor

TimonPost commented Dec 16, 2019

I am not sure if it is even possible to support those combinations with ANSI code parsing. I will have to research those key combinations. Linux and Mac are quite limited in the advanced key codes they sent. We found out that multiple modifiers are very poorly supported for those systems.

@Shnatsel
Copy link
Author

ncurses is a Unix-only library and yet it provides those key combinations, so it must be possible.

@gyscos
Copy link
Owner

gyscos commented Dec 16, 2019

Note that the specific case of Ctrl+Ins may indeed not be detectable - but other combinations, like Ctrl+Del or Alt+Ins should be doable. Running the key_codes cursive example with the default backend is an easy way to see what's available.

One thing to note is that this parsing may not be entirely portable, and the actual codes may change between terminals. For example konsole and gnome-terminals will send different codes for some events like Ctrl+F1 (For gnome-terminal ^[1;2P and ^[O5P for konsole). A portable input library like ncurses would read the terminfo database to get the mappings for the current terminal.

@TimonPost
Copy link
Contributor

TimonPost commented Dec 16, 2019

We do check on different types of ansi strings. However, compared to ncurses it is quite limited.

@zrzka, other maintainer of crossterm, wrote https://crates.io/crates/anes, crossterm is going to use this. This crate provides an ansi code parser for events. I am not sure until how far he implemented those kind of combinations. What I do know is that there were some complications that he encountered.

@zrzka can you elaborate on this discussion in relation to your work on this crate? And is it possible for us to support those key combinations?

@alexanderkjall
Copy link
Contributor

A problem with using crossterm by default is that it links against a library that's called BearLibTerminal, and that isn't packaged by debian/ubuntu yet it seems like, that would limit the usage quite a bit.

Another problem is that ncurses crate links against ncurses 5, and since ncurses 6 have been out quite a number of years it might be time to upgrade.

I have started to look at replacing the ncurses dependency with ncursesw and it doesn't look too hard, mostly a lot of busy-work with renaming things slightly, would you be interested in a pull request if I manage to finish something?

@gyscos
Copy link
Owner

gyscos commented Feb 3, 2020

A problem with using crossterm by default is that it links against a library that's called BearLibTerminal, and that isn't packaged by debian/ubuntu yet it seems like, that would limit the usage quite a bit.

Does it? Cursive does optionally rely on BearLibTerminal, but I don't think crossterm does.

Another problem is that ncurses crate links against ncurses 5, and since ncurses 6 have been out quite a number of years it might be time to upgrade.

Really? It does look for the ncursesw5 lib, but also for ncursesw, so on archlinux for example, it correctly links to libncursesw.so.6. On an ubuntu machine I have here, it links to libncursesw.so.5.9, but it's really part of the ncurses 6.1 package, albeit compiled in a compatible way:

libncursesw5/bionic-updates,now 6.1-1ubuntu1.18.04 amd64 [installed]

@alexanderkjall
Copy link
Contributor

Sorry, I got stuff mixed up, I tried different backends and mixed the blt and the crossterm one.

I didn't know about the ABI compability between ncurses 5 and 6, that's neat.

@gyscos
Copy link
Owner

gyscos commented Feb 4, 2020

It seems to be officially supported (https://www.gnu.org/software/ncurses/):

This release is designed to be source-compatible with ncurses 5.0 through 6.0; providing extensions to the application binary interface (ABI). Although the source can still be configured to support the ncurses 5 ABI, the intent of the release is to provide extensions to the ncurses 6 ABI:

  • improve integration of tput and tset

  • provide support for extended numeric capabilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants