skim: do not panic if terminal is not available

Signed-off-by: Azat Khuzhin <a.khuzhin@semrush.com>
This commit is contained in:
Azat Khuzhin 2022-12-14 16:45:00 +01:00
parent 082f57c40d
commit cf0e0436be
5 changed files with 24 additions and 9 deletions

View File

@ -402,7 +402,15 @@ ReplxxLineReader::ReplxxLineReader(
words.push_back(hs.get().text());
}
std::string new_query(skim(words));
std::string new_query;
try
{
new_query = std::string(skim(words));
}
catch (const std::exception & e)
{
rx.print("skim failed: %s (consider using Ctrl-T for a regular non-fuzzy reverse search)\n", e.what());
}
if (!new_query.empty())
rx.set_state(replxx::Replxx::State(new_query.c_str(), static_cast<int>(new_query.size())));

1
rust/skim/Cargo.lock generated
View File

@ -9,6 +9,7 @@ dependencies = [
"cxx",
"cxx-build",
"skim",
"term",
]
[[package]]

View File

@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
skim = "0.10.2"
cxx = "1.0.83"
term = "0.7.0"
[build-dependencies]
cxx-build = "1.0.83"

View File

@ -87,4 +87,4 @@ private:
} // namespace cxxbridge1
} // namespace rust
::rust::String skim(::std::vector<::std::string> const &words) noexcept;
::rust::String skim(::std::vector<::std::string> const &words);

View File

@ -1,10 +1,11 @@
use skim::prelude::*;
use term::terminfo::TermInfo;
use cxx::{CxxString, CxxVector};
#[cxx::bridge]
mod ffi {
extern "Rust" {
fn skim(words: &CxxVector<CxxString>) -> String;
fn skim(words: &CxxVector<CxxString>) -> Result<String>;
}
}
@ -17,8 +18,12 @@ impl SkimItem for Item {
}
}
fn skim(words: &CxxVector<CxxString>) -> String {
// TODO: configure colors
fn skim(words: &CxxVector<CxxString>) -> Result<String, String> {
// Let's check is terminal available. To avoid panic.
if let Err(err) = TermInfo::from_env() {
return Err(format!("{}", err));
}
let options = SkimOptionsBuilder::default()
.height(Some("30%"))
.tac(true)
@ -35,15 +40,15 @@ fn skim(words: &CxxVector<CxxString>) -> String {
let output = Skim::run_with(&options, Some(rx));
if output.is_none() {
return "".to_string();
return Err("skim return nothing".to_string());
}
let output = output.unwrap();
if output.is_abort {
return "".to_string();
return Ok("".to_string());
}
if output.selected_items.is_empty() {
return "".to_string();
return Err("No items had been selected".to_string());
}
return output.selected_items[0].output().to_string();
return Ok(output.selected_items[0].output().to_string());
}