use reovim_kernel::api::v1::Service;
pub struct LeaderKeyProvider {
key: parking_lot::RwLock<Option<&'static str>>,
}
impl LeaderKeyProvider {
#[must_use]
pub const fn new() -> Self {
Self {
key: parking_lot::RwLock::new(None),
}
}
pub fn set(&self, key: &'static str) -> Option<&'static str> {
self.key.write().replace(key)
}
#[must_use]
pub fn get(&self) -> Option<&'static str> {
*self.key.read()
}
#[must_use]
pub fn expand(&self, keys: &str) -> String {
self.get()
.map_or_else(|| keys.to_owned(), |notation| expand_leader(keys, notation))
}
}
impl Default for LeaderKeyProvider {
fn default() -> Self {
Self::new()
}
}
impl Service for LeaderKeyProvider {}
#[must_use]
pub fn expand_leader(keys: &str, notation: &str) -> String {
if !keys.contains('<') {
return keys.to_owned();
}
let needle = "<leader>";
let mut result = String::with_capacity(keys.len());
let mut remaining = keys;
while let Some(pos) = remaining
.as_bytes()
.windows(needle.len())
.position(|w| w.eq_ignore_ascii_case(needle.as_bytes()))
{
result.push_str(&remaining[..pos]);
result.push_str(notation);
remaining = &remaining[pos + needle.len()..];
}
result.push_str(remaining);
result
}
#[cfg(test)]
#[path = "leader_key_tests.rs"]
mod tests;