Unnamed repository; edit this file 'description' to name the repository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

<style>
body                { margin: 0; }
pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }

.lifetime           { color: #DFAF8F; font-style: italic; }
.label              { color: #DFAF8F; font-style: italic; }
.comment            { color: #7F9F7F; }
.documentation      { color: #629755; }
.intra_doc_link     { font-style: italic; }
.injected           { opacity: 0.65 ; }
.struct, .enum      { color: #7CB8BB; }
.enum_variant       { color: #BDE0F3; }
.string_literal     { color: #CC9393; }
.field              { color: #94BFF3; }
.function           { color: #93E0E3; }
.function.unsafe    { color: #BC8383; }
.trait.unsafe       { color: #BC8383; }
.operator.unsafe    { color: #BC8383; }
.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
.keyword.unsafe     { color: #BC8383; font-weight: bold; }
.macro.unsafe       { color: #BC8383; }
.parameter          { color: #94BFF3; }
.text               { color: #DCDCCC; }
.type               { color: #7CB8BB; }
.builtin_type       { color: #8CD0D3; }
.type_param         { color: #DFAF8F; }
.attribute          { color: #94BFF3; }
.numeric_literal    { color: #BFEBBF; }
.bool_literal       { color: #BFE6EB; }
.macro              { color: #94BFF3; }
.derive             { color: #94BFF3; font-style: italic; }
.module             { color: #AFD8AF; }
.value_param        { color: #DCDCCC; }
.variable           { color: #DCDCCC; }
.format_specifier   { color: #CC696B; }
.mutable            { text-decoration: underline; }
.escape_sequence    { color: #94BFF3; }
.keyword            { color: #F0DFAF; font-weight: bold; }
.control            { font-style: italic; }
.reference          { font-style: italic; font-weight: bold; }

.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root library">foo</span><span class="semicolon">;</span>
<span class="keyword">use</span> <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>

<span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration public">NINETY_TWO</span><span class="colon">:</span> <span class="builtin_type">u8</span> <span class="operator">=</span> <span class="numeric_literal">92</span><span class="semicolon">;</span>

<span class="keyword">use</span> <span class="module crate_root library">foo</span> <span class="keyword">as</span> <span class="module crate_root declaration library">foooo</span><span class="semicolon">;</span>

<span class="keyword">pub</span><span class="parenthesis">(</span><span class="keyword crate_root public">crate</span><span class="parenthesis">)</span> <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
    <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="module default_library library">iter</span><span class="operator">::</span><span class="function default_library library">repeat</span><span class="parenthesis">(</span><span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span>

<span class="keyword">mod</span> <span class="module declaration">bar</span> <span class="brace">{</span>
    <span class="keyword">pub</span><span class="parenthesis">(</span><span class="keyword control">in</span> <span class="keyword crate_root public">super</span><span class="parenthesis">)</span> <span class="keyword">const</span> <span class="constant declaration">FORTY_TWO</span><span class="colon">:</span> <span class="builtin_type">u8</span> <span class="operator">=</span> <span class="numeric_literal">42</span><span class="semicolon">;</span>

    <span class="keyword">mod</span> <span class="module declaration">baz</span> <span class="brace">{</span>
        <span class="keyword">use</span> <span class="keyword">super</span><span class="operator">::</span><span class="keyword crate_root public">super</span><span class="operator">::</span><span class="constant public">NINETY_TWO</span><span class="semicolon">;</span>
        <span class="keyword">use</span> <span class="keyword crate_root public">crate</span><span class="operator">::</span><span class="module crate_root library">foooo</span><span class="operator">::</span><span class="struct library">Point</span><span class="semicolon">;</span>

        <span class="keyword">pub</span><span class="parenthesis">(</span><span class="keyword control">in</span> <span class="keyword">super</span><span class="operator">::</span><span class="keyword crate_root public">super</span><span class="parenthesis">)</span> <span class="keyword">const</span> <span class="constant declaration">TWENTY_NINE</span><span class="colon">:</span> <span class="builtin_type">u8</span> <span class="operator">=</span> <span class="numeric_literal">29</span><span class="semicolon">;</span>
    <span class="brace">}</span>
<span class="brace">}</span>
</code></pre>
, } } } /// Display general diagnostics. pub fn general() -> std::io::Result<()> { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); let config_file = helix_loader::config_file(); let lang_file = helix_loader::lang_config_file(); let log_file = helix_loader::log_file(); let rt_dir = helix_loader::runtime_dir(); if config_file.exists() { writeln!(stdout, "Config file: {}", config_file.display())?; } else { writeln!(stdout, "Config file: default")?; } if lang_file.exists() { writeln!(stdout, "Language file: {}", lang_file.display())?; } else { writeln!(stdout, "Language file: default")?; } writeln!(stdout, "Log file: {}", log_file.display())?; writeln!(stdout, "Runtime directory: {}", rt_dir.display())?; if let Ok(path) = std::fs::read_link(&rt_dir) { let msg = format!("Runtime directory is symlinked to {}", path.display()); writeln!(stdout, "{}", msg.yellow())?; } if !rt_dir.exists() { writeln!(stdout, "{}", "Runtime directory does not exist.".red())?; } if rt_dir.read_dir().ok().map(|it| it.count()) == Some(0) { writeln!(stdout, "{}", "Runtime directory is empty.".red())?; } Ok(()) } pub fn languages_all() -> std::io::Result<()> { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); let mut syn_loader_conf = match user_syntax_loader() { Ok(conf) => conf, Err(err) => { let stderr = std::io::stderr(); let mut stderr = stderr.lock(); writeln!( stderr, "{}: {}", "Error parsing user language config".red(), err )?; writeln!(stderr, "{}", "Using default language config".yellow())?; default_syntax_loader() } }; let mut headings = vec!["Language", "LSP", "DAP"]; for feat in TsFeature::all() { headings.push(feat.short_title()) } let terminal_cols = crossterm::terminal::size().map(|(c, _)| c).unwrap_or(80); let column_width = terminal_cols as usize / headings.len(); let column = |item: &str, color: Color| { let data = format!( "{:width$}", item.get(..column_width - 2) .map(|s| format!("{}…", s)) .unwrap_or_else(|| item.to_string()), width = column_width, ) .stylize() .with(color); // We can't directly use println!() because of // https://github.com/crossterm-rs/crossterm/issues/589 let _ = crossterm::execute!(std::io::stdout(), Print(data)); }; for heading in headings { column(heading, Color::White); } writeln!(stdout)?; syn_loader_conf .language .sort_unstable_by_key(|l| l.language_id.clone()); let check_binary = |cmd: Option<String>| match cmd { Some(cmd) => match which::which(&cmd) { Ok(_) => column(&cmd, Color::Green), Err(_) => column(&cmd, Color::Red), }, None => column("None", Color::Yellow), }; for lang in &syn_loader_conf.language { column(&lang.language_id, Color::Reset); let lsp = lang .language_server .as_ref() .map(|lsp| lsp.command.to_string()); check_binary(lsp); let dap = lang.debugger.as_ref().map(|dap| dap.command.to_string()); check_binary(dap); for ts_feat in TsFeature::all() { match load_runtime_file(&lang.language_id, ts_feat.runtime_filename()).is_ok() { true => column("Found", Color::Green), false => column("Not Found", Color::Red), } } writeln!(stdout)?; } Ok(()) } /// Display diagnostics pertaining to a particular language (LSP, /// highlight queries, etc). pub fn language(lang_str: String) -> std::io::Result<()> { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); let syn_loader_conf = match user_syntax_loader() { Ok(conf) => conf, Err(err) => { let stderr = std::io::stderr(); let mut stderr = stderr.lock(); writeln!( stderr, "{}: {}", "Error parsing user language config".red(), err )?; writeln!(stderr, "{}", "Using default language config".yellow())?; default_syntax_loader() } }; let lang = match syn_loader_conf .language .iter() .find(|l| l.language_id == lang_str) { Some(l) => l, None => { let msg = format!("Language '{}' not found", lang_str); writeln!(stdout, "{}", msg.red())?; let suggestions: Vec<&str> = syn_loader_conf .language .iter() .filter(|l| l.language_id.starts_with(lang_str.chars().next().unwrap())) .map(|l| l.language_id.as_str()) .collect(); if !suggestions.is_empty() { let suggestions = suggestions.join(", "); writeln!( stdout, "Did you mean one of these: {} ?", suggestions.yellow() )?; } return Ok(()); } }; probe_protocol( "language server", lang.language_server .as_ref() .map(|lsp| lsp.command.to_string()), )?; probe_protocol( "debug adapter", lang.debugger.as_ref().map(|dap| dap.command.to_string()), )?; for ts_feat in TsFeature::all() { probe_treesitter_feature(&lang_str, *ts_feat)? } Ok(()) } /// Display diagnostics about LSP and DAP. fn probe_protocol(protocol_name: &str, server_cmd: Option<String>) -> std::io::Result<()> { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); let cmd_name = match server_cmd { Some(ref cmd) => cmd.as_str().green(), None => "None".yellow(), }; writeln!(stdout, "Configured {}: {}", protocol_name, cmd_name)?; if let Some(cmd) = server_cmd { let path = match which::which(&cmd) { Ok(path) => path.display().to_string().green(), Err(_) => "Not found in $PATH".to_string().red(), }; writeln!(stdout, "Binary for {}: {}", protocol_name, path)?; } Ok(()) } /// Display diagnostics about a feature that requires tree-sitter /// query files (highlights, textobjects, etc). fn probe_treesitter_feature(lang: &str, feature: TsFeature) -> std::io::Result<()> { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); let found = match load_runtime_file(lang, feature.runtime_filename()).is_ok() { true => "Found".green(), false => "Not found".red(), }; writeln!(stdout, "{} queries: {}", feature.short_title(), found)?; Ok(()) } pub fn print_health(health_arg: Option<String>) -> std::io::Result<()> { match health_arg.as_deref() { Some("all") => languages_all()?, Some(lang) => language(lang.to_string())?, None => { general()?; writeln!(std::io::stdout().lock())?; languages_all()?; } } Ok(()) }