use crate::lsp::{SignatureHelp, SignatureInfo};
#[derive(Debug, Clone)]
pub struct SignaturePopup {
pub signatures: Vec<SignatureInfo>,
pub active: usize,
}
impl SignaturePopup {
pub fn from_reply(sh: SignatureHelp) -> Option<SignaturePopup> {
if sh.signatures.is_empty() {
return None;
}
let active = sh.active_signature.min(sh.signatures.len() - 1);
Some(SignaturePopup {
signatures: sh.signatures,
active,
})
}
pub fn active_sig(&self) -> &SignatureInfo {
&self.signatures[self.active]
}
pub fn cycle(&mut self) {
if self.signatures.len() > 1 {
self.active = (self.active + 1) % self.signatures.len();
}
}
pub fn cycle_prev(&mut self) {
let n = self.signatures.len();
if n > 1 {
self.active = (self.active + n - 1) % n;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn sig(label: &str, params: &[(usize, usize)], active: Option<usize>) -> SignatureInfo {
SignatureInfo {
label: label.to_string(),
parameters: params.to_vec(),
active_parameter: active,
}
}
#[test]
fn from_reply_picks_active() {
let sh = SignatureHelp {
signatures: vec![
sig("foo()", &[], None),
sig("bar(x: int)", &[(4, 11)], Some(0)),
],
active_signature: 1,
};
let p = SignaturePopup::from_reply(sh).unwrap();
assert_eq!(p.active, 1);
assert_eq!(p.active_sig().label, "bar(x: int)");
}
#[test]
fn from_reply_empty_is_none() {
let sh = SignatureHelp {
signatures: vec![],
active_signature: 0,
};
assert!(SignaturePopup::from_reply(sh).is_none());
}
#[test]
fn cycle_wraps() {
let sh = SignatureHelp {
signatures: vec![sig("a", &[], None), sig("b", &[], None)],
active_signature: 0,
};
let mut p = SignaturePopup::from_reply(sh).unwrap();
p.cycle();
assert_eq!(p.active, 1);
p.cycle();
assert_eq!(p.active, 0);
}
#[test]
fn cycle_prev_wraps() {
let sh = SignatureHelp {
signatures: vec![
sig("a", &[], None),
sig("b", &[], None),
sig("c", &[], None),
],
active_signature: 0,
};
let mut p = SignaturePopup::from_reply(sh).unwrap();
p.cycle_prev();
assert_eq!(p.active, 2);
p.cycle_prev();
assert_eq!(p.active, 1);
}
#[test]
fn cycle_single_is_noop() {
let sh = SignatureHelp {
signatures: vec![sig("solo", &[], None)],
active_signature: 0,
};
let mut p = SignaturePopup::from_reply(sh).unwrap();
p.cycle();
assert_eq!(p.active, 0);
p.cycle_prev();
assert_eq!(p.active, 0);
}
}