just playing with tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cli: config list: show origin of config values

Adds a `templates.config.list` config option to control whether the
detailed list is shown or not.

The `builtin_config_list_detailed` template adds the config origin to
the end of the line for each config value in the list. Options coming
from files will show the file path.

+189 -12
+3
CHANGELOG.md
··· 38 38 39 39 ### New features 40 40 41 + * The command `jj config list` now supports showing the origin of each variable 42 + via the `builtin_config_list_detailed` template. 43 + 41 44 * `jj config {edit,set,unset}` now prompt when multiple config files are found. 42 45 43 46 * `jj diff -r` now allows multiple revisions (as long as there are no gaps in
+27 -4
cli/src/commands/config/list.rs
··· 44 44 pub include_overridden: bool, 45 45 #[command(flatten)] 46 46 pub level: ConfigLevelArgs, 47 - // TODO(#1047): Support --show-origin using StackedConfig. 48 47 /// Render each variable using the given template 49 48 /// 50 49 /// The following keywords are available in the template expression: ··· 52 51 /// * `name: String`: Config name. 53 52 /// * `value: ConfigValue`: Value to be formatted in TOML syntax. 54 53 /// * `overridden: Boolean`: True if the value is shadowed by other. 54 + /// * `source: String`: Source of the value. 55 + /// * `path: String`: Path to the config file. 56 + /// 57 + /// Can be overridden by the `templates.config_list` setting. To 58 + /// see a detailed config list, use the `builtin_config_list_detailed` 59 + /// template. 55 60 /// 56 61 /// See [`jj help -k templates`] for more information. 57 62 /// ··· 73 78 ) -> Result<(), CommandError> { 74 79 let template = { 75 80 let language = config_template_language(command.settings()); 76 - let text = match &args.template { 77 - Some(value) => value.to_owned(), 81 + let template_string = match &args.template { 82 + Some(value) => value.to_string(), 78 83 None => command.settings().get_string("templates.config_list")?, 79 84 }; 80 85 command 81 - .parse_template(ui, &language, &text, GenericTemplateLanguage::wrap_self)? 86 + .parse_template( 87 + ui, 88 + &language, 89 + &template_string, 90 + GenericTemplateLanguage::wrap_self, 91 + )? 82 92 .labeled("config_list") 83 93 }; 84 94 ··· 128 138 // .decorated("", "") to trim leading/trailing whitespace 129 139 let out_property = self_property.map(|annotated| annotated.value.decorated("", "")); 130 140 Ok(L::wrap_config_value(out_property)) 141 + }); 142 + language.add_keyword("source", |self_property| { 143 + let out_property = self_property.map(|annotated| annotated.source.to_string()); 144 + Ok(L::wrap_string(out_property)) 145 + }); 146 + language.add_keyword("path", |self_property| { 147 + let out_property = self_property.map(|annotated| { 148 + annotated 149 + .path 150 + .as_ref() 151 + .map_or_else(String::new, |path| path.to_string_lossy().to_string()) 152 + }); 153 + Ok(L::wrap_string(out_property)) 131 154 }); 132 155 language.add_keyword("overridden", |self_property| { 133 156 let out_property = self_property.map(|annotated| annotated.is_overridden);
+8 -1
cli/src/config.rs
··· 96 96 pub value: ConfigValue, 97 97 /// Source of the configuration value. 98 98 pub source: ConfigSource, 99 - // TODO: add source file path 99 + /// Path to the source file, if available. 100 + pub path: Option<PathBuf>, 100 101 /// True if this value is overridden in higher precedence layers. 101 102 pub is_overridden: bool, 102 103 } ··· 151 152 name, 152 153 value, 153 154 source: layer.source, 155 + path: layer.path.clone(), 154 156 is_overridden, 155 157 }); 156 158 } ··· 969 971 }, 970 972 ), 971 973 source: EnvBase, 974 + path: None, 972 975 is_overridden: false, 973 976 }, 974 977 AnnotatedValue { ··· 996 999 }, 997 1000 ), 998 1001 source: EnvBase, 1002 + path: None, 999 1003 is_overridden: true, 1000 1004 }, 1001 1005 AnnotatedValue { ··· 1023 1027 }, 1024 1028 ), 1025 1029 source: Repo, 1030 + path: None, 1026 1031 is_overridden: false, 1027 1032 }, 1028 1033 ] ··· 1071 1076 }, 1072 1077 ), 1073 1078 source: User, 1079 + path: None, 1074 1080 is_overridden: false, 1075 1081 }, 1076 1082 AnnotatedValue { ··· 1098 1104 }, 1099 1105 ), 1100 1106 source: Repo, 1107 + path: None, 1101 1108 is_overridden: false, 1102 1109 }, 1103 1110 ]
+4
cli/src/config/colors.toml
··· 72 72 73 73 "config_list name" = "green" 74 74 "config_list value" = "yellow" 75 + "config_list source" = "blue" 76 + "config_list path" = "magenta" 75 77 "config_list overridden" = "bright black" 76 78 "config_list overridden name" = "bright black" 77 79 "config_list overridden value" = "bright black" 80 + "config_list overridden source" = "bright black" 81 + "config_list overridden path" = "bright black" 78 82 79 83 "diff header" = "yellow" 80 84 "diff empty" = "cyan"
+18 -6
cli/src/config/templates.toml
··· 31 31 ) ++ ": " ++ content 32 32 ''' 33 33 34 - config_list = ''' 35 - if(overridden, 36 - label("overridden", indent("# ", name ++ " = " ++ value)), 37 - name ++ " = " ++ value, 38 - ) ++ "\n" 39 - ''' 34 + config_list = 'builtin_config_list' 40 35 41 36 draft_commit_description = ''' 42 37 concat( ··· 72 67 ''' 73 68 74 69 [template-aliases] 70 + 71 + builtin_config_item = ''' 72 + if(overridden, 73 + label("overridden", indent("# ", name ++ " = " ++ value)), 74 + name ++ " = " ++ value, 75 + ) 76 + ''' 77 + 78 + builtin_config_list = 'builtin_config_item ++ "\n"' 79 + 80 + builtin_config_list_detailed = ''' 81 + if(overridden, 82 + label("overridden", builtin_config_item ++ " # " ++ separate(" ", source, path)), 83 + builtin_config_item ++ " # " ++ separate(" ", source, path), 84 + ) ++ "\n" 85 + ''' 86 + 75 87 builtin_log_oneline = ''' 76 88 if(root, 77 89 format_root_commit(self),
+6
cli/tests/cli-reference@.md.snap
··· 622 622 * `name: String`: Config name. 623 623 * `value: ConfigValue`: Value to be formatted in TOML syntax. 624 624 * `overridden: Boolean`: True if the value is shadowed by other. 625 + * `source: String`: Source of the value. 626 + * `path: String`: Path to the config file. 627 + 628 + Can be overridden by the `templates.config_list` setting. To 629 + see a detailed config list, use the `builtin_config_list_detailed` 630 + template. 625 631 626 632 See [`jj help -k templates`] for more information. 627 633
+3
cli/tests/test_completion.rs
··· 718 718 719 719 let output = test_env.run_jj_in(dir, ["--", "jj", "log", "-T", ""]); 720 720 insta::assert_snapshot!(output, @r" 721 + builtin_config_item 722 + builtin_config_list 723 + builtin_config_list_detailed 721 724 builtin_log_comfortable 722 725 builtin_log_compact 723 726 builtin_log_compact_full_description
+69
cli/tests/test_config_command.rs
··· 259 259 } 260 260 261 261 #[test] 262 + fn test_config_list_origin() { 263 + let mut test_env = TestEnvironment::default(); 264 + test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 265 + // Test with fresh new config file 266 + let user_config_path = test_env.config_path().join("config.toml"); 267 + test_env.set_config_path(&user_config_path); 268 + let repo_path = test_env.env_root().join("repo"); 269 + 270 + // User 271 + test_env 272 + .run_jj_in( 273 + &repo_path, 274 + ["config", "set", "--user", "test-key", "test-val"], 275 + ) 276 + .success(); 277 + 278 + test_env 279 + .run_jj_in( 280 + &repo_path, 281 + [ 282 + "config", 283 + "set", 284 + "--user", 285 + "test-layered-key", 286 + "test-original-val", 287 + ], 288 + ) 289 + .success(); 290 + 291 + // Repo 292 + test_env 293 + .run_jj_in( 294 + &repo_path, 295 + [ 296 + "config", 297 + "set", 298 + "--repo", 299 + "test-layered-key", 300 + "test-layered-val", 301 + ], 302 + ) 303 + .success(); 304 + 305 + let output = test_env.run_jj_in( 306 + &repo_path, 307 + [ 308 + "config", 309 + "list", 310 + "-Tbuiltin_config_list_detailed", 311 + "--config", 312 + "test-cli-key=test-cli-val", 313 + ], 314 + ); 315 + insta::assert_snapshot!(output, @r#" 316 + test-key = "test-val" # user $TEST_ENV/config/config.toml 317 + test-layered-key = "test-layered-val" # repo $TEST_ENV/repo/.jj/repo/config.toml 318 + user.name = "Test User" # env 319 + user.email = "test.user@example.com" # env 320 + debug.commit-timestamp = "2001-02-03T04:05:11+07:00" # env 321 + debug.randomness-seed = 5 # env 322 + debug.operation-timestamp = "2001-02-03T04:05:11+07:00" # env 323 + operation.hostname = "host.example.com" # env 324 + operation.username = "test-username" # env 325 + test-cli-key = "test-cli-val" # cli 326 + [EOF] 327 + "#); 328 + } 329 + 330 + #[test] 262 331 fn test_config_layer_override_default() { 263 332 let test_env = TestEnvironment::default(); 264 333 test_env.run_jj_in(".", ["git", "init", "repo"]).success();
+3
cli/tests/test_evolog_command.rs
··· 365 365 366 366 For more information, try '--help'. 367 367 Hint: The following template aliases are defined: 368 + - builtin_config_item 369 + - builtin_config_list 370 + - builtin_config_list_detailed 368 371 - builtin_log_comfortable 369 372 - builtin_log_compact 370 373 - builtin_log_compact_full_description
+3
cli/tests/test_log_command.rs
··· 45 45 46 46 For more information, try '--help'. 47 47 Hint: The following template aliases are defined: 48 + - builtin_config_item 49 + - builtin_config_list 50 + - builtin_config_list_detailed 48 51 - builtin_log_comfortable 49 52 - builtin_log_compact 50 53 - builtin_log_compact_full_description
+3
cli/tests/test_operations.rs
··· 170 170 171 171 For more information, try '--help'. 172 172 Hint: The following template aliases are defined: 173 + - builtin_config_item 174 + - builtin_config_list 175 + - builtin_config_list_detailed 173 176 - builtin_log_comfortable 174 177 - builtin_log_compact 175 178 - builtin_log_compact_full_description
+3
cli/tests/test_show_command.rs
··· 270 270 271 271 For more information, try '--help'. 272 272 Hint: The following template aliases are defined: 273 + - builtin_config_item 274 + - builtin_config_list 275 + - builtin_config_list_detailed 273 276 - builtin_log_comfortable 274 277 - builtin_log_compact 275 278 - builtin_log_compact_full_description
+1 -1
cli/tests/test_templater.rs
··· 147 147 | ^-----^ 148 148 | 149 149 = Keyword `builtin` doesn't exist 150 - Hint: Did you mean `builtin_log_comfortable`, `builtin_log_compact`, `builtin_log_compact_full_description`, `builtin_log_detailed`, `builtin_log_node`, `builtin_log_node_ascii`, `builtin_log_oneline`, `builtin_op_log_comfortable`, `builtin_op_log_compact`, `builtin_op_log_node`, `builtin_op_log_node_ascii`, `builtin_op_log_oneline`? 150 + Hint: Did you mean `builtin_config_item`, `builtin_config_list`, `builtin_config_list_detailed`, `builtin_log_comfortable`, `builtin_log_compact`, `builtin_log_compact_full_description`, `builtin_log_detailed`, `builtin_log_node`, `builtin_log_node_ascii`, `builtin_log_oneline`, `builtin_op_log_comfortable`, `builtin_op_log_compact`, `builtin_op_log_node`, `builtin_op_log_node_ascii`, `builtin_op_log_oneline`? 151 151 [EOF] 152 152 [exit status: 1] 153 153 ");
+23
docs/config.md
··· 368 368 You can pass the `--no-edit` flag to `prev` and `next` if you find yourself 369 369 needing the original behavior. 370 370 371 + ## List 372 + 373 + ### Default Template 374 + 375 + You can configure the template used when no `-T` is specified. 376 + 377 + - `templates.config_list` for `jj config list` 378 + 379 + ```toml 380 + [templates] 381 + # Use builtin config list template 382 + config_list = "builtin_config_list" 383 + ``` 384 + 385 + If you want to see the config variable origin (type and path) when you do `jj config list` 386 + you can add this to your config: 387 + 388 + ```toml 389 + [templates] 390 + config_list = "builtin_config_list_detailed" 391 + ``` 392 + 393 + 371 394 ## Log 372 395 373 396 ### Default revisions
+15
lib/src/config.rs
··· 17 17 use std::borrow::Borrow; 18 18 use std::convert::Infallible; 19 19 use std::fmt; 20 + use std::fmt::Display; 20 21 use std::fs; 21 22 use std::io; 22 23 use std::ops::Range; ··· 291 292 EnvOverrides, 292 293 /// Command-line arguments (which has the highest precedence.) 293 294 CommandArg, 295 + } 296 + 297 + impl Display for ConfigSource { 298 + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 299 + use ConfigSource::*; 300 + let c = match self { 301 + Default => "default", 302 + User => "user", 303 + Repo => "repo", 304 + CommandArg => "cli", 305 + EnvBase | EnvOverrides => "env", 306 + }; 307 + write!(f, "{c}") 308 + } 294 309 } 295 310 296 311 /// Set of configuration variables with source information.