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