@@ -14,6 +14,7 @@ use eyre::{
1414} ;
1515use globset:: Glob ;
1616use serde_json:: json;
17+ use strum:: IntoEnumIterator ;
1718
1819use super :: OutputFormat ;
1920use crate :: database:: settings:: Setting ;
@@ -24,7 +25,20 @@ use crate::util::directories;
2425pub 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+
57188impl 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