page_data.rs

   1use settings::{LanguageSettingsContent, SettingsContent};
   2use std::sync::Arc;
   3use ui::{IntoElement, SharedString};
   4
   5use crate::{
   6    SettingField, SettingItem, SettingsFieldMetadata, SettingsPage, SettingsPageItem, SubPageLink,
   7    sub_page_stack,
   8};
   9
  10pub(crate) fn user_settings_data() -> Vec<SettingsPage> {
  11    vec![
  12        SettingsPage {
  13            title: "General Page",
  14            items: vec![
  15                SettingsPageItem::SectionHeader("General"),
  16                SettingsPageItem::SettingItem(SettingItem {
  17                    title: "Confirm Quit",
  18                    description: "Whether to confirm before quitting Zed",
  19                    field: Box::new(SettingField {
  20                        pick: |settings_content| &settings_content.workspace.confirm_quit,
  21                        pick_mut: |settings_content| &mut settings_content.workspace.confirm_quit,
  22                    }),
  23                    metadata: None,
  24                }),
  25                SettingsPageItem::SettingItem(SettingItem {
  26                    title: "Restore On Startup",
  27                    description: "Whether to restore previous session when opening Zed",
  28                    field: Box::new(SettingField {
  29                        pick: |settings_content| &settings_content.workspace.restore_on_startup,
  30                        pick_mut: |settings_content| {
  31                            &mut settings_content.workspace.restore_on_startup
  32                        },
  33                    }),
  34                    metadata: None,
  35                }),
  36                SettingsPageItem::SettingItem(SettingItem {
  37                    title: "Restore File State",
  38                    description: "Whether to restore previous file state when reopening",
  39                    field: Box::new(SettingField {
  40                        pick: |settings_content| &settings_content.workspace.restore_on_file_reopen,
  41                        pick_mut: |settings_content| {
  42                            &mut settings_content.workspace.restore_on_file_reopen
  43                        },
  44                    }),
  45                    metadata: None,
  46                }),
  47                SettingsPageItem::SettingItem(SettingItem {
  48                    title: "Close on File Delete",
  49                    description: "Whether to automatically close files that have been deleted",
  50                    field: Box::new(SettingField {
  51                        pick: |settings_content| &settings_content.workspace.close_on_file_delete,
  52                        pick_mut: |settings_content| {
  53                            &mut settings_content.workspace.close_on_file_delete
  54                        },
  55                    }),
  56                    metadata: None,
  57                }),
  58                SettingsPageItem::SettingItem(SettingItem {
  59                    title: "When Closing With No Tabs",
  60                    description: "What to do when using 'close active item' with no tabs",
  61                    field: Box::new(SettingField {
  62                        pick: |settings_content| {
  63                            &settings_content.workspace.when_closing_with_no_tabs
  64                        },
  65                        pick_mut: |settings_content| {
  66                            &mut settings_content.workspace.when_closing_with_no_tabs
  67                        },
  68                    }),
  69                    metadata: None,
  70                }),
  71                SettingsPageItem::SettingItem(SettingItem {
  72                    title: "On Last Window Closed",
  73                    description: "What to do when the last window is closed",
  74                    field: Box::new(SettingField {
  75                        pick: |settings_content| &settings_content.workspace.on_last_window_closed,
  76                        pick_mut: |settings_content| {
  77                            &mut settings_content.workspace.on_last_window_closed
  78                        },
  79                    }),
  80                    metadata: None,
  81                }),
  82                SettingsPageItem::SettingItem(SettingItem {
  83                    title: "Use System Path Prompts",
  84                    description: "Whether to use system dialogs for Open and Save As",
  85                    field: Box::new(SettingField {
  86                        pick: |settings_content| {
  87                            &settings_content.workspace.use_system_path_prompts
  88                        },
  89                        pick_mut: |settings_content| {
  90                            &mut settings_content.workspace.use_system_path_prompts
  91                        },
  92                    }),
  93                    metadata: None,
  94                }),
  95                SettingsPageItem::SettingItem(SettingItem {
  96                    title: "Use System Prompts",
  97                    description: "Whether to use system prompts for confirmations",
  98                    field: Box::new(SettingField {
  99                        pick: |settings_content| &settings_content.workspace.use_system_prompts,
 100                        pick_mut: |settings_content| {
 101                            &mut settings_content.workspace.use_system_prompts
 102                        },
 103                    }),
 104                    metadata: None,
 105                }),
 106                SettingsPageItem::SectionHeader("Scoped Settings"),
 107                // todo(settings_ui): Implement another setting item type that just shows an edit in settings.json
 108                // SettingsPageItem::SettingItem(SettingItem {
 109                //     title: "Preview Channel",
 110                //     description: "Which settings should be activated only in Preview build of Zed",
 111                //     field: Box::new(SettingField {
 112                //         pick: |settings_content| &settings_content.workspace.use_system_prompts,
 113                //         pick_mut: |settings_content| {
 114                //             &mut settings_content.workspace.use_system_prompts
 115                //         },
 116                //     }),
 117                //     metadata: None,
 118                // }),
 119                // SettingsPageItem::SettingItem(SettingItem {
 120                //     title: "Settings Profiles",
 121                //     description: "Any number of settings profiles that are temporarily applied on top of your existing user settings.",
 122                //     field: Box::new(SettingField {
 123                //         pick: |settings_content| &settings_content.workspace.use_system_prompts,
 124                //         pick_mut: |settings_content| {
 125                //             &mut settings_content.workspace.use_system_prompts
 126                //         },
 127                //     }),
 128                //     metadata: None,
 129                // }),
 130                SettingsPageItem::SectionHeader("Privacy"),
 131                SettingsPageItem::SettingItem(SettingItem {
 132                    title: "Telemetry Diagnostics",
 133                    description: "Send debug info like crash reports.",
 134                    field: Box::new(SettingField {
 135                        pick: |settings_content| {
 136                            if let Some(telemetry) = &settings_content.telemetry {
 137                                &telemetry.diagnostics
 138                            } else {
 139                                &None
 140                            }
 141                        },
 142                        pick_mut: |settings_content| {
 143                            &mut settings_content
 144                                .telemetry
 145                                .get_or_insert_default()
 146                                .diagnostics
 147                        },
 148                    }),
 149                    metadata: None,
 150                }),
 151                SettingsPageItem::SettingItem(SettingItem {
 152                    title: "Telemetry Metrics",
 153                    description: "Send anonymized usage data like what languages you're using Zed with.",
 154                    field: Box::new(SettingField {
 155                        pick: |settings_content| {
 156                            if let Some(telemetry) = &settings_content.telemetry {
 157                                &telemetry.metrics
 158                            } else {
 159                                &None
 160                            }
 161                        },
 162                        pick_mut: |settings_content| {
 163                            &mut settings_content.telemetry.get_or_insert_default().metrics
 164                        },
 165                    }),
 166                    metadata: None,
 167                }),
 168            ],
 169        },
 170        SettingsPage {
 171            title: "Appearance & Behavior",
 172            items: vec![
 173                SettingsPageItem::SectionHeader("Theme"),
 174                // todo(settings_ui): Figure out how we want to add these
 175                // SettingsPageItem::SettingItem(SettingItem {
 176                //     title: "Theme Mode",
 177                //     description: "How to select the theme",
 178                //     field: Box::new(SettingField {
 179                //         pick: |settings_content| &settings_content.theme.theme,
 180                //         pick_mut: |settings_content| &mut settings_content.theme.theme,
 181                //     }),
 182                //     metadata: None,
 183                // }),
 184                // SettingsPageItem::SettingItem(SettingItem {
 185                //     title: "Icon Theme",
 186                //     // todo(settings_ui)
 187                //     // This description is misleading because the icon theme is used in more places than the file explorer)
 188                //     description: "Choose the icon theme for file explorer",
 189                //     field: Box::new(SettingField {
 190                //         pick: |settings_content| &settings_content.theme.icon_theme,
 191                //         pick_mut: |settings_content| &mut settings_content.theme.icon_theme,
 192                //     }),
 193                //     metadata: None,
 194                // }),
 195                SettingsPageItem::SectionHeader("Layout"),
 196                SettingsPageItem::SettingItem(SettingItem {
 197                    title: "Bottom Dock Layout",
 198                    description: "Layout mode for the bottom dock",
 199                    field: Box::new(SettingField {
 200                        pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
 201                        pick_mut: |settings_content| {
 202                            &mut settings_content.workspace.bottom_dock_layout
 203                        },
 204                    }),
 205                    metadata: None,
 206                }),
 207                SettingsPageItem::SettingItem(SettingItem {
 208                    title: "Zoomed Padding",
 209                    description: "Whether to show padding for zoomed panels",
 210                    field: Box::new(SettingField {
 211                        pick: |settings_content| &settings_content.workspace.zoomed_padding,
 212                        pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
 213                    }),
 214                    metadata: None,
 215                }),
 216                SettingsPageItem::SettingItem(SettingItem {
 217                    title: "Use System Window Tabs",
 218                    description: "Whether to allow windows to tab together based on the user's tabbing preference (macOS only)",
 219                    field: Box::new(SettingField {
 220                        pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
 221                        pick_mut: |settings_content| {
 222                            &mut settings_content.workspace.use_system_window_tabs
 223                        },
 224                    }),
 225                    metadata: None,
 226                }),
 227                SettingsPageItem::SectionHeader("Fonts"),
 228                SettingsPageItem::SettingItem(SettingItem {
 229                    title: "Buffer Font Family",
 230                    description: "Font family for editor text",
 231                    field: Box::new(SettingField {
 232                        pick: |settings_content| &settings_content.theme.buffer_font_family,
 233                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_family,
 234                    }),
 235                    metadata: None,
 236                }),
 237                SettingsPageItem::SettingItem(SettingItem {
 238                    title: "Buffer Font Size",
 239                    description: "Font size for editor text",
 240                    field: Box::new(SettingField {
 241                        pick: |settings_content| &settings_content.theme.buffer_font_size,
 242                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_size,
 243                    }),
 244                    metadata: None,
 245                }),
 246                SettingsPageItem::SettingItem(SettingItem {
 247                    title: "Buffer Font Weight",
 248                    description: "Font weight for editor text (100-900)",
 249                    field: Box::new(SettingField {
 250                        pick: |settings_content| &settings_content.theme.buffer_font_weight,
 251                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_weight,
 252                    }),
 253                    metadata: None,
 254                }),
 255                // todo(settings_ui): This needs custom ui
 256                // SettingsPageItem::SettingItem(SettingItem {
 257                //     title: "Buffer Line Height",
 258                //     description: "Line height for editor text",
 259                //     field: Box::new(SettingField {
 260                //         pick: |settings_content| &settings_content.theme.buffer_line_height,
 261                //         pick_mut: |settings_content| &mut settings_content.theme.buffer_line_height,
 262                //     }),
 263                //     metadata: None,
 264                // }),
 265                SettingsPageItem::SettingItem(SettingItem {
 266                    title: "UI Font Family",
 267                    description: "Font family for UI elements",
 268                    field: Box::new(SettingField {
 269                        pick: |settings_content| &settings_content.theme.ui_font_family,
 270                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_family,
 271                    }),
 272                    metadata: None,
 273                }),
 274                SettingsPageItem::SettingItem(SettingItem {
 275                    title: "UI Font Size",
 276                    description: "Font size for UI elements",
 277                    field: Box::new(SettingField {
 278                        pick: |settings_content| &settings_content.theme.ui_font_size,
 279                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_size,
 280                    }),
 281                    metadata: None,
 282                }),
 283                SettingsPageItem::SettingItem(SettingItem {
 284                    title: "UI Font Weight",
 285                    description: "Font weight for UI elements (100-900)",
 286                    field: Box::new(SettingField {
 287                        pick: |settings_content| &settings_content.theme.ui_font_weight,
 288                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_weight,
 289                    }),
 290                    metadata: None,
 291                }),
 292                SettingsPageItem::SectionHeader("Keymap"),
 293                SettingsPageItem::SettingItem(SettingItem {
 294                    title: "Base Keymap",
 295                    description: "The name of a base set of key bindings to use",
 296                    field: Box::new(SettingField {
 297                        pick: |settings_content| &settings_content.base_keymap,
 298                        pick_mut: |settings_content| &mut settings_content.base_keymap,
 299                    }),
 300                    metadata: None,
 301                }),
 302                // todo(settings_ui): Vim/Helix Mode should be apart of one type because it's undefined
 303                // behavior to have them both enabled at the same time
 304                SettingsPageItem::SettingItem(SettingItem {
 305                    title: "Vim Mode",
 306                    description: "Whether to enable vim modes and key bindings",
 307                    field: Box::new(SettingField {
 308                        pick: |settings_content| &settings_content.vim_mode,
 309                        pick_mut: |settings_content| &mut settings_content.vim_mode,
 310                    }),
 311                    metadata: None,
 312                }),
 313                SettingsPageItem::SettingItem(SettingItem {
 314                    title: "Helix Mode",
 315                    description: "Whether to enable helix modes and key bindings",
 316                    field: Box::new(SettingField {
 317                        pick: |settings_content| &settings_content.helix_mode,
 318                        pick_mut: |settings_content| &mut settings_content.helix_mode,
 319                    }),
 320                    metadata: None,
 321                }),
 322                SettingsPageItem::SettingItem(SettingItem {
 323                    title: "Multi Cursor Modifier",
 324                    description: "Modifier key for adding multiple cursors",
 325                    field: Box::new(SettingField {
 326                        pick: |settings_content| &settings_content.editor.multi_cursor_modifier,
 327                        pick_mut: |settings_content| {
 328                            &mut settings_content.editor.multi_cursor_modifier
 329                        },
 330                    }),
 331                    metadata: None,
 332                }),
 333                SettingsPageItem::SectionHeader("Cursor"),
 334                SettingsPageItem::SettingItem(SettingItem {
 335                    title: "Cursor Blink",
 336                    description: "Whether the cursor blinks in the editor",
 337                    field: Box::new(SettingField {
 338                        pick: |settings_content| &settings_content.editor.cursor_blink,
 339                        pick_mut: |settings_content| &mut settings_content.editor.cursor_blink,
 340                    }),
 341                    metadata: None,
 342                }),
 343                SettingsPageItem::SettingItem(SettingItem {
 344                    title: "Cursor Shape",
 345                    description: "Cursor shape for the editor",
 346                    field: Box::new(SettingField {
 347                        pick: |settings_content| &settings_content.editor.cursor_shape,
 348                        pick_mut: |settings_content| &mut settings_content.editor.cursor_shape,
 349                    }),
 350                    metadata: None,
 351                }),
 352                SettingsPageItem::SettingItem(SettingItem {
 353                    title: "Hide Mouse",
 354                    description: "When to hide the mouse cursor",
 355                    field: Box::new(SettingField {
 356                        pick: |settings_content| &settings_content.editor.hide_mouse,
 357                        pick_mut: |settings_content| &mut settings_content.editor.hide_mouse,
 358                    }),
 359                    metadata: None,
 360                }),
 361                SettingsPageItem::SectionHeader("Highlighting"),
 362                SettingsPageItem::SettingItem(SettingItem {
 363                    title: "Unnecessary Code Fade",
 364                    description: "How much to fade out unused code (0.0 - 0.9)",
 365                    field: Box::new(SettingField {
 366                        pick: |settings_content| &settings_content.theme.unnecessary_code_fade,
 367                        pick_mut: |settings_content| {
 368                            &mut settings_content.theme.unnecessary_code_fade
 369                        },
 370                    }),
 371                    metadata: None,
 372                }),
 373                SettingsPageItem::SettingItem(SettingItem {
 374                    title: "Current Line Highlight",
 375                    description: "How to highlight the current line",
 376                    field: Box::new(SettingField {
 377                        pick: |settings_content| &settings_content.editor.current_line_highlight,
 378                        pick_mut: |settings_content| {
 379                            &mut settings_content.editor.current_line_highlight
 380                        },
 381                    }),
 382                    metadata: None,
 383                }),
 384                SettingsPageItem::SettingItem(SettingItem {
 385                    title: "Selection Highlight",
 386                    description: "Whether to highlight all occurrences of selected text",
 387                    field: Box::new(SettingField {
 388                        pick: |settings_content| &settings_content.editor.selection_highlight,
 389                        pick_mut: |settings_content| {
 390                            &mut settings_content.editor.selection_highlight
 391                        },
 392                    }),
 393                    metadata: None,
 394                }),
 395                SettingsPageItem::SettingItem(SettingItem {
 396                    title: "Rounded Selection",
 397                    description: "Whether the text selection should have rounded corners",
 398                    field: Box::new(SettingField {
 399                        pick: |settings_content| &settings_content.editor.rounded_selection,
 400                        pick_mut: |settings_content| &mut settings_content.editor.rounded_selection,
 401                    }),
 402                    metadata: None,
 403                }),
 404                SettingsPageItem::SectionHeader("Guides"),
 405                SettingsPageItem::SettingItem(SettingItem {
 406                    title: "Show Wrap Guides",
 407                    description: "Whether to show wrap guides (vertical rulers)",
 408                    field: Box::new(SettingField {
 409                        pick: |settings_content| {
 410                            &settings_content
 411                                .project
 412                                .all_languages
 413                                .defaults
 414                                .show_wrap_guides
 415                        },
 416                        pick_mut: |settings_content| {
 417                            &mut settings_content
 418                                .project
 419                                .all_languages
 420                                .defaults
 421                                .show_wrap_guides
 422                        },
 423                    }),
 424                    metadata: None,
 425                }),
 426                // todo(settings_ui): This needs a custom component
 427                // SettingsPageItem::SettingItem(SettingItem {
 428                //     title: "Wrap Guides",
 429                //     description: "Character counts at which to show wrap guides",
 430                //     field: Box::new(SettingField {
 431                //         pick: |settings_content| {
 432                //             &settings_content
 433                //                 .project
 434                //                 .all_languages
 435                //                 .defaults
 436                //                 .wrap_guides
 437                //         },
 438                //         pick_mut: |settings_content| {
 439                //             &mut settings_content
 440                //                 .project
 441                //                 .all_languages
 442                //                 .defaults
 443                //                 .wrap_guides
 444                //         },
 445                //     }),
 446                //     metadata: None,
 447                // }),
 448                SettingsPageItem::SectionHeader("Whitespace"),
 449                SettingsPageItem::SettingItem(SettingItem {
 450                    title: "Show Whitespace",
 451                    description: "Whether to show tabs and spaces",
 452                    field: Box::new(SettingField {
 453                        pick: |settings_content| {
 454                            &settings_content
 455                                .project
 456                                .all_languages
 457                                .defaults
 458                                .show_whitespaces
 459                        },
 460                        pick_mut: |settings_content| {
 461                            &mut settings_content
 462                                .project
 463                                .all_languages
 464                                .defaults
 465                                .show_whitespaces
 466                        },
 467                    }),
 468                    metadata: None,
 469                }),
 470                SettingsPageItem::SectionHeader("Window"),
 471                // todo(settings_ui): Should we filter by platform?
 472                SettingsPageItem::SettingItem(SettingItem {
 473                    title: "Use System Window Tabs",
 474                    description: "Whether to allow windows to tab together (macOS only)",
 475                    field: Box::new(SettingField {
 476                        pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
 477                        pick_mut: |settings_content| {
 478                            &mut settings_content.workspace.use_system_window_tabs
 479                        },
 480                    }),
 481                    metadata: None,
 482                }),
 483                SettingsPageItem::SectionHeader("Layout"),
 484                SettingsPageItem::SettingItem(SettingItem {
 485                    title: "Zoomed Padding",
 486                    description: "Whether to show padding for zoomed panels",
 487                    field: Box::new(SettingField {
 488                        pick: |settings_content| &settings_content.workspace.zoomed_padding,
 489                        pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
 490                    }),
 491                    metadata: None,
 492                }),
 493                // todo(settings_ui): Needs numeric stepper   option within an option
 494                // SettingsPageItem::SettingItem(SettingItem {
 495                //     title: "Centered Layout Left Padding",
 496                //     description: "Left padding for centered layout",
 497                //     field: Box::new(SettingField {
 498                //         pick: |settings_content| {
 499                //             &settings_content.workspace.centered_layout.left_padding
 500                //         },
 501                //         pick_mut: |settings_content| {
 502                //             &mut settings_content.workspace.centered_layout.left_padding
 503                //         },
 504                //     }),
 505                //     metadata: None,
 506                // }),
 507                // SettingsPageItem::SettingItem(SettingItem {
 508                //     title: "Centered Layout Right Padding",
 509                //     description: "Right padding for centered layout",
 510                //     field: Box::new(SettingField {
 511                //         pick: |settings_content| {
 512                //             if let Some(centered_layout) =
 513                //                 &settings_content.workspace.centered_layout
 514                //             {
 515                //                 &centered_layout.right_padding
 516                //             } else {
 517                //                 &None
 518                //             }
 519                //         },
 520                //         pick_mut: |settings_content| {
 521                //             if let Some(mut centered_layout) =
 522                //                 settings_content.workspace.centered_layout
 523                //             {
 524                //                 &mut centered_layout.right_padding
 525                //             } else {
 526                //                 &mut None
 527                //             }
 528                //         },
 529                //     }),
 530                //     metadata: None,
 531                // }),
 532                SettingsPageItem::SettingItem(SettingItem {
 533                    title: "Bottom Dock Layout",
 534                    description: "Layout mode of the bottom dock",
 535                    field: Box::new(SettingField {
 536                        pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
 537                        pick_mut: |settings_content| {
 538                            &mut settings_content.workspace.bottom_dock_layout
 539                        },
 540                    }),
 541                    metadata: None,
 542                }),
 543            ],
 544        },
 545        SettingsPage {
 546            title: "Editor",
 547            items: vec![
 548                SettingsPageItem::SectionHeader("Indentation"),
 549                // todo(settings_ui): Needs numeric stepper
 550                SettingsPageItem::SettingItem(SettingItem {
 551                    title: "Tab Size",
 552                    description: "How many columns a tab should occupy",
 553                    field: Box::new(SettingField {
 554                        pick: |settings_content| {
 555                            &settings_content.project.all_languages.defaults.tab_size
 556                        },
 557                        pick_mut: |settings_content| {
 558                            &mut settings_content.project.all_languages.defaults.tab_size
 559                        },
 560                    }),
 561                    metadata: None,
 562                }),
 563                SettingsPageItem::SettingItem(SettingItem {
 564                    title: "Hard Tabs",
 565                    description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
 566                    field: Box::new(SettingField {
 567                        pick: |settings_content| {
 568                            &settings_content.project.all_languages.defaults.hard_tabs
 569                        },
 570                        pick_mut: |settings_content| {
 571                            &mut settings_content.project.all_languages.defaults.hard_tabs
 572                        },
 573                    }),
 574                    metadata: None,
 575                }),
 576                SettingsPageItem::SettingItem(SettingItem {
 577                    title: "Auto Indent",
 578                    description: "Whether indentation should be adjusted based on the context whilst typing",
 579                    field: Box::new(SettingField {
 580                        pick: |settings_content| {
 581                            &settings_content.project.all_languages.defaults.auto_indent
 582                        },
 583                        pick_mut: |settings_content| {
 584                            &mut settings_content.project.all_languages.defaults.auto_indent
 585                        },
 586                    }),
 587                    metadata: None,
 588                }),
 589                SettingsPageItem::SettingItem(SettingItem {
 590                    title: "Auto Indent On Paste",
 591                    description: "Whether indentation of pasted content should be adjusted based on the context",
 592                    field: Box::new(SettingField {
 593                        pick: |settings_content| {
 594                            &settings_content
 595                                .project
 596                                .all_languages
 597                                .defaults
 598                                .auto_indent_on_paste
 599                        },
 600                        pick_mut: |settings_content| {
 601                            &mut settings_content
 602                                .project
 603                                .all_languages
 604                                .defaults
 605                                .auto_indent_on_paste
 606                        },
 607                    }),
 608                    metadata: None,
 609                }),
 610                SettingsPageItem::SectionHeader("Wrapping"),
 611                // todo(settings_ui): Needs numeric stepper
 612                // SettingsPageItem::SettingItem(SettingItem {
 613                //     title: "Preferred Line Length",
 614                //     description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
 615                //     field: Box::new(SettingField {
 616                //         pick: |settings_content| &settings_content.project.all_languages.defaults.preferred_line_length,
 617                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.preferred_line_length,
 618                //     }),
 619                //     metadata: None,
 620                // }),
 621                SettingsPageItem::SettingItem(SettingItem {
 622                    title: "Soft Wrap",
 623                    description: "How to soft-wrap long lines of text",
 624                    field: Box::new(SettingField {
 625                        pick: |settings_content| {
 626                            &settings_content.project.all_languages.defaults.soft_wrap
 627                        },
 628                        pick_mut: |settings_content| {
 629                            &mut settings_content.project.all_languages.defaults.soft_wrap
 630                        },
 631                    }),
 632                    metadata: None,
 633                }),
 634                SettingsPageItem::SectionHeader("Search"),
 635                SettingsPageItem::SettingItem(SettingItem {
 636                    title: "Search Wrap",
 637                    description: "Whether the editor search results will loop",
 638                    field: Box::new(SettingField {
 639                        pick: |settings_content| &settings_content.editor.search_wrap,
 640                        pick_mut: |settings_content| &mut settings_content.editor.search_wrap,
 641                    }),
 642                    metadata: None,
 643                }),
 644                SettingsPageItem::SettingItem(SettingItem {
 645                    title: "Seed Search Query From Cursor",
 646                    description: "When to populate a new search's query based on the text under the cursor",
 647                    field: Box::new(SettingField {
 648                        pick: |settings_content| {
 649                            &settings_content.editor.seed_search_query_from_cursor
 650                        },
 651                        pick_mut: |settings_content| {
 652                            &mut settings_content.editor.seed_search_query_from_cursor
 653                        },
 654                    }),
 655                    metadata: None,
 656                }),
 657                SettingsPageItem::SettingItem(SettingItem {
 658                    title: "Use Smartcase Search",
 659                    description: "Whether to use smartcase search",
 660                    field: Box::new(SettingField {
 661                        pick: |settings_content| &settings_content.editor.use_smartcase_search,
 662                        pick_mut: |settings_content| {
 663                            &mut settings_content.editor.use_smartcase_search
 664                        },
 665                    }),
 666                    metadata: None,
 667                }),
 668                SettingsPageItem::SectionHeader("Editor Behavior"),
 669                SettingsPageItem::SettingItem(SettingItem {
 670                    title: "Redact Private Values",
 671                    description: "Hide the values of variables in private files",
 672                    field: Box::new(SettingField {
 673                        pick: |settings_content| &settings_content.editor.redact_private_values,
 674                        pick_mut: |settings_content| {
 675                            &mut settings_content.editor.redact_private_values
 676                        },
 677                    }),
 678                    metadata: None,
 679                }),
 680                SettingsPageItem::SettingItem(SettingItem {
 681                    title: "Middle Click Paste",
 682                    description: "Whether to enable middle-click paste on Linux",
 683                    field: Box::new(SettingField {
 684                        pick: |settings_content| &settings_content.editor.middle_click_paste,
 685                        pick_mut: |settings_content| {
 686                            &mut settings_content.editor.middle_click_paste
 687                        },
 688                    }),
 689                    metadata: None,
 690                }),
 691                SettingsPageItem::SettingItem(SettingItem {
 692                    title: "Double Click In Multibuffer",
 693                    description: "What to do when multibuffer is double clicked in some of its excerpts",
 694                    field: Box::new(SettingField {
 695                        pick: |settings_content| {
 696                            &settings_content.editor.double_click_in_multibuffer
 697                        },
 698                        pick_mut: |settings_content| {
 699                            &mut settings_content.editor.double_click_in_multibuffer
 700                        },
 701                    }),
 702                    metadata: None,
 703                }),
 704                SettingsPageItem::SettingItem(SettingItem {
 705                    title: "Go To Definition Fallback",
 706                    description: "Whether to follow-up empty go to definition responses from the language server",
 707                    field: Box::new(SettingField {
 708                        pick: |settings_content| &settings_content.editor.go_to_definition_fallback,
 709                        pick_mut: |settings_content| {
 710                            &mut settings_content.editor.go_to_definition_fallback
 711                        },
 712                    }),
 713                    metadata: None,
 714                }),
 715                SettingsPageItem::SectionHeader("Scrolling"),
 716                SettingsPageItem::SettingItem(SettingItem {
 717                    title: "Scroll Beyond Last Line",
 718                    description: "Whether the editor will scroll beyond the last line",
 719                    field: Box::new(SettingField {
 720                        pick: |settings_content| &settings_content.editor.scroll_beyond_last_line,
 721                        pick_mut: |settings_content| {
 722                            &mut settings_content.editor.scroll_beyond_last_line
 723                        },
 724                    }),
 725                    metadata: None,
 726                }),
 727                SettingsPageItem::SettingItem(SettingItem {
 728                    title: "Vertical Scroll Margin",
 729                    description: "The number of lines to keep above/below the cursor when auto-scrolling",
 730                    field: Box::new(SettingField {
 731                        pick: |settings_content| &settings_content.editor.vertical_scroll_margin,
 732                        pick_mut: |settings_content| {
 733                            &mut settings_content.editor.vertical_scroll_margin
 734                        },
 735                    }),
 736                    metadata: None,
 737                }),
 738                SettingsPageItem::SettingItem(SettingItem {
 739                    title: "Horizontal Scroll Margin",
 740                    description: "The number of characters to keep on either side when scrolling with the mouse",
 741                    field: Box::new(SettingField {
 742                        pick: |settings_content| &settings_content.editor.horizontal_scroll_margin,
 743                        pick_mut: |settings_content| {
 744                            &mut settings_content.editor.horizontal_scroll_margin
 745                        },
 746                    }),
 747                    metadata: None,
 748                }),
 749                SettingsPageItem::SettingItem(SettingItem {
 750                    title: "Scroll Sensitivity",
 751                    description: "Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 752                    field: Box::new(SettingField {
 753                        pick: |settings_content| &settings_content.editor.scroll_sensitivity,
 754                        pick_mut: |settings_content| {
 755                            &mut settings_content.editor.scroll_sensitivity
 756                        },
 757                    }),
 758                    metadata: None,
 759                }),
 760                SettingsPageItem::SettingItem(SettingItem {
 761                    title: "Fast Scroll Sensitivity",
 762                    description: "Fast Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 763                    field: Box::new(SettingField {
 764                        pick: |settings_content| &settings_content.editor.fast_scroll_sensitivity,
 765                        pick_mut: |settings_content| {
 766                            &mut settings_content.editor.fast_scroll_sensitivity
 767                        },
 768                    }),
 769                    metadata: None,
 770                }),
 771                SettingsPageItem::SettingItem(SettingItem {
 772                    title: "Autoscroll On Clicks",
 773                    description: "Whether to scroll when clicking near the edge of the visible text area",
 774                    field: Box::new(SettingField {
 775                        pick: |settings_content| &settings_content.editor.autoscroll_on_clicks,
 776                        pick_mut: |settings_content| {
 777                            &mut settings_content.editor.autoscroll_on_clicks
 778                        },
 779                    }),
 780                    metadata: None,
 781                }),
 782                SettingsPageItem::SectionHeader("Auto Actions"),
 783                SettingsPageItem::SettingItem(SettingItem {
 784                    title: "Use Autoclose",
 785                    description: "Whether to automatically type closing characters for you",
 786                    field: Box::new(SettingField {
 787                        pick: |settings_content| {
 788                            &settings_content
 789                                .project
 790                                .all_languages
 791                                .defaults
 792                                .use_autoclose
 793                        },
 794                        pick_mut: |settings_content| {
 795                            &mut settings_content
 796                                .project
 797                                .all_languages
 798                                .defaults
 799                                .use_autoclose
 800                        },
 801                    }),
 802                    metadata: None,
 803                }),
 804                SettingsPageItem::SettingItem(SettingItem {
 805                    title: "Use Auto Surround",
 806                    description: "Whether to automatically surround text with characters for you",
 807                    field: Box::new(SettingField {
 808                        pick: |settings_content| {
 809                            &settings_content
 810                                .project
 811                                .all_languages
 812                                .defaults
 813                                .use_auto_surround
 814                        },
 815                        pick_mut: |settings_content| {
 816                            &mut settings_content
 817                                .project
 818                                .all_languages
 819                                .defaults
 820                                .use_auto_surround
 821                        },
 822                    }),
 823                    metadata: None,
 824                }),
 825                SettingsPageItem::SettingItem(SettingItem {
 826                    title: "Use On Type Format",
 827                    description: "Whether to use additional LSP queries to format the code after every trigger symbol input",
 828                    field: Box::new(SettingField {
 829                        pick: |settings_content| {
 830                            &settings_content
 831                                .project
 832                                .all_languages
 833                                .defaults
 834                                .use_on_type_format
 835                        },
 836                        pick_mut: |settings_content| {
 837                            &mut settings_content
 838                                .project
 839                                .all_languages
 840                                .defaults
 841                                .use_on_type_format
 842                        },
 843                    }),
 844                    metadata: None,
 845                }),
 846                SettingsPageItem::SettingItem(SettingItem {
 847                    title: "Always Treat Brackets As Autoclosed",
 848                    description: "Controls how the editor handles the autoclosed characters",
 849                    field: Box::new(SettingField {
 850                        pick: |settings_content| {
 851                            &settings_content
 852                                .project
 853                                .all_languages
 854                                .defaults
 855                                .always_treat_brackets_as_autoclosed
 856                        },
 857                        pick_mut: |settings_content| {
 858                            &mut settings_content
 859                                .project
 860                                .all_languages
 861                                .defaults
 862                                .always_treat_brackets_as_autoclosed
 863                        },
 864                    }),
 865                    metadata: None,
 866                }),
 867                SettingsPageItem::SectionHeader("Formatting"),
 868                SettingsPageItem::SettingItem(SettingItem {
 869                    title: "Remove Trailing Whitespace On Save",
 870                    description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
 871                    field: Box::new(SettingField {
 872                        pick: |settings_content| {
 873                            &settings_content
 874                                .project
 875                                .all_languages
 876                                .defaults
 877                                .remove_trailing_whitespace_on_save
 878                        },
 879                        pick_mut: |settings_content| {
 880                            &mut settings_content
 881                                .project
 882                                .all_languages
 883                                .defaults
 884                                .remove_trailing_whitespace_on_save
 885                        },
 886                    }),
 887                    metadata: None,
 888                }),
 889                SettingsPageItem::SettingItem(SettingItem {
 890                    title: "Ensure Final Newline On Save",
 891                    description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
 892                    field: Box::new(SettingField {
 893                        pick: |settings_content| {
 894                            &settings_content
 895                                .project
 896                                .all_languages
 897                                .defaults
 898                                .ensure_final_newline_on_save
 899                        },
 900                        pick_mut: |settings_content| {
 901                            &mut settings_content
 902                                .project
 903                                .all_languages
 904                                .defaults
 905                                .ensure_final_newline_on_save
 906                        },
 907                    }),
 908                    metadata: None,
 909                }),
 910                SettingsPageItem::SettingItem(SettingItem {
 911                    title: "Extend Comment On Newline",
 912                    description: "Whether to start a new line with a comment when a previous line is a comment as well",
 913                    field: Box::new(SettingField {
 914                        pick: |settings_content| {
 915                            &settings_content
 916                                .project
 917                                .all_languages
 918                                .defaults
 919                                .extend_comment_on_newline
 920                        },
 921                        pick_mut: |settings_content| {
 922                            &mut settings_content
 923                                .project
 924                                .all_languages
 925                                .defaults
 926                                .extend_comment_on_newline
 927                        },
 928                    }),
 929                    metadata: None,
 930                }),
 931                SettingsPageItem::SectionHeader("Completions"),
 932                SettingsPageItem::SettingItem(SettingItem {
 933                    title: "Show Completions On Input",
 934                    description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
 935                    field: Box::new(SettingField {
 936                        pick: |settings_content| {
 937                            &settings_content
 938                                .project
 939                                .all_languages
 940                                .defaults
 941                                .show_completions_on_input
 942                        },
 943                        pick_mut: |settings_content| {
 944                            &mut settings_content
 945                                .project
 946                                .all_languages
 947                                .defaults
 948                                .show_completions_on_input
 949                        },
 950                    }),
 951                    metadata: None,
 952                }),
 953                SettingsPageItem::SettingItem(SettingItem {
 954                    title: "Show Completion Documentation",
 955                    description: "Whether to display inline and alongside documentation for items in the completions menu",
 956                    field: Box::new(SettingField {
 957                        pick: |settings_content| {
 958                            &settings_content
 959                                .project
 960                                .all_languages
 961                                .defaults
 962                                .show_completion_documentation
 963                        },
 964                        pick_mut: |settings_content| {
 965                            &mut settings_content
 966                                .project
 967                                .all_languages
 968                                .defaults
 969                                .show_completion_documentation
 970                        },
 971                    }),
 972                    metadata: None,
 973                }),
 974                SettingsPageItem::SettingItem(SettingItem {
 975                    title: "Auto Signature Help",
 976                    description: "Whether to automatically show a signature help pop-up or not",
 977                    field: Box::new(SettingField {
 978                        pick: |settings_content| &settings_content.editor.auto_signature_help,
 979                        pick_mut: |settings_content| {
 980                            &mut settings_content.editor.auto_signature_help
 981                        },
 982                    }),
 983                    metadata: None,
 984                }),
 985                SettingsPageItem::SettingItem(SettingItem {
 986                    title: "Show Signature Help After Edits",
 987                    description: "Whether to show the signature help pop-up after completions or bracket pairs inserted",
 988                    field: Box::new(SettingField {
 989                        pick: |settings_content| {
 990                            &settings_content.editor.show_signature_help_after_edits
 991                        },
 992                        pick_mut: |settings_content| {
 993                            &mut settings_content.editor.show_signature_help_after_edits
 994                        },
 995                    }),
 996                    metadata: None,
 997                }),
 998                SettingsPageItem::SettingItem(SettingItem {
 999                    title: "Snippet Sort Order",
1000                    description: "Determines how snippets are sorted relative to other completion items",
1001                    field: Box::new(SettingField {
1002                        pick: |settings_content| &settings_content.editor.snippet_sort_order,
1003                        pick_mut: |settings_content| {
1004                            &mut settings_content.editor.snippet_sort_order
1005                        },
1006                    }),
1007                    metadata: None,
1008                }),
1009                SettingsPageItem::SectionHeader("Hover"),
1010                SettingsPageItem::SettingItem(SettingItem {
1011                    title: "Hover Popover Enabled",
1012                    description: "Whether to show the informational hover box when moving the mouse over symbols in the editor",
1013                    field: Box::new(SettingField {
1014                        pick: |settings_content| &settings_content.editor.hover_popover_enabled,
1015                        pick_mut: |settings_content| {
1016                            &mut settings_content.editor.hover_popover_enabled
1017                        },
1018                    }),
1019                    metadata: None,
1020                }),
1021                // todo(settings ui): add units to this numeric stepper
1022                SettingsPageItem::SettingItem(SettingItem {
1023                    title: "Hover Popover Delay",
1024                    description: "Time to wait in milliseconds before showing the informational hover box",
1025                    field: Box::new(SettingField {
1026                        pick: |settings_content| &settings_content.editor.hover_popover_delay,
1027                        pick_mut: |settings_content| {
1028                            &mut settings_content.editor.hover_popover_delay
1029                        },
1030                    }),
1031                    metadata: None,
1032                }),
1033                SettingsPageItem::SectionHeader("Code Actions"),
1034                SettingsPageItem::SettingItem(SettingItem {
1035                    title: "Inline Code Actions",
1036                    description: "Whether to show code action button at start of buffer line",
1037                    field: Box::new(SettingField {
1038                        pick: |settings_content| &settings_content.editor.inline_code_actions,
1039                        pick_mut: |settings_content| {
1040                            &mut settings_content.editor.inline_code_actions
1041                        },
1042                    }),
1043                    metadata: None,
1044                }),
1045                SettingsPageItem::SectionHeader("Selection"),
1046                SettingsPageItem::SettingItem(SettingItem {
1047                    title: "Drag And Drop Selection",
1048                    description: "Whether to enable drag and drop selection",
1049                    field: Box::new(SettingField {
1050                        pick: |settings_content| {
1051                            if let Some(drag_and_drop) =
1052                                &settings_content.editor.drag_and_drop_selection
1053                            {
1054                                &drag_and_drop.enabled
1055                            } else {
1056                                &None
1057                            }
1058                        },
1059                        pick_mut: |settings_content| {
1060                            &mut settings_content
1061                                .editor
1062                                .drag_and_drop_selection
1063                                .get_or_insert_default()
1064                                .enabled
1065                        },
1066                    }),
1067                    metadata: None,
1068                }),
1069                // todo(settings_ui): Needs numeric stepper
1070                // SettingsPageItem::SettingItem(SettingItem {
1071                //     title: "Drag And Drop Selection Delay",
1072                //     description: "Delay in milliseconds before drag and drop selection starts",
1073                //     field: Box::new(SettingField {
1074                //         pick: |settings_content| {
1075                //             if let Some(drag_and_drop) = &settings_content.editor.drag_and_drop_selection {
1076                //                 &drag_and_drop.delay
1077                //             } else {
1078                //                 &None
1079                //             }
1080                //         },
1081                //         pick_mut: |settings_content| {
1082                //             &mut settings_content.editor.drag_and_drop_selection.get_or_insert_default().delay
1083                //         },
1084                //     }),
1085                //     metadata: None,
1086                // }),
1087                SettingsPageItem::SectionHeader("Line Numbers"),
1088                SettingsPageItem::SettingItem(SettingItem {
1089                    title: "Relative Line Numbers",
1090                    description: "Whether the line numbers on editors gutter are relative or not",
1091                    field: Box::new(SettingField {
1092                        pick: |settings_content| &settings_content.editor.relative_line_numbers,
1093                        pick_mut: |settings_content| {
1094                            &mut settings_content.editor.relative_line_numbers
1095                        },
1096                    }),
1097                    metadata: None,
1098                }),
1099                SettingsPageItem::SectionHeader("Gutter"),
1100                SettingsPageItem::SettingItem(SettingItem {
1101                    title: "Show Line Numbers",
1102                    description: "Whether to show line numbers in the gutter",
1103                    field: Box::new(SettingField {
1104                        pick: |settings_content| {
1105                            if let Some(gutter) = &settings_content.editor.gutter {
1106                                &gutter.line_numbers
1107                            } else {
1108                                &None
1109                            }
1110                        },
1111                        pick_mut: |settings_content| {
1112                            &mut settings_content
1113                                .editor
1114                                .gutter
1115                                .get_or_insert_default()
1116                                .line_numbers
1117                        },
1118                    }),
1119                    metadata: None,
1120                }),
1121                SettingsPageItem::SettingItem(SettingItem {
1122                    title: "Show Runnables",
1123                    description: "Whether to show runnable buttons in the gutter",
1124                    field: Box::new(SettingField {
1125                        pick: |settings_content| {
1126                            if let Some(gutter) = &settings_content.editor.gutter {
1127                                &gutter.runnables
1128                            } else {
1129                                &None
1130                            }
1131                        },
1132                        pick_mut: |settings_content| {
1133                            &mut settings_content
1134                                .editor
1135                                .gutter
1136                                .get_or_insert_default()
1137                                .runnables
1138                        },
1139                    }),
1140                    metadata: None,
1141                }),
1142                SettingsPageItem::SettingItem(SettingItem {
1143                    title: "Show Breakpoints",
1144                    description: "Whether to show breakpoints in the gutter",
1145                    field: Box::new(SettingField {
1146                        pick: |settings_content| {
1147                            if let Some(gutter) = &settings_content.editor.gutter {
1148                                &gutter.breakpoints
1149                            } else {
1150                                &None
1151                            }
1152                        },
1153                        pick_mut: |settings_content| {
1154                            &mut settings_content
1155                                .editor
1156                                .gutter
1157                                .get_or_insert_default()
1158                                .breakpoints
1159                        },
1160                    }),
1161                    metadata: None,
1162                }),
1163                SettingsPageItem::SettingItem(SettingItem {
1164                    title: "Show Folds",
1165                    description: "Whether to show code folding controls in the gutter",
1166                    field: Box::new(SettingField {
1167                        pick: |settings_content| {
1168                            if let Some(gutter) = &settings_content.editor.gutter {
1169                                &gutter.folds
1170                            } else {
1171                                &None
1172                            }
1173                        },
1174                        pick_mut: |settings_content| {
1175                            &mut settings_content.editor.gutter.get_or_insert_default().folds
1176                        },
1177                    }),
1178                    metadata: None,
1179                }),
1180                SettingsPageItem::SectionHeader("Tabs"),
1181                SettingsPageItem::SettingItem(SettingItem {
1182                    title: "Show Tab Bar",
1183                    description: "Whether or not to show the tab bar in the editor",
1184                    field: Box::new(SettingField {
1185                        pick: |settings_content| {
1186                            if let Some(tab_bar) = &settings_content.tab_bar {
1187                                &tab_bar.show
1188                            } else {
1189                                &None
1190                            }
1191                        },
1192                        pick_mut: |settings_content| {
1193                            &mut settings_content.tab_bar.get_or_insert_default().show
1194                        },
1195                    }),
1196                    metadata: None,
1197                }),
1198                SettingsPageItem::SettingItem(SettingItem {
1199                    title: "Show Git Status In Tabs",
1200                    description: "Whether to show the Git file status on a tab item",
1201                    field: Box::new(SettingField {
1202                        pick: |settings_content| {
1203                            if let Some(tabs) = &settings_content.tabs {
1204                                &tabs.git_status
1205                            } else {
1206                                &None
1207                            }
1208                        },
1209                        pick_mut: |settings_content| {
1210                            &mut settings_content.tabs.get_or_insert_default().git_status
1211                        },
1212                    }),
1213                    metadata: None,
1214                }),
1215                SettingsPageItem::SettingItem(SettingItem {
1216                    title: "Show File Icons In Tabs",
1217                    description: "Whether to show the file icon for a tab",
1218                    field: Box::new(SettingField {
1219                        pick: |settings_content| {
1220                            if let Some(tabs) = &settings_content.tabs {
1221                                &tabs.file_icons
1222                            } else {
1223                                &None
1224                            }
1225                        },
1226                        pick_mut: |settings_content| {
1227                            &mut settings_content.tabs.get_or_insert_default().file_icons
1228                        },
1229                    }),
1230                    metadata: None,
1231                }),
1232                SettingsPageItem::SettingItem(SettingItem {
1233                    title: "Tab Close Position",
1234                    description: "Position of the close button in a tab",
1235                    field: Box::new(SettingField {
1236                        pick: |settings_content| {
1237                            if let Some(tabs) = &settings_content.tabs {
1238                                &tabs.close_position
1239                            } else {
1240                                &None
1241                            }
1242                        },
1243                        pick_mut: |settings_content| {
1244                            &mut settings_content.tabs.get_or_insert_default().close_position
1245                        },
1246                    }),
1247                    metadata: None,
1248                }),
1249                // todo(settings_ui): Needs numeric stepper
1250                // SettingsPageItem::SettingItem(SettingItem {
1251                //     title: "Maximum Tabs",
1252                //     description: "Maximum open tabs in a pane. Will not close an unsaved tab",
1253                //     field: Box::new(SettingField {
1254                //         pick: |settings_content| &settings_content.workspace.max_tabs,
1255                //         pick_mut: |settings_content| &mut settings_content.workspace.max_tabs,
1256                //     }),
1257                //     metadata: None,
1258                // }),
1259                SettingsPageItem::SectionHeader("Toolbar"),
1260                SettingsPageItem::SettingItem(SettingItem {
1261                    title: "Breadcrumbs",
1262                    description: "Whether to show breadcrumbs",
1263                    field: Box::new(SettingField {
1264                        pick: |settings_content| {
1265                            if let Some(toolbar) = &settings_content.editor.toolbar {
1266                                &toolbar.breadcrumbs
1267                            } else {
1268                                &None
1269                            }
1270                        },
1271                        pick_mut: |settings_content| {
1272                            &mut settings_content
1273                                .editor
1274                                .toolbar
1275                                .get_or_insert_default()
1276                                .breadcrumbs
1277                        },
1278                    }),
1279                    metadata: None,
1280                }),
1281                SettingsPageItem::SettingItem(SettingItem {
1282                    title: "Quick Actions",
1283                    description: "Whether to show quick action buttons",
1284                    field: Box::new(SettingField {
1285                        pick: |settings_content| {
1286                            if let Some(toolbar) = &settings_content.editor.toolbar {
1287                                &toolbar.quick_actions
1288                            } else {
1289                                &None
1290                            }
1291                        },
1292                        pick_mut: |settings_content| {
1293                            &mut settings_content
1294                                .editor
1295                                .toolbar
1296                                .get_or_insert_default()
1297                                .quick_actions
1298                        },
1299                    }),
1300                    metadata: None,
1301                }),
1302                SettingsPageItem::SettingItem(SettingItem {
1303                    title: "Selections Menu",
1304                    description: "Whether to show the selections menu in the editor toolbar",
1305                    field: Box::new(SettingField {
1306                        pick: |settings_content| {
1307                            if let Some(toolbar) = &settings_content.editor.toolbar {
1308                                &toolbar.selections_menu
1309                            } else {
1310                                &None
1311                            }
1312                        },
1313                        pick_mut: |settings_content| {
1314                            &mut settings_content
1315                                .editor
1316                                .toolbar
1317                                .get_or_insert_default()
1318                                .selections_menu
1319                        },
1320                    }),
1321                    metadata: None,
1322                }),
1323                SettingsPageItem::SettingItem(SettingItem {
1324                    title: "Agent Review",
1325                    description: "Whether to show agent review buttons in the editor toolbar",
1326                    field: Box::new(SettingField {
1327                        pick: |settings_content| {
1328                            if let Some(toolbar) = &settings_content.editor.toolbar {
1329                                &toolbar.agent_review
1330                            } else {
1331                                &None
1332                            }
1333                        },
1334                        pick_mut: |settings_content| {
1335                            &mut settings_content
1336                                .editor
1337                                .toolbar
1338                                .get_or_insert_default()
1339                                .agent_review
1340                        },
1341                    }),
1342                    metadata: None,
1343                }),
1344                SettingsPageItem::SettingItem(SettingItem {
1345                    title: "Code Actions",
1346                    description: "Whether to show code action buttons in the editor toolbar",
1347                    field: Box::new(SettingField {
1348                        pick: |settings_content| {
1349                            if let Some(toolbar) = &settings_content.editor.toolbar {
1350                                &toolbar.code_actions
1351                            } else {
1352                                &None
1353                            }
1354                        },
1355                        pick_mut: |settings_content| {
1356                            &mut settings_content
1357                                .editor
1358                                .toolbar
1359                                .get_or_insert_default()
1360                                .code_actions
1361                        },
1362                    }),
1363                    metadata: None,
1364                }),
1365            ],
1366        },
1367        SettingsPage {
1368            title: "Languages & Frameworks",
1369            items: {
1370                let mut items = vec![
1371                    SettingsPageItem::SectionHeader(LANGUAGES_SECTION_HEADER),
1372                    SettingsPageItem::SubPageLink(SubPageLink {
1373                        title: "JSON",
1374                        render: Arc::new(|this, window, cx| {
1375                            this.render_page_items(language_settings_data().iter(), window, cx)
1376                                .into_any_element()
1377                        }),
1378                    }),
1379                    SettingsPageItem::SubPageLink(SubPageLink {
1380                        title: "JSONC",
1381                        render: Arc::new(|this, window, cx| {
1382                            this.render_page_items(language_settings_data().iter(), window, cx)
1383                                .into_any_element()
1384                        }),
1385                    }),
1386                    SettingsPageItem::SubPageLink(SubPageLink {
1387                        title: "Rust",
1388                        render: Arc::new(|this, window, cx| {
1389                            this.render_page_items(language_settings_data().iter(), window, cx)
1390                                .into_any_element()
1391                        }),
1392                    }),
1393                    SettingsPageItem::SubPageLink(SubPageLink {
1394                        title: "Python",
1395                        render: Arc::new(|this, window, cx| {
1396                            this.render_page_items(language_settings_data().iter(), window, cx)
1397                                .into_any_element()
1398                        }),
1399                    }),
1400                    SettingsPageItem::SubPageLink(SubPageLink {
1401                        title: "TSX",
1402                        render: Arc::new(|this, window, cx| {
1403                            this.render_page_items(language_settings_data().iter(), window, cx)
1404                                .into_any_element()
1405                        }),
1406                    }),
1407                ];
1408
1409                items.push(SettingsPageItem::SectionHeader("Default Language Settings"));
1410                items.extend(language_settings_data());
1411
1412                items
1413            },
1414        },
1415        SettingsPage {
1416            title: "Workbench & Window",
1417            items: vec![
1418                SettingsPageItem::SectionHeader("Workbench"),
1419                SettingsPageItem::SettingItem(SettingItem {
1420                    title: "Editor Tabs",
1421                    description: "Whether or not to show the tab bar in the editor",
1422                    field: Box::new(SettingField {
1423                        pick: |settings_content| {
1424                            if let Some(tab_bar) = &settings_content.tab_bar {
1425                                &tab_bar.show
1426                            } else {
1427                                &None
1428                            }
1429                        },
1430                        pick_mut: |settings_content| {
1431                            &mut settings_content.tab_bar.get_or_insert_default().show
1432                        },
1433                    }),
1434                    metadata: None,
1435                }),
1436                SettingsPageItem::SettingItem(SettingItem {
1437                    title: "Active Language Button",
1438                    description: "Whether to show the active language button in the status bar",
1439                    field: Box::new(SettingField {
1440                        pick: |settings_content| {
1441                            if let Some(status_bar) = &settings_content.status_bar {
1442                                &status_bar.active_language_button
1443                            } else {
1444                                &None
1445                            }
1446                        },
1447                        pick_mut: |settings_content| {
1448                            &mut settings_content
1449                                .status_bar
1450                                .get_or_insert_default()
1451                                .active_language_button
1452                        },
1453                    }),
1454                    metadata: None,
1455                }),
1456                SettingsPageItem::SettingItem(SettingItem {
1457                    title: "Cursor Position Button",
1458                    description: "Whether to show the cursor position button in the status bar",
1459                    field: Box::new(SettingField {
1460                        pick: |settings_content| {
1461                            if let Some(status_bar) = &settings_content.status_bar {
1462                                &status_bar.cursor_position_button
1463                            } else {
1464                                &None
1465                            }
1466                        },
1467                        pick_mut: |settings_content| {
1468                            &mut settings_content
1469                                .status_bar
1470                                .get_or_insert_default()
1471                                .cursor_position_button
1472                        },
1473                    }),
1474                    metadata: None,
1475                }),
1476                SettingsPageItem::SectionHeader("Terminal"),
1477                SettingsPageItem::SettingItem(SettingItem {
1478                    title: "Terminal Button",
1479                    description: "Whether to show the terminal button in the status bar",
1480                    field: Box::new(SettingField {
1481                        pick: |settings_content| {
1482                            if let Some(terminal) = &settings_content.terminal {
1483                                &terminal.button
1484                            } else {
1485                                &None
1486                            }
1487                        },
1488                        pick_mut: |settings_content| {
1489                            &mut settings_content.terminal.get_or_insert_default().button
1490                        },
1491                    }),
1492                    metadata: None,
1493                }),
1494                SettingsPageItem::SettingItem(SettingItem {
1495                    title: "Show Navigation History Buttons",
1496                    description: "Whether or not to show the navigation history buttons in the tab bar",
1497                    field: Box::new(SettingField {
1498                        pick: |settings_content| {
1499                            if let Some(tab_bar) = &settings_content.tab_bar {
1500                                &tab_bar.show_nav_history_buttons
1501                            } else {
1502                                &None
1503                            }
1504                        },
1505                        pick_mut: |settings_content| {
1506                            &mut settings_content
1507                                .tab_bar
1508                                .get_or_insert_default()
1509                                .show_nav_history_buttons
1510                        },
1511                    }),
1512                    metadata: None,
1513                }),
1514                SettingsPageItem::SectionHeader("Title Bar"),
1515                SettingsPageItem::SettingItem(SettingItem {
1516                    title: "Show Branch Icon",
1517                    description: "Whether to show the branch icon beside branch switcher in the titlebar",
1518                    field: Box::new(SettingField {
1519                        pick: |settings_content| {
1520                            if let Some(title_bar) = &settings_content.title_bar {
1521                                &title_bar.show_branch_icon
1522                            } else {
1523                                &None
1524                            }
1525                        },
1526                        pick_mut: |settings_content| {
1527                            &mut settings_content
1528                                .title_bar
1529                                .get_or_insert_default()
1530                                .show_branch_icon
1531                        },
1532                    }),
1533                    metadata: None,
1534                }),
1535                SettingsPageItem::SettingItem(SettingItem {
1536                    title: "Show Branch Name",
1537                    description: "Whether to show the branch name button in the titlebar",
1538                    field: Box::new(SettingField {
1539                        pick: |settings_content| {
1540                            if let Some(title_bar) = &settings_content.title_bar {
1541                                &title_bar.show_branch_name
1542                            } else {
1543                                &None
1544                            }
1545                        },
1546                        pick_mut: |settings_content| {
1547                            &mut settings_content
1548                                .title_bar
1549                                .get_or_insert_default()
1550                                .show_branch_name
1551                        },
1552                    }),
1553                    metadata: None,
1554                }),
1555                SettingsPageItem::SettingItem(SettingItem {
1556                    title: "Show Project Items",
1557                    description: "Whether to show the project host and name in the titlebar",
1558                    field: Box::new(SettingField {
1559                        pick: |settings_content| {
1560                            if let Some(title_bar) = &settings_content.title_bar {
1561                                &title_bar.show_project_items
1562                            } else {
1563                                &None
1564                            }
1565                        },
1566                        pick_mut: |settings_content| {
1567                            &mut settings_content
1568                                .title_bar
1569                                .get_or_insert_default()
1570                                .show_project_items
1571                        },
1572                    }),
1573                    metadata: None,
1574                }),
1575                SettingsPageItem::SettingItem(SettingItem {
1576                    title: "Show Onboarding Banner",
1577                    description: "Whether to show onboarding banners in the titlebar",
1578                    field: Box::new(SettingField {
1579                        pick: |settings_content| {
1580                            if let Some(title_bar) = &settings_content.title_bar {
1581                                &title_bar.show_onboarding_banner
1582                            } else {
1583                                &None
1584                            }
1585                        },
1586                        pick_mut: |settings_content| {
1587                            &mut settings_content
1588                                .title_bar
1589                                .get_or_insert_default()
1590                                .show_onboarding_banner
1591                        },
1592                    }),
1593                    metadata: None,
1594                }),
1595                SettingsPageItem::SettingItem(SettingItem {
1596                    title: "Show User Picture",
1597                    description: "Whether to show user picture in the titlebar",
1598                    field: Box::new(SettingField {
1599                        pick: |settings_content| {
1600                            if let Some(title_bar) = &settings_content.title_bar {
1601                                &title_bar.show_user_picture
1602                            } else {
1603                                &None
1604                            }
1605                        },
1606                        pick_mut: |settings_content| {
1607                            &mut settings_content
1608                                .title_bar
1609                                .get_or_insert_default()
1610                                .show_user_picture
1611                        },
1612                    }),
1613                    metadata: None,
1614                }),
1615                SettingsPageItem::SettingItem(SettingItem {
1616                    title: "Show Sign In",
1617                    description: "Whether to show the sign in button in the titlebar",
1618                    field: Box::new(SettingField {
1619                        pick: |settings_content| {
1620                            if let Some(title_bar) = &settings_content.title_bar {
1621                                &title_bar.show_sign_in
1622                            } else {
1623                                &None
1624                            }
1625                        },
1626                        pick_mut: |settings_content| {
1627                            &mut settings_content
1628                                .title_bar
1629                                .get_or_insert_default()
1630                                .show_sign_in
1631                        },
1632                    }),
1633                    metadata: None,
1634                }),
1635                SettingsPageItem::SettingItem(SettingItem {
1636                    title: "Show Menus",
1637                    description: "Whether to show the menus in the titlebar",
1638                    field: Box::new(SettingField {
1639                        pick: |settings_content| {
1640                            if let Some(title_bar) = &settings_content.title_bar {
1641                                &title_bar.show_menus
1642                            } else {
1643                                &None
1644                            }
1645                        },
1646                        pick_mut: |settings_content| {
1647                            &mut settings_content
1648                                .title_bar
1649                                .get_or_insert_default()
1650                                .show_menus
1651                        },
1652                    }),
1653                    metadata: None,
1654                }),
1655                SettingsPageItem::SectionHeader("Search Settings"),
1656                SettingsPageItem::SettingItem(SettingItem {
1657                    title: "Search Button",
1658                    description: "Whether to show the project search button in the status bar",
1659                    field: Box::new(SettingField {
1660                        pick: |settings_content| {
1661                            if let Some(search) = &settings_content.editor.search {
1662                                &search.button
1663                            } else {
1664                                &None
1665                            }
1666                        },
1667                        pick_mut: |settings_content| {
1668                            &mut settings_content
1669                                .editor
1670                                .search
1671                                .get_or_insert_default()
1672                                .button
1673                        },
1674                    }),
1675                    metadata: None,
1676                }),
1677                SettingsPageItem::SettingItem(SettingItem {
1678                    title: "Whole Word",
1679                    description: "Whether to search for whole words by default",
1680                    field: Box::new(SettingField {
1681                        pick: |settings_content| {
1682                            if let Some(search) = &settings_content.editor.search {
1683                                &search.whole_word
1684                            } else {
1685                                &None
1686                            }
1687                        },
1688                        pick_mut: |settings_content| {
1689                            &mut settings_content
1690                                .editor
1691                                .search
1692                                .get_or_insert_default()
1693                                .whole_word
1694                        },
1695                    }),
1696                    metadata: None,
1697                }),
1698                SettingsPageItem::SettingItem(SettingItem {
1699                    title: "Case Sensitive",
1700                    description: "Whether to search case-sensitively by default",
1701                    field: Box::new(SettingField {
1702                        pick: |settings_content| {
1703                            if let Some(search) = &settings_content.editor.search {
1704                                &search.case_sensitive
1705                            } else {
1706                                &None
1707                            }
1708                        },
1709                        pick_mut: |settings_content| {
1710                            &mut settings_content
1711                                .editor
1712                                .search
1713                                .get_or_insert_default()
1714                                .case_sensitive
1715                        },
1716                    }),
1717                    metadata: None,
1718                }),
1719                SettingsPageItem::SettingItem(SettingItem {
1720                    title: "Include Ignored",
1721                    description: "Whether to include ignored files in search results by default",
1722                    field: Box::new(SettingField {
1723                        pick: |settings_content| {
1724                            if let Some(search) = &settings_content.editor.search {
1725                                &search.include_ignored
1726                            } else {
1727                                &None
1728                            }
1729                        },
1730                        pick_mut: |settings_content| {
1731                            &mut settings_content
1732                                .editor
1733                                .search
1734                                .get_or_insert_default()
1735                                .include_ignored
1736                        },
1737                    }),
1738                    metadata: None,
1739                }),
1740                SettingsPageItem::SettingItem(SettingItem {
1741                    title: "Regex",
1742                    description: "Whether to use regex search by default",
1743                    field: Box::new(SettingField {
1744                        pick: |settings_content| {
1745                            if let Some(search) = &settings_content.editor.search {
1746                                &search.regex
1747                            } else {
1748                                &None
1749                            }
1750                        },
1751                        pick_mut: |settings_content| {
1752                            &mut settings_content.editor.search.get_or_insert_default().regex
1753                        },
1754                    }),
1755                    metadata: None,
1756                }),
1757                SettingsPageItem::SectionHeader("File Finder"),
1758                SettingsPageItem::SettingItem(SettingItem {
1759                    title: "File Icons",
1760                    description: "Whether to show file icons in the file finder",
1761                    field: Box::new(SettingField {
1762                        pick: |settings_content| {
1763                            if let Some(file_finder) = &settings_content.file_finder {
1764                                &file_finder.file_icons
1765                            } else {
1766                                &None
1767                            }
1768                        },
1769                        pick_mut: |settings_content| {
1770                            &mut settings_content
1771                                .file_finder
1772                                .get_or_insert_default()
1773                                .file_icons
1774                        },
1775                    }),
1776                    metadata: None,
1777                }),
1778                SettingsPageItem::SettingItem(SettingItem {
1779                    title: "Modal Max Width",
1780                    description: "Determines how much space the file finder can take up in relation to the available window width",
1781                    field: Box::new(SettingField {
1782                        pick: |settings_content| {
1783                            if let Some(file_finder) = &settings_content.file_finder {
1784                                &file_finder.modal_max_width
1785                            } else {
1786                                &None
1787                            }
1788                        },
1789                        pick_mut: |settings_content| {
1790                            &mut settings_content
1791                                .file_finder
1792                                .get_or_insert_default()
1793                                .modal_max_width
1794                        },
1795                    }),
1796                    metadata: None,
1797                }),
1798                SettingsPageItem::SettingItem(SettingItem {
1799                    title: "Skip Focus For Active In Search",
1800                    description: "Whether the file finder should skip focus for the active file in search results",
1801                    field: Box::new(SettingField {
1802                        pick: |settings_content| {
1803                            if let Some(file_finder) = &settings_content.file_finder {
1804                                &file_finder.skip_focus_for_active_in_search
1805                            } else {
1806                                &None
1807                            }
1808                        },
1809                        pick_mut: |settings_content| {
1810                            &mut settings_content
1811                                .file_finder
1812                                .get_or_insert_default()
1813                                .skip_focus_for_active_in_search
1814                        },
1815                    }),
1816                    metadata: None,
1817                }),
1818                SettingsPageItem::SettingItem(SettingItem {
1819                    title: "Git Status",
1820                    description: "Whether to show the git status in the file finder",
1821                    field: Box::new(SettingField {
1822                        pick: |settings_content| {
1823                            if let Some(file_finder) = &settings_content.file_finder {
1824                                &file_finder.git_status
1825                            } else {
1826                                &None
1827                            }
1828                        },
1829                        pick_mut: |settings_content| {
1830                            &mut settings_content
1831                                .file_finder
1832                                .get_or_insert_default()
1833                                .git_status
1834                        },
1835                    }),
1836                    metadata: None,
1837                }),
1838                // todo: null by default
1839                // SettingsPageItem::SettingItem(SettingItem {
1840                //     title: "Include Ignored",
1841                //     description: "Whether to use gitignored files when searching",
1842                //     field: Box::new(SettingField {
1843                //         pick: |settings_content| {
1844                //             if let Some(file_finder) = &settings_content.file_finder {
1845                //                 &file_finder.include_ignored
1846                //             } else {
1847                //                 &None
1848                //             }
1849                //         },
1850                //         pick_mut: |settings_content| {
1851                //             &mut settings_content
1852                //                 .file_finder
1853                //                 .get_or_insert_default()
1854                //                 .include_ignored
1855                //         },
1856                //     }),
1857                //     metadata: None,
1858                // }),
1859            ],
1860        },
1861        SettingsPage {
1862            title: "Panels & Tools",
1863            items: vec![
1864                SettingsPageItem::SectionHeader("Project Panel"),
1865                SettingsPageItem::SettingItem(SettingItem {
1866                    title: "Project Panel Button",
1867                    description: "Whether to show the project panel button in the status bar",
1868                    field: Box::new(SettingField {
1869                        pick: |settings_content| {
1870                            if let Some(project_panel) = &settings_content.project_panel {
1871                                &project_panel.button
1872                            } else {
1873                                &None
1874                            }
1875                        },
1876                        pick_mut: |settings_content| {
1877                            &mut settings_content
1878                                .project_panel
1879                                .get_or_insert_default()
1880                                .button
1881                        },
1882                    }),
1883                    metadata: None,
1884                }),
1885                SettingsPageItem::SettingItem(SettingItem {
1886                    title: "Project Panel Dock",
1887                    description: "Where to dock the project panel",
1888                    field: Box::new(SettingField {
1889                        pick: |settings_content| {
1890                            if let Some(project_panel) = &settings_content.project_panel {
1891                                &project_panel.dock
1892                            } else {
1893                                &None
1894                            }
1895                        },
1896                        pick_mut: |settings_content| {
1897                            &mut settings_content.project_panel.get_or_insert_default().dock
1898                        },
1899                    }),
1900                    metadata: None,
1901                }),
1902                SettingsPageItem::SettingItem(SettingItem {
1903                    title: "Project Panel Default Width",
1904                    description: "Default width of the project panel in pixels",
1905                    field: Box::new(SettingField {
1906                        pick: |settings_content| {
1907                            if let Some(project_panel) = &settings_content.project_panel {
1908                                &project_panel.default_width
1909                            } else {
1910                                &None
1911                            }
1912                        },
1913                        pick_mut: |settings_content| {
1914                            &mut settings_content
1915                                .project_panel
1916                                .get_or_insert_default()
1917                                .default_width
1918                        },
1919                    }),
1920                    metadata: None,
1921                }),
1922                SettingsPageItem::SettingItem(SettingItem {
1923                    title: "Hide .gitignore",
1924                    description: "Whether to hide the gitignore entries in the project panel",
1925                    field: Box::new(SettingField {
1926                        pick: |settings_content| {
1927                            if let Some(project_panel) = &settings_content.project_panel {
1928                                &project_panel.hide_gitignore
1929                            } else {
1930                                &None
1931                            }
1932                        },
1933                        pick_mut: |settings_content| {
1934                            &mut settings_content
1935                                .project_panel
1936                                .get_or_insert_default()
1937                                .hide_gitignore
1938                        },
1939                    }),
1940                    metadata: None,
1941                }),
1942                SettingsPageItem::SettingItem(SettingItem {
1943                    title: "Entry Spacing",
1944                    description: "Spacing between worktree entries in the project panel",
1945                    field: Box::new(SettingField {
1946                        pick: |settings_content| {
1947                            if let Some(project_panel) = &settings_content.project_panel {
1948                                &project_panel.entry_spacing
1949                            } else {
1950                                &None
1951                            }
1952                        },
1953                        pick_mut: |settings_content| {
1954                            &mut settings_content
1955                                .project_panel
1956                                .get_or_insert_default()
1957                                .entry_spacing
1958                        },
1959                    }),
1960                    metadata: None,
1961                }),
1962                SettingsPageItem::SettingItem(SettingItem {
1963                    title: "File Icons",
1964                    description: "Whether to show folder icons or chevrons for directories in the project panel",
1965                    field: Box::new(SettingField {
1966                        pick: |settings_content| {
1967                            if let Some(project_panel) = &settings_content.project_panel {
1968                                &project_panel.file_icons
1969                            } else {
1970                                &None
1971                            }
1972                        },
1973                        pick_mut: |settings_content| {
1974                            &mut settings_content
1975                                .project_panel
1976                                .get_or_insert_default()
1977                                .file_icons
1978                        },
1979                    }),
1980                    metadata: None,
1981                }),
1982                SettingsPageItem::SettingItem(SettingItem {
1983                    title: "Folder Icons",
1984                    description: "Whether to show folder icons or chevrons for directories in the project panel",
1985                    field: Box::new(SettingField {
1986                        pick: |settings_content| {
1987                            if let Some(project_panel) = &settings_content.project_panel {
1988                                &project_panel.folder_icons
1989                            } else {
1990                                &None
1991                            }
1992                        },
1993                        pick_mut: |settings_content| {
1994                            &mut settings_content
1995                                .project_panel
1996                                .get_or_insert_default()
1997                                .folder_icons
1998                        },
1999                    }),
2000                    metadata: None,
2001                }),
2002                SettingsPageItem::SettingItem(SettingItem {
2003                    title: "Git Status",
2004                    description: "Whether to show the git status in the project panel",
2005                    field: Box::new(SettingField {
2006                        pick: |settings_content| {
2007                            if let Some(project_panel) = &settings_content.project_panel {
2008                                &project_panel.git_status
2009                            } else {
2010                                &None
2011                            }
2012                        },
2013                        pick_mut: |settings_content| {
2014                            &mut settings_content
2015                                .project_panel
2016                                .get_or_insert_default()
2017                                .git_status
2018                        },
2019                    }),
2020                    metadata: None,
2021                }),
2022                SettingsPageItem::SettingItem(SettingItem {
2023                    title: "Indent Size",
2024                    description: "Amount of indentation for nested items",
2025                    field: Box::new(SettingField {
2026                        pick: |settings_content| {
2027                            if let Some(project_panel) = &settings_content.project_panel {
2028                                &project_panel.indent_size
2029                            } else {
2030                                &None
2031                            }
2032                        },
2033                        pick_mut: |settings_content| {
2034                            &mut settings_content
2035                                .project_panel
2036                                .get_or_insert_default()
2037                                .indent_size
2038                        },
2039                    }),
2040                    metadata: None,
2041                }),
2042                SettingsPageItem::SettingItem(SettingItem {
2043                    title: "Auto Reveal Entries",
2044                    description: "Whether to reveal it in the project panel automatically when a corresponding project entry becomes active",
2045                    field: Box::new(SettingField {
2046                        pick: |settings_content| {
2047                            if let Some(project_panel) = &settings_content.project_panel {
2048                                &project_panel.auto_reveal_entries
2049                            } else {
2050                                &None
2051                            }
2052                        },
2053                        pick_mut: |settings_content| {
2054                            &mut settings_content
2055                                .project_panel
2056                                .get_or_insert_default()
2057                                .auto_reveal_entries
2058                        },
2059                    }),
2060                    metadata: None,
2061                }),
2062                SettingsPageItem::SettingItem(SettingItem {
2063                    title: "Starts Open",
2064                    description: "Whether the project panel should open on startup",
2065                    field: Box::new(SettingField {
2066                        pick: |settings_content| {
2067                            if let Some(project_panel) = &settings_content.project_panel {
2068                                &project_panel.starts_open
2069                            } else {
2070                                &None
2071                            }
2072                        },
2073                        pick_mut: |settings_content| {
2074                            &mut settings_content
2075                                .project_panel
2076                                .get_or_insert_default()
2077                                .starts_open
2078                        },
2079                    }),
2080                    metadata: None,
2081                }),
2082                SettingsPageItem::SettingItem(SettingItem {
2083                    title: "Auto Fold Directories",
2084                    description: "Whether to fold directories automatically and show compact folders when a directory has only one subdirectory inside",
2085                    field: Box::new(SettingField {
2086                        pick: |settings_content| {
2087                            if let Some(project_panel) = &settings_content.project_panel {
2088                                &project_panel.auto_fold_dirs
2089                            } else {
2090                                &None
2091                            }
2092                        },
2093                        pick_mut: |settings_content| {
2094                            &mut settings_content
2095                                .project_panel
2096                                .get_or_insert_default()
2097                                .auto_fold_dirs
2098                        },
2099                    }),
2100                    metadata: None,
2101                }),
2102                // SettingsPageItem::SettingItem(SettingItem {
2103                //     title: "Scrollbar Show",
2104                //     description: "When to show the scrollbar in the project panel",
2105                //     field: Box::new(SettingField {
2106                //         pick: |settings_content| {
2107                //             if let Some(project_panel) = &settings_content.project_panel {
2108                //                 if let Some(scrollbar) = &project_panel.scrollbar {
2109                //                     &scrollbar.show
2110                //                 } else {
2111                //                     &None
2112                //                 }
2113                //             } else {
2114                //                 &None
2115                //             }
2116                //         },
2117                //         pick_mut: |settings_content| {
2118                //             &mut settings_content
2119                //                 .project_panel
2120                //                 .get_or_insert_default()
2121                //                 .scrollbar
2122                //         },
2123                //     }),
2124                //     metadata: None,
2125                // }),
2126                SettingsPageItem::SettingItem(SettingItem {
2127                    title: "Show Diagnostics",
2128                    description: "Which files containing diagnostic errors/warnings to mark in the project panel",
2129                    field: Box::new(SettingField {
2130                        pick: |settings_content| {
2131                            if let Some(project_panel) = &settings_content.project_panel {
2132                                &project_panel.show_diagnostics
2133                            } else {
2134                                &None
2135                            }
2136                        },
2137                        pick_mut: |settings_content| {
2138                            &mut settings_content
2139                                .project_panel
2140                                .get_or_insert_default()
2141                                .show_diagnostics
2142                        },
2143                    }),
2144                    metadata: None,
2145                }),
2146                SettingsPageItem::SettingItem(SettingItem {
2147                    title: "Sticky Scroll",
2148                    description: "Whether to stick parent directories at top of the project panel",
2149                    field: Box::new(SettingField {
2150                        pick: |settings_content| {
2151                            if let Some(project_panel) = &settings_content.project_panel {
2152                                &project_panel.sticky_scroll
2153                            } else {
2154                                &None
2155                            }
2156                        },
2157                        pick_mut: |settings_content| {
2158                            &mut settings_content
2159                                .project_panel
2160                                .get_or_insert_default()
2161                                .sticky_scroll
2162                        },
2163                    }),
2164                    metadata: None,
2165                }),
2166                // SettingsPageItem::SettingItem(SettingItem {
2167                //     title: "Indent Guides Show",
2168                //     description: "When to show indent guides in the project panel",
2169                //     field: Box::new(SettingField {
2170                //         pick: |settings_content| {
2171                //             if let Some(project_panel) = &settings_content.project_panel {
2172                //                 if let Some(indent_guides) = &project_panel.indent_guides {
2173                //                     &indent_guides.show
2174                //                 } else {
2175                //                     &None
2176                //                 }
2177                //             } else {
2178                //                 &None
2179                //             }
2180                //         },
2181                //         pick_mut: |settings_content| {
2182                //             &mut settings_content
2183                //                 .project_panel
2184                //                 .get_or_insert_default()
2185                //                 .indent_guides
2186                //                 .get_or_insert_default()
2187                //                 .show
2188                //         },
2189                //     }),
2190                //     metadata: None,
2191                // }),
2192                SettingsPageItem::SettingItem(SettingItem {
2193                    title: "Drag and Drop",
2194                    description: "Whether to enable drag-and-drop operations in the project panel",
2195                    field: Box::new(SettingField {
2196                        pick: |settings_content| {
2197                            if let Some(project_panel) = &settings_content.project_panel {
2198                                &project_panel.drag_and_drop
2199                            } else {
2200                                &None
2201                            }
2202                        },
2203                        pick_mut: |settings_content| {
2204                            &mut settings_content
2205                                .project_panel
2206                                .get_or_insert_default()
2207                                .drag_and_drop
2208                        },
2209                    }),
2210                    metadata: None,
2211                }),
2212                SettingsPageItem::SettingItem(SettingItem {
2213                    title: "Hide Root",
2214                    description: "Whether to hide the root entry when only one folder is open in the window",
2215                    field: Box::new(SettingField {
2216                        pick: |settings_content| {
2217                            if let Some(project_panel) = &settings_content.project_panel {
2218                                &project_panel.hide_root
2219                            } else {
2220                                &None
2221                            }
2222                        },
2223                        pick_mut: |settings_content| {
2224                            &mut settings_content
2225                                .project_panel
2226                                .get_or_insert_default()
2227                                .hide_root
2228                        },
2229                    }),
2230                    metadata: None,
2231                }),
2232                SettingsPageItem::SectionHeader("Terminal Panel"),
2233                SettingsPageItem::SettingItem(SettingItem {
2234                    title: "Terminal Dock",
2235                    description: "Where to dock the terminal panel",
2236                    field: Box::new(SettingField {
2237                        pick: |settings_content| {
2238                            if let Some(terminal) = &settings_content.terminal {
2239                                &terminal.dock
2240                            } else {
2241                                &None
2242                            }
2243                        },
2244                        pick_mut: |settings_content| {
2245                            &mut settings_content.terminal.get_or_insert_default().dock
2246                        },
2247                    }),
2248                    metadata: None,
2249                }),
2250                SettingsPageItem::SectionHeader("Outline Panel"),
2251                SettingsPageItem::SettingItem(SettingItem {
2252                    title: "Outline Panel Button",
2253                    description: "Whether to show the outline panel button in the status bar",
2254                    field: Box::new(SettingField {
2255                        pick: |settings_content| {
2256                            if let Some(outline_panel) = &settings_content.outline_panel {
2257                                &outline_panel.button
2258                            } else {
2259                                &None
2260                            }
2261                        },
2262                        pick_mut: |settings_content| {
2263                            &mut settings_content
2264                                .outline_panel
2265                                .get_or_insert_default()
2266                                .button
2267                        },
2268                    }),
2269                    metadata: None,
2270                }),
2271                SettingsPageItem::SettingItem(SettingItem {
2272                    title: "Outline Panel Dock",
2273                    description: "Where to dock the outline panel",
2274                    field: Box::new(SettingField {
2275                        pick: |settings_content| {
2276                            if let Some(outline_panel) = &settings_content.outline_panel {
2277                                &outline_panel.dock
2278                            } else {
2279                                &None
2280                            }
2281                        },
2282                        pick_mut: |settings_content| {
2283                            &mut settings_content.outline_panel.get_or_insert_default().dock
2284                        },
2285                    }),
2286                    metadata: None,
2287                }),
2288                SettingsPageItem::SettingItem(SettingItem {
2289                    title: "Outline Panel Default Width",
2290                    description: "Default width of the outline panel in pixels",
2291                    field: Box::new(SettingField {
2292                        pick: |settings_content| {
2293                            if let Some(outline_panel) = &settings_content.outline_panel {
2294                                &outline_panel.default_width
2295                            } else {
2296                                &None
2297                            }
2298                        },
2299                        pick_mut: |settings_content| {
2300                            &mut settings_content
2301                                .outline_panel
2302                                .get_or_insert_default()
2303                                .default_width
2304                        },
2305                    }),
2306                    metadata: None,
2307                }),
2308                SettingsPageItem::SettingItem(SettingItem {
2309                    title: "File Icons",
2310                    description: "Whether to show file icons in the outline panel",
2311                    field: Box::new(SettingField {
2312                        pick: |settings_content| {
2313                            if let Some(outline_panel) = &settings_content.outline_panel {
2314                                &outline_panel.file_icons
2315                            } else {
2316                                &None
2317                            }
2318                        },
2319                        pick_mut: |settings_content| {
2320                            &mut settings_content
2321                                .outline_panel
2322                                .get_or_insert_default()
2323                                .file_icons
2324                        },
2325                    }),
2326                    metadata: None,
2327                }),
2328                SettingsPageItem::SettingItem(SettingItem {
2329                    title: "Folder Icons",
2330                    description: "Whether to show folder icons or chevrons for directories in the outline panel",
2331                    field: Box::new(SettingField {
2332                        pick: |settings_content| {
2333                            if let Some(outline_panel) = &settings_content.outline_panel {
2334                                &outline_panel.folder_icons
2335                            } else {
2336                                &None
2337                            }
2338                        },
2339                        pick_mut: |settings_content| {
2340                            &mut settings_content
2341                                .outline_panel
2342                                .get_or_insert_default()
2343                                .folder_icons
2344                        },
2345                    }),
2346                    metadata: None,
2347                }),
2348                SettingsPageItem::SettingItem(SettingItem {
2349                    title: "Git Status",
2350                    description: "Whether to show the git status in the outline panel",
2351                    field: Box::new(SettingField {
2352                        pick: |settings_content| {
2353                            if let Some(outline_panel) = &settings_content.outline_panel {
2354                                &outline_panel.git_status
2355                            } else {
2356                                &None
2357                            }
2358                        },
2359                        pick_mut: |settings_content| {
2360                            &mut settings_content
2361                                .outline_panel
2362                                .get_or_insert_default()
2363                                .git_status
2364                        },
2365                    }),
2366                    metadata: None,
2367                }),
2368                SettingsPageItem::SettingItem(SettingItem {
2369                    title: "Indent Size",
2370                    description: "Amount of indentation for nested items",
2371                    field: Box::new(SettingField {
2372                        pick: |settings_content| {
2373                            if let Some(outline_panel) = &settings_content.outline_panel {
2374                                &outline_panel.indent_size
2375                            } else {
2376                                &None
2377                            }
2378                        },
2379                        pick_mut: |settings_content| {
2380                            &mut settings_content
2381                                .outline_panel
2382                                .get_or_insert_default()
2383                                .indent_size
2384                        },
2385                    }),
2386                    metadata: None,
2387                }),
2388                SettingsPageItem::SettingItem(SettingItem {
2389                    title: "Auto Reveal Entries",
2390                    description: "Whether to reveal when a corresponding outline entry becomes active",
2391                    field: Box::new(SettingField {
2392                        pick: |settings_content| {
2393                            if let Some(outline_panel) = &settings_content.outline_panel {
2394                                &outline_panel.auto_reveal_entries
2395                            } else {
2396                                &None
2397                            }
2398                        },
2399                        pick_mut: |settings_content| {
2400                            &mut settings_content
2401                                .outline_panel
2402                                .get_or_insert_default()
2403                                .auto_reveal_entries
2404                        },
2405                    }),
2406                    metadata: None,
2407                }),
2408                SettingsPageItem::SettingItem(SettingItem {
2409                    title: "Auto Fold Directories",
2410                    description: "Whether to fold directories automatically when a directory has only one directory inside",
2411                    field: Box::new(SettingField {
2412                        pick: |settings_content| {
2413                            if let Some(outline_panel) = &settings_content.outline_panel {
2414                                &outline_panel.auto_fold_dirs
2415                            } else {
2416                                &None
2417                            }
2418                        },
2419                        pick_mut: |settings_content| {
2420                            &mut settings_content
2421                                .outline_panel
2422                                .get_or_insert_default()
2423                                .auto_fold_dirs
2424                        },
2425                    }),
2426                    metadata: None,
2427                }),
2428                // SettingsPageItem::SettingItem(SettingItem {
2429                //     title: "Indent Guides Show",
2430                //     description: "When to show indent guides in the outline panel",
2431                //     field: Box::new(SettingField {
2432                //         pick: |settings_content| {
2433                //             if let Some(outline_panel) = &settings_content.outline_panel {
2434                //                 if let Some(indent_guides) = &outline_panel.indent_guides {
2435                //                     &indent_guides.show
2436                //                 } else {
2437                //                     &None
2438                //                 }
2439                //             } else {
2440                //                 &None
2441                //             }
2442                //         },
2443                //         pick_mut: |settings_content| {
2444                //             &mut settings_content
2445                //                 .outline_panel
2446                //                 .get_or_insert_default()
2447                //                 .indent_guides
2448                //                 .get_or_insert_default()
2449                //                 .show
2450                //         },
2451                //     }),
2452                //     metadata: None,
2453                // }),
2454                SettingsPageItem::SectionHeader("Notification Panel"),
2455                SettingsPageItem::SettingItem(SettingItem {
2456                    title: "Notification Panel Button",
2457                    description: "Whether to show the notification panel button in the status bar",
2458                    field: Box::new(SettingField {
2459                        pick: |settings_content| {
2460                            if let Some(notification_panel) = &settings_content.notification_panel {
2461                                &notification_panel.button
2462                            } else {
2463                                &None
2464                            }
2465                        },
2466                        pick_mut: |settings_content| {
2467                            &mut settings_content
2468                                .notification_panel
2469                                .get_or_insert_default()
2470                                .button
2471                        },
2472                    }),
2473                    metadata: None,
2474                }),
2475                SettingsPageItem::SettingItem(SettingItem {
2476                    title: "Notification Panel Dock",
2477                    description: "Where to dock the notification panel",
2478                    field: Box::new(SettingField {
2479                        pick: |settings_content| {
2480                            if let Some(notification_panel) = &settings_content.notification_panel {
2481                                &notification_panel.dock
2482                            } else {
2483                                &None
2484                            }
2485                        },
2486                        pick_mut: |settings_content| {
2487                            &mut settings_content
2488                                .notification_panel
2489                                .get_or_insert_default()
2490                                .dock
2491                        },
2492                    }),
2493                    metadata: None,
2494                }),
2495                SettingsPageItem::SettingItem(SettingItem {
2496                    title: "Notification Panel Default Width",
2497                    description: "Default width of the notification panel in pixels",
2498                    field: Box::new(SettingField {
2499                        pick: |settings_content| {
2500                            if let Some(notification_panel) = &settings_content.notification_panel {
2501                                &notification_panel.default_width
2502                            } else {
2503                                &None
2504                            }
2505                        },
2506                        pick_mut: |settings_content| {
2507                            &mut settings_content
2508                                .notification_panel
2509                                .get_or_insert_default()
2510                                .default_width
2511                        },
2512                    }),
2513                    metadata: None,
2514                }),
2515                SettingsPageItem::SectionHeader("Collaboration Panel"),
2516                SettingsPageItem::SettingItem(SettingItem {
2517                    title: "Collaboration Panel Button",
2518                    description: "Whether to show the collaboration panel button in the status bar",
2519                    field: Box::new(SettingField {
2520                        pick: |settings_content| {
2521                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
2522                            {
2523                                &collaboration_panel.button
2524                            } else {
2525                                &None
2526                            }
2527                        },
2528                        pick_mut: |settings_content| {
2529                            &mut settings_content
2530                                .collaboration_panel
2531                                .get_or_insert_default()
2532                                .button
2533                        },
2534                    }),
2535                    metadata: None,
2536                }),
2537                SettingsPageItem::SettingItem(SettingItem {
2538                    title: "Collaboration Panel Dock",
2539                    description: "Where to dock the collaboration panel",
2540                    field: Box::new(SettingField {
2541                        pick: |settings_content| {
2542                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
2543                            {
2544                                &collaboration_panel.dock
2545                            } else {
2546                                &None
2547                            }
2548                        },
2549                        pick_mut: |settings_content| {
2550                            &mut settings_content
2551                                .collaboration_panel
2552                                .get_or_insert_default()
2553                                .dock
2554                        },
2555                    }),
2556                    metadata: None,
2557                }),
2558                SettingsPageItem::SettingItem(SettingItem {
2559                    title: "Collaboration Panel Default Width",
2560                    description: "Default width of the collaboration panel in pixels",
2561                    field: Box::new(SettingField {
2562                        pick: |settings_content| {
2563                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
2564                            {
2565                                &collaboration_panel.default_width
2566                            } else {
2567                                &None
2568                            }
2569                        },
2570                        pick_mut: |settings_content| {
2571                            &mut settings_content
2572                                .collaboration_panel
2573                                .get_or_insert_default()
2574                                .default_width
2575                        },
2576                    }),
2577                    metadata: None,
2578                }),
2579                SettingsPageItem::SectionHeader("Tab Settings"),
2580                SettingsPageItem::SettingItem(SettingItem {
2581                    title: "Activate On Close",
2582                    description: "What to do after closing the current tab",
2583                    field: Box::new(SettingField {
2584                        pick: |settings_content| {
2585                            if let Some(tabs) = &settings_content.tabs {
2586                                &tabs.activate_on_close
2587                            } else {
2588                                &None
2589                            }
2590                        },
2591                        pick_mut: |settings_content| {
2592                            &mut settings_content
2593                                .tabs
2594                                .get_or_insert_default()
2595                                .activate_on_close
2596                        },
2597                    }),
2598                    metadata: None,
2599                }),
2600                SettingsPageItem::SettingItem(SettingItem {
2601                    title: "Tab Show Diagnostics",
2602                    description: "Which files containing diagnostic errors/warnings to mark in the tabs",
2603                    field: Box::new(SettingField {
2604                        pick: |settings_content| {
2605                            if let Some(tabs) = &settings_content.tabs {
2606                                &tabs.show_diagnostics
2607                            } else {
2608                                &None
2609                            }
2610                        },
2611                        pick_mut: |settings_content| {
2612                            &mut settings_content
2613                                .tabs
2614                                .get_or_insert_default()
2615                                .show_diagnostics
2616                        },
2617                    }),
2618                    metadata: None,
2619                }),
2620                SettingsPageItem::SettingItem(SettingItem {
2621                    title: "Show Close Button",
2622                    description: "Controls the appearance behavior of the tab's close button",
2623                    field: Box::new(SettingField {
2624                        pick: |settings_content| {
2625                            if let Some(tabs) = &settings_content.tabs {
2626                                &tabs.show_close_button
2627                            } else {
2628                                &None
2629                            }
2630                        },
2631                        pick_mut: |settings_content| {
2632                            &mut settings_content
2633                                .tabs
2634                                .get_or_insert_default()
2635                                .show_close_button
2636                        },
2637                    }),
2638                    metadata: None,
2639                }),
2640                SettingsPageItem::SectionHeader("Preview Tabs"),
2641                SettingsPageItem::SettingItem(SettingItem {
2642                    title: "Preview Tabs Enabled",
2643                    description: "Whether to show opened editors as preview tabs",
2644                    field: Box::new(SettingField {
2645                        pick: |settings_content| {
2646                            if let Some(preview_tabs) = &settings_content.preview_tabs {
2647                                &preview_tabs.enabled
2648                            } else {
2649                                &None
2650                            }
2651                        },
2652                        pick_mut: |settings_content| {
2653                            &mut settings_content
2654                                .preview_tabs
2655                                .get_or_insert_default()
2656                                .enabled
2657                        },
2658                    }),
2659                    metadata: None,
2660                }),
2661                SettingsPageItem::SettingItem(SettingItem {
2662                    title: "Enable Preview From File Finder",
2663                    description: "Whether to open tabs in preview mode when selected from the file finder",
2664                    field: Box::new(SettingField {
2665                        pick: |settings_content| {
2666                            if let Some(preview_tabs) = &settings_content.preview_tabs {
2667                                &preview_tabs.enable_preview_from_file_finder
2668                            } else {
2669                                &None
2670                            }
2671                        },
2672                        pick_mut: |settings_content| {
2673                            &mut settings_content
2674                                .preview_tabs
2675                                .get_or_insert_default()
2676                                .enable_preview_from_file_finder
2677                        },
2678                    }),
2679                    metadata: None,
2680                }),
2681                SettingsPageItem::SettingItem(SettingItem {
2682                    title: "Enable Preview From Code Navigation",
2683                    description: "Whether a preview tab gets replaced when code navigation is used to navigate away from the tab",
2684                    field: Box::new(SettingField {
2685                        pick: |settings_content| {
2686                            if let Some(preview_tabs) = &settings_content.preview_tabs {
2687                                &preview_tabs.enable_preview_from_code_navigation
2688                            } else {
2689                                &None
2690                            }
2691                        },
2692                        pick_mut: |settings_content| {
2693                            &mut settings_content
2694                                .preview_tabs
2695                                .get_or_insert_default()
2696                                .enable_preview_from_code_navigation
2697                        },
2698                    }),
2699                    metadata: None,
2700                }),
2701            ],
2702        },
2703        SettingsPage {
2704            title: "Version Control",
2705            items: vec![
2706                SettingsPageItem::SectionHeader("Git"),
2707                SettingsPageItem::SettingItem(SettingItem {
2708                    title: "Git Gutter",
2709                    description: "Control whether the git gutter is shown",
2710                    field: Box::new(SettingField {
2711                        pick: |settings_content| {
2712                            if let Some(git) = &settings_content.git {
2713                                &git.git_gutter
2714                            } else {
2715                                &None
2716                            }
2717                        },
2718                        pick_mut: |settings_content| {
2719                            &mut settings_content.git.get_or_insert_default().git_gutter
2720                        },
2721                    }),
2722                    metadata: None,
2723                }),
2724                // todo(settings_ui): Figure out the right default for this value in default.json
2725                // SettingsPageItem::SettingItem(SettingItem {
2726                //     title: "Gutter Debounce",
2727                //     description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
2728                //     field: Box::new(SettingField {
2729                //         pick: |settings_content| {
2730                //             if let Some(git) = &settings_content.git {
2731                //                 &git.gutter_debounce
2732                //             } else {
2733                //                 &None
2734                //             }
2735                //         },
2736                //         pick_mut: |settings_content| {
2737                //             &mut settings_content.git.get_or_insert_default().gutter_debounce
2738                //         },
2739                //     }),
2740                //     metadata: None,
2741                // }),
2742                SettingsPageItem::SettingItem(SettingItem {
2743                    title: "Inline Blame Enabled",
2744                    description: "Whether or not to show git blame data inline in the currently focused line",
2745                    field: Box::new(SettingField {
2746                        pick: |settings_content| {
2747                            if let Some(git) = &settings_content.git {
2748                                if let Some(inline_blame) = &git.inline_blame {
2749                                    &inline_blame.enabled
2750                                } else {
2751                                    &None
2752                                }
2753                            } else {
2754                                &None
2755                            }
2756                        },
2757                        pick_mut: |settings_content| {
2758                            &mut settings_content
2759                                .git
2760                                .get_or_insert_default()
2761                                .inline_blame
2762                                .get_or_insert_default()
2763                                .enabled
2764                        },
2765                    }),
2766                    metadata: None,
2767                }),
2768                SettingsPageItem::SettingItem(SettingItem {
2769                    title: "Inline Blame Delay",
2770                    description: "The delay after which the inline blame information is shown",
2771                    field: Box::new(SettingField {
2772                        pick: |settings_content| {
2773                            if let Some(git) = &settings_content.git {
2774                                if let Some(inline_blame) = &git.inline_blame {
2775                                    &inline_blame.delay_ms
2776                                } else {
2777                                    &None
2778                                }
2779                            } else {
2780                                &None
2781                            }
2782                        },
2783                        pick_mut: |settings_content| {
2784                            &mut settings_content
2785                                .git
2786                                .get_or_insert_default()
2787                                .inline_blame
2788                                .get_or_insert_default()
2789                                .delay_ms
2790                        },
2791                    }),
2792                    metadata: None,
2793                }),
2794                SettingsPageItem::SettingItem(SettingItem {
2795                    title: "Inline Blame Padding",
2796                    description: "Padding between the end of the source line and the start of the inline blame in columns",
2797                    field: Box::new(SettingField {
2798                        pick: |settings_content| {
2799                            if let Some(git) = &settings_content.git {
2800                                if let Some(inline_blame) = &git.inline_blame {
2801                                    &inline_blame.padding
2802                                } else {
2803                                    &None
2804                                }
2805                            } else {
2806                                &None
2807                            }
2808                        },
2809                        pick_mut: |settings_content| {
2810                            &mut settings_content
2811                                .git
2812                                .get_or_insert_default()
2813                                .inline_blame
2814                                .get_or_insert_default()
2815                                .padding
2816                        },
2817                    }),
2818                    metadata: None,
2819                }),
2820                SettingsPageItem::SettingItem(SettingItem {
2821                    title: "Inline Blame Min Column",
2822                    description: "The minimum column number to show the inline blame information at",
2823                    field: Box::new(SettingField {
2824                        pick: |settings_content| {
2825                            if let Some(git) = &settings_content.git {
2826                                if let Some(inline_blame) = &git.inline_blame {
2827                                    &inline_blame.min_column
2828                                } else {
2829                                    &None
2830                                }
2831                            } else {
2832                                &None
2833                            }
2834                        },
2835                        pick_mut: |settings_content| {
2836                            &mut settings_content
2837                                .git
2838                                .get_or_insert_default()
2839                                .inline_blame
2840                                .get_or_insert_default()
2841                                .min_column
2842                        },
2843                    }),
2844                    metadata: None,
2845                }),
2846                SettingsPageItem::SettingItem(SettingItem {
2847                    title: "Show Commit Summary",
2848                    description: "Whether to show commit summary as part of the inline blame",
2849                    field: Box::new(SettingField {
2850                        pick: |settings_content| {
2851                            if let Some(git) = &settings_content.git {
2852                                if let Some(inline_blame) = &git.inline_blame {
2853                                    &inline_blame.show_commit_summary
2854                                } else {
2855                                    &None
2856                                }
2857                            } else {
2858                                &None
2859                            }
2860                        },
2861                        pick_mut: |settings_content| {
2862                            &mut settings_content
2863                                .git
2864                                .get_or_insert_default()
2865                                .inline_blame
2866                                .get_or_insert_default()
2867                                .show_commit_summary
2868                        },
2869                    }),
2870                    metadata: None,
2871                }),
2872                SettingsPageItem::SettingItem(SettingItem {
2873                    title: "Show Avatar",
2874                    description: "Whether to show the avatar of the author of the commit",
2875                    field: Box::new(SettingField {
2876                        pick: |settings_content| {
2877                            if let Some(git) = &settings_content.git {
2878                                if let Some(blame) = &git.blame {
2879                                    &blame.show_avatar
2880                                } else {
2881                                    &None
2882                                }
2883                            } else {
2884                                &None
2885                            }
2886                        },
2887                        pick_mut: |settings_content| {
2888                            &mut settings_content
2889                                .git
2890                                .get_or_insert_default()
2891                                .blame
2892                                .get_or_insert_default()
2893                                .show_avatar
2894                        },
2895                    }),
2896                    metadata: None,
2897                }),
2898                SettingsPageItem::SettingItem(SettingItem {
2899                    title: "Show Author Name In Branch Picker",
2900                    description: "Whether to show author name as part of the commit information in branch picker",
2901                    field: Box::new(SettingField {
2902                        pick: |settings_content| {
2903                            if let Some(git) = &settings_content.git {
2904                                if let Some(branch_picker) = &git.branch_picker {
2905                                    &branch_picker.show_author_name
2906                                } else {
2907                                    &None
2908                                }
2909                            } else {
2910                                &None
2911                            }
2912                        },
2913                        pick_mut: |settings_content| {
2914                            &mut settings_content
2915                                .git
2916                                .get_or_insert_default()
2917                                .branch_picker
2918                                .get_or_insert_default()
2919                                .show_author_name
2920                        },
2921                    }),
2922                    metadata: None,
2923                }),
2924                SettingsPageItem::SettingItem(SettingItem {
2925                    title: "Hunk Style",
2926                    description: "How git hunks are displayed visually in the editor",
2927                    field: Box::new(SettingField {
2928                        pick: |settings_content| {
2929                            if let Some(git) = &settings_content.git {
2930                                &git.hunk_style
2931                            } else {
2932                                &None
2933                            }
2934                        },
2935                        pick_mut: |settings_content| {
2936                            &mut settings_content.git.get_or_insert_default().hunk_style
2937                        },
2938                    }),
2939                    metadata: None,
2940                }),
2941            ],
2942        },
2943        SettingsPage {
2944            title: "System & Network",
2945            items: vec![
2946                SettingsPageItem::SectionHeader("Network"),
2947                // todo(settings_ui): Proxy needs a default
2948                // SettingsPageItem::SettingItem(SettingItem {
2949                //     title: "Proxy",
2950                //     description: "The proxy to use for network requests",
2951                //     field: Box::new(SettingField {
2952                //         pick: |settings_content| &settings_content.proxy,
2953                //         pick_mut: |settings_content| &mut settings_content.proxy,
2954                //     }),
2955                //     metadata: Some(Box::new(SettingsFieldMetadata {
2956                //         placeholder: Some("socks5h://localhost:10808"),
2957                //     })),
2958                // }),
2959                SettingsPageItem::SettingItem(SettingItem {
2960                    title: "Server URL",
2961                    description: "The URL of the Zed server to connect to",
2962                    field: Box::new(SettingField {
2963                        pick: |settings_content| &settings_content.server_url,
2964                        pick_mut: |settings_content| &mut settings_content.server_url,
2965                    }),
2966                    metadata: Some(Box::new(SettingsFieldMetadata {
2967                        placeholder: Some("https://zed.dev"),
2968                    })),
2969                }),
2970                SettingsPageItem::SectionHeader("System"),
2971                SettingsPageItem::SettingItem(SettingItem {
2972                    title: "Auto Update",
2973                    description: "Whether or not to automatically check for updates",
2974                    field: Box::new(SettingField {
2975                        pick: |settings_content| &settings_content.auto_update,
2976                        pick_mut: |settings_content| &mut settings_content.auto_update,
2977                    }),
2978                    metadata: None,
2979                }),
2980            ],
2981        },
2982        SettingsPage {
2983            title: "Diagnostics & Errors",
2984            items: vec![
2985                SettingsPageItem::SectionHeader("Display"),
2986                SettingsPageItem::SettingItem(SettingItem {
2987                    title: "Diagnostics Button",
2988                    description: "Whether to show the project diagnostics button in the status bar",
2989                    field: Box::new(SettingField {
2990                        pick: |settings_content| {
2991                            if let Some(diagnostics) = &settings_content.diagnostics {
2992                                &diagnostics.button
2993                            } else {
2994                                &None
2995                            }
2996                        },
2997                        pick_mut: |settings_content| {
2998                            &mut settings_content.diagnostics.get_or_insert_default().button
2999                        },
3000                    }),
3001                    metadata: None,
3002                }),
3003                SettingsPageItem::SectionHeader("Filtering"),
3004                SettingsPageItem::SettingItem(SettingItem {
3005                    title: "Max Severity",
3006                    description: "Which level to use to filter out diagnostics displayed in the editor",
3007                    field: Box::new(SettingField {
3008                        pick: |settings_content| &settings_content.editor.diagnostics_max_severity,
3009                        pick_mut: |settings_content| {
3010                            &mut settings_content.editor.diagnostics_max_severity
3011                        },
3012                    }),
3013                    metadata: None,
3014                }),
3015                SettingsPageItem::SettingItem(SettingItem {
3016                    title: "Include Warnings",
3017                    description: "Whether to show warnings or not by default",
3018                    field: Box::new(SettingField {
3019                        pick: |settings_content| {
3020                            if let Some(diagnostics) = &settings_content.diagnostics {
3021                                &diagnostics.include_warnings
3022                            } else {
3023                                &None
3024                            }
3025                        },
3026                        pick_mut: |settings_content| {
3027                            &mut settings_content
3028                                .diagnostics
3029                                .get_or_insert_default()
3030                                .include_warnings
3031                        },
3032                    }),
3033                    metadata: None,
3034                }),
3035                SettingsPageItem::SectionHeader("Inline"),
3036                SettingsPageItem::SettingItem(SettingItem {
3037                    title: "Inline Diagnostics Enabled",
3038                    description: "Whether to show diagnostics inline or not",
3039                    field: Box::new(SettingField {
3040                        pick: |settings_content| {
3041                            if let Some(diagnostics) = &settings_content.diagnostics {
3042                                if let Some(inline) = &diagnostics.inline {
3043                                    &inline.enabled
3044                                } else {
3045                                    &None
3046                                }
3047                            } else {
3048                                &None
3049                            }
3050                        },
3051                        pick_mut: |settings_content| {
3052                            &mut settings_content
3053                                .diagnostics
3054                                .get_or_insert_default()
3055                                .inline
3056                                .get_or_insert_default()
3057                                .enabled
3058                        },
3059                    }),
3060                    metadata: None,
3061                }),
3062                // todo(settings_ui): Needs numeric stepper
3063                SettingsPageItem::SettingItem(SettingItem {
3064                    title: "Inline Update Debounce",
3065                    description: "The delay in milliseconds to show inline diagnostics after the last diagnostic update",
3066                    field: Box::new(SettingField {
3067                        pick: |settings_content| {
3068                            if let Some(diagnostics) = &settings_content.diagnostics {
3069                                if let Some(inline) = &diagnostics.inline {
3070                                    &inline.update_debounce_ms
3071                                } else {
3072                                    &None
3073                                }
3074                            } else {
3075                                &None
3076                            }
3077                        },
3078                        pick_mut: |settings_content| {
3079                            &mut settings_content
3080                                .diagnostics
3081                                .get_or_insert_default()
3082                                .inline
3083                                .get_or_insert_default()
3084                                .update_debounce_ms
3085                        },
3086                    }),
3087                    metadata: None,
3088                }),
3089                // todo(settings_ui): Needs numeric stepper
3090                SettingsPageItem::SettingItem(SettingItem {
3091                    title: "Inline Padding",
3092                    description: "The amount of padding between the end of the source line and the start of the inline diagnostic",
3093                    field: Box::new(SettingField {
3094                        pick: |settings_content| {
3095                            if let Some(diagnostics) = &settings_content.diagnostics {
3096                                if let Some(inline) = &diagnostics.inline {
3097                                    &inline.padding
3098                                } else {
3099                                    &None
3100                                }
3101                            } else {
3102                                &None
3103                            }
3104                        },
3105                        pick_mut: |settings_content| {
3106                            &mut settings_content
3107                                .diagnostics
3108                                .get_or_insert_default()
3109                                .inline
3110                                .get_or_insert_default()
3111                                .padding
3112                        },
3113                    }),
3114                    metadata: None,
3115                }),
3116                // todo(settings_ui): Needs numeric stepper
3117                SettingsPageItem::SettingItem(SettingItem {
3118                    title: "Inline Min Column",
3119                    description: "The minimum column to display inline diagnostics",
3120                    field: Box::new(SettingField {
3121                        pick: |settings_content| {
3122                            if let Some(diagnostics) = &settings_content.diagnostics {
3123                                if let Some(inline) = &diagnostics.inline {
3124                                    &inline.min_column
3125                                } else {
3126                                    &None
3127                                }
3128                            } else {
3129                                &None
3130                            }
3131                        },
3132                        pick_mut: |settings_content| {
3133                            &mut settings_content
3134                                .diagnostics
3135                                .get_or_insert_default()
3136                                .inline
3137                                .get_or_insert_default()
3138                                .min_column
3139                        },
3140                    }),
3141                    metadata: None,
3142                }),
3143                SettingsPageItem::SectionHeader("Performance"),
3144                SettingsPageItem::SettingItem(SettingItem {
3145                    title: "LSP Pull Diagnostics Enabled",
3146                    description: "Whether to pull for diagnostics or not",
3147                    field: Box::new(SettingField {
3148                        pick: |settings_content| {
3149                            if let Some(diagnostics) = &settings_content.diagnostics {
3150                                if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
3151                                    &lsp_pull.enabled
3152                                } else {
3153                                    &None
3154                                }
3155                            } else {
3156                                &None
3157                            }
3158                        },
3159                        pick_mut: |settings_content| {
3160                            &mut settings_content
3161                                .diagnostics
3162                                .get_or_insert_default()
3163                                .lsp_pull_diagnostics
3164                                .get_or_insert_default()
3165                                .enabled
3166                        },
3167                    }),
3168                    metadata: None,
3169                }),
3170                // todo(settings_ui): Needs unit
3171                SettingsPageItem::SettingItem(SettingItem {
3172                    title: "LSP Pull Debounce",
3173                    description: "Minimum time to wait before pulling diagnostics from the language server(s)",
3174                    field: Box::new(SettingField {
3175                        pick: |settings_content| {
3176                            if let Some(diagnostics) = &settings_content.diagnostics {
3177                                if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
3178                                    &lsp_pull.debounce_ms
3179                                } else {
3180                                    &None
3181                                }
3182                            } else {
3183                                &None
3184                            }
3185                        },
3186                        pick_mut: |settings_content| {
3187                            &mut settings_content
3188                                .diagnostics
3189                                .get_or_insert_default()
3190                                .lsp_pull_diagnostics
3191                                .get_or_insert_default()
3192                                .debounce_ms
3193                        },
3194                    }),
3195                    metadata: None,
3196                }),
3197            ],
3198        },
3199        SettingsPage {
3200            title: "Collaboration",
3201            items: vec![
3202                SettingsPageItem::SectionHeader("Calls"),
3203                SettingsPageItem::SettingItem(SettingItem {
3204                    title: "Mute On Join",
3205                    description: "Whether the microphone should be muted when joining a channel or a call",
3206                    field: Box::new(SettingField {
3207                        pick: |settings_content| {
3208                            if let Some(calls) = &settings_content.calls {
3209                                &calls.mute_on_join
3210                            } else {
3211                                &None
3212                            }
3213                        },
3214                        pick_mut: |settings_content| {
3215                            &mut settings_content.calls.get_or_insert_default().mute_on_join
3216                        },
3217                    }),
3218                    metadata: None,
3219                }),
3220                SettingsPageItem::SettingItem(SettingItem {
3221                    title: "Share On Join",
3222                    description: "Whether your current project should be shared when joining an empty channel",
3223                    field: Box::new(SettingField {
3224                        pick: |settings_content| {
3225                            if let Some(calls) = &settings_content.calls {
3226                                &calls.share_on_join
3227                            } else {
3228                                &None
3229                            }
3230                        },
3231                        pick_mut: |settings_content| {
3232                            &mut settings_content.calls.get_or_insert_default().share_on_join
3233                        },
3234                    }),
3235                    metadata: None,
3236                }),
3237                SettingsPageItem::SectionHeader("Experimental"),
3238                SettingsPageItem::SettingItem(SettingItem {
3239                    title: "Rodio Audio",
3240                    description: "Opt into the new audio system",
3241                    field: Box::new(SettingField {
3242                        pick: |settings_content| {
3243                            if let Some(audio) = &settings_content.audio {
3244                                &audio.rodio_audio
3245                            } else {
3246                                &None
3247                            }
3248                        },
3249                        pick_mut: |settings_content| {
3250                            &mut settings_content.audio.get_or_insert_default().rodio_audio
3251                        },
3252                    }),
3253                    metadata: None,
3254                }),
3255            ],
3256        },
3257        SettingsPage {
3258            title: "AI",
3259            items: vec![
3260                SettingsPageItem::SectionHeader("General"),
3261                SettingsPageItem::SettingItem(SettingItem {
3262                    title: "Disable AI",
3263                    description: "Whether to disable all AI features in Zed",
3264                    field: Box::new(SettingField {
3265                        pick: |settings_content| &settings_content.disable_ai,
3266                        pick_mut: |settings_content| &mut settings_content.disable_ai,
3267                    }),
3268                    metadata: None,
3269                }),
3270            ],
3271        },
3272    ]
3273}
3274
3275pub(crate) fn project_settings_data() -> Vec<SettingsPage> {
3276    vec![
3277        SettingsPage {
3278            title: "Project",
3279            items: vec![
3280                SettingsPageItem::SectionHeader("Worktree Settings Content"),
3281                SettingsPageItem::SettingItem(SettingItem {
3282                    title: "Project Name",
3283                    description: "The displayed name of this project. If not set, the root directory name",
3284                    field: Box::new(SettingField {
3285                        pick: |settings_content| &settings_content.project.worktree.project_name,
3286                        pick_mut: |settings_content| {
3287                            &mut settings_content.project.worktree.project_name
3288                        },
3289                    }),
3290                    metadata: Some(Box::new(SettingsFieldMetadata {
3291                        placeholder: Some("A new name"),
3292                    })),
3293                }),
3294            ],
3295        },
3296        SettingsPage {
3297            title: "Appearance & Behavior",
3298            items: vec![
3299                SettingsPageItem::SectionHeader("Guides"),
3300                SettingsPageItem::SettingItem(SettingItem {
3301                    title: "Show Wrap Guides",
3302                    description: "Whether to show wrap guides (vertical rulers)",
3303                    field: Box::new(SettingField {
3304                        pick: |settings_content| {
3305                            &settings_content
3306                                .project
3307                                .all_languages
3308                                .defaults
3309                                .show_wrap_guides
3310                        },
3311                        pick_mut: |settings_content| {
3312                            &mut settings_content
3313                                .project
3314                                .all_languages
3315                                .defaults
3316                                .show_wrap_guides
3317                        },
3318                    }),
3319                    metadata: None,
3320                }),
3321                // todo(settings_ui): This needs a custom component
3322                // SettingsPageItem::SettingItem(SettingItem {
3323                //     title: "Wrap Guides",
3324                //     description: "Character counts at which to show wrap guides",
3325                //     field: Box::new(SettingField {
3326                //         pick: |settings_content| {
3327                //             &settings_content
3328                //                 .project
3329                //                 .all_languages
3330                //                 .defaults
3331                //                 .wrap_guides
3332                //         },
3333                //         pick_mut: |settings_content| {
3334                //             &mut settings_content
3335                //                 .project
3336                //                 .all_languages
3337                //                 .defaults
3338                //                 .wrap_guides
3339                //         },
3340                //     }),
3341                //     metadata: None,
3342                // }),
3343                SettingsPageItem::SectionHeader("Whitespace"),
3344                SettingsPageItem::SettingItem(SettingItem {
3345                    title: "Show Whitespace",
3346                    description: "Whether to show tabs and spaces",
3347                    field: Box::new(SettingField {
3348                        pick: |settings_content| {
3349                            &settings_content
3350                                .project
3351                                .all_languages
3352                                .defaults
3353                                .show_whitespaces
3354                        },
3355                        pick_mut: |settings_content| {
3356                            &mut settings_content
3357                                .project
3358                                .all_languages
3359                                .defaults
3360                                .show_whitespaces
3361                        },
3362                    }),
3363                    metadata: None,
3364                }),
3365            ],
3366        },
3367        SettingsPage {
3368            title: "Editing",
3369            items: vec![
3370                SettingsPageItem::SectionHeader("Indentation"),
3371                // todo(settings_ui): Needs numeric stepper
3372                // SettingsPageItem::SettingItem(SettingItem {
3373                //     title: "Tab Size",
3374                //     description: "How many columns a tab should occupy",
3375                //     field: Box::new(SettingField {
3376                //         pick: |settings_content| &settings_content.project.all_languages.defaults.tab_size,
3377                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.tab_size,
3378                //     }),
3379                //     metadata: None,
3380                // }),
3381                SettingsPageItem::SettingItem(SettingItem {
3382                    title: "Hard Tabs",
3383                    description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
3384                    field: Box::new(SettingField {
3385                        pick: |settings_content| {
3386                            &settings_content.project.all_languages.defaults.hard_tabs
3387                        },
3388                        pick_mut: |settings_content| {
3389                            &mut settings_content.project.all_languages.defaults.hard_tabs
3390                        },
3391                    }),
3392                    metadata: None,
3393                }),
3394                SettingsPageItem::SettingItem(SettingItem {
3395                    title: "Auto Indent",
3396                    description: "Whether indentation should be adjusted based on the context whilst typing",
3397                    field: Box::new(SettingField {
3398                        pick: |settings_content| {
3399                            &settings_content.project.all_languages.defaults.auto_indent
3400                        },
3401                        pick_mut: |settings_content| {
3402                            &mut settings_content.project.all_languages.defaults.auto_indent
3403                        },
3404                    }),
3405                    metadata: None,
3406                }),
3407                SettingsPageItem::SettingItem(SettingItem {
3408                    title: "Auto Indent On Paste",
3409                    description: "Whether indentation of pasted content should be adjusted based on the context",
3410                    field: Box::new(SettingField {
3411                        pick: |settings_content| {
3412                            &settings_content
3413                                .project
3414                                .all_languages
3415                                .defaults
3416                                .auto_indent_on_paste
3417                        },
3418                        pick_mut: |settings_content| {
3419                            &mut settings_content
3420                                .project
3421                                .all_languages
3422                                .defaults
3423                                .auto_indent_on_paste
3424                        },
3425                    }),
3426                    metadata: None,
3427                }),
3428                SettingsPageItem::SectionHeader("Wrapping"),
3429                // todo(settings_ui): Needs numeric stepper
3430                // SettingsPageItem::SettingItem(SettingItem {
3431                //     title: "Preferred Line Length",
3432                //     description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
3433                //     field: Box::new(SettingField {
3434                //         pick: |settings_content| &settings_content.project.all_languages.defaults.preferred_line_length,
3435                //         pick_mut: |settings_content| &mut settings_content.project.all_languages.defaults.preferred_line_length,
3436                //     }),
3437                //     metadata: None,
3438                // }),
3439                SettingsPageItem::SettingItem(SettingItem {
3440                    title: "Soft Wrap",
3441                    description: "How to soft-wrap long lines of text",
3442                    field: Box::new(SettingField {
3443                        pick: |settings_content| {
3444                            &settings_content.project.all_languages.defaults.soft_wrap
3445                        },
3446                        pick_mut: |settings_content| {
3447                            &mut settings_content.project.all_languages.defaults.soft_wrap
3448                        },
3449                    }),
3450                    metadata: None,
3451                }),
3452                SettingsPageItem::SectionHeader("Auto Actions"),
3453                SettingsPageItem::SettingItem(SettingItem {
3454                    title: "Use Autoclose",
3455                    description: "Whether to automatically type closing characters for you",
3456                    field: Box::new(SettingField {
3457                        pick: |settings_content| {
3458                            &settings_content
3459                                .project
3460                                .all_languages
3461                                .defaults
3462                                .use_autoclose
3463                        },
3464                        pick_mut: |settings_content| {
3465                            &mut settings_content
3466                                .project
3467                                .all_languages
3468                                .defaults
3469                                .use_autoclose
3470                        },
3471                    }),
3472                    metadata: None,
3473                }),
3474                SettingsPageItem::SettingItem(SettingItem {
3475                    title: "Use Auto Surround",
3476                    description: "Whether to automatically surround text with characters for you",
3477                    field: Box::new(SettingField {
3478                        pick: |settings_content| {
3479                            &settings_content
3480                                .project
3481                                .all_languages
3482                                .defaults
3483                                .use_auto_surround
3484                        },
3485                        pick_mut: |settings_content| {
3486                            &mut settings_content
3487                                .project
3488                                .all_languages
3489                                .defaults
3490                                .use_auto_surround
3491                        },
3492                    }),
3493                    metadata: None,
3494                }),
3495                SettingsPageItem::SettingItem(SettingItem {
3496                    title: "Use On Type Format",
3497                    description: "Whether to use additional LSP queries to format the code after every trigger symbol input",
3498                    field: Box::new(SettingField {
3499                        pick: |settings_content| {
3500                            &settings_content
3501                                .project
3502                                .all_languages
3503                                .defaults
3504                                .use_on_type_format
3505                        },
3506                        pick_mut: |settings_content| {
3507                            &mut settings_content
3508                                .project
3509                                .all_languages
3510                                .defaults
3511                                .use_on_type_format
3512                        },
3513                    }),
3514                    metadata: None,
3515                }),
3516                SettingsPageItem::SettingItem(SettingItem {
3517                    title: "Always Treat Brackets As Autoclosed",
3518                    description: "Controls how the editor handles the autoclosed characters",
3519                    field: Box::new(SettingField {
3520                        pick: |settings_content| {
3521                            &settings_content
3522                                .project
3523                                .all_languages
3524                                .defaults
3525                                .always_treat_brackets_as_autoclosed
3526                        },
3527                        pick_mut: |settings_content| {
3528                            &mut settings_content
3529                                .project
3530                                .all_languages
3531                                .defaults
3532                                .always_treat_brackets_as_autoclosed
3533                        },
3534                    }),
3535                    metadata: None,
3536                }),
3537                SettingsPageItem::SectionHeader("Formatting"),
3538                SettingsPageItem::SettingItem(SettingItem {
3539                    title: "Remove Trailing Whitespace On Save",
3540                    description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
3541                    field: Box::new(SettingField {
3542                        pick: |settings_content| {
3543                            &settings_content
3544                                .project
3545                                .all_languages
3546                                .defaults
3547                                .remove_trailing_whitespace_on_save
3548                        },
3549                        pick_mut: |settings_content| {
3550                            &mut settings_content
3551                                .project
3552                                .all_languages
3553                                .defaults
3554                                .remove_trailing_whitespace_on_save
3555                        },
3556                    }),
3557                    metadata: None,
3558                }),
3559                SettingsPageItem::SettingItem(SettingItem {
3560                    title: "Ensure Final Newline On Save",
3561                    description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
3562                    field: Box::new(SettingField {
3563                        pick: |settings_content| {
3564                            &settings_content
3565                                .project
3566                                .all_languages
3567                                .defaults
3568                                .ensure_final_newline_on_save
3569                        },
3570                        pick_mut: |settings_content| {
3571                            &mut settings_content
3572                                .project
3573                                .all_languages
3574                                .defaults
3575                                .ensure_final_newline_on_save
3576                        },
3577                    }),
3578                    metadata: None,
3579                }),
3580                SettingsPageItem::SettingItem(SettingItem {
3581                    title: "Extend Comment On Newline",
3582                    description: "Whether to start a new line with a comment when a previous line is a comment as well",
3583                    field: Box::new(SettingField {
3584                        pick: |settings_content| {
3585                            &settings_content
3586                                .project
3587                                .all_languages
3588                                .defaults
3589                                .extend_comment_on_newline
3590                        },
3591                        pick_mut: |settings_content| {
3592                            &mut settings_content
3593                                .project
3594                                .all_languages
3595                                .defaults
3596                                .extend_comment_on_newline
3597                        },
3598                    }),
3599                    metadata: None,
3600                }),
3601                SettingsPageItem::SectionHeader("Completions"),
3602                SettingsPageItem::SettingItem(SettingItem {
3603                    title: "Show Completions On Input",
3604                    description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
3605                    field: Box::new(SettingField {
3606                        pick: |settings_content| {
3607                            &settings_content
3608                                .project
3609                                .all_languages
3610                                .defaults
3611                                .show_completions_on_input
3612                        },
3613                        pick_mut: |settings_content| {
3614                            &mut settings_content
3615                                .project
3616                                .all_languages
3617                                .defaults
3618                                .show_completions_on_input
3619                        },
3620                    }),
3621                    metadata: None,
3622                }),
3623                SettingsPageItem::SettingItem(SettingItem {
3624                    title: "Show Completion Documentation",
3625                    description: "Whether to display inline and alongside documentation for items in the completions menu",
3626                    field: Box::new(SettingField {
3627                        pick: |settings_content| {
3628                            &settings_content
3629                                .project
3630                                .all_languages
3631                                .defaults
3632                                .show_completion_documentation
3633                        },
3634                        pick_mut: |settings_content| {
3635                            &mut settings_content
3636                                .project
3637                                .all_languages
3638                                .defaults
3639                                .show_completion_documentation
3640                        },
3641                    }),
3642                    metadata: None,
3643                }),
3644            ],
3645        },
3646    ]
3647}
3648
3649const LANGUAGES_SECTION_HEADER: &'static str = "Languages";
3650
3651fn language_settings_data() -> Vec<SettingsPageItem> {
3652    fn current_language() -> Option<SharedString> {
3653        sub_page_stack().iter().find_map(|page| {
3654            (page.section_header == LANGUAGES_SECTION_HEADER)
3655                .then(|| SharedString::new_static(page.link.title))
3656        })
3657    }
3658
3659    fn language_settings_field<T>(
3660        settings_content: &SettingsContent,
3661        get: fn(&LanguageSettingsContent) -> &Option<T>,
3662    ) -> &Option<T> {
3663        let all_languages = &settings_content.project.all_languages;
3664        let mut language_content = None;
3665        if let Some(current_language) = current_language() {
3666            language_content = all_languages.languages.0.get(&current_language);
3667        }
3668        let value = language_content
3669            .map(get)
3670            .unwrap_or_else(|| get(&all_languages.defaults));
3671        return value;
3672    }
3673
3674    fn language_settings_field_mut<T>(
3675        settings_content: &mut SettingsContent,
3676        get: fn(&mut LanguageSettingsContent) -> &mut Option<T>,
3677    ) -> &mut Option<T> {
3678        let all_languages = &mut settings_content.project.all_languages;
3679        let language_content = if let Some(current_language) = current_language() {
3680            all_languages
3681                .languages
3682                .0
3683                .entry(current_language)
3684                .or_default()
3685        } else {
3686            &mut all_languages.defaults
3687        };
3688        return get(language_content);
3689    }
3690
3691    vec![
3692        SettingsPageItem::SectionHeader("Indentation"),
3693        SettingsPageItem::SettingItem(SettingItem {
3694            title: "Tab Size",
3695            description: "How many columns a tab should occupy",
3696            field: Box::new(SettingField {
3697                pick: |settings_content| {
3698                    language_settings_field(settings_content, |language| &language.tab_size)
3699                },
3700                pick_mut: |settings_content| {
3701                    language_settings_field_mut(settings_content, |language| &mut language.tab_size)
3702                },
3703            }),
3704            metadata: None,
3705        }),
3706        SettingsPageItem::SettingItem(SettingItem {
3707            title: "Hard Tabs",
3708            description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
3709            field: Box::new(SettingField {
3710                pick: |settings_content| {
3711                    language_settings_field(settings_content, |language| &language.hard_tabs)
3712                },
3713                pick_mut: |settings_content| {
3714                    language_settings_field_mut(settings_content, |language| {
3715                        &mut language.hard_tabs
3716                    })
3717                },
3718            }),
3719            metadata: None,
3720        }),
3721        SettingsPageItem::SettingItem(SettingItem {
3722            title: "Auto Indent",
3723            description: "Whether indentation should be adjusted based on the context whilst typing",
3724            field: Box::new(SettingField {
3725                pick: |settings_content| {
3726                    language_settings_field(settings_content, |language| &language.auto_indent)
3727                },
3728                pick_mut: |settings_content| {
3729                    language_settings_field_mut(settings_content, |language| {
3730                        &mut language.auto_indent
3731                    })
3732                },
3733            }),
3734            metadata: None,
3735        }),
3736        SettingsPageItem::SettingItem(SettingItem {
3737            title: "Auto Indent On Paste",
3738            description: "Whether indentation of pasted content should be adjusted based on the context",
3739            field: Box::new(SettingField {
3740                pick: |settings_content| {
3741                    language_settings_field(settings_content, |language| {
3742                        &language.auto_indent_on_paste
3743                    })
3744                },
3745                pick_mut: |settings_content| {
3746                    language_settings_field_mut(settings_content, |language| {
3747                        &mut language.auto_indent_on_paste
3748                    })
3749                },
3750            }),
3751            metadata: None,
3752        }),
3753        SettingsPageItem::SectionHeader("Wrapping"),
3754        SettingsPageItem::SettingItem(SettingItem {
3755            title: "Soft Wrap",
3756            description: "How to soft-wrap long lines of text",
3757            field: Box::new(SettingField {
3758                pick: |settings_content| {
3759                    language_settings_field(settings_content, |language| &language.soft_wrap)
3760                },
3761                pick_mut: |settings_content| {
3762                    language_settings_field_mut(settings_content, |language| {
3763                        &mut language.soft_wrap
3764                    })
3765                },
3766            }),
3767            metadata: None,
3768        }),
3769        SettingsPageItem::SettingItem(SettingItem {
3770            title: "Show Wrap Guides",
3771            description: "Whether to show wrap guides in the editor. Setting this to true will show a guide at the 'preferred_line_length' value if softwrap is set to 'preferred_line_length', and will show any additional guides as specified by the 'wrap_guides' setting",
3772            field: Box::new(SettingField {
3773                pick: |settings_content| {
3774                    language_settings_field(settings_content, |language| &language.show_wrap_guides)
3775                },
3776                pick_mut: |settings_content| {
3777                    language_settings_field_mut(settings_content, |language| {
3778                        &mut language.show_wrap_guides
3779                    })
3780                },
3781            }),
3782            metadata: None,
3783        }),
3784        SettingsPageItem::SettingItem(SettingItem {
3785            title: "Preferred Line Length",
3786            description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
3787            field: Box::new(SettingField {
3788                pick: |settings_content| {
3789                    language_settings_field(settings_content, |language| {
3790                        &language.preferred_line_length
3791                    })
3792                },
3793                pick_mut: |settings_content| {
3794                    language_settings_field_mut(settings_content, |language| {
3795                        &mut language.preferred_line_length
3796                    })
3797                },
3798            }),
3799            metadata: None,
3800        }),
3801        SettingsPageItem::SettingItem(SettingItem {
3802            title: "Wrap Guides",
3803            description: "Character counts at which to show wrap guides in the editor",
3804            field: Box::new(
3805                SettingField {
3806                    pick: |settings_content| {
3807                        language_settings_field(settings_content, |language| &language.wrap_guides)
3808                    },
3809                    pick_mut: |settings_content| {
3810                        language_settings_field_mut(settings_content, |language| {
3811                            &mut language.wrap_guides
3812                        })
3813                    },
3814                }
3815                .unimplemented(),
3816            ),
3817            metadata: None,
3818        }),
3819        SettingsPageItem::SettingItem(SettingItem {
3820            title: "Allow Rewrap",
3821            description: "Controls where the `editor::Rewrap` action is allowed for this language",
3822            field: Box::new(SettingField {
3823                pick: |settings_content| {
3824                    language_settings_field(settings_content, |language| &language.allow_rewrap)
3825                },
3826                pick_mut: |settings_content| {
3827                    language_settings_field_mut(settings_content, |language| {
3828                        &mut language.allow_rewrap
3829                    })
3830                },
3831            }),
3832            metadata: None,
3833        }),
3834        SettingsPageItem::SectionHeader("Indent Guides"),
3835        SettingsPageItem::SettingItem(SettingItem {
3836            title: "Enabled",
3837            description: "Whether to display indent guides in the editor",
3838            field: Box::new(SettingField {
3839                pick: |settings_content| {
3840                    language_settings_field(settings_content, |language| {
3841                        if let Some(indent_guides) = &language.indent_guides {
3842                            &indent_guides.enabled
3843                        } else {
3844                            &None
3845                        }
3846                    })
3847                },
3848                pick_mut: |settings_content| {
3849                    language_settings_field_mut(settings_content, |language| {
3850                        &mut language.indent_guides.get_or_insert_default().enabled
3851                    })
3852                },
3853            }),
3854            metadata: None,
3855        }),
3856        SettingsPageItem::SettingItem(SettingItem {
3857            title: "Line Width",
3858            description: "The width of the indent guides in pixels, between 1 and 10",
3859            field: Box::new(SettingField {
3860                pick: |settings_content| {
3861                    language_settings_field(settings_content, |language| {
3862                        if let Some(indent_guides) = &language.indent_guides {
3863                            &indent_guides.line_width
3864                        } else {
3865                            &None
3866                        }
3867                    })
3868                },
3869                pick_mut: |settings_content| {
3870                    language_settings_field_mut(settings_content, |language| {
3871                        &mut language.indent_guides.get_or_insert_default().line_width
3872                    })
3873                },
3874            }),
3875            metadata: None,
3876        }),
3877        SettingsPageItem::SettingItem(SettingItem {
3878            title: "Active Line Width",
3879            description: "The width of the active indent guide in pixels, between 1 and 10",
3880            field: Box::new(SettingField {
3881                pick: |settings_content| {
3882                    language_settings_field(settings_content, |language| {
3883                        if let Some(indent_guides) = &language.indent_guides {
3884                            &indent_guides.active_line_width
3885                        } else {
3886                            &None
3887                        }
3888                    })
3889                },
3890                pick_mut: |settings_content| {
3891                    language_settings_field_mut(settings_content, |language| {
3892                        &mut language
3893                            .indent_guides
3894                            .get_or_insert_default()
3895                            .active_line_width
3896                    })
3897                },
3898            }),
3899            metadata: None,
3900        }),
3901        SettingsPageItem::SettingItem(SettingItem {
3902            title: "Coloring",
3903            description: "Determines how indent guides are colored",
3904            field: Box::new(SettingField {
3905                pick: |settings_content| {
3906                    language_settings_field(settings_content, |language| {
3907                        if let Some(indent_guides) = &language.indent_guides {
3908                            &indent_guides.coloring
3909                        } else {
3910                            &None
3911                        }
3912                    })
3913                },
3914                pick_mut: |settings_content| {
3915                    language_settings_field_mut(settings_content, |language| {
3916                        &mut language.indent_guides.get_or_insert_default().coloring
3917                    })
3918                },
3919            }),
3920            metadata: None,
3921        }),
3922        SettingsPageItem::SettingItem(SettingItem {
3923            title: "Background Coloring",
3924            description: "Determines how indent guide backgrounds are colored",
3925            field: Box::new(SettingField {
3926                pick: |settings_content| {
3927                    language_settings_field(settings_content, |language| {
3928                        if let Some(indent_guides) = &language.indent_guides {
3929                            &indent_guides.background_coloring
3930                        } else {
3931                            &None
3932                        }
3933                    })
3934                },
3935                pick_mut: |settings_content| {
3936                    language_settings_field_mut(settings_content, |language| {
3937                        &mut language
3938                            .indent_guides
3939                            .get_or_insert_default()
3940                            .background_coloring
3941                    })
3942                },
3943            }),
3944            metadata: None,
3945        }),
3946        SettingsPageItem::SectionHeader("Formatting"),
3947        SettingsPageItem::SettingItem(SettingItem {
3948            title: "Format On Save",
3949            description: "Whether or not to perform a buffer format before saving",
3950            field: Box::new(
3951                // TODO(settings_ui): this setting should just be a bool
3952                SettingField {
3953                    pick: |settings_content| {
3954                        language_settings_field(settings_content, |language| {
3955                            &language.format_on_save
3956                        })
3957                    },
3958                    pick_mut: |settings_content| {
3959                        language_settings_field_mut(settings_content, |language| {
3960                            &mut language.format_on_save
3961                        })
3962                    },
3963                },
3964            ),
3965            metadata: None,
3966        }),
3967        SettingsPageItem::SettingItem(SettingItem {
3968            title: "Remove Trailing Whitespace On Save",
3969            description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
3970            field: Box::new(SettingField {
3971                pick: |settings_content| {
3972                    language_settings_field(settings_content, |language| {
3973                        &language.remove_trailing_whitespace_on_save
3974                    })
3975                },
3976                pick_mut: |settings_content| {
3977                    language_settings_field_mut(settings_content, |language| {
3978                        &mut language.remove_trailing_whitespace_on_save
3979                    })
3980                },
3981            }),
3982            metadata: None,
3983        }),
3984        SettingsPageItem::SettingItem(SettingItem {
3985            title: "Ensure Final Newline On Save",
3986            description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
3987            field: Box::new(SettingField {
3988                pick: |settings_content| {
3989                    language_settings_field(settings_content, |language| {
3990                        &language.ensure_final_newline_on_save
3991                    })
3992                },
3993                pick_mut: |settings_content| {
3994                    language_settings_field_mut(settings_content, |language| {
3995                        &mut language.ensure_final_newline_on_save
3996                    })
3997                },
3998            }),
3999            metadata: None,
4000        }),
4001        SettingsPageItem::SettingItem(SettingItem {
4002            title: "Formatter",
4003            description: "How to perform a buffer format",
4004            field: Box::new(
4005                SettingField {
4006                    pick: |settings_content| {
4007                        language_settings_field(settings_content, |language| &language.formatter)
4008                    },
4009                    pick_mut: |settings_content| {
4010                        language_settings_field_mut(settings_content, |language| {
4011                            &mut language.formatter
4012                        })
4013                    },
4014                }
4015                .unimplemented(),
4016            ),
4017            metadata: None,
4018        }),
4019        SettingsPageItem::SettingItem(SettingItem {
4020            title: "Use On Type Format",
4021            description: "Whether to use additional LSP queries to format (and amend) the code after every \"trigger\" symbol input, defined by LSP server capabilities",
4022            field: Box::new(SettingField {
4023                pick: |settings_content| {
4024                    language_settings_field(settings_content, |language| {
4025                        &language.use_on_type_format
4026                    })
4027                },
4028                pick_mut: |settings_content| {
4029                    language_settings_field_mut(settings_content, |language| {
4030                        &mut language.use_on_type_format
4031                    })
4032                },
4033            }),
4034            metadata: None,
4035        }),
4036        SettingsPageItem::SettingItem(SettingItem {
4037            title: "Code Actions On Format",
4038            description: "Which code actions to run on save after the formatter. These are not run if formatting is off",
4039            field: Box::new(
4040                SettingField {
4041                    pick: |settings_content| {
4042                        language_settings_field(settings_content, |language| {
4043                            &language.code_actions_on_format
4044                        })
4045                    },
4046                    pick_mut: |settings_content| {
4047                        language_settings_field_mut(settings_content, |language| {
4048                            &mut language.code_actions_on_format
4049                        })
4050                    },
4051                }
4052                .unimplemented(),
4053            ),
4054            metadata: None,
4055        }),
4056        SettingsPageItem::SectionHeader("Prettier"),
4057        SettingsPageItem::SettingItem(SettingItem {
4058            title: "Allowed",
4059            description: "Enables or disables formatting with Prettier for a given language",
4060            field: Box::new(SettingField {
4061                pick: |settings_content| {
4062                    language_settings_field(settings_content, |language| {
4063                        if let Some(prettier) = &language.prettier {
4064                            &prettier.allowed
4065                        } else {
4066                            &None
4067                        }
4068                    })
4069                },
4070                pick_mut: |settings_content| {
4071                    language_settings_field_mut(settings_content, |language| {
4072                        &mut language.prettier.get_or_insert_default().allowed
4073                    })
4074                },
4075            }),
4076            metadata: None,
4077        }),
4078        SettingsPageItem::SettingItem(SettingItem {
4079            title: "Parser",
4080            description: "Forces Prettier integration to use a specific parser name when formatting files with the language",
4081            field: Box::new(SettingField {
4082                pick: |settings_content| {
4083                    language_settings_field(settings_content, |language| {
4084                        if let Some(prettier) = &language.prettier {
4085                            &prettier.parser
4086                        } else {
4087                            &None
4088                        }
4089                    })
4090                },
4091                pick_mut: |settings_content| {
4092                    language_settings_field_mut(settings_content, |language| {
4093                        &mut language.prettier.get_or_insert_default().parser
4094                    })
4095                },
4096            }),
4097            metadata: None,
4098        }),
4099        SettingsPageItem::SettingItem(SettingItem {
4100            title: "Plugins",
4101            description: "Forces Prettier integration to use specific plugins when formatting files with the language",
4102            field: Box::new(
4103                SettingField {
4104                    pick: |settings_content| {
4105                        language_settings_field(settings_content, |language| {
4106                            if let Some(prettier) = &language.prettier {
4107                                &prettier.plugins
4108                            } else {
4109                                &None
4110                            }
4111                        })
4112                    },
4113                    pick_mut: |settings_content| {
4114                        language_settings_field_mut(settings_content, |language| {
4115                            &mut language.prettier.get_or_insert_default().plugins
4116                        })
4117                    },
4118                }
4119                .unimplemented(),
4120            ),
4121            metadata: None,
4122        }),
4123        SettingsPageItem::SettingItem(SettingItem {
4124            title: "Options",
4125            description: "Default Prettier options, in the format as in package.json section for Prettier",
4126            field: Box::new(
4127                SettingField {
4128                    pick: |settings_content| {
4129                        language_settings_field(settings_content, |language| {
4130                            if let Some(prettier) = &language.prettier {
4131                                &prettier.options
4132                            } else {
4133                                &None
4134                            }
4135                        })
4136                    },
4137                    pick_mut: |settings_content| {
4138                        language_settings_field_mut(settings_content, |language| {
4139                            &mut language.prettier.get_or_insert_default().options
4140                        })
4141                    },
4142                }
4143                .unimplemented(),
4144            ),
4145            metadata: None,
4146        }),
4147        SettingsPageItem::SectionHeader("Autoclose"),
4148        SettingsPageItem::SettingItem(SettingItem {
4149            title: "Use Autoclose",
4150            description: "Whether to automatically type closing characters for you. For example, when you type (, Zed will automatically add a closing ) at the correct position",
4151            field: Box::new(SettingField {
4152                pick: |settings_content| {
4153                    language_settings_field(settings_content, |language| &language.use_autoclose)
4154                },
4155                pick_mut: |settings_content| {
4156                    language_settings_field_mut(settings_content, |language| {
4157                        &mut language.use_autoclose
4158                    })
4159                },
4160            }),
4161            metadata: None,
4162        }),
4163        SettingsPageItem::SettingItem(SettingItem {
4164            title: "Use Auto Surround",
4165            description: "Whether to automatically surround text with characters for you. For example, when you select text and type (, Zed will automatically surround text with ()",
4166            field: Box::new(SettingField {
4167                pick: |settings_content| {
4168                    language_settings_field(settings_content, |language| {
4169                        &language.use_auto_surround
4170                    })
4171                },
4172                pick_mut: |settings_content| {
4173                    language_settings_field_mut(settings_content, |language| {
4174                        &mut language.use_auto_surround
4175                    })
4176                },
4177            }),
4178            metadata: None,
4179        }),
4180        SettingsPageItem::SettingItem(SettingItem {
4181            title: "Always Treat Brackets As Autoclosed",
4182            description: "Controls how the editor handles the autoclosed characters. When set to `false`(default), skipping over and auto-removing of the closing characters happen only for auto-inserted characters. Otherwise(when `true`), the closing characters are always skipped over and auto-removed no matter how they were inserted",
4183            field: Box::new(SettingField {
4184                pick: |settings_content| {
4185                    language_settings_field(settings_content, |language| {
4186                        &language.always_treat_brackets_as_autoclosed
4187                    })
4188                },
4189                pick_mut: |settings_content| {
4190                    language_settings_field_mut(settings_content, |language| {
4191                        &mut language.always_treat_brackets_as_autoclosed
4192                    })
4193                },
4194            }),
4195            metadata: None,
4196        }),
4197        SettingsPageItem::SettingItem(SettingItem {
4198            title: "Jsx Tag Auto Close",
4199            description: "Whether to automatically close JSX tags",
4200            field: Box::new(SettingField {
4201                // TODO(settings_ui): this setting should just be a bool
4202                pick: |settings_content| {
4203                    language_settings_field(settings_content, |language| {
4204                        match language.jsx_tag_auto_close.as_ref() {
4205                            Some(s) => &s.enabled,
4206                            None => &None,
4207                        }
4208                    })
4209                },
4210                pick_mut: |settings_content| {
4211                    language_settings_field_mut(settings_content, |language| {
4212                        &mut language.jsx_tag_auto_close.get_or_insert_default().enabled
4213                    })
4214                },
4215            }),
4216            metadata: None,
4217        }),
4218        SettingsPageItem::SectionHeader("LSP"),
4219        SettingsPageItem::SettingItem(SettingItem {
4220            title: "Enable Language Server",
4221            description: "Whether to use language servers to provide code intelligence",
4222            field: Box::new(SettingField {
4223                pick: |settings_content| {
4224                    language_settings_field(settings_content, |language| {
4225                        &language.enable_language_server
4226                    })
4227                },
4228                pick_mut: |settings_content| {
4229                    language_settings_field_mut(settings_content, |language| {
4230                        &mut language.enable_language_server
4231                    })
4232                },
4233            }),
4234            metadata: None,
4235        }),
4236        SettingsPageItem::SettingItem(SettingItem {
4237            title: "Language Servers",
4238            description: "The list of language servers to use (or disable) for this language",
4239            field: Box::new(
4240                SettingField {
4241                    pick: |settings_content| {
4242                        language_settings_field(settings_content, |language| {
4243                            &language.language_servers
4244                        })
4245                    },
4246                    pick_mut: |settings_content| {
4247                        language_settings_field_mut(settings_content, |language| {
4248                            &mut language.language_servers
4249                        })
4250                    },
4251                }
4252                .unimplemented(),
4253            ),
4254            metadata: None,
4255        }),
4256        SettingsPageItem::SettingItem(SettingItem {
4257            title: "Linked Edits",
4258            description: "Whether to perform linked edits of associated ranges, if the language server supports it. For example, when editing opening <html> tag, the contents of the closing </html> tag will be edited as well",
4259            field: Box::new(SettingField {
4260                pick: |settings_content| {
4261                    language_settings_field(settings_content, |language| &language.linked_edits)
4262                },
4263                pick_mut: |settings_content| {
4264                    language_settings_field_mut(settings_content, |language| {
4265                        &mut language.linked_edits
4266                    })
4267                },
4268            }),
4269            metadata: None,
4270        }),
4271        SettingsPageItem::SectionHeader("Edit Predictions"),
4272        SettingsPageItem::SettingItem(SettingItem {
4273            title: "Show Edit Predictions",
4274            description: "Controls whether edit predictions are shown immediately (true) or manually by triggering `editor::ShowEditPrediction` (false)",
4275            field: Box::new(SettingField {
4276                pick: |settings_content| {
4277                    language_settings_field(settings_content, |language| {
4278                        &language.show_edit_predictions
4279                    })
4280                },
4281                pick_mut: |settings_content| {
4282                    language_settings_field_mut(settings_content, |language| {
4283                        &mut language.show_edit_predictions
4284                    })
4285                },
4286            }),
4287            metadata: None,
4288        }),
4289        SettingsPageItem::SettingItem(SettingItem {
4290            title: "Edit Predictions Disabled In",
4291            description: "Controls whether edit predictions are shown in the given language scopes",
4292            field: Box::new(
4293                SettingField {
4294                    pick: |settings_content| {
4295                        language_settings_field(settings_content, |language| {
4296                            &language.edit_predictions_disabled_in
4297                        })
4298                    },
4299                    pick_mut: |settings_content| {
4300                        language_settings_field_mut(settings_content, |language| {
4301                            &mut language.edit_predictions_disabled_in
4302                        })
4303                    },
4304                }
4305                .unimplemented(),
4306            ),
4307            metadata: None,
4308        }),
4309        SettingsPageItem::SectionHeader("Whitespace"),
4310        SettingsPageItem::SettingItem(SettingItem {
4311            title: "Show Whitespaces",
4312            description: "Whether to show tabs and spaces in the editor",
4313            field: Box::new(SettingField {
4314                pick: |settings_content| {
4315                    language_settings_field(settings_content, |language| &language.show_whitespaces)
4316                },
4317                pick_mut: |settings_content| {
4318                    language_settings_field_mut(settings_content, |language| {
4319                        &mut language.show_whitespaces
4320                    })
4321                },
4322            }),
4323            metadata: None,
4324        }),
4325        SettingsPageItem::SettingItem(SettingItem {
4326            title: "Space Whitespace Indicator",
4327            description: "Visible character used to render space characters when show_whitespaces is enabled (default: \"\")",
4328            field: Box::new(
4329                SettingField {
4330                    pick: |settings_content| {
4331                        language_settings_field(settings_content, |language| {
4332                            if let Some(whitespace_map) = &language.whitespace_map {
4333                                &whitespace_map.space
4334                            } else {
4335                                &None
4336                            }
4337                        })
4338                    },
4339                    pick_mut: |settings_content| {
4340                        language_settings_field_mut(settings_content, |language| {
4341                            &mut language.whitespace_map.get_or_insert_default().space
4342                        })
4343                    },
4344                }
4345                .unimplemented(),
4346            ),
4347            metadata: None,
4348        }),
4349        SettingsPageItem::SettingItem(SettingItem {
4350            title: "Tab Whitespace Indicator",
4351            description: "Visible character used to render tab characters when show_whitespaces is enabled (default: \"\")",
4352            field: Box::new(
4353                SettingField {
4354                    pick: |settings_content| {
4355                        language_settings_field(settings_content, |language| {
4356                            if let Some(whitespace_map) = &language.whitespace_map {
4357                                &whitespace_map.tab
4358                            } else {
4359                                &None
4360                            }
4361                        })
4362                    },
4363                    pick_mut: |settings_content| {
4364                        language_settings_field_mut(settings_content, |language| {
4365                            &mut language.whitespace_map.get_or_insert_default().tab
4366                        })
4367                    },
4368                }
4369                .unimplemented(),
4370            ),
4371            metadata: None,
4372        }),
4373        SettingsPageItem::SectionHeader("Completions"),
4374        SettingsPageItem::SettingItem(SettingItem {
4375            title: "Show Completions On Input",
4376            description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
4377            field: Box::new(SettingField {
4378                pick: |settings_content| {
4379                    language_settings_field(settings_content, |language| {
4380                        &language.show_completions_on_input
4381                    })
4382                },
4383                pick_mut: |settings_content| {
4384                    language_settings_field_mut(settings_content, |language| {
4385                        &mut language.show_completions_on_input
4386                    })
4387                },
4388            }),
4389            metadata: None,
4390        }),
4391        SettingsPageItem::SettingItem(SettingItem {
4392            title: "Show Completion Documentation",
4393            description: "Whether to display inline and alongside documentation for items in the completions menu",
4394            field: Box::new(SettingField {
4395                pick: |settings_content| {
4396                    language_settings_field(settings_content, |language| {
4397                        &language.show_completion_documentation
4398                    })
4399                },
4400                pick_mut: |settings_content| {
4401                    language_settings_field_mut(settings_content, |language| {
4402                        &mut language.show_completion_documentation
4403                    })
4404                },
4405            }),
4406            metadata: None,
4407        }),
4408        SettingsPageItem::SettingItem(SettingItem {
4409            title: "Words",
4410            description: "Controls how words are completed",
4411            field: Box::new(SettingField {
4412                pick: |settings_content| {
4413                    language_settings_field(settings_content, |language| {
4414                        if let Some(completions) = &language.completions {
4415                            &completions.words
4416                        } else {
4417                            &None
4418                        }
4419                    })
4420                },
4421                pick_mut: |settings_content| {
4422                    language_settings_field_mut(settings_content, |language| {
4423                        &mut language.completions.get_or_insert_default().words
4424                    })
4425                },
4426            }),
4427            metadata: None,
4428        }),
4429        SettingsPageItem::SettingItem(SettingItem {
4430            title: "Words Min Length",
4431            description: "How many characters has to be in the completions query to automatically show the words-based completions",
4432            field: Box::new(SettingField {
4433                pick: |settings_content| {
4434                    language_settings_field(settings_content, |language| {
4435                        if let Some(completions) = &language.completions {
4436                            &completions.words_min_length
4437                        } else {
4438                            &None
4439                        }
4440                    })
4441                },
4442                pick_mut: |settings_content| {
4443                    language_settings_field_mut(settings_content, |language| {
4444                        &mut language
4445                            .completions
4446                            .get_or_insert_default()
4447                            .words_min_length
4448                    })
4449                },
4450            }),
4451            metadata: None,
4452        }),
4453        SettingsPageItem::SettingItem(SettingItem {
4454            title: "Lsp",
4455            description: "Whether to fetch LSP completions or not",
4456            field: Box::new(SettingField {
4457                pick: |settings_content| {
4458                    language_settings_field(settings_content, |language| {
4459                        if let Some(completions) = &language.completions {
4460                            &completions.lsp
4461                        } else {
4462                            &None
4463                        }
4464                    })
4465                },
4466                pick_mut: |settings_content| {
4467                    language_settings_field_mut(settings_content, |language| {
4468                        &mut language.completions.get_or_insert_default().lsp
4469                    })
4470                },
4471            }),
4472            metadata: None,
4473        }),
4474        SettingsPageItem::SettingItem(SettingItem {
4475            title: "Lsp Fetch Timeout Ms",
4476            description: "When fetching LSP completions, determines how long to wait for a response of a particular server (set to 0 to wait indefinitely)",
4477            field: Box::new(SettingField {
4478                pick: |settings_content| {
4479                    language_settings_field(settings_content, |language| {
4480                        if let Some(completions) = &language.completions {
4481                            &completions.lsp_fetch_timeout_ms
4482                        } else {
4483                            &None
4484                        }
4485                    })
4486                },
4487                pick_mut: |settings_content| {
4488                    language_settings_field_mut(settings_content, |language| {
4489                        &mut language
4490                            .completions
4491                            .get_or_insert_default()
4492                            .lsp_fetch_timeout_ms
4493                    })
4494                },
4495            }),
4496            metadata: None,
4497        }),
4498        SettingsPageItem::SettingItem(SettingItem {
4499            title: "Lsp Insert Mode",
4500            description: "Controls how LSP completions are inserted",
4501            field: Box::new(SettingField {
4502                pick: |settings_content| {
4503                    language_settings_field(settings_content, |language| {
4504                        if let Some(completions) = &language.completions {
4505                            &completions.lsp_insert_mode
4506                        } else {
4507                            &None
4508                        }
4509                    })
4510                },
4511                pick_mut: |settings_content| {
4512                    language_settings_field_mut(settings_content, |language| {
4513                        &mut language.completions.get_or_insert_default().lsp_insert_mode
4514                    })
4515                },
4516            }),
4517            metadata: None,
4518        }),
4519        SettingsPageItem::SectionHeader("Inlay Hints"),
4520        SettingsPageItem::SettingItem(SettingItem {
4521            title: "Enabled",
4522            description: "Global switch to toggle hints on and off",
4523            field: Box::new(SettingField {
4524                pick: |settings_content| {
4525                    language_settings_field(settings_content, |language| {
4526                        if let Some(inlay_hints) = &language.inlay_hints {
4527                            &inlay_hints.enabled
4528                        } else {
4529                            &None
4530                        }
4531                    })
4532                },
4533                pick_mut: |settings_content| {
4534                    language_settings_field_mut(settings_content, |language| {
4535                        &mut language.inlay_hints.get_or_insert_default().enabled
4536                    })
4537                },
4538            }),
4539            metadata: None,
4540        }),
4541        SettingsPageItem::SettingItem(SettingItem {
4542            title: "Show Value Hints",
4543            description: "Global switch to toggle inline values on and off when debugging",
4544            field: Box::new(SettingField {
4545                pick: |settings_content| {
4546                    language_settings_field(settings_content, |language| {
4547                        if let Some(inlay_hints) = &language.inlay_hints {
4548                            &inlay_hints.show_value_hints
4549                        } else {
4550                            &None
4551                        }
4552                    })
4553                },
4554                pick_mut: |settings_content| {
4555                    language_settings_field_mut(settings_content, |language| {
4556                        &mut language
4557                            .inlay_hints
4558                            .get_or_insert_default()
4559                            .show_value_hints
4560                    })
4561                },
4562            }),
4563            metadata: None,
4564        }),
4565        SettingsPageItem::SettingItem(SettingItem {
4566            title: "Show Type Hints",
4567            description: "Whether type hints should be shown",
4568            field: Box::new(SettingField {
4569                pick: |settings_content| {
4570                    language_settings_field(settings_content, |language| {
4571                        if let Some(inlay_hints) = &language.inlay_hints {
4572                            &inlay_hints.show_type_hints
4573                        } else {
4574                            &None
4575                        }
4576                    })
4577                },
4578                pick_mut: |settings_content| {
4579                    language_settings_field_mut(settings_content, |language| {
4580                        &mut language.inlay_hints.get_or_insert_default().show_type_hints
4581                    })
4582                },
4583            }),
4584            metadata: None,
4585        }),
4586        SettingsPageItem::SettingItem(SettingItem {
4587            title: "Show Parameter Hints",
4588            description: "Whether parameter hints should be shown",
4589            field: Box::new(SettingField {
4590                pick: |settings_content| {
4591                    language_settings_field(settings_content, |language| {
4592                        if let Some(inlay_hints) = &language.inlay_hints {
4593                            &inlay_hints.show_parameter_hints
4594                        } else {
4595                            &None
4596                        }
4597                    })
4598                },
4599                pick_mut: |settings_content| {
4600                    language_settings_field_mut(settings_content, |language| {
4601                        &mut language
4602                            .inlay_hints
4603                            .get_or_insert_default()
4604                            .show_parameter_hints
4605                    })
4606                },
4607            }),
4608            metadata: None,
4609        }),
4610        SettingsPageItem::SettingItem(SettingItem {
4611            title: "Show Other Hints",
4612            description: "Whether other hints should be shown",
4613            field: Box::new(SettingField {
4614                pick: |settings_content| {
4615                    language_settings_field(settings_content, |language| {
4616                        if let Some(inlay_hints) = &language.inlay_hints {
4617                            &inlay_hints.show_other_hints
4618                        } else {
4619                            &None
4620                        }
4621                    })
4622                },
4623                pick_mut: |settings_content| {
4624                    language_settings_field_mut(settings_content, |language| {
4625                        &mut language
4626                            .inlay_hints
4627                            .get_or_insert_default()
4628                            .show_other_hints
4629                    })
4630                },
4631            }),
4632            metadata: None,
4633        }),
4634        SettingsPageItem::SettingItem(SettingItem {
4635            title: "Show Background",
4636            description: "Whether to show a background for inlay hints",
4637            field: Box::new(SettingField {
4638                pick: |settings_content| {
4639                    language_settings_field(settings_content, |language| {
4640                        if let Some(inlay_hints) = &language.inlay_hints {
4641                            &inlay_hints.show_background
4642                        } else {
4643                            &None
4644                        }
4645                    })
4646                },
4647                pick_mut: |settings_content| {
4648                    language_settings_field_mut(settings_content, |language| {
4649                        &mut language.inlay_hints.get_or_insert_default().show_background
4650                    })
4651                },
4652            }),
4653            metadata: None,
4654        }),
4655        SettingsPageItem::SettingItem(SettingItem {
4656            title: "Edit Debounce Ms",
4657            description: "Whether or not to debounce inlay hints updates after buffer edits (set to 0 to disable debouncing)",
4658            field: Box::new(SettingField {
4659                pick: |settings_content| {
4660                    language_settings_field(settings_content, |language| {
4661                        if let Some(inlay_hints) = &language.inlay_hints {
4662                            &inlay_hints.edit_debounce_ms
4663                        } else {
4664                            &None
4665                        }
4666                    })
4667                },
4668                pick_mut: |settings_content| {
4669                    language_settings_field_mut(settings_content, |language| {
4670                        &mut language
4671                            .inlay_hints
4672                            .get_or_insert_default()
4673                            .edit_debounce_ms
4674                    })
4675                },
4676            }),
4677            metadata: None,
4678        }),
4679        SettingsPageItem::SettingItem(SettingItem {
4680            title: "Scroll Debounce Ms",
4681            description: "Whether or not to debounce inlay hints updates after buffer scrolls (set to 0 to disable debouncing)",
4682            field: Box::new(SettingField {
4683                pick: |settings_content| {
4684                    language_settings_field(settings_content, |language| {
4685                        if let Some(inlay_hints) = &language.inlay_hints {
4686                            &inlay_hints.scroll_debounce_ms
4687                        } else {
4688                            &None
4689                        }
4690                    })
4691                },
4692                pick_mut: |settings_content| {
4693                    language_settings_field_mut(settings_content, |language| {
4694                        &mut language
4695                            .inlay_hints
4696                            .get_or_insert_default()
4697                            .scroll_debounce_ms
4698                    })
4699                },
4700            }),
4701            metadata: None,
4702        }),
4703        SettingsPageItem::SettingItem(SettingItem {
4704            title: "Toggle On Modifiers Press",
4705            description: "Toggles inlay hints (hides or shows) when the user presses the modifiers specified",
4706            field: Box::new(
4707                SettingField {
4708                    pick: |settings_content| {
4709                        language_settings_field(settings_content, |language| {
4710                            if let Some(inlay_hints) = &language.inlay_hints {
4711                                &inlay_hints.toggle_on_modifiers_press
4712                            } else {
4713                                &None
4714                            }
4715                        })
4716                    },
4717                    pick_mut: |settings_content| {
4718                        language_settings_field_mut(settings_content, |language| {
4719                            &mut language
4720                                .inlay_hints
4721                                .get_or_insert_default()
4722                                .toggle_on_modifiers_press
4723                        })
4724                    },
4725                }
4726                .unimplemented(),
4727            ),
4728            metadata: None,
4729        }),
4730        SettingsPageItem::SectionHeader("Tasks"),
4731        SettingsPageItem::SettingItem(SettingItem {
4732            title: "Enabled",
4733            description: "Whether tasks are enabled for this language",
4734            field: Box::new(SettingField {
4735                pick: |settings_content| {
4736                    language_settings_field(settings_content, |language| {
4737                        if let Some(tasks) = &language.tasks {
4738                            &tasks.enabled
4739                        } else {
4740                            &None
4741                        }
4742                    })
4743                },
4744                pick_mut: |settings_content| {
4745                    language_settings_field_mut(settings_content, |language| {
4746                        &mut language.tasks.get_or_insert_default().enabled
4747                    })
4748                },
4749            }),
4750            metadata: None,
4751        }),
4752        SettingsPageItem::SettingItem(SettingItem {
4753            title: "Variables",
4754            description: "Extra task variables to set for a particular language",
4755            field: Box::new(
4756                SettingField {
4757                    pick: |settings_content| {
4758                        language_settings_field(settings_content, |language| {
4759                            if let Some(tasks) = &language.tasks {
4760                                &tasks.variables
4761                            } else {
4762                                &None
4763                            }
4764                        })
4765                    },
4766                    pick_mut: |settings_content| {
4767                        language_settings_field_mut(settings_content, |language| {
4768                            &mut language.tasks.get_or_insert_default().variables
4769                        })
4770                    },
4771                }
4772                .unimplemented(),
4773            ),
4774            metadata: None,
4775        }),
4776        SettingsPageItem::SettingItem(SettingItem {
4777            title: "Prefer Lsp",
4778            description: "Use LSP tasks over Zed language extension ones",
4779            field: Box::new(SettingField {
4780                pick: |settings_content| {
4781                    language_settings_field(settings_content, |language| {
4782                        if let Some(tasks) = &language.tasks {
4783                            &tasks.prefer_lsp
4784                        } else {
4785                            &None
4786                        }
4787                    })
4788                },
4789                pick_mut: |settings_content| {
4790                    language_settings_field_mut(settings_content, |language| {
4791                        &mut language.tasks.get_or_insert_default().prefer_lsp
4792                    })
4793                },
4794            }),
4795            metadata: None,
4796        }),
4797        SettingsPageItem::SectionHeader("Miscellaneous"),
4798        SettingsPageItem::SettingItem(SettingItem {
4799            title: "Debuggers",
4800            description: "Preferred debuggers for this language",
4801            field: Box::new(
4802                SettingField {
4803                    pick: |settings_content| {
4804                        language_settings_field(settings_content, |language| &language.debuggers)
4805                    },
4806                    pick_mut: |settings_content| {
4807                        language_settings_field_mut(settings_content, |language| {
4808                            &mut language.debuggers
4809                        })
4810                    },
4811                }
4812                .unimplemented(),
4813            ),
4814            metadata: None,
4815        }),
4816        SettingsPageItem::SettingItem(SettingItem {
4817            title: "Extend Comment On Newline",
4818            description: "Whether to start a new line with a comment when a previous line is a comment as well",
4819            field: Box::new(SettingField {
4820                pick: |settings_content| {
4821                    language_settings_field(settings_content, |language| {
4822                        &language.extend_comment_on_newline
4823                    })
4824                },
4825                pick_mut: |settings_content| {
4826                    language_settings_field_mut(settings_content, |language| {
4827                        &mut language.extend_comment_on_newline
4828                    })
4829                },
4830            }),
4831            metadata: None,
4832        }),
4833    ]
4834}