Use termion backend for cursive

With this patch, we replace cursive’s default ncurses backend with the
termion backend.  This has multiple reasons:
- The ncurses backend has safety issues, see [0].
- ncurses requires a pre-installed library and a C compiler, introducing
  additional build dependencies.  Termion is implemented in Rust only.
- ncurses does not work on Windows, while termion works in all terminals
  that support ANSI escape codes.

Per default, the termion backend does not buffer the output which may
cause flickering [1].  Therefore, we also use the
cursive_buffered_backend that buffers the output and fixes the
flickering problem.

[0] https://github.com/gyscos/cursive/issues/488
[1] https://github.com/gyscos/cursive/issues/142
This commit is contained in:
Robin Krahl 2020-10-08 10:19:21 +02:00
parent 568fb0acc8
commit 8db34e33b2
No known key found for this signature in database
GPG Key ID: 8E9B0870524F69D8
5 changed files with 59 additions and 49 deletions

65
Cargo.lock generated
View File

@ -228,10 +228,8 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -246,6 +244,19 @@ dependencies = [
"unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cursive_buffered_backend"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cursive_core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"enumset 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cursive_core"
version = "0.1.1"
@ -600,11 +611,6 @@ name = "mac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "markup5ever"
version = "0.10.0"
@ -670,16 +676,6 @@ dependencies = [
"adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ncurses"
version = "5.99.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
@ -747,6 +743,11 @@ dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "onig"
version = "6.0.0"
@ -985,6 +986,14 @@ name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.18"
@ -1016,6 +1025,7 @@ dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"cursive 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cursive-markup 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cursive_buffered_backend 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"html2text 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"insta 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1306,8 +1316,8 @@ dependencies = [
]
[[package]]
name = "term_size"
version = "0.3.2"
name = "terminal_size"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1315,12 +1325,14 @@ dependencies = [
]
[[package]]
name = "terminal_size"
version = "0.1.13"
name = "termion"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1627,6 +1639,7 @@ dependencies = [
"checksum cssparser-macros 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e"
"checksum cursive 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9f12332ab2bca26979ef00cfef9a1c2e287db03b787a83d892ad9961f81374"
"checksum cursive-markup 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "108cee1e66cebbf78ae2e08a53c2dfcfe6f8d536abcebbb6bb614f5ab1955868"
"checksum cursive_buffered_backend 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75baaba7a90dc9d2f94693f28a299a652d3b8a21f49707ff5f8a2114244d4522"
"checksum cursive_core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "85fc5b6a8ba2f1bc743892068bde466438f78d6247197e2dc094bfd53fdea4b7"
"checksum darling 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
"checksum darling_core 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
@ -1669,7 +1682,6 @@ dependencies = [
"checksum linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
"checksum markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aae38d669396ca9b707bfc3db254bc382ddb94f57cc5c235f34623a669a01dab"
"checksum markup5ever_rcdom 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f015da43bcd8d4f144559a3423f4591d69b8ce0652c905374da7205df336ae2b"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
@ -1677,7 +1689,6 @@ dependencies = [
"checksum merge 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
"checksum merge_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
"checksum miniz_oxide 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
"checksum ncurses 5.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15699bee2f37e9f8828c7b35b2bc70d13846db453f2d507713b758fabe536b82"
"checksum new_debug_unreachable 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
"checksum num 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3e176191bc4faad357e3122c4747aa098ac880e88b168f106386128736cf4a"
@ -1686,6 +1697,7 @@ dependencies = [
"checksum num-iter 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
"checksum num-rational 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
"checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum onig 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd91ccd8a02fce2f7e8a86655aec67bc6c171e6f8e704118a0e8c4b866a05a8a"
"checksum onig_sys 69.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3814583fad89f3c60ae0701d80e87e1fd3028741723deda72d0d4a0ecf0cb0db"
"checksum owning_ref 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
@ -1714,6 +1726,7 @@ dependencies = [
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
"checksum redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)" = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
"checksum remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
@ -1745,8 +1758,8 @@ dependencies = [
"checksum syntect 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b57a45fdcf4891bc79f635be5c559210a4cfa464891f969724944c713282eedb"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum tendril 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b"
"checksum term_size 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
"checksum terminal_size 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13"
"checksum termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
"checksum termios 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f0fcee7b24a25675de40d5bb4de6e41b0df07bc9856295e7e2b3a3600c400c2"
"checksum text-style 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01ecc55ab699ed1b4d0ebe64d7a8ee2611f55d0de4042e9c1ee5a81dee89e332"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"

View File

@ -19,7 +19,7 @@ exclude = [".builds/*", "tests/html/*", "tests/snapshots/*"]
ansi_term = "0.12.1"
anyhow = "1.0.31"
atty = "0.2.14"
cursive = "0.15.0"
cursive_buffered_backend = "0.4"
cursive-markup = "0.1"
html2text = "0.2.1"
kuchiki = "0.8.0"
@ -36,6 +36,11 @@ url = "2.1.1"
webbrowser = "0.5.5"
xdg = "2.2.0"
[dependencies.cursive]
version = "0.15"
default-features = false
features = ["termion-backend"]
[dependencies.env_logger]
version = "0.7.1"
default-features = false

View File

@ -16,23 +16,7 @@ rusty-man packages are available for these distributions:
### Build Requirements
To compile rusty-man, you need Rust 1.40 or later. The `tui` backend requires
the ncurses library in the default search path and a C compiler.
If you dont want to use ncurses, you can select another [`cursive`][] backend
by replacing this line in `Cargo.toml`:
```toml
cursive = "0.15.0"
```
with this:
```toml
cursive = { version = "0.15.0", default-features = false, feature = ["termion-backend"] }
```
[`cursive`]: https://lib.rs/cursive
To compile rusty-man, you need Rust 1.40 or later.
### Installing from Git

View File

@ -72,10 +72,10 @@ information. rusty-man is also available as a package for these distributions:
- Arch Linux: [`rusty-man`][pkg-aur] in the Arch User Repository
rusty-man is developed for Unix-like systems. It should run on other platforms
too, but with some limitations: The `rich` viewer uses ANSI escape codes,
which are not supported on older Windows versions. The `tui` viewer requires
the ncurses library. If you have trouble running rusty-man on your platform or
if you want to help porting rusty-man to other platforms, please let me know.
too, but with some limitations: The `rich` and `tui` viewers uses ANSI escape
codes, which are not supported on older Windows versions. If you have trouble
running rusty-man on your platform or if you want to help porting rusty-man to
other platforms, please let me know.
## Integrations

View File

@ -189,11 +189,19 @@ fn indent_view<V>(indent: impl Into<usize>, view: V) -> PaddedView<V> {
PaddedView::lrtb(indent.into(), 0, 0, 0, view)
}
fn create_backend() -> anyhow::Result<Box<dyn cursive::backend::Backend>> {
let termion =
cursive::backends::termion::Backend::init().context("Could not create termion backend")?;
let buffered = cursive_buffered_backend::BufferedBackend::new(termion);
Ok(Box::new(buffered))
}
fn create_cursive(
sources: Vec<Box<dyn source::Source>>,
args: args::ViewerArgs,
) -> anyhow::Result<cursive::Cursive> {
let mut cursive = cursive::default();
let mut cursive =
cursive::Cursive::try_new(create_backend).context("Could not create Cursive instance")?;
cursive.set_user_data(Context::new(sources, args)?);