diff --git a/src/help.rs b/src/help.rs index faa4986..f8460fd 100644 --- a/src/help.rs +++ b/src/help.rs @@ -83,6 +83,21 @@ fn ignorecase_pattern(text: &str) -> String { }) } +// Taken from the main repo +// https://github.com/neovim/neovim/blob/master/scripts/gen_help_html.lua#L110-L117 +fn encode_url(name: &str) -> String { + const NO_ESCAPE: &str = "()'_.~-"; + name.chars() + .map(|c| { + if c.is_ascii_alphanumeric() || NO_ESCAPE.find(c).is_some() { + c.to_string() + } else { + format!("%{:2>X}", c as u32) + } + }) + .collect() +} + fn generate_search_patterns(name: &str) -> Option { let name = if let Some(replacement) = FULL_REPLACEMENTS.get(&name) { replacement.to_string() @@ -220,7 +235,8 @@ impl<'a> Tag<'a> { format!( "https://neovim.io/doc/user/{}.html#{}", - file_without_ext, self.name + file_without_ext, + encode_url(self.name) ) } } @@ -252,4 +268,18 @@ mod test { t!("wildmenu", "'wildmenu'", "options.txt"); t!("'wildmenu'", "'wildmenu'", "options.txt"); } + + #[test] + fn encode_works() { + assert_eq!(encode_url(":terminal"), "%3Aterminal"); + assert_eq!(encode_url("/character-classes"), "%2Fcharacter-classes"); + assert_eq!(encode_url("[["), "%5B%5B"); + assert_eq!(encode_url("=="), "%3D%3D"); + assert_eq!(encode_url("s/\\~"), "s%2F%5C~"); + assert_eq!(encode_url(""), "%3CCR%3E"); + + assert_eq!(encode_url("abdcefghijklmnopqrstuvwxyz"), "abdcefghijklmnopqrstuvwxyz"); + assert_eq!(encode_url("0123456789"), "0123456789"); + assert_eq!(encode_url("()'_.~-"), "()'_.~-"); + } }