Something went wrong. Try again.
A post-modern development environment.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198use crate::helpers;use crate::path;use crate::DynError;
use helix_term::commands::MappableCommand;use helix_term::commands::TYPABLE_COMMAND_LIST;use helix_term::health::TsFeature;use helix_view::document::Mode;
use std::collections::HashSet;use std::fs;
pub const TYPABLE_COMMANDS_MD_OUTPUT: &str = "typable-cmd.md";pub const STATIC_COMMANDS_MD_OUTPUT: &str = "static-cmd.md";pub const LANG_SUPPORT_MD_OUTPUT: &str = "lang-support.md";
fn md_table_heading(cols: &[String]) -> String { let mut header = String::new(); header += &md_table_row(cols); header += &md_table_row(&vec!["---".to_string(); cols.len()]); header}
fn md_table_row(cols: &[String]) -> String { format!("| {} |\n", cols.join(" | "))}
fn md_mono(s: &str) -> String { format!("`{}`", s)}
pub fn typable_commands() -> Result<String, DynError> { let mut md = String::new(); md.push_str(&md_table_heading(&[ "Name".to_owned(), "Description".to_owned(), ]));
// escape | so it doesn't get rendered as a column separator let cmdify = |s: &str| format!("`:{}`", s.replace('|', "\\|"));
for cmd in TYPABLE_COMMAND_LIST { let names = std::iter::once(&cmd.name) .chain(cmd.aliases.iter()) .map(|a| cmdify(a)) .collect::<Vec<_>>() .join(", ");
let doc = cmd.doc.replace('\n', "<br>");
md.push_str(&md_table_row(&[names.to_owned(), doc.to_owned()])); }
Ok(md)}
pub fn static_commands() -> Result<String, DynError> { let mut md = String::new(); let keymap = helix_term::keymap::default(); let keymaps = [ ("normal", keymap[&Mode::Normal].reverse_map()), ("select", keymap[&Mode::Select].reverse_map()), ("insert", keymap[&Mode::Insert].reverse_map()), ];
md.push_str(&md_table_heading(&[ "Name".to_owned(), "Description".to_owned(), "Default keybinds".to_owned(), ]));
for cmd in MappableCommand::STATIC_COMMAND_LIST { let keymap_strings: Vec<_> = keymaps .iter() .map(|(mode, keymap)| { let bindings = keymap .get(cmd.name()) .map(|bindings| { let mut bind_strings: Vec<_> = bindings .iter() .map(|bind| { let keys = &bind .iter() .map(|key| key.key_sequence_format()) .collect::<String>() // escape | so it doesn't get rendered as a column separator .replace('|', "\\|"); format!("`` {} ``", keys) }) .collect(); // sort for stable output. sorting by length puts simple // keybindings first and groups similar keys together bind_strings.sort_by_key(|s| (s.len(), s.to_owned())); bind_strings.join(", ") }) .unwrap_or_default();
(mode, bindings) }) .collect();
let keymap_string = keymap_strings .iter() .filter(|(_, bindings)| !bindings.is_empty()) .map(|(mode, bindings)| format!("{}: {}", mode, bindings)) .collect::<Vec<_>>() .join(", ");
md.push_str(&md_table_row(&[ md_mono(cmd.name()), cmd.doc().to_owned(), keymap_string, ])); }
Ok(md)}
pub fn lang_features() -> Result<String, DynError> { let mut md = String::new(); let ts_features = TsFeature::all();
let mut cols = vec!["Language".to_owned()]; cols.append( &mut ts_features .iter() .map(|t| t.long_title().to_string()) .collect::<Vec<_>>(), ); cols.push("Default language servers".to_owned());
md.push_str(&md_table_heading(&cols)); let config = helix_core::config::default_lang_config();
let mut langs = config .language .iter() .map(|l| l.language_id.clone()) .collect::<Vec<_>>(); langs.sort_unstable();
let mut ts_features_to_langs = Vec::new(); for &feat in ts_features { ts_features_to_langs.push((feat, helpers::ts_lang_support(feat))); }
let mut row = Vec::new(); for lang in langs { let lc = config .language .iter() .find(|l| l.language_id == lang) .unwrap(); // lang comes from config row.push(lc.language_id.clone());
for (_feat, support_list) in &ts_features_to_langs { row.push( if support_list.contains(&lang) { "✓" } else { "" } .to_owned(), ); } let mut seen_commands = HashSet::new(); let mut commands = String::new(); for ls_config in lc .language_servers .iter() .filter_map(|ls| config.language_server.get(&ls.name)) { let command = &ls_config.command; if !seen_commands.insert(command) { continue; }
if !commands.is_empty() { commands.push_str(", "); }
commands.push_str(&md_mono(command)); } row.push(commands);
md.push_str(&md_table_row(&row)); row.clear(); }
Ok(md)}
pub fn write(filename: &str, data: &str) { let error = format!("Could not write to {}", filename); let path = path::book_gen().join(filename); fs::write(path, data).expect(&error);}