use crate::{
keys::{self, KeyOrLeader},
yml::{GlobalConfig, LeaderKeys},
};
fn print_zsh_chpwd_hook() {
println!(
"
## blaze-keys: start
##
## Warning: You should avoid putting this output directly in your .zshrc in case the content changes in future versions.
## This is why the command is called dynamically to initialise the bindings in the .zshrc.
##
##### The zsh hook which is called on changing directories. #####
autoload -U add-zsh-hook
run_on_cd() {{
source <(blz porcelain blat)
}}
add-zsh-hook chpwd run_on_cd
source <(blz porcelain --ignore-leader-state blat)
"
);
}
pub fn print_export_leaders(leaders: &Option<&Vec<LeaderKeys>>) {
println!(
"export BLZ_LEADER_STATE='{}'",
super::leaders_to_state(leaders)
);
}
pub fn print_zsh_hook(global: &Option<GlobalConfig>) {
print_zsh_chpwd_hook();
if let Some(g) = global.as_ref().and_then(|g| g.global.as_ref()) {
print_export_leaders(&g.leader_keys.as_ref());
if let Some(ref leaders) = g.leader_keys {
if !leaders.is_empty() {
println!("##### The zsh widgets which provide the leader key functionality. #####");
}
for (index, leader) in leaders.iter().enumerate() {
for (_i, k) in [&leader.exec_mode, &leader.abbr_mode].iter().enumerate() {
let abbr = _i == 1;
let key = keys::get_key_zsh_representation(k);
let func_name = format!(
"_zsh_leader{index}{}",
if abbr { "_abbr " } else { "_exec" }
);
let key_zsh = match &key {
Some(KeyOrLeader::Key(k)) => k,
_ => panic!("invalid keybind for leader"),
};
let (flag, spacing, zle_accept) = match abbr {
true => ("--abbr ", " ", ""),
false => ("", "", "\n zle accept-line"),
};
println!(
"function {} {{
tmpfile=$(mktemp)
blz porcelain leader-key {} {}--tmpfile $tmpfile < /dev/tty
content=$(cat $tmpfile)
if [[ $content =~ '^zle .*' ]]; then
eval $content
else
LBUFFER+=\"$(cat $tmpfile){}\"{}
fi
rm $tmpfile
}}
zle -N {func_name}
bindkey '{key_zsh}' {func_name}
",
func_name,
leader.sanitized_name(),
flag,
spacing,
zle_accept,
)
}
}
}
println!("## blaze-keys: end");
} else {
print_export_leaders(&None);
}
}