122 lines
4.0 KiB
Rust
122 lines
4.0 KiB
Rust
pub mod render;
|
|
pub mod settings;
|
|
pub mod success_block;
|
|
pub mod trigger_state;
|
|
|
|
use crate::terminal::model::terminal_model::SubshellInitializationInfo;
|
|
use crate::terminal::shell::ShellType;
|
|
use crate::ASSETS;
|
|
use channel_versions::overrides::TargetOS;
|
|
use warpui::AssetProvider;
|
|
|
|
#[derive(Debug)]
|
|
pub enum WarpificationSource {
|
|
Ssh,
|
|
Subshell,
|
|
}
|
|
|
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
pub enum SubshellSource {
|
|
Command(String),
|
|
EnvVarCollection(String),
|
|
}
|
|
|
|
/// This template is for the snippet that appears in the output grid for the success block if the
|
|
/// subshell is local.
|
|
fn get_subshell_bootstrap_success_block_path(shell_type: ShellType) -> Option<&'static str> {
|
|
match shell_type {
|
|
ShellType::Bash | ShellType::Zsh => {
|
|
Some("bundled/bootstrap/bash_zsh_subshell_bootstrap_block_output.txt")
|
|
}
|
|
ShellType::Fish => Some("bundled/bootstrap/fish_subshell_bootstrap_block_output.txt"),
|
|
ShellType::PowerShell => None,
|
|
}
|
|
}
|
|
|
|
/// Returns OutputGrid bytes to be rendered in the hardcoded "Warpified subshell" block that's added
|
|
/// to the blocklist upon successful subshell bootstrap.
|
|
///
|
|
/// The exact block contents varies based on whether or not the session is local or remote, in
|
|
/// addition to the given `shell_type`.
|
|
pub fn subshell_bootstrap_success_block_bytes(
|
|
subshell_initialization_info: &SubshellInitializationInfo,
|
|
shell_type: ShellType,
|
|
os: TargetOS,
|
|
disable_tmux: bool,
|
|
) -> (Vec<u8>, bool) {
|
|
let from_env_var_collection = subshell_initialization_info
|
|
.env_var_collection_name
|
|
.is_some();
|
|
|
|
if from_env_var_collection {
|
|
return (vec![], false);
|
|
}
|
|
|
|
let Some(subshell_bootstrap_success_block_path) =
|
|
get_subshell_bootstrap_success_block_path(shell_type)
|
|
else {
|
|
return ("".into(), false);
|
|
};
|
|
|
|
let templated_subshell_bootstrap_success_block_output_bytes = ASSETS
|
|
.get(subshell_bootstrap_success_block_path)
|
|
.unwrap_or_else(|_| {
|
|
panic!("Failed to retrieve {subshell_bootstrap_success_block_path} from assets.")
|
|
})
|
|
.to_vec();
|
|
|
|
let rc_file_paths = shell_type.rc_file_paths(os);
|
|
let mut is_executable = true;
|
|
let commands: Vec<Vec<u8>> = rc_file_paths
|
|
.iter()
|
|
.map(|rc_file_path| {
|
|
let rc_file_path = rc_file_path.to_str();
|
|
is_executable &= rc_file_path.is_some();
|
|
replace_template_chars_with_arguments(
|
|
templated_subshell_bootstrap_success_block_output_bytes
|
|
.trim_ascii_end()
|
|
.to_owned()
|
|
.to_vec(),
|
|
vec![
|
|
shell_type.name().to_owned(),
|
|
if disable_tmux {
|
|
", \"tmux\": false"
|
|
} else {
|
|
""
|
|
}
|
|
.to_owned(),
|
|
rc_file_path.unwrap_or("<Your RC file>").to_owned(),
|
|
],
|
|
)
|
|
})
|
|
.collect();
|
|
(commands.concat(), is_executable)
|
|
}
|
|
|
|
/// Replaces each instance of '%' in the given `templated_bytes` vector with `String` in
|
|
/// `arguments`, in order.
|
|
///
|
|
/// The bundled block content txt files are templated using '%' as a placeholder to be dynamically
|
|
/// replaced at runtime. This is useful to cater the exact block contents to the bootstrapped
|
|
/// subshell.
|
|
fn replace_template_chars_with_arguments(
|
|
mut templated_bytes: Vec<u8>,
|
|
arguments: Vec<String>,
|
|
) -> Vec<u8> {
|
|
// This was an arbitrarily chosen character.
|
|
const TEMPLATE_CHAR: u8 = b'%';
|
|
|
|
for argument in arguments {
|
|
let template_i = templated_bytes.iter().position(|b| b == &TEMPLATE_CHAR);
|
|
if let Some(template_i) = template_i {
|
|
templated_bytes.splice(
|
|
template_i..template_i + 1,
|
|
argument.into_bytes().into_iter(),
|
|
);
|
|
} else {
|
|
debug_assert!(false, "Number of arguments does not match number of template chars (%) in hardcoded subshell block bytes.");
|
|
}
|
|
}
|
|
templated_bytes
|
|
}
|