From aa998d923aa3c7a6417e934d3c662ea06f3d8652 Mon Sep 17 00:00:00 2001 From: Sylvain Terrien Date: Tue, 6 May 2025 18:04:05 +0200 Subject: [PATCH] feat: add language filtering to hx --health `hx --health` and `hx --health languages` are now filtered to display only languages corresponding to the 'use-grammars' config. `hx --health all` remains unfiltered, and a new `hx --health all-languages` is added, which is the same as `languages`, but unfiltered. --- contrib/completion/hx.bash | 4 ++-- contrib/completion/hx.fish | 6 +++++- contrib/completion/hx.nu | 4 ++-- contrib/completion/hx.zsh | 2 +- helix-loader/src/grammar.rs | 21 +++++++++++++++++++++ helix-term/src/health.rs | 37 ++++++++++++++++++++++++++++++++++--- helix-term/src/main.rs | 6 ++++-- 7 files changed, 69 insertions(+), 11 deletions(-) diff --git a/contrib/completion/hx.bash b/contrib/completion/hx.bash index 37893bf56..bad3fa059 100644 --- a/contrib/completion/hx.bash +++ b/contrib/completion/hx.bash @@ -13,8 +13,8 @@ _hx() { return 0 ;; --health) - languages=$(hx --health | tail -n '+7' | awk '{print $1}' | sed 's/\x1b\[[0-9;]*m//g') - mapfile -t COMPREPLY < <(compgen -W """$languages""" -- "$cur") + languages=$(hx --health all-languages | tail -n '+2' | awk '{print $1}' | sed 's/\x1b\[[0-9;]*m//g') + mapfile -t COMPREPLY < <(compgen -W """clipboard languages all-languages all $languages""" -- "$cur") return 0 ;; esac diff --git a/contrib/completion/hx.fish b/contrib/completion/hx.fish index f05dba8dd..d7ce7e892 100644 --- a/contrib/completion/hx.fish +++ b/contrib/completion/hx.fish @@ -4,6 +4,10 @@ complete -c hx -s h -l help -d "Prints help information" complete -c hx -l tutor -d "Loads the tutorial" complete -c hx -l health -xa "(__hx_langs_ops)" -d "Checks for errors" +complete -c hx -l health -xka all -d "Prints all diagnostic informations" +complete -c hx -l health -xka all-languages -d "Lists all languages" +complete -c hx -l health -xka languages -d "Lists user configured languages" +complete -c hx -l health -xka clipboard -d "Prints system clipboard provider" complete -c hx -s g -l grammar -x -a "fetch build" -d "Fetch or build tree-sitter grammars" complete -c hx -s v -o vv -o vvv -d "Increases logging verbosity" complete -c hx -s V -l version -d "Prints version information" @@ -14,5 +18,5 @@ complete -c hx -l log -r -d "Specifies a file to use for logging" complete -c hx -s w -l working-dir -d "Specify initial working directory" -xa "(__fish_complete_directories)" function __hx_langs_ops - hx --health languages | tail -n '+2' | string replace -fr '^(\S+) .*' '$1' + hx --health all-languages | tail -n '+2' | string replace -fr '^(\S+) .*' '$1' end diff --git a/contrib/completion/hx.nu b/contrib/completion/hx.nu index 30eeb20fc..816b403a6 100644 --- a/contrib/completion/hx.nu +++ b/contrib/completion/hx.nu @@ -5,8 +5,8 @@ # The help message won't be overridden though, so it will still be present here def health_categories [] { - let languages = ^hx --health languages | detect columns | get Language | where { $in != null } - let completions = [ "all", "clipboard", "languages" ] | append $languages + let languages = ^hx --health all-languages | detect columns | get Language | where { $in != null } + let completions = [ "all", "clipboard", "languages", "all-languages" ] | append $languages return $completions } diff --git a/contrib/completion/hx.zsh b/contrib/completion/hx.zsh index 2631d2283..6ffccb186 100644 --- a/contrib/completion/hx.zsh +++ b/contrib/completion/hx.zsh @@ -25,7 +25,7 @@ _hx() { case "$state" in health) - local languages=($(hx --health | tail -n '+11' | awk '{print $1}' | sed 's/\x1b\[[0-9;]*m//g;s/[✘✓]//g')) + local languages=($(hx --health all-languages | tail -n '+2' | awk '{print $1}' | sed 's/\x1b\[[0-9;]*m//g;s/[✘✓]//g')) _values 'language' $languages ;; grammar) diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs index 362d3ba09..11ddc0e4b 100644 --- a/helix-loader/src/grammar.rs +++ b/helix-loader/src/grammar.rs @@ -213,6 +213,27 @@ fn get_grammar_configs() -> Result> { Ok(grammars) } +pub fn get_grammar_names() -> Result>> { + let config: Configuration = crate::config::user_lang_config() + .context("Could not parse languages.toml")? + .try_into()?; + + let grammars = match config.grammar_selection { + Some(GrammarSelection::Only { only: selections }) => Some(selections), + Some(GrammarSelection::Except { except: rejections }) => Some( + config + .grammar + .into_iter() + .map(|grammar| grammar.grammar_id) + .filter(|id| !rejections.contains(id)) + .collect(), + ), + None => None, + }; + + Ok(grammars) +} + fn run_parallel(grammars: Vec, job: F) -> Vec<(String, Result)> where F: Fn(GrammarConfiguration) -> Result + Send + 'static + Clone, diff --git a/helix-term/src/health.rs b/helix-term/src/health.rs index aeb7f7249..fcaf2b568 100644 --- a/helix-term/src/health.rs +++ b/helix-term/src/health.rs @@ -5,7 +5,7 @@ use crossterm::{ }; use helix_core::config::{default_lang_config, user_lang_config}; use helix_loader::grammar::load_runtime_file; -use std::io::Write; +use std::{collections::HashSet, io::Write}; #[derive(Copy, Clone)] pub enum TsFeature { @@ -143,6 +143,15 @@ pub fn clipboard() -> std::io::Result<()> { } pub fn languages_all() -> std::io::Result<()> { + languages(None) +} + +pub fn languages_selection() -> std::io::Result<()> { + let selection = helix_loader::grammar::get_grammar_names().unwrap_or_default(); + languages(selection) +} + +fn languages(selection: Option>) -> std::io::Result<()> { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); @@ -205,6 +214,13 @@ pub fn languages_all() -> std::io::Result<()> { let check_binary = |cmd: Option<&str>| check_binary_with_name(cmd.map(|cmd| (cmd, cmd))); for lang in &syn_loader_conf.language { + if selection + .as_ref() + .is_some_and(|s| !s.contains(&lang.language_id)) + { + continue; + } + write!(stdout, "{}", fit(&lang.language_id))?; let mut cmds = lang.language_servers.iter().filter_map(|ls| { @@ -239,6 +255,14 @@ pub fn languages_all() -> std::io::Result<()> { } } + if selection.is_some() { + writeln!( + stdout, + "\nThis list is filtered according to the 'use-grammars' option in languages.toml file.\n\ + To see the full list, use the '--health all' or '--health all-languages' option." + )?; + } + Ok(()) } @@ -400,9 +424,16 @@ fn probe_treesitter_feature(lang: &str, feature: TsFeature) -> std::io::Result<( pub fn print_health(health_arg: Option) -> std::io::Result<()> { match health_arg.as_deref() { - Some("languages") => languages_all()?, + Some("languages") => languages_selection()?, + Some("all-languages") => languages_all()?, Some("clipboard") => clipboard()?, - None | Some("all") => { + None => { + general()?; + clipboard()?; + writeln!(std::io::stdout().lock())?; + languages_selection()?; + } + Some("all") => { general()?; clipboard()?; writeln!(std::io::stdout().lock())?; diff --git a/helix-term/src/main.rs b/helix-term/src/main.rs index 31ab85cff..ccbba2e99 100644 --- a/helix-term/src/main.rs +++ b/helix-term/src/main.rs @@ -63,8 +63,10 @@ FLAGS: -h, --help Prints help information --tutor Loads the tutorial --health [CATEGORY] Checks for potential errors in editor setup - CATEGORY can be a language or one of 'clipboard', 'languages' - or 'all'. 'all' is the default if not specified. + CATEGORY can be a language or one of 'clipboard', 'languages', + 'all-languages' or 'all'. 'languages' is filtered according to + user config, 'all-languages' and 'all' are not. If not specified, + the default is the same as 'all', but with languages filtering. -g, --grammar {{fetch|build}} Fetches or builds tree-sitter grammars listed in languages.toml -c, --config Specifies a file to use for configuration -v Increases logging verbosity each use for up to 3 times