2021-06-18 06:09:10 +08:00
|
|
|
#[macro_use]
|
|
|
|
extern crate helix_view;
|
|
|
|
|
2021-06-07 12:40:21 +08:00
|
|
|
pub mod application;
|
|
|
|
pub mod args;
|
|
|
|
pub mod commands;
|
|
|
|
pub mod compositor;
|
2021-06-17 19:08:05 +08:00
|
|
|
pub mod config;
|
2023-12-01 07:03:26 +08:00
|
|
|
pub mod events;
|
2022-03-08 13:25:46 +08:00
|
|
|
pub mod health;
|
2021-06-28 20:48:38 +08:00
|
|
|
pub mod job;
|
2021-06-07 12:40:21 +08:00
|
|
|
pub mod keymap;
|
|
|
|
pub mod ui;
|
2023-12-01 07:03:26 +08:00
|
|
|
|
2023-02-03 01:14:02 +08:00
|
|
|
use std::path::Path;
|
|
|
|
|
2024-01-18 01:24:38 +08:00
|
|
|
use futures_util::Future;
|
2023-12-01 07:03:26 +08:00
|
|
|
mod handlers;
|
|
|
|
|
2023-02-03 01:14:02 +08:00
|
|
|
use ignore::DirEntry;
|
2024-01-18 01:24:38 +08:00
|
|
|
use url::Url;
|
|
|
|
|
2021-12-03 11:41:13 +08:00
|
|
|
#[cfg(windows)]
|
|
|
|
fn true_color() -> bool {
|
|
|
|
true
|
|
|
|
}
|
2023-02-03 01:14:02 +08:00
|
|
|
|
2024-02-12 01:38:09 +08:00
|
|
|
#[cfg(not(windows))]
|
|
|
|
fn true_color() -> bool {
|
|
|
|
if matches!(
|
|
|
|
std::env::var("COLORTERM").map(|v| matches!(v.as_str(), "truecolor" | "24bit")),
|
|
|
|
Ok(true)
|
|
|
|
) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
match termini::TermInfo::from_env() {
|
|
|
|
Ok(t) => {
|
|
|
|
t.extended_cap("RGB").is_some()
|
|
|
|
|| t.extended_cap("Tc").is_some()
|
|
|
|
|| (t.extended_cap("setrgbf").is_some() && t.extended_cap("setrgbb").is_some())
|
|
|
|
}
|
|
|
|
Err(_) => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-03 01:14:02 +08:00
|
|
|
/// Function used for filtering dir entries in the various file pickers.
|
|
|
|
fn filter_picker_entry(entry: &DirEntry, root: &Path, dedup_symlinks: bool) -> bool {
|
2024-03-19 22:08:50 +08:00
|
|
|
// We always want to ignore popular VCS directories, otherwise if
|
2023-02-03 01:14:02 +08:00
|
|
|
// `ignore` is turned off, we end up with a lot of noise
|
|
|
|
// in our picker.
|
2024-03-19 22:08:50 +08:00
|
|
|
if matches!(
|
|
|
|
entry.file_name().to_str(),
|
2024-04-21 11:00:30 +08:00
|
|
|
Some(".git" | ".pijul" | ".jj" | ".hg" | ".svn")
|
2024-03-19 22:08:50 +08:00
|
|
|
) {
|
2023-02-03 01:14:02 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We also ignore symlinks that point inside the current directory
|
|
|
|
// if `dedup_links` is enabled.
|
|
|
|
if dedup_symlinks && entry.path_is_symlink() {
|
|
|
|
return entry
|
|
|
|
.path()
|
|
|
|
.canonicalize()
|
|
|
|
.ok()
|
2025-01-10 01:02:21 +08:00
|
|
|
.is_some_and(|path| !path.starts_with(root));
|
2023-02-03 01:14:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
true
|
|
|
|
}
|
2024-01-18 01:24:38 +08:00
|
|
|
|
|
|
|
/// Opens URL in external program.
|
|
|
|
fn open_external_url_callback(
|
|
|
|
url: Url,
|
|
|
|
) -> impl Future<Output = Result<job::Callback, anyhow::Error>> + Send + 'static {
|
|
|
|
let commands = open::commands(url.as_str());
|
|
|
|
async {
|
|
|
|
for cmd in commands {
|
2025-06-14 21:54:09 +08:00
|
|
|
let mut command: tokio::process::Command = cmd.into();
|
2024-01-18 01:24:38 +08:00
|
|
|
if command.output().await.is_ok() {
|
|
|
|
return Ok(job::Callback::Editor(Box::new(|_| {})));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(job::Callback::Editor(Box::new(move |editor| {
|
|
|
|
editor.set_error("Opening URL in external program failed")
|
|
|
|
})))
|
|
|
|
}
|
|
|
|
}
|