create clickable links in ls output if configured (#6333)

* create clickable links in ls output if configured

* move some comments
This commit is contained in:
Darren Schroeder 2022-08-18 05:45:49 -05:00 committed by GitHub
parent ec4e3a6d5c
commit 1843fdc060
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 5 deletions

View file

@ -9,12 +9,14 @@ use nu_protocol::{
}; };
use nu_table::{Alignments, StyledString, TableTheme, TextStyle}; use nu_table::{Alignments, StyledString, TableTheme, TextStyle};
use nu_utils::get_ls_colors; use nu_utils::get_ls_colors;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::time::Instant; use std::time::Instant;
use std::{
path::PathBuf,
sync::atomic::{AtomicBool, Ordering},
};
use terminal_size::{Height, Width}; use terminal_size::{Height, Width};
use url::Url;
//use super::lscolor_ansiterm::ToNuAnsiStyle;
const STREAM_PAGE_SIZE: usize = 1000; const STREAM_PAGE_SIZE: usize = 1000;
const STREAM_TIMEOUT_CHECK_INTERVAL: usize = 100; const STREAM_TIMEOUT_CHECK_INTERVAL: usize = 100;
@ -258,6 +260,7 @@ fn handle_row_stream(
None => None, None => None,
}; };
let ls_colors = get_ls_colors(ls_colors_env_str); let ls_colors = get_ls_colors(ls_colors_env_str);
let show_clickable_links = config.show_clickable_links_in_ls;
ListStream::from_stream( ListStream::from_stream(
stream.map(move |(mut x, _)| match &mut x { stream.map(move |(mut x, _)| match &mut x {
@ -279,9 +282,20 @@ fn handle_row_stream(
.unwrap_or_default(); .unwrap_or_default();
let use_ls_colors = config.use_ls_colors; let use_ls_colors = config.use_ls_colors;
let full_path = PathBuf::from(path.clone())
.canonicalize()
.unwrap_or_else(|_| PathBuf::from(path));
let full_path_link = make_clickable_link(
full_path.display().to_string(),
Some(&path.clone()),
show_clickable_links,
);
if use_ls_colors { if use_ls_colors {
vals[idx] = Value::String { vals[idx] = Value::String {
val: ansi_style.apply(path).to_string(), val: ansi_style
.apply(full_path_link)
.to_string(),
span: *span, span: *span,
}; };
} }
@ -294,9 +308,20 @@ fn handle_row_stream(
.unwrap_or_default(); .unwrap_or_default();
let use_ls_colors = config.use_ls_colors; let use_ls_colors = config.use_ls_colors;
let full_path = PathBuf::from(path.clone())
.canonicalize()
.unwrap_or_else(|_| PathBuf::from(path));
let full_path_link = make_clickable_link(
full_path.display().to_string(),
Some(&path.clone()),
show_clickable_links,
);
if use_ls_colors { if use_ls_colors {
vals[idx] = Value::String { vals[idx] = Value::String {
val: ansi_style.apply(path).to_string(), val: ansi_style
.apply(full_path_link)
.to_string(),
span: *span, span: *span,
}; };
} }
@ -341,6 +366,30 @@ fn handle_row_stream(
}) })
} }
fn make_clickable_link(
full_path: String,
link_name: Option<&str>,
show_clickable_links: bool,
) -> String {
// uri's based on this https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
if show_clickable_links {
format!(
"\x1b]8;;{}\x1b\\{}\x1b]8;;\x1b\\",
match Url::from_file_path(full_path.clone()) {
Ok(url) => url.to_string(),
Err(_) => full_path.clone(),
},
link_name.unwrap_or(full_path.as_str())
)
} else {
match link_name {
Some(link_name) => link_name.to_string(),
None => full_path,
}
}
}
fn convert_to_table( fn convert_to_table(
row_offset: usize, row_offset: usize,
input: &[Value], input: &[Value],

View file

@ -82,6 +82,7 @@ pub struct Config {
pub enable_external_completion: bool, pub enable_external_completion: bool,
pub trim_strategy: TrimStrategy, pub trim_strategy: TrimStrategy,
pub show_banner: bool, pub show_banner: bool,
pub show_clickable_links_in_ls: bool,
} }
impl Default for Config { impl Default for Config {
@ -117,6 +118,7 @@ impl Default for Config {
enable_external_completion: true, enable_external_completion: true,
trim_strategy: TRIM_STRATEGY_DEFAULT, trim_strategy: TRIM_STRATEGY_DEFAULT,
show_banner: true, show_banner: true,
show_clickable_links_in_ls: true,
} }
} }
} }
@ -397,6 +399,13 @@ impl Value {
eprintln!("$config.show_banner is not a bool") eprintln!("$config.show_banner is not a bool")
} }
} }
"show_clickable_links_in_ls" => {
if let Ok(b) = value.as_bool() {
config.show_clickable_links_in_ls = b;
} else {
eprintln!("$config.show_clickable_links_in_ls is not a bool")
}
}
x => { x => {
eprintln!("$config.{} is an unknown config setting", x) eprintln!("$config.{} is an unknown config setting", x)
} }

View file

@ -266,6 +266,7 @@ let-env config = {
# truncating_suffix: "..." # truncating_suffix: "..."
} }
show_banner: true # true or false to enable or disable the banner show_banner: true # true or false to enable or disable the banner
show_clickable_links_in_ls: true # true or false to enable or disable clickable links in the ls listing. your terminal has to support links.
hooks: { hooks: {
pre_prompt: [{ pre_prompt: [{