From 2fd8819e1190d8ce9b8af7671ca0a1af7c333042 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Sat, 14 Dec 2024 14:03:58 +0000 Subject: [PATCH] chore: added comfy-table I think I prefer this table library, testing it out on 1 command for now --- Cargo.lock | 35 ++++++++++ Cargo.toml | 1 + README.md | 2 +- docs/cli/config/ls.md | 6 +- e2e/cli/test_ls | 8 +-- e2e/cli/test_upgrade | 8 +-- e2e/cli/test_use | 4 +- e2e/config/test_config_env | 10 +-- e2e/config/test_config_ignore | 24 +++---- src/cli/config/ls.rs | 65 +++++++----------- src/cli/ls.rs | 117 +++++++++++++------------------- src/toolset/tool_request_set.rs | 2 +- src/ui/style.rs | 9 ++- src/ui/table.rs | 57 +++++++++++++++- xtasks/fig/src/mise.ts | 3 +- 15 files changed, 208 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index def3cc779..e5f5317d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,18 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "comfy-table" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24f165e7b643266ea80cb858aed492ad9280e3e05ce24d4a99d7d7b889b6a4d9" +dependencies = [ + "crossterm", + "strum", + "strum_macros", + "unicode-width 0.2.0", +] + [[package]] name = "confique" version = "0.3.0" @@ -698,6 +710,28 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags", + "crossterm_winapi", + "parking_lot", + "rustix", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -2109,6 +2143,7 @@ dependencies = [ "clap_mangen", "color-eyre", "color-print", + "comfy-table", "confique", "console", "contracts", diff --git a/Cargo.toml b/Cargo.toml index b65bae995..cd1f3f27a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,7 @@ clap = { version = "4", features = ["env", "derive", "string"] } clap_mangen = { version = "0.2", optional = true } color-eyre = "0.6" color-print = "0.3" +comfy-table = "7.1.3" confique = { version = "0.3", default-features = false } console = "0.15" contracts = "0.6" diff --git a/README.md b/README.md index 1698ed9b2..7db07feec 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Install mise (other methods [here](https://mise.jdx.dev/getting-started.html)): ```sh-session $ curl https://mise.run | sh $ ~/.local/bin/mise --version -2024.12.9 macos-arm64 (a1b2d3e 2024-12-14) +2024.12.8 macos-arm64 (a1b2d3e 2024-12-12) ``` or install a specific a version: diff --git a/docs/cli/config/ls.md b/docs/cli/config/ls.md index 04bf93f5c..e22cc522b 100644 --- a/docs/cli/config/ls.md +++ b/docs/cli/config/ls.md @@ -1,6 +1,7 @@ # `mise config ls` - **Usage**: `mise config ls [--no-header] [-J --json]` +- **Aliases**: `list` - **Source code**: [`src/cli/config/ls.rs`](https://github.com/jdx/mise/blob/main/src/cli/config/ls.rs) List config files currently in use @@ -17,4 +18,7 @@ Output in JSON format Examples: - mise config ls + $ mise config ls + Path Tools + ~/.config/mise/config.toml pitchfork + ~/src/mise/mise.toml actionlint, bun, cargo-binstall, cargo:cargo-edit, cargo:cargo-insta diff --git a/e2e/cli/test_ls b/e2e/cli/test_ls index d2ae4e0d1..0d5d7e265 100644 --- a/e2e/cli/test_ls +++ b/e2e/cli/test_ls @@ -2,8 +2,8 @@ assert "mise use -g dummy@ref:master" assert "mise use tiny@3" -assert_contains "mise ls" "dummy ref:master ~/.config/mise/config.toml ref:master" -assert_contains "mise ls tiny" "tiny 3.1.0 ~/workdir/mise.toml 3" +assert_contains "mise ls" "dummy ref:master ~/.config/mise/config.toml ref:master" +assert_contains "mise ls tiny" "tiny 3.1.0 ~/workdir/mise.toml 3" assert "mise i tiny@2.0.0" assert_contains "mise ls" "tiny 2.0.0" assert_not_contains "mise ls -c" "tiny 2.0.0" @@ -24,8 +24,8 @@ assert "cat json | jq -r '.tiny[1].version'" "3.1.0" assert "cat json | jq -r '.tiny[1].install_path'" "$MISE_DATA_DIR/installs/tiny/3.1.0" assert "mise rm tiny@3.1.0" -assert_contains "mise ls tiny" "tiny 3.1.0 (missing) ~/workdir/mise.toml 3" -assert_contains "mise ls --missing tiny" "tiny 3.1.0 (missing) ~/workdir/mise.toml 3" +assert_contains "mise ls tiny" "tiny 3.1.0 (missing) ~/workdir/mise.toml 3" +assert_contains "mise ls --missing tiny" "tiny 3.1.0 (missing) ~/workdir/mise.toml 3" assert_not_contains "mise ls --missing tiny" "2.0.0" assert_fail "mise ls missing-tool" "missing-tool not found in mise tool registry" diff --git a/e2e/cli/test_upgrade b/e2e/cli/test_upgrade index 08401eb04..449ab3169 100644 --- a/e2e/cli/test_upgrade +++ b/e2e/cli/test_upgrade @@ -29,16 +29,16 @@ rm -f .tool-versions echo "tools.dummy = 'prefix:1'" >mise.toml mise uninstall dummy --all mkdir -p "$MISE_DATA_DIR/installs/dummy/1.0.0" -assert "mise ls dummy --outdated" "dummy 1.0.0 (outdated) ~/workdir/mise.toml prefix:1" +assert "mise ls dummy --outdated" "dummy 1.0.0 (outdated) ~/workdir/mise.toml prefix:1" assert "mise up -n" "Would uninstall dummy@1.0.0 Would install dummy@1.1.0" mise up -assert "mise ls dummy" "dummy 1.1.0 ~/workdir/mise.toml prefix:1" +assert "mise ls dummy" "dummy 1.1.0 ~/workdir/mise.toml prefix:1" assert "mise up dummy -n --bump" "Would uninstall dummy@1.1.0 Would install dummy@2.0.0 Would bump dummy@prefix:2 in ~/workdir/mise.toml" mise up dummy --bump -assert "mise ls dummy" "dummy 2.0.0 ~/workdir/mise.toml prefix:2" +assert "mise ls dummy" "dummy 2.0.0 ~/workdir/mise.toml prefix:2" echo "tools.dummy = 'prefix:1'" >mise.toml mise uninstall dummy --all mise i dummy@1.0.0 @@ -46,4 +46,4 @@ assert "mise up dummy -n --bump" "Would uninstall dummy@1.0.0 Would install dummy@2.0.0 Would bump dummy@prefix:2 in ~/workdir/mise.toml" mise up dummy --bump -assert "mise ls dummy" "dummy 2.0.0 ~/workdir/mise.toml prefix:2" +assert "mise ls dummy" "dummy 2.0.0 ~/workdir/mise.toml prefix:2" diff --git a/e2e/cli/test_use b/e2e/cli/test_use index 3fbd1a834..d1abcc7a3 100644 --- a/e2e/cli/test_use +++ b/e2e/cli/test_use @@ -67,11 +67,11 @@ rm -f ~/.config/mise/config.toml mise uninstall dummy --all mise use dummy@system -assert "mise ls dummy" "dummy system ~/workdir/mise.toml system" +assert "mise ls dummy" "dummy system ~/workdir/mise.toml system" mkdir -p ~/workdir/mydummy mise use "dummy@path:~/workdir/mydummy" -assert_contains "mise ls dummy" "dummy path:~/workdir/mydummy ~/workdir/mise.toml path:~/workdir/mydummy" +assert_contains "mise ls dummy" "dummy path:~/workdir/mydummy ~/workdir/mise.toml path:~/workdir/mydummy" cd "$HOME" || exit 1 assert_contains "mise use dummy@system" "mise ~/.config/mise/config.toml tools: dummy@system" diff --git a/e2e/config/test_config_env b/e2e/config/test_config_env index a49532615..1e9fdb477 100644 --- a/e2e/config/test_config_env +++ b/e2e/config/test_config_env @@ -4,8 +4,8 @@ echo "tools.dummy = '1'" >mise.toml echo "tools.dummy = '2'" >mise.test.toml echo "tools.dummy = '3'" >mise.ci.toml -assert "mise ls dummy" "dummy 1.1.0 (missing) ~/workdir/mise.toml 1" -MISE_ENV=test assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/mise.test.toml 2" -MISE_ENV=ci assert "mise ls dummy" "dummy 3 (missing) ~/workdir/mise.ci.toml 3" -MISE_ENV=ci,test assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/mise.test.toml 2" -MISE_ENV=test,ci assert "mise ls dummy" "dummy 3 (missing) ~/workdir/mise.ci.toml 3" +assert "mise ls dummy" "dummy 1.1.0 (missing) ~/workdir/mise.toml 1" +MISE_ENV=test assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/mise.test.toml 2" +MISE_ENV=ci assert "mise ls dummy" "dummy 3 (missing) ~/workdir/mise.ci.toml 3" +MISE_ENV=ci,test assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/mise.test.toml 2" +MISE_ENV=test,ci assert "mise ls dummy" "dummy 3 (missing) ~/workdir/mise.ci.toml 3" diff --git a/e2e/config/test_config_ignore b/e2e/config/test_config_ignore index d2debd42b..4d2c800d3 100644 --- a/e2e/config/test_config_ignore +++ b/e2e/config/test_config_ignore @@ -19,28 +19,28 @@ EOF cd subdir || exit 1 assert "mise trust --all" -assert "mise cfg" "~/workdir/mise.toml dummy -~/workdir/subdir/mise.toml dummy" -assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/subdir/mise.toml 2.0.0" +assert "mise cfg" "~/workdir/mise.toml dummy +~/workdir/subdir/mise.toml dummy" +assert "mise ls dummy" "dummy 2.0.0 (missing) ~/workdir/subdir/mise.toml 2.0.0" assert "mise settings get go_download_mirror" "subdir/mise.toml" assert "mise trust --ignore" -assert "mise cfg" "~/workdir/mise.toml dummy" +assert "mise cfg" "~/workdir/mise.toml dummy" assert "mise settings get go_download_mirror" "mise.toml" -assert "mise ls dummy" "dummy 1.0.0 (missing) ~/workdir/mise.toml 1.0.0" +assert "mise ls dummy" "dummy 1.0.0 (missing) ~/workdir/mise.toml 1.0.0" assert "mise trust ." -assert "mise cfg" "~/workdir/mise.toml dummy -~/workdir/subdir/mise.toml dummy" -assert "MISE_IGNORED_CONFIG_PATHS=~/workdir/subdir mise cfg" "~/workdir/mise.toml dummy" +assert "mise cfg" "~/workdir/mise.toml dummy +~/workdir/subdir/mise.toml dummy" +assert "MISE_IGNORED_CONFIG_PATHS=~/workdir/subdir mise cfg" "~/workdir/mise.toml dummy" assert "MISE_IGNORED_CONFIG_PATHS=~ mise cfg" "" assert "mise trust --ignore mise.toml" assert "mise trust --ignore .." assert "mise cfg" "" assert "mise trust --all" -assert "mise cfg" "~/workdir/mise.toml dummy -~/workdir/subdir/mise.toml dummy" +assert "mise cfg" "~/workdir/mise.toml dummy +~/workdir/subdir/mise.toml dummy" rm -rf "$MISE_STATE_DIR" export MISE_PARANOID=1 assert "mise trust --all" -assert "mise cfg" "~/workdir/mise.toml dummy -~/workdir/subdir/mise.toml dummy" +assert "mise cfg" "~/workdir/mise.toml dummy +~/workdir/subdir/mise.toml dummy" diff --git a/src/cli/config/ls.rs b/src/cli/config/ls.rs index 1ff59357b..49953e5da 100644 --- a/src/cli/config/ls.rs +++ b/src/cli/config/ls.rs @@ -1,17 +1,14 @@ use crate::config::config_file::ConfigFile; use crate::config::Config; use crate::file::display_path; -use crate::ui::table; -use console::style; +use crate::ui::table::MiseTable; +use comfy_table::{Attribute, Cell}; use eyre::Result; use itertools::Itertools; -use tabled::settings::object::Columns; -use tabled::settings::{Modify, Width}; -use tabled::Tabled; /// List config files currently in use #[derive(Debug, clap::Args)] -#[clap(verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)] +#[clap(visible_alias="list", verbatim_doc_comment, after_long_help = AFTER_LONG_HELP)] pub struct ConfigLs { /// Do not print table header #[clap(long, alias = "no-headers", verbatim_doc_comment)] @@ -33,17 +30,27 @@ impl ConfigLs { } fn display(&self) -> Result<()> { - let rows = Config::get() + let config = Config::get(); + let configs = config .config_files .values() .rev() - .map(|cf| cf.as_ref().into()) - .collect::>(); - let mut table = tabled::Table::new(rows); - table::default_style(&mut table, self.no_header); - table.with(Modify::new(Columns::last()).with(Width::truncate(40).suffix("…"))); - miseprintln!("{table}"); - Ok(()) + .map(|cf| cf.as_ref()) + .collect_vec(); + let mut table = MiseTable::new(self.no_header, &["Path", "Tools"]); + for cfg in configs { + let ts = cfg.to_tool_request_set().unwrap(); + let tools = ts.list_tools().into_iter().join(", "); + let tools = if tools.is_empty() { + Cell::new("(none)") + .add_attribute(Attribute::Italic) + .add_attribute(Attribute::Dim) + } else { + Cell::new(tools).add_attribute(Attribute::Dim) + }; + table.add_row(vec![Cell::new(display_path(cfg.get_path())), tools]); + } + table.truncate(true).print() } fn display_json(&self) -> Result<()> { @@ -60,7 +67,7 @@ impl ConfigLs { let plugins = c .to_tool_request_set() .unwrap() - .list_plugins() + .list_tools() .into_iter() .map(|s| serde_json::Value::String(s.to_string())) .collect::>(); @@ -74,34 +81,12 @@ impl ConfigLs { } } -fn format_tools_cell(s: String) -> String { - match s.is_empty() { - true => style("(none)").italic().dim().to_string(), - false => style(s).dim().to_string(), - } -} - -#[derive(Tabled)] -#[tabled(rename_all = "PascalCase")] -struct Row { - path: String, - tools: String, -} - -impl From<&dyn ConfigFile> for Row { - fn from(cf: &dyn ConfigFile) -> Self { - let path = display_path(cf.get_path()); - let ts = cf.to_tool_request_set().unwrap(); - let plugins = ts.list_plugins().into_iter().join(", "); - let tools = format_tools_cell(plugins); - Self { path, tools } - } -} - -// TODO: fill this out static AFTER_LONG_HELP: &str = color_print::cstr!( r#"Examples: $ mise config ls + Path Tools + ~/.config/mise/config.toml pitchfork + ~/src/mise/mise.toml actionlint, bun, cargo-binstall, cargo:cargo-edit, cargo:cargo-insta "# ); diff --git a/src/cli/ls.rs b/src/cli/ls.rs index 8f5de48a0..24c7d7db9 100644 --- a/src/cli/ls.rs +++ b/src/cli/ls.rs @@ -1,14 +1,11 @@ -use std::fmt::{Display, Formatter}; -use std::path::PathBuf; -use std::sync::Arc; - -use console::style; +use comfy_table::{Attribute, Cell, Color}; use eyre::{ensure, Result}; use indexmap::IndexMap; use itertools::Itertools; use rayon::prelude::*; use serde_derive::Serialize; -use tabled::{Table, Tabled}; +use std::path::PathBuf; +use std::sync::Arc; use versions::Versioning; use crate::backend::Backend; @@ -16,7 +13,7 @@ use crate::cli::args::BackendArg; use crate::config; use crate::config::Config; use crate::toolset::{ToolSource, ToolVersion, Toolset}; -use crate::ui::table; +use crate::ui::table::MiseTable; /// List installed and active tool versions /// @@ -139,10 +136,6 @@ impl Ls { } fn display_user(&self, runtimes: Vec) -> Result<()> { - // let data = runtimes - // .into_iter() - // .map(|(plugin, tv, source)| (plugin.to_string(), tv.to_string())) - // .collect_vec(); let rows = runtimes .into_par_iter() .map(|(ls, p, tv, source)| Row { @@ -159,10 +152,17 @@ impl Ls { }, }) .collect::>(); - let mut table = Table::new(rows); - table::default_style(&mut table, self.no_header); - miseprintln!("{}", table.to_string()); - Ok(()) + let mut table = MiseTable::new(self.no_header, &["Path", "Tools"]); + for r in rows { + let row = vec![ + r.display_tool(), + r.display_version(), + r.display_source(), + r.display_requested(), + ]; + table.add_row(row); + } + table.truncate(true).print() } fn get_runtime_list(&self, config: &Config) -> Result> { @@ -227,33 +227,52 @@ struct JSONToolVersion { type RuntimeRow<'a> = (&'a Ls, Arc, ToolVersion, ToolSource); -#[derive(Tabled)] -#[tabled(rename_all = "PascalCase")] struct Row { - #[tabled(display_with = "Self::display_tool")] tool: Arc, version: VersionStatus, - #[tabled(rename = "Config Source", display_with = "Self::display_source")] source: Option, - #[tabled(display_with = "Self::display_option")] requested: Option, } impl Row { - fn display_option(arg: &Option) -> String { - match arg { - Some(s) => s.clone(), - None => String::new(), - } + fn display_tool(&self) -> Cell { + Cell::new(&self.tool).fg(Color::Blue) } - fn display_tool(tool: &Arc) -> String { - style(tool).blue().to_string() + fn display_version(&self) -> Cell { + match &self.version { + VersionStatus::Active(version, outdated) => { + if *outdated { + Cell::new(format!("{version} (outdated)")) + .fg(Color::Yellow) + .add_attribute(Attribute::Bold) + } else { + Cell::new(version).fg(Color::Green) + } + } + VersionStatus::Inactive(version) => Cell::new(version).add_attribute(Attribute::Dim), + VersionStatus::Missing(version) => Cell::new(format!("{version} (missing)")) + .fg(Color::Red) + .add_attribute(Attribute::CrossedOut), + VersionStatus::Symlink(version, active) => { + let mut cell = Cell::new(format!("{version} (symlink)")); + if !*active { + cell = cell.add_attribute(Attribute::Dim); + } + cell + } + } } - fn display_source(source: &Option) -> String { - match source { + fn display_source(&self) -> Cell { + Cell::new(match &self.source { Some(source) => source.to_string(), None => String::new(), - } + }) + } + fn display_requested(&self) -> Cell { + Cell::new(match &self.requested { + Some(s) => s.clone(), + None => String::new(), + }) } } @@ -307,44 +326,6 @@ impl From<(&Ls, &dyn Backend, &ToolVersion, &ToolSource)> for VersionStatus { } } -impl Display for VersionStatus { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - VersionStatus::Active(version, outdated) => { - if *outdated { - write!( - f, - "{} {}", - style(version).yellow(), - style("(outdated)").yellow() - ) - } else { - write!(f, "{}", style(version).green()) - } - } - VersionStatus::Inactive(version) => write!(f, "{}", style(version).dim()), - VersionStatus::Missing(version) => write!( - f, - "{} {}", - style(version).strikethrough().red(), - style("(missing)").red() - ), - VersionStatus::Symlink(version, active) => { - write!( - f, - "{} {}", - if *active { - style(version) - } else { - style(version).dim() - }, - style("(symlink)").dim() - ) - } - } - } -} - static AFTER_LONG_HELP: &str = color_print::cstr!( r#"Examples: diff --git a/src/toolset/tool_request_set.rs b/src/toolset/tool_request_set.rs index 37891d320..63f6e8303 100644 --- a/src/toolset/tool_request_set.rs +++ b/src/toolset/tool_request_set.rs @@ -48,7 +48,7 @@ impl ToolRequestSet { .collect() } - pub fn list_plugins(&self) -> Vec<&BackendArg> { + pub fn list_tools(&self) -> Vec<&BackendArg> { self.tools.keys().collect() } diff --git a/src/ui/style.rs b/src/ui/style.rs index b9aa99fa7..064c28521 100644 --- a/src/ui/style.rs +++ b/src/ui/style.rs @@ -1,8 +1,8 @@ use std::path::Path; -use console::{style, StyledObject}; - +use crate::env::TERM_WIDTH; use crate::file::display_path; +use console::{style, StyledObject}; pub fn ereset() -> String { if console::colors_enabled_stderr() { @@ -91,3 +91,8 @@ pub fn nred(val: D) -> StyledObject { pub fn ndim(val: D) -> StyledObject { nstyle(val).dim() } + +#[allow(unused)] +pub fn truncate_str(s: impl AsRef) -> String { + console::truncate_str(s.as_ref(), *TERM_WIDTH - 14, "…").to_string() +} diff --git a/src/ui/table.rs b/src/ui/table.rs index 4979d8fc9..cae462b4c 100644 --- a/src/ui/table.rs +++ b/src/ui/table.rs @@ -1,11 +1,14 @@ +use crate::env::TERM_WIDTH; +use crate::Result; +use comfy_table::{Attribute, Cell, Color, ContentArrangement, Row}; use console::style; +use itertools::Itertools; use tabled::settings::object::{Columns, Rows}; use tabled::settings::peaker::PriorityMax; use tabled::settings::width::{MinWidth, Wrap}; use tabled::settings::{Format, Margin, Modify, Padding, Remove, Settings, Style, Width}; use tabled::Table; - -use crate::env::TERM_WIDTH; +use xx::regex; type SettingPriority = Settings>; type SettingMinWidth = Settings; @@ -43,3 +46,53 @@ pub fn disable_columns(table: &mut Table, col_idxs: Vec) { table.with(Remove::column(Columns::single(idx))); } } + +pub struct MiseTable { + table: comfy_table::Table, + truncate: bool, +} + +impl MiseTable { + pub fn new(no_header: bool, headers: &[&str]) -> Self { + let mut table = comfy_table::Table::new(); + table + .load_preset(comfy_table::presets::NOTHING) + .set_content_arrangement(ContentArrangement::Dynamic); + if !no_header && console::user_attended() { + let headers = headers.iter().map(Self::header).collect_vec(); + table.set_header(headers); + } + Self { + table, + truncate: false, + } + } + + pub fn truncate(&mut self, truncate: bool) -> &mut Self { + self.truncate = truncate; + self + } + + fn header(title: impl ToString) -> Cell { + Cell::new(title) + .add_attribute(Attribute::Italic) + .fg(Color::Magenta) + } + + pub fn add_row(&mut self, row: impl Into) { + let mut row = row.into(); + row.max_height(1); + self.table.add_row(row); + } + + pub fn print(&self) -> Result<()> { + let table = self.table.to_string(); + // trim first character, skipping color characters + let re = regex!(r"^(\x{1b}[^ ]*\d+m) "); + for line in table.lines() { + let line = re.replacen(line.trim(), 1, "$1"); + println!("{}", line); + } + Ok(()) + } +} diff --git a/xtasks/fig/src/mise.ts b/xtasks/fig/src/mise.ts index 052e715ae..9b99e1de9 100644 --- a/xtasks/fig/src/mise.ts +++ b/xtasks/fig/src/mise.ts @@ -736,7 +736,8 @@ const completionSpec: Fig.Spec = { }, { "name": [ - "ls" + "ls", + "list" ], "description": "List config files currently in use", "options": [