diff --git a/client/src/cmd.rs b/client/src/cmd.rs index b950e36488..dd5dd8ba06 100644 --- a/client/src/cmd.rs +++ b/client/src/cmd.rs @@ -9,6 +9,7 @@ impl TabComplete for ArgumentSpec { fn complete(&self, part: &str, client: &Client) -> Vec { 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 { .collect() } +fn complete_site(mut part: &str, client: &Client) -> Vec { + 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 { let part = part.strip_prefix('/').unwrap_or(part); diff --git a/common/src/cmd.rs b/common/src/cmd.rs index 0d104684f0..63dbdd34e3 100644 --- a/common/src/cmd.rs +++ b/common/src/cmd.rs @@ -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 { + "".to_string() + } else { + "[site]".to_string() + } + }, ArgumentSpec::Float(label, _, req) => { if &Requirement::Required == req { format!("<{}>", label) diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs index d7f0b5af95..db7ca32be0 100644 --- a/voxygen/src/hud/chat.rs +++ b/voxygen/src/hud/chat.rs @@ -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_quotation = false; for (char_i, (byte_i, c)) in input.char_indices().enumerate() { - if c.is_whitespace() && c != '\t' { + if c == '"' { + in_quotation = !in_quotation; + } else if !in_quotation && c.is_whitespace() && c != '\t' { if char_i < cursor { pre_ws = Some(byte_i); } else {