site command completion

This commit is contained in:
IsseW 2022-05-15 23:57:21 +02:00
parent eec2d67bb7
commit fb7aa07b01
3 changed files with 38 additions and 2 deletions

View File

@ -9,6 +9,7 @@ impl TabComplete for ArgumentSpec {
fn complete(&self, part: &str, client: &Client) -> Vec<String> {
match self {
ArgumentSpec::PlayerName(_) => complete_player(part, client),
ArgumentSpec::SiteName(_) => complete_site(part, client),
ArgumentSpec::Float(_, x, _) => {
if part.is_empty() {
vec![format!("{:.1}", x)]
@ -51,6 +52,28 @@ fn complete_player(part: &str, client: &Client) -> Vec<String> {
.collect()
}
fn complete_site(mut part: &str, client: &Client) -> Vec<String> {
if let Some(p) = part.strip_prefix('"') {
part = p;
}
client
.sites
.values()
.filter_map(|site| match site.site.kind {
common_net::msg::world_msg::SiteKind::Cave => None,
_ => site.site.name.as_ref(),
})
.filter(|name| name.starts_with(part))
.map(|name| {
if name.contains(' ') {
format!("\"{}\"", name)
} else {
name.clone()
}
})
.collect()
}
fn complete_command(part: &str) -> Vec<String> {
let part = part.strip_prefix('/').unwrap_or(part);

View File

@ -588,7 +588,7 @@ impl ChatCommand {
// Uses Message because site names can contain spaces,
// which would be assumed to be separators otherwise
ChatCommand::Site => cmd(
vec![Message(Required)],
vec![SiteName(Required)],
"Teleport to a site",
Some(Moderator),
),
@ -786,6 +786,7 @@ impl ChatCommand {
.iter()
.map(|arg| match arg {
ArgumentSpec::PlayerName(_) => "{}",
ArgumentSpec::SiteName(_) => "{/.*/}",
ArgumentSpec::Float(_, _, _) => "{}",
ArgumentSpec::Integer(_, _, _) => "{d}",
ArgumentSpec::Any(_, _) => "{}",
@ -843,6 +844,8 @@ pub enum Requirement {
pub enum ArgumentSpec {
/// The argument refers to a player by alias
PlayerName(Requirement),
// The argument refers to a site, by name.
SiteName(Requirement),
/// The argument is a float. The associated values are
/// * label
/// * suggested tab-completion
@ -884,6 +887,13 @@ impl ArgumentSpec {
"[player]".to_string()
}
},
ArgumentSpec::SiteName(req) => {
if &Requirement::Required == req {
"<site>".to_string()
} else {
"[site]".to_string()
}
},
ArgumentSpec::Float(label, _, req) => {
if &Requirement::Required == req {
format!("<{}>", label)

View File

@ -678,8 +678,11 @@ impl<'a> Widget for Chat<'a> {
fn do_tab_completion(cursor: usize, input: &str, word: &str) -> (String, usize) {
let mut pre_ws = None;
let mut post_ws = None;
let mut in_qoutation = false;
for (char_i, (byte_i, c)) in input.char_indices().enumerate() {
if c.is_whitespace() && c != '\t' {
if c == '"' {
in_qoutation = !in_qoutation;
} else if !in_qoutation && c.is_whitespace() && c != '\t' {
if char_i < cursor {
pre_ws = Some(byte_i);
} else {