Skip to content

Commit 1999b5a

Browse files
authored
fix: improve settings list display (#3167)
* fix: improve settings list display * fix: q settings list with --all option
1 parent 6327829 commit 1999b5a

File tree

1 file changed

+147
-17
lines changed

1 file changed

+147
-17
lines changed

crates/chat-cli/src/cli/settings.rs

Lines changed: 147 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use eyre::{
1414
};
1515
use globset::Glob;
1616
use serde_json::json;
17+
use strum::IntoEnumIterator;
1718

1819
use super::OutputFormat;
1920
use crate::database::settings::Setting;
@@ -24,7 +25,20 @@ use crate::util::directories;
2425
pub enum SettingsSubcommands {
2526
/// Open the settings file
2627
Open,
27-
/// List all the settings
28+
/// List settings
29+
List {
30+
/// Show all available settings
31+
#[arg(long)]
32+
all: bool,
33+
/// Format of the output
34+
#[arg(long, short, value_enum, default_value_t)]
35+
format: OutputFormat,
36+
/// Whether or not we want to modify state instead
37+
#[arg(long, short, hide = true)]
38+
state: bool,
39+
},
40+
/// List configured settings
41+
#[command(hide = true)]
2842
All {
2943
/// Format of the output
3044
#[arg(long, short, value_enum, default_value_t)]
@@ -54,6 +68,123 @@ pub struct SettingsArgs {
5468
format: OutputFormat,
5569
}
5670

71+
#[derive(Debug)]
72+
struct SettingInfo {
73+
/// Setting key
74+
key: String,
75+
/// Setting description
76+
description: String,
77+
/// Current setting value
78+
current_value: Option<serde_json::Value>,
79+
}
80+
81+
/// Print configured settings
82+
fn print_configured_settings(os: &Os, format: OutputFormat) -> Result<()> {
83+
let settings = os.database.settings.map().clone();
84+
match format {
85+
OutputFormat::Plain => {
86+
for (key, value) in settings {
87+
println!("{key} = {value}");
88+
}
89+
},
90+
OutputFormat::Json => {
91+
println!("{}", serde_json::to_string(&settings)?);
92+
},
93+
OutputFormat::JsonPretty => {
94+
println!("{}", serde_json::to_string_pretty(&settings)?);
95+
},
96+
}
97+
Ok(())
98+
}
99+
100+
/// Print internal state table dump (hidden debug feature)
101+
fn print_state_dump(os: &Os, format: OutputFormat) -> Result<()> {
102+
let settings = os.database.get_all_entries()?;
103+
match format {
104+
OutputFormat::Plain => {
105+
for (key, value) in settings {
106+
println!("{key} = {value}");
107+
}
108+
},
109+
OutputFormat::Json => {
110+
println!("{}", serde_json::to_string(&settings)?);
111+
},
112+
OutputFormat::JsonPretty => {
113+
println!("{}", serde_json::to_string_pretty(&settings)?);
114+
},
115+
}
116+
Ok(())
117+
}
118+
119+
/// Collect all settings with their metadata and current values
120+
fn collect_settings(os: &Os) -> Vec<SettingInfo> {
121+
use strum::EnumMessage;
122+
123+
Setting::iter()
124+
.map(|setting| {
125+
let key = setting.as_ref().to_string();
126+
let description = setting.get_message().unwrap_or("No description").to_string();
127+
let current_value = os.database.settings.get(setting).cloned();
128+
129+
SettingInfo {
130+
key,
131+
description,
132+
current_value,
133+
}
134+
})
135+
.collect()
136+
}
137+
138+
/// Print settings list in plain text format with colors
139+
fn print_settings_plain(settings: &[SettingInfo]) {
140+
for setting in settings {
141+
println!("{}", setting.key.as_str().cyan().bold());
142+
println!(" Description: {}", setting.description);
143+
match &setting.current_value {
144+
Some(value) => println!(" Current: {}", value.to_string().green()),
145+
None => println!(" Current: {}", "not set".dim()),
146+
}
147+
println!();
148+
}
149+
}
150+
151+
/// Print settings list in JSON or JSON Pretty format
152+
fn print_settings_json(settings: &[SettingInfo], pretty: bool) -> Result<()> {
153+
let settings_list: Vec<_> = settings
154+
.iter()
155+
.map(|s| {
156+
json!({
157+
"key": s.key,
158+
"description": s.description,
159+
"current_value": s.current_value,
160+
})
161+
})
162+
.collect();
163+
164+
let output = if pretty {
165+
serde_json::to_string_pretty(&settings_list)?
166+
} else {
167+
serde_json::to_string(&settings_list)?
168+
};
169+
170+
println!("{}", output);
171+
Ok(())
172+
}
173+
174+
/// Print all available settings
175+
fn print_all_settings(os: &Os, format: OutputFormat) -> Result<()> {
176+
let settings = collect_settings(os);
177+
178+
match format {
179+
OutputFormat::Plain => {
180+
print_settings_plain(&settings);
181+
Ok(())
182+
},
183+
OutputFormat::Json => print_settings_json(&settings, false),
184+
OutputFormat::JsonPretty => print_settings_json(&settings, true),
185+
}
186+
}
187+
57188
impl SettingsArgs {
58189
pub async fn execute(&self, os: &mut Os) -> Result<ExitCode> {
59190
match self.cmd {
@@ -66,24 +197,23 @@ impl SettingsArgs {
66197
bail!("The EDITOR environment variable is not set")
67198
}
68199
},
200+
Some(SettingsSubcommands::List { all, format, state }) => {
201+
if state {
202+
print_state_dump(os, format)?;
203+
} else if all {
204+
print_all_settings(os, format)?;
205+
} else {
206+
print_configured_settings(os, format)?;
207+
}
208+
Ok(ExitCode::SUCCESS)
209+
},
69210
Some(SettingsSubcommands::All { format, state }) => {
70-
let settings = match state {
71-
true => os.database.get_all_entries()?,
72-
false => os.database.settings.map().clone(),
73-
};
74-
75-
match format {
76-
OutputFormat::Plain => {
77-
for (key, value) in settings {
78-
println!("{key} = {value}");
79-
}
80-
},
81-
OutputFormat::Json => println!("{}", serde_json::to_string(&settings)?),
82-
OutputFormat::JsonPretty => {
83-
println!("{}", serde_json::to_string_pretty(&settings)?);
84-
},
211+
// Deprecated: redirect to List behavior for backward compatibility
212+
if state {
213+
print_state_dump(os, format)?;
214+
} else {
215+
print_configured_settings(os, format)?;
85216
}
86-
87217
Ok(ExitCode::SUCCESS)
88218
},
89219
None => {

0 commit comments

Comments
 (0)