1use gpui::App;
   2use settings::{LanguageSettingsContent, SettingsContent};
   3use std::sync::Arc;
   4use ui::{IntoElement, SharedString};
   5
   6use crate::{
   7    LOCAL, SettingField, SettingItem, SettingsFieldMetadata, SettingsPage, SettingsPageItem,
   8    SubPageLink, USER, all_language_names, sub_page_stack,
   9};
  10
  11pub(crate) fn settings_data(cx: &App) -> Vec<SettingsPage> {
  12    vec![
  13        SettingsPage {
  14            title: "General",
  15            items: vec![
  16                SettingsPageItem::SectionHeader("General Settings"),
  17                SettingsPageItem::SettingItem(SettingItem {
  18                    title: "Confirm Quit",
  19                    description: "Confirm before quitting Zed",
  20                    field: Box::new(SettingField {
  21                        pick: |settings_content| &settings_content.workspace.confirm_quit,
  22                        pick_mut: |settings_content| &mut settings_content.workspace.confirm_quit,
  23                    }),
  24                    metadata: None,
  25                    files: USER,
  26                }),
  27                SettingsPageItem::SettingItem(SettingItem {
  28                    title: "When Closing With No Tabs",
  29                    description: "What to do when using the 'close active item' action with no tabs",
  30                    field: Box::new(SettingField {
  31                        pick: |settings_content| {
  32                            &settings_content.workspace.when_closing_with_no_tabs
  33                        },
  34                        pick_mut: |settings_content| {
  35                            &mut settings_content.workspace.when_closing_with_no_tabs
  36                        },
  37                    }),
  38                    metadata: None,
  39                    files: USER,
  40                }),
  41                SettingsPageItem::SettingItem(SettingItem {
  42                    title: "On Last Window Closed",
  43                    description: "What to do when the last window is closed",
  44                    field: Box::new(SettingField {
  45                        pick: |settings_content| &settings_content.workspace.on_last_window_closed,
  46                        pick_mut: |settings_content| {
  47                            &mut settings_content.workspace.on_last_window_closed
  48                        },
  49                    }),
  50                    metadata: None,
  51                    files: USER,
  52                }),
  53                SettingsPageItem::SettingItem(SettingItem {
  54                    title: "Use System Path Prompts",
  55                    description: "Use native OS dialogs for 'Open' and 'Save As'",
  56                    field: Box::new(SettingField {
  57                        pick: |settings_content| {
  58                            &settings_content.workspace.use_system_path_prompts
  59                        },
  60                        pick_mut: |settings_content| {
  61                            &mut settings_content.workspace.use_system_path_prompts
  62                        },
  63                    }),
  64                    metadata: None,
  65                    files: USER,
  66                }),
  67                SettingsPageItem::SettingItem(SettingItem {
  68                    title: "Use System Prompts",
  69                    description: "Use native OS dialogs for confirmations",
  70                    field: Box::new(SettingField {
  71                        pick: |settings_content| &settings_content.workspace.use_system_prompts,
  72                        pick_mut: |settings_content| {
  73                            &mut settings_content.workspace.use_system_prompts
  74                        },
  75                    }),
  76                    metadata: None,
  77                    files: USER,
  78                }),
  79                SettingsPageItem::SettingItem(SettingItem {
  80                    title: "Redact Private Values",
  81                    description: "Hide the values of variables in private files",
  82                    field: Box::new(SettingField {
  83                        pick: |settings_content| &settings_content.editor.redact_private_values,
  84                        pick_mut: |settings_content| {
  85                            &mut settings_content.editor.redact_private_values
  86                        },
  87                    }),
  88                    metadata: None,
  89                    files: USER,
  90                }),
  91                SettingsPageItem::SettingItem(SettingItem {
  92                    title: "Private Files",
  93                    description: "Globs to match against file paths to determine if a file is private",
  94                    field: Box::new(
  95                        SettingField {
  96                            pick: |settings_content| {
  97                                &settings_content.project.worktree.private_files
  98                            },
  99                            pick_mut: |settings_content| {
 100                                &mut settings_content.project.worktree.private_files
 101                            },
 102                        }
 103                        .unimplemented(),
 104                    ),
 105                    metadata: None,
 106                    files: USER,
 107                }),
 108                SettingsPageItem::SectionHeader("Workspace Restoration"),
 109                SettingsPageItem::SettingItem(SettingItem {
 110                    title: "Restore Unsaved Buffers",
 111                    description: "Whether or not to restore unsaved buffers on restart",
 112                    field: Box::new(SettingField {
 113                        pick: |settings_content| match settings_content.session.as_ref() {
 114                            Some(session) => &session.restore_unsaved_buffers,
 115                            None => &None,
 116                        },
 117                        pick_mut: |settings_content| {
 118                            &mut settings_content
 119                                .session
 120                                .get_or_insert_default()
 121                                .restore_unsaved_buffers
 122                        },
 123                    }),
 124                    metadata: None,
 125                    files: USER,
 126                }),
 127                SettingsPageItem::SettingItem(SettingItem {
 128                    title: "Restore On Startup",
 129                    description: "What to restore from the previous session when opening Zed",
 130                    field: Box::new(SettingField {
 131                        pick: |settings_content| &settings_content.workspace.restore_on_startup,
 132                        pick_mut: |settings_content| {
 133                            &mut settings_content.workspace.restore_on_startup
 134                        },
 135                    }),
 136                    metadata: None,
 137                    files: USER,
 138                }),
 139                SettingsPageItem::SectionHeader("Scoped Settings"),
 140                SettingsPageItem::SettingItem(SettingItem {
 141                    // todo(settings_ui): Implement another setting item type that just shows an edit in settings.json
 142                    files: USER,
 143                    title: "Preview Channel",
 144                    description: "Which settings should be activated only in Preview build of Zed",
 145                    field: Box::new(
 146                        SettingField {
 147                            pick: |settings_content| &settings_content.workspace.use_system_prompts,
 148                            pick_mut: |settings_content| {
 149                                &mut settings_content.workspace.use_system_prompts
 150                            },
 151                        }
 152                        .unimplemented(),
 153                    ),
 154                    metadata: None,
 155                }),
 156                SettingsPageItem::SettingItem(SettingItem {
 157                    files: USER,
 158                    title: "Settings Profiles",
 159                    description: "Any number of settings profiles that are temporarily applied on top of your existing user settings",
 160                    field: Box::new(
 161                        SettingField {
 162                            pick: |settings_content| &settings_content.workspace.use_system_prompts,
 163                            pick_mut: |settings_content| {
 164                                &mut settings_content.workspace.use_system_prompts
 165                            },
 166                        }
 167                        .unimplemented(),
 168                    ),
 169                    metadata: None,
 170                }),
 171                SettingsPageItem::SectionHeader("Privacy"),
 172                SettingsPageItem::SettingItem(SettingItem {
 173                    title: "Telemetry Diagnostics",
 174                    description: "Send debug information like crash reports",
 175                    field: Box::new(SettingField {
 176                        pick: |settings_content| {
 177                            if let Some(telemetry) = &settings_content.telemetry {
 178                                &telemetry.diagnostics
 179                            } else {
 180                                &None
 181                            }
 182                        },
 183                        pick_mut: |settings_content| {
 184                            &mut settings_content
 185                                .telemetry
 186                                .get_or_insert_default()
 187                                .diagnostics
 188                        },
 189                    }),
 190                    metadata: None,
 191                    files: USER,
 192                }),
 193                SettingsPageItem::SettingItem(SettingItem {
 194                    title: "Telemetry Metrics",
 195                    description: "Send anonymized usage data like what languages you're using Zed with",
 196                    field: Box::new(SettingField {
 197                        pick: |settings_content| {
 198                            if let Some(telemetry) = &settings_content.telemetry {
 199                                &telemetry.metrics
 200                            } else {
 201                                &None
 202                            }
 203                        },
 204                        pick_mut: |settings_content| {
 205                            &mut settings_content.telemetry.get_or_insert_default().metrics
 206                        },
 207                    }),
 208                    metadata: None,
 209                    files: USER,
 210                }),
 211                SettingsPageItem::SectionHeader("Auto Update"),
 212                SettingsPageItem::SettingItem(SettingItem {
 213                    title: "Auto Update",
 214                    description: "Whether or not to automatically check for updates",
 215                    field: Box::new(SettingField {
 216                        pick: |settings_content| &settings_content.auto_update,
 217                        pick_mut: |settings_content| &mut settings_content.auto_update,
 218                    }),
 219                    metadata: None,
 220                    files: USER,
 221                }),
 222            ],
 223        },
 224        SettingsPage {
 225            title: "Appearance",
 226            items: vec![
 227                SettingsPageItem::SectionHeader("Theme"),
 228                // todo(settings_ui): Figure out how we want to add these
 229                SettingsPageItem::SettingItem(SettingItem {
 230                    files: USER,
 231                    title: "Theme Mode",
 232                    description: "How to select the theme",
 233                    field: Box::new(
 234                        SettingField {
 235                            pick: |settings_content| &settings_content.theme.theme,
 236                            pick_mut: |settings_content| &mut settings_content.theme.theme,
 237                        }
 238                        .unimplemented(),
 239                    ),
 240                    metadata: None,
 241                }),
 242                SettingsPageItem::SettingItem(SettingItem {
 243                    files: USER,
 244                    title: "Icon Theme",
 245                    // todo(settings_ui)
 246                    // This description is misleading because the icon theme is used in more places than the file explorer)
 247                    description: "Choose the icon theme for file explorer",
 248                    field: Box::new(
 249                        SettingField {
 250                            pick: |settings_content| &settings_content.theme.icon_theme,
 251                            pick_mut: |settings_content| &mut settings_content.theme.icon_theme,
 252                        }
 253                        .unimplemented(),
 254                    ),
 255                    metadata: None,
 256                }),
 257                SettingsPageItem::SectionHeader("Fonts"),
 258                SettingsPageItem::SettingItem(SettingItem {
 259                    title: "Buffer Font Family",
 260                    description: "Font family for editor text",
 261                    field: Box::new(SettingField {
 262                        pick: |settings_content| &settings_content.theme.buffer_font_family,
 263                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_family,
 264                    }),
 265                    metadata: None,
 266                    files: USER,
 267                }),
 268                SettingsPageItem::SettingItem(SettingItem {
 269                    title: "Buffer Font Size",
 270                    description: "Font size for editor text",
 271                    field: Box::new(SettingField {
 272                        pick: |settings_content| &settings_content.theme.buffer_font_size,
 273                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_size,
 274                    }),
 275                    metadata: None,
 276                    files: USER,
 277                }),
 278                SettingsPageItem::SettingItem(SettingItem {
 279                    title: "Buffer Font Weight",
 280                    description: "Font weight for editor text (100-900)",
 281                    field: Box::new(SettingField {
 282                        pick: |settings_content| &settings_content.theme.buffer_font_weight,
 283                        pick_mut: |settings_content| &mut settings_content.theme.buffer_font_weight,
 284                    }),
 285                    metadata: None,
 286                    files: USER,
 287                }),
 288                // todo(settings_ui): This needs custom ui
 289                SettingsPageItem::SettingItem(SettingItem {
 290                    files: USER,
 291                    title: "Buffer Line Height",
 292                    description: "Line height for editor text",
 293                    field: Box::new(
 294                        SettingField {
 295                            pick: |settings_content| &settings_content.theme.buffer_line_height,
 296                            pick_mut: |settings_content| {
 297                                &mut settings_content.theme.buffer_line_height
 298                            },
 299                        }
 300                        .unimplemented(),
 301                    ),
 302                    metadata: None,
 303                }),
 304                SettingsPageItem::SettingItem(SettingItem {
 305                    files: USER,
 306                    title: "Buffer Font Features",
 307                    description: "The OpenType features to enable for rendering in text buffers.",
 308                    field: Box::new(
 309                        SettingField {
 310                            pick: |settings_content| &settings_content.theme.buffer_font_features,
 311                            pick_mut: |settings_content| {
 312                                &mut settings_content.theme.buffer_font_features
 313                            },
 314                        }
 315                        .unimplemented(),
 316                    ),
 317                    metadata: None,
 318                }),
 319                SettingsPageItem::SettingItem(SettingItem {
 320                    files: USER,
 321                    title: "Buffer Font Fallbacks",
 322                    description: "The font fallbacks to use for rendering in text buffers.",
 323                    field: Box::new(
 324                        SettingField {
 325                            pick: |settings_content| &settings_content.theme.buffer_font_fallbacks,
 326                            pick_mut: |settings_content| {
 327                                &mut settings_content.theme.buffer_font_fallbacks
 328                            },
 329                        }
 330                        .unimplemented(),
 331                    ),
 332                    metadata: None,
 333                }),
 334                SettingsPageItem::SettingItem(SettingItem {
 335                    title: "UI Font Family",
 336                    description: "Font family for UI elements",
 337                    field: Box::new(SettingField {
 338                        pick: |settings_content| &settings_content.theme.ui_font_family,
 339                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_family,
 340                    }),
 341                    metadata: None,
 342                    files: USER,
 343                }),
 344                SettingsPageItem::SettingItem(SettingItem {
 345                    title: "UI Font Size",
 346                    description: "Font size for UI elements",
 347                    field: Box::new(SettingField {
 348                        pick: |settings_content| &settings_content.theme.ui_font_size,
 349                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_size,
 350                    }),
 351                    metadata: None,
 352                    files: USER,
 353                }),
 354                SettingsPageItem::SettingItem(SettingItem {
 355                    title: "UI Font Weight",
 356                    description: "Font weight for UI elements (100-900)",
 357                    field: Box::new(SettingField {
 358                        pick: |settings_content| &settings_content.theme.ui_font_weight,
 359                        pick_mut: |settings_content| &mut settings_content.theme.ui_font_weight,
 360                    }),
 361                    metadata: None,
 362                    files: USER,
 363                }),
 364                SettingsPageItem::SettingItem(SettingItem {
 365                    files: USER,
 366                    title: "UI Font Features",
 367                    description: "The OpenType features to enable for rendering in UI elements.",
 368                    field: Box::new(
 369                        SettingField {
 370                            pick: |settings_content| &settings_content.theme.ui_font_features,
 371                            pick_mut: |settings_content| {
 372                                &mut settings_content.theme.ui_font_features
 373                            },
 374                        }
 375                        .unimplemented(),
 376                    ),
 377                    metadata: None,
 378                }),
 379                SettingsPageItem::SettingItem(SettingItem {
 380                    files: USER,
 381                    title: "UI Font Fallbacks",
 382                    description: "The font fallbacks to use for rendering in the UI.",
 383                    field: Box::new(
 384                        SettingField {
 385                            pick: |settings_content| &settings_content.theme.ui_font_fallbacks,
 386                            pick_mut: |settings_content| {
 387                                &mut settings_content.theme.ui_font_fallbacks
 388                            },
 389                        }
 390                        .unimplemented(),
 391                    ),
 392                    metadata: None,
 393                }),
 394                SettingsPageItem::SettingItem(SettingItem {
 395                    title: "Agent Panel UI Font Size",
 396                    description: "Font size for agent response text in the agent panel. Falls back to the regular UI font size.",
 397                    field: Box::new(SettingField {
 398                        pick: |settings_content| {
 399                            if settings_content.theme.agent_ui_font_size.is_some() {
 400                                &settings_content.theme.agent_ui_font_size
 401                            } else {
 402                                &settings_content.theme.ui_font_size
 403                            }
 404                        },
 405                        pick_mut: |settings_content| &mut settings_content.theme.agent_ui_font_size,
 406                    }),
 407                    metadata: None,
 408                    files: USER,
 409                }),
 410                SettingsPageItem::SettingItem(SettingItem {
 411                    title: "Agent Panel Buffer Font Size",
 412                    description: "Font size for user messages text in the agent panel",
 413                    field: Box::new(SettingField {
 414                        pick: |settings_content| &settings_content.theme.agent_buffer_font_size,
 415                        pick_mut: |settings_content| {
 416                            &mut settings_content.theme.agent_buffer_font_size
 417                        },
 418                    }),
 419                    metadata: None,
 420                    files: USER,
 421                }),
 422                SettingsPageItem::SettingItem(SettingItem {
 423                    title: "Multi Cursor Modifier",
 424                    description: "Modifier key for adding multiple cursors",
 425                    field: Box::new(SettingField {
 426                        pick: |settings_content| &settings_content.editor.multi_cursor_modifier,
 427                        pick_mut: |settings_content| {
 428                            &mut settings_content.editor.multi_cursor_modifier
 429                        },
 430                    }),
 431                    metadata: None,
 432                    files: USER,
 433                }),
 434                SettingsPageItem::SectionHeader("Cursor"),
 435                SettingsPageItem::SettingItem(SettingItem {
 436                    title: "Cursor Blink",
 437                    description: "Whether the cursor blinks in the editor",
 438                    field: Box::new(SettingField {
 439                        pick: |settings_content| &settings_content.editor.cursor_blink,
 440                        pick_mut: |settings_content| &mut settings_content.editor.cursor_blink,
 441                    }),
 442                    metadata: None,
 443                    files: USER,
 444                }),
 445                SettingsPageItem::SettingItem(SettingItem {
 446                    title: "Cursor Shape",
 447                    description: "Cursor shape for the editor",
 448                    field: Box::new(SettingField {
 449                        pick: |settings_content| &settings_content.editor.cursor_shape,
 450                        pick_mut: |settings_content| &mut settings_content.editor.cursor_shape,
 451                    }),
 452                    metadata: None,
 453                    files: USER,
 454                }),
 455                SettingsPageItem::SettingItem(SettingItem {
 456                    title: "Hide Mouse",
 457                    description: "When to hide the mouse cursor",
 458                    field: Box::new(SettingField {
 459                        pick: |settings_content| &settings_content.editor.hide_mouse,
 460                        pick_mut: |settings_content| &mut settings_content.editor.hide_mouse,
 461                    }),
 462                    metadata: None,
 463                    files: USER,
 464                }),
 465                SettingsPageItem::SectionHeader("Highlighting"),
 466                SettingsPageItem::SettingItem(SettingItem {
 467                    title: "Unnecessary Code Fade",
 468                    description: "How much to fade out unused code (0.0 - 0.9)",
 469                    field: Box::new(SettingField {
 470                        pick: |settings_content| &settings_content.theme.unnecessary_code_fade,
 471                        pick_mut: |settings_content| {
 472                            &mut settings_content.theme.unnecessary_code_fade
 473                        },
 474                    }),
 475                    metadata: None,
 476                    files: USER,
 477                }),
 478                SettingsPageItem::SettingItem(SettingItem {
 479                    title: "Current Line Highlight",
 480                    description: "How to highlight the current line",
 481                    field: Box::new(SettingField {
 482                        pick: |settings_content| &settings_content.editor.current_line_highlight,
 483                        pick_mut: |settings_content| {
 484                            &mut settings_content.editor.current_line_highlight
 485                        },
 486                    }),
 487                    metadata: None,
 488                    files: USER,
 489                }),
 490                SettingsPageItem::SettingItem(SettingItem {
 491                    title: "Selection Highlight",
 492                    description: "Highlight all occurrences of selected text",
 493                    field: Box::new(SettingField {
 494                        pick: |settings_content| &settings_content.editor.selection_highlight,
 495                        pick_mut: |settings_content| {
 496                            &mut settings_content.editor.selection_highlight
 497                        },
 498                    }),
 499                    metadata: None,
 500                    files: USER,
 501                }),
 502                SettingsPageItem::SettingItem(SettingItem {
 503                    title: "Rounded Selection",
 504                    description: "Whether the text selection should have rounded corners",
 505                    field: Box::new(SettingField {
 506                        pick: |settings_content| &settings_content.editor.rounded_selection,
 507                        pick_mut: |settings_content| &mut settings_content.editor.rounded_selection,
 508                    }),
 509                    metadata: None,
 510                    files: USER,
 511                }),
 512                SettingsPageItem::SettingItem(SettingItem {
 513                    title: "Minimum Contrast For Highlights",
 514                    description: "The minimum APCA perceptual contrast to maintain when rendering text over highlight backgrounds",
 515                    field: Box::new(SettingField {
 516                        pick: |settings_content| {
 517                            &settings_content.editor.minimum_contrast_for_highlights
 518                        },
 519                        pick_mut: |settings_content| {
 520                            &mut settings_content.editor.minimum_contrast_for_highlights
 521                        },
 522                    }),
 523                    metadata: None,
 524                    files: USER,
 525                }),
 526                SettingsPageItem::SectionHeader("Guides"),
 527                SettingsPageItem::SettingItem(SettingItem {
 528                    title: "Show Wrap Guides",
 529                    description: "Show wrap guides (vertical rulers)",
 530                    field: Box::new(SettingField {
 531                        pick: |settings_content| {
 532                            &settings_content
 533                                .project
 534                                .all_languages
 535                                .defaults
 536                                .show_wrap_guides
 537                        },
 538                        pick_mut: |settings_content| {
 539                            &mut settings_content
 540                                .project
 541                                .all_languages
 542                                .defaults
 543                                .show_wrap_guides
 544                        },
 545                    }),
 546                    metadata: None,
 547                    files: USER | LOCAL,
 548                }),
 549                // todo(settings_ui): This needs a custom component
 550                SettingsPageItem::SettingItem(SettingItem {
 551                    title: "Wrap Guides",
 552                    description: "Character counts at which to show wrap guides",
 553                    field: Box::new(
 554                        SettingField {
 555                            pick: |settings_content| {
 556                                &settings_content.project.all_languages.defaults.wrap_guides
 557                            },
 558                            pick_mut: |settings_content| {
 559                                &mut settings_content.project.all_languages.defaults.wrap_guides
 560                            },
 561                        }
 562                        .unimplemented(),
 563                    ),
 564                    metadata: None,
 565                    files: USER | LOCAL,
 566                }),
 567            ],
 568        },
 569        SettingsPage {
 570            title: "Keymap",
 571            items: vec![
 572                SettingsPageItem::SectionHeader("Base Keymap"),
 573                SettingsPageItem::SettingItem(SettingItem {
 574                    title: "Base Keymap",
 575                    description: "The name of a base set of key bindings to use",
 576                    field: Box::new(SettingField {
 577                        pick: |settings_content| &settings_content.base_keymap,
 578                        pick_mut: |settings_content| &mut settings_content.base_keymap,
 579                    }),
 580                    metadata: Some(Box::new(SettingsFieldMetadata {
 581                        should_do_titlecase: Some(false),
 582                        ..Default::default()
 583                    })),
 584                    files: USER,
 585                }),
 586                SettingsPageItem::SectionHeader("Modal Editing"),
 587                // todo(settings_ui): Vim/Helix Mode should be apart of one type because it's undefined
 588                // behavior to have them both enabled at the same time
 589                SettingsPageItem::SettingItem(SettingItem {
 590                    title: "Vim Mode",
 591                    description: "Enable vim modes and key bindings",
 592                    field: Box::new(SettingField {
 593                        pick: |settings_content| &settings_content.vim_mode,
 594                        pick_mut: |settings_content| &mut settings_content.vim_mode,
 595                    }),
 596                    metadata: None,
 597                    files: USER,
 598                }),
 599                SettingsPageItem::SettingItem(SettingItem {
 600                    title: "Helix Mode",
 601                    description: "Enable helix modes and key bindings",
 602                    field: Box::new(SettingField {
 603                        pick: |settings_content| &settings_content.helix_mode,
 604                        pick_mut: |settings_content| &mut settings_content.helix_mode,
 605                    }),
 606                    metadata: None,
 607                    files: USER,
 608                }),
 609            ],
 610        },
 611        SettingsPage {
 612            title: "Editor",
 613            items: {
 614                let mut items = vec![
 615                    SettingsPageItem::SectionHeader("Auto Save"),
 616                    SettingsPageItem::SettingItem(SettingItem {
 617                        title: "Auto Save Mode",
 618                        description: "When to Auto Save Buffer Changes",
 619                        field: Box::new(
 620                            SettingField {
 621                                pick: |settings_content| &settings_content.workspace.autosave,
 622                                pick_mut: |settings_content| {
 623                                    &mut settings_content.workspace.autosave
 624                                },
 625                            }
 626                            .unimplemented(),
 627                        ),
 628                        metadata: None,
 629                        files: USER,
 630                    }),
 631                    SettingsPageItem::SectionHeader("Multibuffer"),
 632                    SettingsPageItem::SettingItem(SettingItem {
 633                        title: "Double Click In Multibuffer",
 634                        description: "What to do when multibuffer is double-clicked in some of its excerpts",
 635                        field: Box::new(SettingField {
 636                            pick: |settings_content| {
 637                                &settings_content.editor.double_click_in_multibuffer
 638                            },
 639                            pick_mut: |settings_content| {
 640                                &mut settings_content.editor.double_click_in_multibuffer
 641                            },
 642                        }),
 643                        metadata: None,
 644                        files: USER,
 645                    }),
 646                    SettingsPageItem::SettingItem(SettingItem {
 647                        title: "Expand Excerpt Lines",
 648                        description: "How many lines to expand the multibuffer excerpts by default",
 649                        field: Box::new(SettingField {
 650                            pick: |settings_content| &settings_content.editor.expand_excerpt_lines,
 651                            pick_mut: |settings_content| {
 652                                &mut settings_content.editor.expand_excerpt_lines
 653                            },
 654                        }),
 655                        metadata: None,
 656                        files: USER,
 657                    }),
 658                    SettingsPageItem::SettingItem(SettingItem {
 659                        title: "Excerpt Context Lines",
 660                        description: "How many lines of context to provide in multibuffer excerpts by default",
 661                        field: Box::new(SettingField {
 662                            pick: |settings_content| &settings_content.editor.excerpt_context_lines,
 663                            pick_mut: |settings_content| {
 664                                &mut settings_content.editor.excerpt_context_lines
 665                            },
 666                        }),
 667                        metadata: None,
 668                        files: USER,
 669                    }),
 670                    SettingsPageItem::SettingItem(SettingItem {
 671                        title: "Expand Outlines With Depth",
 672                        description: "Default depth to expand outline items in the current file",
 673                        field: Box::new(SettingField {
 674                            pick: |settings_content| {
 675                                if let Some(outline_panel) = &settings_content.outline_panel {
 676                                    &outline_panel.expand_outlines_with_depth
 677                                } else {
 678                                    &None
 679                                }
 680                            },
 681                            pick_mut: |settings_content| {
 682                                &mut settings_content
 683                                    .outline_panel
 684                                    .get_or_insert_default()
 685                                    .expand_outlines_with_depth
 686                            },
 687                        }),
 688                        metadata: None,
 689                        files: USER,
 690                    }),
 691                    SettingsPageItem::SectionHeader("Scrolling"),
 692                    SettingsPageItem::SettingItem(SettingItem {
 693                        title: "Scroll Beyond Last Line",
 694                        description: "Whether the editor will scroll beyond the last line",
 695                        field: Box::new(SettingField {
 696                            pick: |settings_content| {
 697                                &settings_content.editor.scroll_beyond_last_line
 698                            },
 699                            pick_mut: |settings_content| {
 700                                &mut settings_content.editor.scroll_beyond_last_line
 701                            },
 702                        }),
 703                        metadata: None,
 704                        files: USER,
 705                    }),
 706                    SettingsPageItem::SettingItem(SettingItem {
 707                        title: "Vertical Scroll Margin",
 708                        description: "The number of lines to keep above/below the cursor when auto-scrolling",
 709                        field: Box::new(SettingField {
 710                            pick: |settings_content| {
 711                                &settings_content.editor.vertical_scroll_margin
 712                            },
 713                            pick_mut: |settings_content| {
 714                                &mut settings_content.editor.vertical_scroll_margin
 715                            },
 716                        }),
 717                        metadata: None,
 718                        files: USER,
 719                    }),
 720                    SettingsPageItem::SettingItem(SettingItem {
 721                        title: "Horizontal Scroll Margin",
 722                        description: "The number of characters to keep on either side when scrolling with the mouse",
 723                        field: Box::new(SettingField {
 724                            pick: |settings_content| {
 725                                &settings_content.editor.horizontal_scroll_margin
 726                            },
 727                            pick_mut: |settings_content| {
 728                                &mut settings_content.editor.horizontal_scroll_margin
 729                            },
 730                        }),
 731                        metadata: None,
 732                        files: USER,
 733                    }),
 734                    SettingsPageItem::SettingItem(SettingItem {
 735                        title: "Scroll Sensitivity",
 736                        description: "Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 737                        field: Box::new(SettingField {
 738                            pick: |settings_content| &settings_content.editor.scroll_sensitivity,
 739                            pick_mut: |settings_content| {
 740                                &mut settings_content.editor.scroll_sensitivity
 741                            },
 742                        }),
 743                        metadata: None,
 744                        files: USER,
 745                    }),
 746                    SettingsPageItem::SettingItem(SettingItem {
 747                        title: "Fast Scroll Sensitivity",
 748                        description: "Fast Scroll sensitivity multiplier for both horizontal and vertical scrolling",
 749                        field: Box::new(SettingField {
 750                            pick: |settings_content| {
 751                                &settings_content.editor.fast_scroll_sensitivity
 752                            },
 753                            pick_mut: |settings_content| {
 754                                &mut settings_content.editor.fast_scroll_sensitivity
 755                            },
 756                        }),
 757                        metadata: None,
 758                        files: USER,
 759                    }),
 760                    SettingsPageItem::SettingItem(SettingItem {
 761                        title: "Autoscroll On Clicks",
 762                        description: "Whether to scroll when clicking near the edge of the visible text area",
 763                        field: Box::new(SettingField {
 764                            pick: |settings_content| &settings_content.editor.autoscroll_on_clicks,
 765                            pick_mut: |settings_content| {
 766                                &mut settings_content.editor.autoscroll_on_clicks
 767                            },
 768                        }),
 769                        metadata: None,
 770                        files: USER,
 771                    }),
 772                    SettingsPageItem::SectionHeader("Signature Help"),
 773                    SettingsPageItem::SettingItem(SettingItem {
 774                        title: "Auto Signature Help",
 775                        description: "Automatically show a signature help pop-up",
 776                        field: Box::new(SettingField {
 777                            pick: |settings_content| &settings_content.editor.auto_signature_help,
 778                            pick_mut: |settings_content| {
 779                                &mut settings_content.editor.auto_signature_help
 780                            },
 781                        }),
 782                        metadata: None,
 783                        files: USER,
 784                    }),
 785                    SettingsPageItem::SettingItem(SettingItem {
 786                        title: "Show Signature Help After Edits",
 787                        description: "Show the signature help pop-up after completions or bracket pairs are inserted",
 788                        field: Box::new(SettingField {
 789                            pick: |settings_content| {
 790                                &settings_content.editor.show_signature_help_after_edits
 791                            },
 792                            pick_mut: |settings_content| {
 793                                &mut settings_content.editor.show_signature_help_after_edits
 794                            },
 795                        }),
 796                        metadata: None,
 797                        files: USER,
 798                    }),
 799                    SettingsPageItem::SettingItem(SettingItem {
 800                        title: "Snippet Sort Order",
 801                        description: "Determines how snippets are sorted relative to other completion items",
 802                        field: Box::new(SettingField {
 803                            pick: |settings_content| &settings_content.editor.snippet_sort_order,
 804                            pick_mut: |settings_content| {
 805                                &mut settings_content.editor.snippet_sort_order
 806                            },
 807                        }),
 808                        metadata: None,
 809                        files: USER,
 810                    }),
 811                    SettingsPageItem::SectionHeader("Hover"),
 812                    SettingsPageItem::SettingItem(SettingItem {
 813                        title: "Hover Popover Enabled",
 814                        description: "Show the informational hover box when moving the mouse over symbols in the editor",
 815                        field: Box::new(SettingField {
 816                            pick: |settings_content| &settings_content.editor.hover_popover_enabled,
 817                            pick_mut: |settings_content| {
 818                                &mut settings_content.editor.hover_popover_enabled
 819                            },
 820                        }),
 821                        metadata: None,
 822                        files: USER,
 823                    }),
 824                    // todo(settings ui): add units to this number input
 825                    SettingsPageItem::SettingItem(SettingItem {
 826                        title: "Hover Popover Delay",
 827                        description: "Time to wait in milliseconds before showing the informational hover box",
 828                        field: Box::new(SettingField {
 829                            pick: |settings_content| &settings_content.editor.hover_popover_delay,
 830                            pick_mut: |settings_content| {
 831                                &mut settings_content.editor.hover_popover_delay
 832                            },
 833                        }),
 834                        metadata: None,
 835                        files: USER,
 836                    }),
 837                    SettingsPageItem::SectionHeader("Code Actions & Selection"),
 838                    SettingsPageItem::SettingItem(SettingItem {
 839                        title: "Inline Code Actions",
 840                        description: "Show code action button at start of buffer line",
 841                        field: Box::new(SettingField {
 842                            pick: |settings_content| &settings_content.editor.inline_code_actions,
 843                            pick_mut: |settings_content| {
 844                                &mut settings_content.editor.inline_code_actions
 845                            },
 846                        }),
 847                        metadata: None,
 848                        files: USER,
 849                    }),
 850                    SettingsPageItem::SettingItem(SettingItem {
 851                        title: "Drag And Drop Selection",
 852                        description: "Enable drag and drop selection",
 853                        field: Box::new(SettingField {
 854                            pick: |settings_content| {
 855                                if let Some(drag_and_drop) =
 856                                    &settings_content.editor.drag_and_drop_selection
 857                                {
 858                                    &drag_and_drop.enabled
 859                                } else {
 860                                    &None
 861                                }
 862                            },
 863                            pick_mut: |settings_content| {
 864                                &mut settings_content
 865                                    .editor
 866                                    .drag_and_drop_selection
 867                                    .get_or_insert_default()
 868                                    .enabled
 869                            },
 870                        }),
 871                        metadata: None,
 872                        files: USER,
 873                    }),
 874                    SettingsPageItem::SettingItem(SettingItem {
 875                        title: "Drag And Drop Selection Delay",
 876                        description: "Delay in milliseconds before drag and drop selection starts",
 877                        field: Box::new(SettingField {
 878                            pick: |settings_content| {
 879                                if let Some(drag_and_drop) =
 880                                    &settings_content.editor.drag_and_drop_selection
 881                                {
 882                                    &drag_and_drop.delay
 883                                } else {
 884                                    &None
 885                                }
 886                            },
 887                            pick_mut: |settings_content| {
 888                                &mut settings_content
 889                                    .editor
 890                                    .drag_and_drop_selection
 891                                    .get_or_insert_default()
 892                                    .delay
 893                            },
 894                        }),
 895                        metadata: None,
 896                        files: USER,
 897                    }),
 898                    SettingsPageItem::SectionHeader("Gutter"),
 899                    SettingsPageItem::SettingItem(SettingItem {
 900                        title: "Show Line Numbers",
 901                        description: "Show line numbers in the gutter",
 902                        field: Box::new(SettingField {
 903                            pick: |settings_content| {
 904                                if let Some(gutter) = &settings_content.editor.gutter {
 905                                    &gutter.line_numbers
 906                                } else {
 907                                    &None
 908                                }
 909                            },
 910                            pick_mut: |settings_content| {
 911                                &mut settings_content
 912                                    .editor
 913                                    .gutter
 914                                    .get_or_insert_default()
 915                                    .line_numbers
 916                            },
 917                        }),
 918                        metadata: None,
 919                        files: USER,
 920                    }),
 921                    SettingsPageItem::SettingItem(SettingItem {
 922                        title: "Relative Line Numbers",
 923                        description: "Whether the line numbers in the editor's gutter are relative or not",
 924                        field: Box::new(SettingField {
 925                            pick: |settings_content| &settings_content.editor.relative_line_numbers,
 926                            pick_mut: |settings_content| {
 927                                &mut settings_content.editor.relative_line_numbers
 928                            },
 929                        }),
 930                        metadata: None,
 931                        files: USER,
 932                    }),
 933                    SettingsPageItem::SettingItem(SettingItem {
 934                        title: "Show Runnables",
 935                        description: "Show runnable buttons in the gutter",
 936                        field: Box::new(SettingField {
 937                            pick: |settings_content| {
 938                                if let Some(gutter) = &settings_content.editor.gutter {
 939                                    &gutter.runnables
 940                                } else {
 941                                    &None
 942                                }
 943                            },
 944                            pick_mut: |settings_content| {
 945                                &mut settings_content
 946                                    .editor
 947                                    .gutter
 948                                    .get_or_insert_default()
 949                                    .runnables
 950                            },
 951                        }),
 952                        metadata: None,
 953                        files: USER,
 954                    }),
 955                    SettingsPageItem::SettingItem(SettingItem {
 956                        title: "Show Breakpoints",
 957                        description: "Show breakpoints in the gutter",
 958                        field: Box::new(SettingField {
 959                            pick: |settings_content| {
 960                                if let Some(gutter) = &settings_content.editor.gutter {
 961                                    &gutter.breakpoints
 962                                } else {
 963                                    &None
 964                                }
 965                            },
 966                            pick_mut: |settings_content| {
 967                                &mut settings_content
 968                                    .editor
 969                                    .gutter
 970                                    .get_or_insert_default()
 971                                    .breakpoints
 972                            },
 973                        }),
 974                        metadata: None,
 975                        files: USER,
 976                    }),
 977                    SettingsPageItem::SettingItem(SettingItem {
 978                        title: "Show Folds",
 979                        description: "Show code folding controls in the gutter",
 980                        field: Box::new(SettingField {
 981                            pick: |settings_content| {
 982                                if let Some(gutter) = &settings_content.editor.gutter {
 983                                    &gutter.folds
 984                                } else {
 985                                    &None
 986                                }
 987                            },
 988                            pick_mut: |settings_content| {
 989                                &mut settings_content.editor.gutter.get_or_insert_default().folds
 990                            },
 991                        }),
 992                        metadata: None,
 993                        files: USER,
 994                    }),
 995                    SettingsPageItem::SettingItem(SettingItem {
 996                        title: "Min Line Number Digits",
 997                        description: "Minimum number of characters to reserve space for in the gutter",
 998                        field: Box::new(SettingField {
 999                            pick: |settings_content| {
1000                                if let Some(gutter) = &settings_content.editor.gutter {
1001                                    &gutter.min_line_number_digits
1002                                } else {
1003                                    &None
1004                                }
1005                            },
1006                            pick_mut: |settings_content| {
1007                                &mut settings_content
1008                                    .editor
1009                                    .gutter
1010                                    .get_or_insert_default()
1011                                    .min_line_number_digits
1012                            },
1013                        }),
1014                        metadata: None,
1015                        files: USER,
1016                    }),
1017                    SettingsPageItem::SectionHeader("Scrollbar"),
1018                    SettingsPageItem::SettingItem(SettingItem {
1019                        title: "Show",
1020                        description: "When to show the scrollbar in the editor",
1021                        field: Box::new(SettingField {
1022                            pick: |settings_content| {
1023                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1024                                    &scrollbar.show
1025                                } else {
1026                                    &None
1027                                }
1028                            },
1029                            pick_mut: |settings_content| {
1030                                &mut settings_content
1031                                    .editor
1032                                    .scrollbar
1033                                    .get_or_insert_default()
1034                                    .show
1035                            },
1036                        }),
1037                        metadata: None,
1038                        files: USER,
1039                    }),
1040                    SettingsPageItem::SettingItem(SettingItem {
1041                        title: "Cursors",
1042                        description: "Show cursor positions in the scrollbar",
1043                        field: Box::new(SettingField {
1044                            pick: |settings_content| {
1045                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1046                                    &scrollbar.cursors
1047                                } else {
1048                                    &None
1049                                }
1050                            },
1051                            pick_mut: |settings_content| {
1052                                &mut settings_content
1053                                    .editor
1054                                    .scrollbar
1055                                    .get_or_insert_default()
1056                                    .cursors
1057                            },
1058                        }),
1059                        metadata: None,
1060                        files: USER,
1061                    }),
1062                    SettingsPageItem::SettingItem(SettingItem {
1063                        title: "Git Diff",
1064                        description: "Show git diff indicators in the scrollbar",
1065                        field: Box::new(SettingField {
1066                            pick: |settings_content| {
1067                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1068                                    &scrollbar.git_diff
1069                                } else {
1070                                    &None
1071                                }
1072                            },
1073                            pick_mut: |settings_content| {
1074                                &mut settings_content
1075                                    .editor
1076                                    .scrollbar
1077                                    .get_or_insert_default()
1078                                    .git_diff
1079                            },
1080                        }),
1081                        metadata: None,
1082                        files: USER,
1083                    }),
1084                    SettingsPageItem::SettingItem(SettingItem {
1085                        title: "Search Results",
1086                        description: "Show buffer search result indicators in the scrollbar",
1087                        field: Box::new(SettingField {
1088                            pick: |settings_content| {
1089                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1090                                    &scrollbar.search_results
1091                                } else {
1092                                    &None
1093                                }
1094                            },
1095                            pick_mut: |settings_content| {
1096                                &mut settings_content
1097                                    .editor
1098                                    .scrollbar
1099                                    .get_or_insert_default()
1100                                    .search_results
1101                            },
1102                        }),
1103                        metadata: None,
1104                        files: USER,
1105                    }),
1106                    SettingsPageItem::SettingItem(SettingItem {
1107                        title: "Selected Text",
1108                        description: "Show selected text occurrences in the scrollbar",
1109                        field: Box::new(SettingField {
1110                            pick: |settings_content| {
1111                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1112                                    &scrollbar.selected_text
1113                                } else {
1114                                    &None
1115                                }
1116                            },
1117                            pick_mut: |settings_content| {
1118                                &mut settings_content
1119                                    .editor
1120                                    .scrollbar
1121                                    .get_or_insert_default()
1122                                    .selected_text
1123                            },
1124                        }),
1125                        metadata: None,
1126                        files: USER,
1127                    }),
1128                    SettingsPageItem::SettingItem(SettingItem {
1129                        title: "Selected Symbol",
1130                        description: "Show selected symbol occurrences in the scrollbar",
1131                        field: Box::new(SettingField {
1132                            pick: |settings_content| {
1133                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1134                                    &scrollbar.selected_symbol
1135                                } else {
1136                                    &None
1137                                }
1138                            },
1139                            pick_mut: |settings_content| {
1140                                &mut settings_content
1141                                    .editor
1142                                    .scrollbar
1143                                    .get_or_insert_default()
1144                                    .selected_symbol
1145                            },
1146                        }),
1147                        metadata: None,
1148                        files: USER,
1149                    }),
1150                    SettingsPageItem::SettingItem(SettingItem {
1151                        title: "Diagnostics",
1152                        description: "Which diagnostic indicators to show in the scrollbar",
1153                        field: Box::new(SettingField {
1154                            pick: |settings_content| {
1155                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1156                                    &scrollbar.diagnostics
1157                                } else {
1158                                    &None
1159                                }
1160                            },
1161                            pick_mut: |settings_content| {
1162                                &mut settings_content
1163                                    .editor
1164                                    .scrollbar
1165                                    .get_or_insert_default()
1166                                    .diagnostics
1167                            },
1168                        }),
1169                        metadata: None,
1170                        files: USER,
1171                    }),
1172                    SettingsPageItem::SettingItem(SettingItem {
1173                        title: "Horizontal Scrollbar",
1174                        description: "When false, forcefully disables the horizontal scrollbar",
1175                        field: Box::new(SettingField {
1176                            pick: |settings_content| {
1177                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1178                                    if let Some(axes) = &scrollbar.axes {
1179                                        &axes.horizontal
1180                                    } else {
1181                                        &None
1182                                    }
1183                                } else {
1184                                    &None
1185                                }
1186                            },
1187                            pick_mut: |settings_content| {
1188                                &mut settings_content
1189                                    .editor
1190                                    .scrollbar
1191                                    .get_or_insert_default()
1192                                    .axes
1193                                    .get_or_insert_default()
1194                                    .horizontal
1195                            },
1196                        }),
1197                        metadata: None,
1198                        files: USER,
1199                    }),
1200                    SettingsPageItem::SettingItem(SettingItem {
1201                        title: "Vertical Scrollbar",
1202                        description: "When false, forcefully disables the vertical scrollbar",
1203                        field: Box::new(SettingField {
1204                            pick: |settings_content| {
1205                                if let Some(scrollbar) = &settings_content.editor.scrollbar {
1206                                    if let Some(axes) = &scrollbar.axes {
1207                                        &axes.vertical
1208                                    } else {
1209                                        &None
1210                                    }
1211                                } else {
1212                                    &None
1213                                }
1214                            },
1215                            pick_mut: |settings_content| {
1216                                &mut settings_content
1217                                    .editor
1218                                    .scrollbar
1219                                    .get_or_insert_default()
1220                                    .axes
1221                                    .get_or_insert_default()
1222                                    .vertical
1223                            },
1224                        }),
1225                        metadata: None,
1226                        files: USER,
1227                    }),
1228                    SettingsPageItem::SectionHeader("Minimap"),
1229                    SettingsPageItem::SettingItem(SettingItem {
1230                        title: "Show",
1231                        description: "When to show the minimap in the editor",
1232                        field: Box::new(SettingField {
1233                            pick: |settings_content| {
1234                                if let Some(minimap) = &settings_content.editor.minimap {
1235                                    &minimap.show
1236                                } else {
1237                                    &None
1238                                }
1239                            },
1240                            pick_mut: |settings_content| {
1241                                &mut settings_content.editor.minimap.get_or_insert_default().show
1242                            },
1243                        }),
1244                        metadata: None,
1245                        files: USER,
1246                    }),
1247                    SettingsPageItem::SettingItem(SettingItem {
1248                        title: "Display In",
1249                        description: "Where to show the minimap in the editor",
1250                        field: Box::new(SettingField {
1251                            pick: |settings_content| {
1252                                if let Some(minimap) = &settings_content.editor.minimap {
1253                                    &minimap.display_in
1254                                } else {
1255                                    &None
1256                                }
1257                            },
1258                            pick_mut: |settings_content| {
1259                                &mut settings_content
1260                                    .editor
1261                                    .minimap
1262                                    .get_or_insert_default()
1263                                    .display_in
1264                            },
1265                        }),
1266                        metadata: None,
1267                        files: USER,
1268                    }),
1269                    SettingsPageItem::SettingItem(SettingItem {
1270                        title: "Thumb",
1271                        description: "When to show the minimap thumb",
1272                        field: Box::new(SettingField {
1273                            pick: |settings_content| {
1274                                if let Some(minimap) = &settings_content.editor.minimap {
1275                                    &minimap.thumb
1276                                } else {
1277                                    &None
1278                                }
1279                            },
1280                            pick_mut: |settings_content| {
1281                                &mut settings_content
1282                                    .editor
1283                                    .minimap
1284                                    .get_or_insert_default()
1285                                    .thumb
1286                            },
1287                        }),
1288                        metadata: None,
1289                        files: USER,
1290                    }),
1291                    SettingsPageItem::SettingItem(SettingItem {
1292                        title: "Thumb Border",
1293                        description: "Border style for the minimap's scrollbar thumb",
1294                        field: Box::new(SettingField {
1295                            pick: |settings_content| {
1296                                if let Some(minimap) = &settings_content.editor.minimap {
1297                                    &minimap.thumb_border
1298                                } else {
1299                                    &None
1300                                }
1301                            },
1302                            pick_mut: |settings_content| {
1303                                &mut settings_content
1304                                    .editor
1305                                    .minimap
1306                                    .get_or_insert_default()
1307                                    .thumb_border
1308                            },
1309                        }),
1310                        metadata: None,
1311                        files: USER,
1312                    }),
1313                    SettingsPageItem::SettingItem(SettingItem {
1314                        title: "Current Line Highlight",
1315                        description: "How to highlight the current line in the minimap",
1316                        field: Box::new(SettingField {
1317                            pick: |settings_content| {
1318                                if let Some(minimap) = &settings_content.editor.minimap
1319                                    && minimap.current_line_highlight.is_some()
1320                                {
1321                                    &minimap.current_line_highlight
1322                                } else {
1323                                    &settings_content.editor.current_line_highlight
1324                                }
1325                            },
1326                            pick_mut: |settings_content| {
1327                                &mut settings_content
1328                                    .editor
1329                                    .minimap
1330                                    .get_or_insert_default()
1331                                    .current_line_highlight
1332                            },
1333                        }),
1334                        metadata: None,
1335                        files: USER,
1336                    }),
1337                    SettingsPageItem::SettingItem(SettingItem {
1338                        title: "Max Width Columns",
1339                        description: "Maximum number of columns to display in the minimap",
1340                        field: Box::new(SettingField {
1341                            pick: |settings_content| {
1342                                if let Some(minimap) = &settings_content.editor.minimap {
1343                                    &minimap.max_width_columns
1344                                } else {
1345                                    &None
1346                                }
1347                            },
1348                            pick_mut: |settings_content| {
1349                                &mut settings_content
1350                                    .editor
1351                                    .minimap
1352                                    .get_or_insert_default()
1353                                    .max_width_columns
1354                            },
1355                        }),
1356                        metadata: None,
1357                        files: USER,
1358                    }),
1359                    SettingsPageItem::SectionHeader("Toolbar"),
1360                    SettingsPageItem::SettingItem(SettingItem {
1361                        title: "Breadcrumbs",
1362                        description: "Show breadcrumbs",
1363                        field: Box::new(SettingField {
1364                            pick: |settings_content| {
1365                                if let Some(toolbar) = &settings_content.editor.toolbar {
1366                                    &toolbar.breadcrumbs
1367                                } else {
1368                                    &None
1369                                }
1370                            },
1371                            pick_mut: |settings_content| {
1372                                &mut settings_content
1373                                    .editor
1374                                    .toolbar
1375                                    .get_or_insert_default()
1376                                    .breadcrumbs
1377                            },
1378                        }),
1379                        metadata: None,
1380                        files: USER,
1381                    }),
1382                    SettingsPageItem::SettingItem(SettingItem {
1383                        title: "Quick Actions",
1384                        description: "Show quick action buttons (e.g., search, selection, editor controls, etc.)",
1385                        field: Box::new(SettingField {
1386                            pick: |settings_content| {
1387                                if let Some(toolbar) = &settings_content.editor.toolbar {
1388                                    &toolbar.quick_actions
1389                                } else {
1390                                    &None
1391                                }
1392                            },
1393                            pick_mut: |settings_content| {
1394                                &mut settings_content
1395                                    .editor
1396                                    .toolbar
1397                                    .get_or_insert_default()
1398                                    .quick_actions
1399                            },
1400                        }),
1401                        metadata: None,
1402                        files: USER,
1403                    }),
1404                    SettingsPageItem::SettingItem(SettingItem {
1405                        title: "Selections Menu",
1406                        description: "Show the selections menu in the editor toolbar",
1407                        field: Box::new(SettingField {
1408                            pick: |settings_content| {
1409                                if let Some(toolbar) = &settings_content.editor.toolbar {
1410                                    &toolbar.selections_menu
1411                                } else {
1412                                    &None
1413                                }
1414                            },
1415                            pick_mut: |settings_content| {
1416                                &mut settings_content
1417                                    .editor
1418                                    .toolbar
1419                                    .get_or_insert_default()
1420                                    .selections_menu
1421                            },
1422                        }),
1423                        metadata: None,
1424                        files: USER,
1425                    }),
1426                    SettingsPageItem::SettingItem(SettingItem {
1427                        title: "Agent Review",
1428                        description: "Show agent review buttons in the editor toolbar",
1429                        field: Box::new(SettingField {
1430                            pick: |settings_content| {
1431                                if let Some(toolbar) = &settings_content.editor.toolbar {
1432                                    &toolbar.agent_review
1433                                } else {
1434                                    &None
1435                                }
1436                            },
1437                            pick_mut: |settings_content| {
1438                                &mut settings_content
1439                                    .editor
1440                                    .toolbar
1441                                    .get_or_insert_default()
1442                                    .agent_review
1443                            },
1444                        }),
1445                        metadata: None,
1446                        files: USER,
1447                    }),
1448                    SettingsPageItem::SettingItem(SettingItem {
1449                        title: "Code Actions",
1450                        description: "Show code action buttons in the editor toolbar",
1451                        field: Box::new(SettingField {
1452                            pick: |settings_content| {
1453                                if let Some(toolbar) = &settings_content.editor.toolbar {
1454                                    &toolbar.code_actions
1455                                } else {
1456                                    &None
1457                                }
1458                            },
1459                            pick_mut: |settings_content| {
1460                                &mut settings_content
1461                                    .editor
1462                                    .toolbar
1463                                    .get_or_insert_default()
1464                                    .code_actions
1465                            },
1466                        }),
1467                        metadata: None,
1468                        files: USER,
1469                    }),
1470                ];
1471                items.extend(language_settings_data());
1472                items
1473            },
1474        },
1475        SettingsPage {
1476            title: "Languages & Tools",
1477            items: {
1478                let mut items = vec![];
1479                items.extend(non_editor_language_settings_data());
1480                items.extend([
1481                    SettingsPageItem::SectionHeader("File Types"),
1482                    SettingsPageItem::SettingItem(SettingItem {
1483                        title: "File Type Associations",
1484                        description: "A Mapping from Languages to files and file extensions that should be treated as that language",
1485                        field: Box::new(
1486                            SettingField {
1487                                pick: |settings_content| {
1488                                    &settings_content.project.all_languages.file_types
1489                                },
1490                                pick_mut: |settings_content| {
1491                                    &mut settings_content.project.all_languages.file_types
1492                                },
1493                            }
1494                            .unimplemented(),
1495                        ),
1496                        metadata: None,
1497                        files: USER | LOCAL,
1498                    }),
1499                ]);
1500
1501                items.extend([
1502                    SettingsPageItem::SectionHeader("Diagnostics"),
1503                                    SettingsPageItem::SettingItem(SettingItem {
1504                                        title: "Max Severity",
1505                                        description: "Which level to use to filter out diagnostics displayed in the editor",
1506                                        field: Box::new(SettingField {
1507                                            pick: |settings_content| &settings_content.editor.diagnostics_max_severity,
1508                                            pick_mut: |settings_content| {
1509                                                &mut settings_content.editor.diagnostics_max_severity
1510                                            },
1511                                        }),
1512                                        metadata: None,
1513                                        files: USER,
1514                                    }),
1515                                    SettingsPageItem::SettingItem(SettingItem {
1516                                        title: "Include Warnings",
1517                                        description: "Whether to show warnings or not by default",
1518                                        field: Box::new(SettingField {
1519                                            pick: |settings_content| {
1520                                                if let Some(diagnostics) = &settings_content.diagnostics {
1521                                                    &diagnostics.include_warnings
1522                                                } else {
1523                                                    &None
1524                                                }
1525                                            },
1526                                            pick_mut: |settings_content| {
1527                                                &mut settings_content
1528                                                    .diagnostics
1529                                                    .get_or_insert_default()
1530                                                    .include_warnings
1531                                            },
1532                                        }),
1533                                        metadata: None,
1534                                        files: USER,
1535                                    }),
1536                                    SettingsPageItem::SectionHeader("Inline Diagnostics"),
1537                                    SettingsPageItem::SettingItem(SettingItem {
1538                                        title: "Enabled",
1539                                        description: "Whether to show diagnostics inline or not",
1540                                        field: Box::new(SettingField {
1541                                            pick: |settings_content| {
1542                                                if let Some(diagnostics) = &settings_content.diagnostics {
1543                                                    if let Some(inline) = &diagnostics.inline {
1544                                                        &inline.enabled
1545                                                    } else {
1546                                                        &None
1547                                                    }
1548                                                } else {
1549                                                    &None
1550                                                }
1551                                            },
1552                                            pick_mut: |settings_content| {
1553                                                &mut settings_content
1554                                                    .diagnostics
1555                                                    .get_or_insert_default()
1556                                                    .inline
1557                                                    .get_or_insert_default()
1558                                                    .enabled
1559                                            },
1560                                        }),
1561                                        metadata: None,
1562                                        files: USER,
1563                                    }),
1564                                    SettingsPageItem::SettingItem(SettingItem {
1565                                        title: "Update Debounce",
1566                                        description: "The delay in milliseconds to show inline diagnostics after the last diagnostic update",
1567                                        field: Box::new(SettingField {
1568                                            pick: |settings_content| {
1569                                                if let Some(diagnostics) = &settings_content.diagnostics {
1570                                                    if let Some(inline) = &diagnostics.inline {
1571                                                        &inline.update_debounce_ms
1572                                                    } else {
1573                                                        &None
1574                                                    }
1575                                                } else {
1576                                                    &None
1577                                                }
1578                                            },
1579                                            pick_mut: |settings_content| {
1580                                                &mut settings_content
1581                                                    .diagnostics
1582                                                    .get_or_insert_default()
1583                                                    .inline
1584                                                    .get_or_insert_default()
1585                                                    .update_debounce_ms
1586                                            },
1587                                        }),
1588                                        metadata: None,
1589                                        files: USER,
1590                                    }),
1591                                    SettingsPageItem::SettingItem(SettingItem {
1592                                        title: "Padding",
1593                                        description: "The amount of padding between the end of the source line and the start of the inline diagnostic",
1594                                        field: Box::new(SettingField {
1595                                            pick: |settings_content| {
1596                                                if let Some(diagnostics) = &settings_content.diagnostics {
1597                                                    if let Some(inline) = &diagnostics.inline {
1598                                                        &inline.padding
1599                                                    } else {
1600                                                        &None
1601                                                    }
1602                                                } else {
1603                                                    &None
1604                                                }
1605                                            },
1606                                            pick_mut: |settings_content| {
1607                                                &mut settings_content
1608                                                    .diagnostics
1609                                                    .get_or_insert_default()
1610                                                    .inline
1611                                                    .get_or_insert_default()
1612                                                    .padding
1613                                            },
1614                                        }),
1615                                        metadata: None,
1616                                        files: USER,
1617                                    }),
1618                                    SettingsPageItem::SettingItem(SettingItem {
1619                                        title: "Minimum Column",
1620                                        description: "The minimum column at which to display inline diagnostics",
1621                                        field: Box::new(SettingField {
1622                                            pick: |settings_content| {
1623                                                if let Some(diagnostics) = &settings_content.diagnostics {
1624                                                    if let Some(inline) = &diagnostics.inline {
1625                                                        &inline.min_column
1626                                                    } else {
1627                                                        &None
1628                                                    }
1629                                                } else {
1630                                                    &None
1631                                                }
1632                                            },
1633                                            pick_mut: |settings_content| {
1634                                                &mut settings_content
1635                                                    .diagnostics
1636                                                    .get_or_insert_default()
1637                                                    .inline
1638                                                    .get_or_insert_default()
1639                                                    .min_column
1640                                            },
1641                                        }),
1642                                        metadata: None,
1643                                        files: USER,
1644                                    }),
1645                                    SettingsPageItem::SectionHeader("LSP Pull Diagnostics"),
1646                                    SettingsPageItem::SettingItem(SettingItem {
1647                                        title: "Enabled",
1648                                        description: "Whether to pull for language server-powered diagnostics or not",
1649                                        field: Box::new(SettingField {
1650                                            pick: |settings_content| {
1651                                                if let Some(diagnostics) = &settings_content.diagnostics {
1652                                                    if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
1653                                                        &lsp_pull.enabled
1654                                                    } else {
1655                                                        &None
1656                                                    }
1657                                                } else {
1658                                                    &None
1659                                                }
1660                                            },
1661                                            pick_mut: |settings_content| {
1662                                                &mut settings_content
1663                                                    .diagnostics
1664                                                    .get_or_insert_default()
1665                                                    .lsp_pull_diagnostics
1666                                                    .get_or_insert_default()
1667                                                    .enabled
1668                                            },
1669                                        }),
1670                                        metadata: None,
1671                                        files: USER,
1672                                    }),
1673                                    // todo(settings_ui): Needs unit
1674                                    SettingsPageItem::SettingItem(SettingItem {
1675                                        title: "Debounce",
1676                                        description: "Minimum time to wait before pulling diagnostics from the language server(s)",
1677                                        field: Box::new(SettingField {
1678                                            pick: |settings_content| {
1679                                                if let Some(diagnostics) = &settings_content.diagnostics {
1680                                                    if let Some(lsp_pull) = &diagnostics.lsp_pull_diagnostics {
1681                                                        &lsp_pull.debounce_ms
1682                                                    } else {
1683                                                        &None
1684                                                    }
1685                                                } else {
1686                                                    &None
1687                                                }
1688                                            },
1689                                            pick_mut: |settings_content| {
1690                                                &mut settings_content
1691                                                    .diagnostics
1692                                                    .get_or_insert_default()
1693                                                    .lsp_pull_diagnostics
1694                                                    .get_or_insert_default()
1695                                                    .debounce_ms
1696                                            },
1697                                        }),
1698                                        metadata: None,
1699                                        files: USER,
1700                                    }),
1701                                    SettingsPageItem::SectionHeader("LSP Highlights"),
1702                                    SettingsPageItem::SettingItem(SettingItem {
1703                                        title: "Debounce",
1704                                        description: "The debounce delay before querying highlights from the language",
1705                                        field: Box::new(SettingField {
1706                                            pick: |settings_content| &settings_content.editor.lsp_highlight_debounce,
1707                                            pick_mut: |settings_content| {
1708                                                &mut settings_content.editor.lsp_highlight_debounce
1709                                            },
1710                                        }),
1711                                        metadata: None,
1712                                        files: USER,
1713                                    }),
1714                ]);
1715
1716                // todo(settings_ui): Refresh on extension (un)/installed
1717                // Note that `crates/json_schema_store` solves the same problem, there is probably a way to unify the two
1718                items.push(SettingsPageItem::SectionHeader(LANGUAGES_SECTION_HEADER));
1719                items.extend(all_language_names(cx).into_iter().map(|language_name| {
1720                    SettingsPageItem::SubPageLink(SubPageLink {
1721                        title: language_name,
1722                        files: USER | LOCAL,
1723                        render: Arc::new(|this, window, cx| {
1724                            this.render_page_items(
1725                                language_settings_data()
1726                                    .iter()
1727                                    .chain(non_editor_language_settings_data().iter())
1728                                    .enumerate(),
1729                                None,
1730                                window,
1731                                cx,
1732                            )
1733                            .into_any_element()
1734                        }),
1735                    })
1736                }));
1737                items
1738            },
1739        },
1740        SettingsPage {
1741            title: "Search & Files",
1742            items: vec![
1743                SettingsPageItem::SectionHeader("Search"),
1744                SettingsPageItem::SettingItem(SettingItem {
1745                    title: "Whole Word",
1746                    description: "Search for whole words by default",
1747                    field: Box::new(SettingField {
1748                        pick: |settings_content| {
1749                            if let Some(search) = &settings_content.editor.search {
1750                                &search.whole_word
1751                            } else {
1752                                &None
1753                            }
1754                        },
1755                        pick_mut: |settings_content| {
1756                            &mut settings_content
1757                                .editor
1758                                .search
1759                                .get_or_insert_default()
1760                                .whole_word
1761                        },
1762                    }),
1763                    metadata: None,
1764                    files: USER,
1765                }),
1766                SettingsPageItem::SettingItem(SettingItem {
1767                    title: "Case Sensitive",
1768                    description: "Search case-sensitively by default",
1769                    field: Box::new(SettingField {
1770                        pick: |settings_content| {
1771                            if let Some(search) = &settings_content.editor.search {
1772                                &search.case_sensitive
1773                            } else {
1774                                &None
1775                            }
1776                        },
1777                        pick_mut: |settings_content| {
1778                            &mut settings_content
1779                                .editor
1780                                .search
1781                                .get_or_insert_default()
1782                                .case_sensitive
1783                        },
1784                    }),
1785                    metadata: None,
1786                    files: USER,
1787                }),
1788                SettingsPageItem::SettingItem(SettingItem {
1789                    title: "Use Smartcase Search",
1790                    description: "Whether to automatically enable case-sensitive search based on the search query",
1791                    field: Box::new(SettingField {
1792                        pick: |settings_content| &settings_content.editor.use_smartcase_search,
1793                        pick_mut: |settings_content| {
1794                            &mut settings_content.editor.use_smartcase_search
1795                        },
1796                    }),
1797                    metadata: None,
1798                    files: USER,
1799                }),
1800                SettingsPageItem::SettingItem(SettingItem {
1801                    title: "Include Ignored",
1802                    description: "Include ignored files in search results by default",
1803                    field: Box::new(SettingField {
1804                        pick: |settings_content| {
1805                            if let Some(search) = &settings_content.editor.search {
1806                                &search.include_ignored
1807                            } else {
1808                                &None
1809                            }
1810                        },
1811                        pick_mut: |settings_content| {
1812                            &mut settings_content
1813                                .editor
1814                                .search
1815                                .get_or_insert_default()
1816                                .include_ignored
1817                        },
1818                    }),
1819                    metadata: None,
1820                    files: USER,
1821                }),
1822                SettingsPageItem::SettingItem(SettingItem {
1823                    title: "Regex",
1824                    description: "Use regex search by default",
1825                    field: Box::new(SettingField {
1826                        pick: |settings_content| {
1827                            if let Some(search) = &settings_content.editor.search {
1828                                &search.regex
1829                            } else {
1830                                &None
1831                            }
1832                        },
1833                        pick_mut: |settings_content| {
1834                            &mut settings_content.editor.search.get_or_insert_default().regex
1835                        },
1836                    }),
1837                    metadata: None,
1838                    files: USER,
1839                }),
1840                SettingsPageItem::SettingItem(SettingItem {
1841                    title: "Search Wrap",
1842                    description: "Whether the editor search results will loop",
1843                    field: Box::new(SettingField {
1844                        pick: |settings_content| &settings_content.editor.search_wrap,
1845                        pick_mut: |settings_content| &mut settings_content.editor.search_wrap,
1846                    }),
1847                    metadata: None,
1848                    files: USER,
1849                }),
1850                SettingsPageItem::SettingItem(SettingItem {
1851                    title: "Seed Search Query From Cursor",
1852                    description: "When to populate a new search's query based on the text under the cursor",
1853                    field: Box::new(SettingField {
1854                        pick: |settings_content| {
1855                            &settings_content.editor.seed_search_query_from_cursor
1856                        },
1857                        pick_mut: |settings_content| {
1858                            &mut settings_content.editor.seed_search_query_from_cursor
1859                        },
1860                    }),
1861                    metadata: None,
1862                    files: USER,
1863                }),
1864                SettingsPageItem::SectionHeader("File Finder"),
1865                // todo: null by default
1866                SettingsPageItem::SettingItem(SettingItem {
1867                    title: "Include Ignored in Search",
1868                    description: "Use gitignored files when searching",
1869                    field: Box::new(
1870                        SettingField {
1871                            pick: |settings_content| {
1872                                if let Some(file_finder) = &settings_content.file_finder {
1873                                    &file_finder.include_ignored
1874                                } else {
1875                                    &None
1876                                }
1877                            },
1878                            pick_mut: |settings_content| {
1879                                &mut settings_content
1880                                    .file_finder
1881                                    .get_or_insert_default()
1882                                    .include_ignored
1883                            },
1884                        }
1885                        .unimplemented(),
1886                    ),
1887                    metadata: None,
1888                    files: USER,
1889                }),
1890                SettingsPageItem::SettingItem(SettingItem {
1891                    title: "File Icons",
1892                    description: "Show file icons in the file finder",
1893                    field: Box::new(SettingField {
1894                        pick: |settings_content| {
1895                            if let Some(file_finder) = &settings_content.file_finder {
1896                                &file_finder.file_icons
1897                            } else {
1898                                &None
1899                            }
1900                        },
1901                        pick_mut: |settings_content| {
1902                            &mut settings_content
1903                                .file_finder
1904                                .get_or_insert_default()
1905                                .file_icons
1906                        },
1907                    }),
1908                    metadata: None,
1909                    files: USER,
1910                }),
1911                SettingsPageItem::SettingItem(SettingItem {
1912                    title: "Modal Max Width",
1913                    description: "Determines how much space the file finder can take up in relation to the available window width",
1914                    field: Box::new(SettingField {
1915                        pick: |settings_content| {
1916                            if let Some(file_finder) = &settings_content.file_finder {
1917                                &file_finder.modal_max_width
1918                            } else {
1919                                &None
1920                            }
1921                        },
1922                        pick_mut: |settings_content| {
1923                            &mut settings_content
1924                                .file_finder
1925                                .get_or_insert_default()
1926                                .modal_max_width
1927                        },
1928                    }),
1929                    metadata: None,
1930                    files: USER,
1931                }),
1932                SettingsPageItem::SettingItem(SettingItem {
1933                    title: "Skip Focus For Active In Search",
1934                    description: "Whether the file finder should skip focus for the active file in search results",
1935                    field: Box::new(SettingField {
1936                        pick: |settings_content| {
1937                            if let Some(file_finder) = &settings_content.file_finder {
1938                                &file_finder.skip_focus_for_active_in_search
1939                            } else {
1940                                &None
1941                            }
1942                        },
1943                        pick_mut: |settings_content| {
1944                            &mut settings_content
1945                                .file_finder
1946                                .get_or_insert_default()
1947                                .skip_focus_for_active_in_search
1948                        },
1949                    }),
1950                    metadata: None,
1951                    files: USER,
1952                }),
1953                SettingsPageItem::SettingItem(SettingItem {
1954                    title: "Git Status",
1955                    description: "Show the git status in the file finder",
1956                    field: Box::new(SettingField {
1957                        pick: |settings_content| {
1958                            if let Some(file_finder) = &settings_content.file_finder {
1959                                &file_finder.git_status
1960                            } else {
1961                                &None
1962                            }
1963                        },
1964                        pick_mut: |settings_content| {
1965                            &mut settings_content
1966                                .file_finder
1967                                .get_or_insert_default()
1968                                .git_status
1969                        },
1970                    }),
1971                    metadata: None,
1972                    files: USER,
1973                }),
1974                SettingsPageItem::SectionHeader("File Scan"),
1975                SettingsPageItem::SettingItem(SettingItem {
1976                    title: "File Scan Exclusions",
1977                    description: "Files or globs of files that will be excluded by Zed entirely. They will be skipped during file scans, file searches, and not be displayed in the project file tree. Takes precedence over \"File Scan Inclusions\"",
1978                    field: Box::new(
1979                        SettingField {
1980                            pick: |settings_content| {
1981                                &settings_content.project.worktree.file_scan_exclusions
1982                            },
1983                            pick_mut: |settings_content| {
1984                                &mut settings_content.project.worktree.file_scan_exclusions
1985                            },
1986                        }
1987                        .unimplemented(),
1988                    ),
1989                    metadata: None,
1990                    files: USER,
1991                }),
1992                SettingsPageItem::SettingItem(SettingItem {
1993                    title: "File Scan Inclusions",
1994                    description: "Files or globs of files that will be included by Zed, even when ignored by git. This is useful for files that are not tracked by git, but are still important to your project. Note that globs that are overly broad can slow down Zed's file scanning. \"File Scan Exclusions\" takes precedence over these inclusions",
1995                    field: Box::new(
1996                        SettingField {
1997                            pick: |settings_content| {
1998                                &settings_content.project.worktree.file_scan_exclusions
1999                            },
2000                            pick_mut: |settings_content| {
2001                                &mut settings_content.project.worktree.file_scan_exclusions
2002                            },
2003                        }
2004                        .unimplemented(),
2005                    ),
2006                    metadata: None,
2007                    files: USER,
2008                }),
2009                SettingsPageItem::SettingItem(SettingItem {
2010                    title: "Restore File State",
2011                    description: "Restore previous file state when reopening",
2012                    field: Box::new(SettingField {
2013                        pick: |settings_content| &settings_content.workspace.restore_on_file_reopen,
2014                        pick_mut: |settings_content| {
2015                            &mut settings_content.workspace.restore_on_file_reopen
2016                        },
2017                    }),
2018                    metadata: None,
2019                    files: USER,
2020                }),
2021                SettingsPageItem::SettingItem(SettingItem {
2022                    title: "Close on File Delete",
2023                    description: "Automatically close files that have been deleted",
2024                    field: Box::new(SettingField {
2025                        pick: |settings_content| &settings_content.workspace.close_on_file_delete,
2026                        pick_mut: |settings_content| {
2027                            &mut settings_content.workspace.close_on_file_delete
2028                        },
2029                    }),
2030                    metadata: None,
2031                    files: USER,
2032                }),
2033            ],
2034        },
2035        SettingsPage {
2036            title: "Window & Layout",
2037            items: vec![
2038                SettingsPageItem::SectionHeader("Status Bar"),
2039                SettingsPageItem::SettingItem(SettingItem {
2040                    title: "Project Panel Button",
2041                    description: "Show the project panel button in the status bar",
2042                    field: Box::new(SettingField {
2043                        pick: |settings_content| {
2044                            if let Some(project_panel) = &settings_content.project_panel {
2045                                &project_panel.button
2046                            } else {
2047                                &None
2048                            }
2049                        },
2050                        pick_mut: |settings_content| {
2051                            &mut settings_content
2052                                .project_panel
2053                                .get_or_insert_default()
2054                                .button
2055                        },
2056                    }),
2057                    metadata: None,
2058                    files: USER,
2059                }),
2060                SettingsPageItem::SettingItem(SettingItem {
2061                    title: "Active Language Button",
2062                    description: "Show the active language button in the status bar",
2063                    field: Box::new(SettingField {
2064                        pick: |settings_content| {
2065                            if let Some(status_bar) = &settings_content.status_bar {
2066                                &status_bar.active_language_button
2067                            } else {
2068                                &None
2069                            }
2070                        },
2071                        pick_mut: |settings_content| {
2072                            &mut settings_content
2073                                .status_bar
2074                                .get_or_insert_default()
2075                                .active_language_button
2076                        },
2077                    }),
2078                    metadata: None,
2079                    files: USER,
2080                }),
2081                SettingsPageItem::SettingItem(SettingItem {
2082                    title: "Cursor Position Button",
2083                    description: "Show the cursor position button in the status bar",
2084                    field: Box::new(SettingField {
2085                        pick: |settings_content| {
2086                            if let Some(status_bar) = &settings_content.status_bar {
2087                                &status_bar.cursor_position_button
2088                            } else {
2089                                &None
2090                            }
2091                        },
2092                        pick_mut: |settings_content| {
2093                            &mut settings_content
2094                                .status_bar
2095                                .get_or_insert_default()
2096                                .cursor_position_button
2097                        },
2098                    }),
2099                    metadata: None,
2100                    files: USER,
2101                }),
2102                SettingsPageItem::SettingItem(SettingItem {
2103                    title: "Terminal Button",
2104                    description: "Show the terminal button in the status bar",
2105                    field: Box::new(SettingField {
2106                        pick: |settings_content| {
2107                            if let Some(terminal) = &settings_content.terminal {
2108                                &terminal.button
2109                            } else {
2110                                &None
2111                            }
2112                        },
2113                        pick_mut: |settings_content| {
2114                            &mut settings_content.terminal.get_or_insert_default().button
2115                        },
2116                    }),
2117                    metadata: None,
2118                    files: USER,
2119                }),
2120                SettingsPageItem::SettingItem(SettingItem {
2121                    title: "Diagnostics Button",
2122                    description: "Show the project diagnostics button in the status bar",
2123                    field: Box::new(SettingField {
2124                        pick: |settings_content| {
2125                            if let Some(diagnostics) = &settings_content.diagnostics {
2126                                &diagnostics.button
2127                            } else {
2128                                &None
2129                            }
2130                        },
2131                        pick_mut: |settings_content| {
2132                            &mut settings_content.diagnostics.get_or_insert_default().button
2133                        },
2134                    }),
2135                    metadata: None,
2136                    files: USER,
2137                }),
2138                SettingsPageItem::SettingItem(SettingItem {
2139                    title: "Project Search Button",
2140                    description: "Show the project search button in the status bar",
2141                    field: Box::new(SettingField {
2142                        pick: |settings_content| {
2143                            if let Some(search) = &settings_content.editor.search {
2144                                &search.button
2145                            } else {
2146                                &None
2147                            }
2148                        },
2149                        pick_mut: |settings_content| {
2150                            &mut settings_content
2151                                .editor
2152                                .search
2153                                .get_or_insert_default()
2154                                .button
2155                        },
2156                    }),
2157                    metadata: None,
2158                    files: USER,
2159                }),
2160                SettingsPageItem::SettingItem(SettingItem {
2161                    title: "Debugger Button",
2162                    description: "Show the debugger button in the status bar",
2163                    field: Box::new(SettingField {
2164                        pick: |settings_content| {
2165                            if let Some(debugger) = &settings_content.debugger {
2166                                &debugger.button
2167                            } else {
2168                                &None
2169                            }
2170                        },
2171                        pick_mut: |settings_content| {
2172                            &mut settings_content.debugger.get_or_insert_default().button
2173                        },
2174                    }),
2175                    metadata: None,
2176                    files: USER,
2177                }),
2178                SettingsPageItem::SectionHeader("Title Bar"),
2179                SettingsPageItem::SettingItem(SettingItem {
2180                    title: "Show Branch Icon",
2181                    description: "Show the branch icon beside branch switcher in the titlebar",
2182                    field: Box::new(SettingField {
2183                        pick: |settings_content| {
2184                            if let Some(title_bar) = &settings_content.title_bar {
2185                                &title_bar.show_branch_icon
2186                            } else {
2187                                &None
2188                            }
2189                        },
2190                        pick_mut: |settings_content| {
2191                            &mut settings_content
2192                                .title_bar
2193                                .get_or_insert_default()
2194                                .show_branch_icon
2195                        },
2196                    }),
2197                    metadata: None,
2198                    files: USER,
2199                }),
2200                SettingsPageItem::SettingItem(SettingItem {
2201                    title: "Show Branch Name",
2202                    description: "Show the branch name button in the titlebar",
2203                    field: Box::new(SettingField {
2204                        pick: |settings_content| {
2205                            if let Some(title_bar) = &settings_content.title_bar {
2206                                &title_bar.show_branch_name
2207                            } else {
2208                                &None
2209                            }
2210                        },
2211                        pick_mut: |settings_content| {
2212                            &mut settings_content
2213                                .title_bar
2214                                .get_or_insert_default()
2215                                .show_branch_name
2216                        },
2217                    }),
2218                    metadata: None,
2219                    files: USER,
2220                }),
2221                SettingsPageItem::SettingItem(SettingItem {
2222                    title: "Show Project Items",
2223                    description: "Show the project host and name in the titlebar",
2224                    field: Box::new(SettingField {
2225                        pick: |settings_content| {
2226                            if let Some(title_bar) = &settings_content.title_bar {
2227                                &title_bar.show_project_items
2228                            } else {
2229                                &None
2230                            }
2231                        },
2232                        pick_mut: |settings_content| {
2233                            &mut settings_content
2234                                .title_bar
2235                                .get_or_insert_default()
2236                                .show_project_items
2237                        },
2238                    }),
2239                    metadata: None,
2240                    files: USER,
2241                }),
2242                SettingsPageItem::SettingItem(SettingItem {
2243                    title: "Show Onboarding Banner",
2244                    description: "Show banners announcing new features in the titlebar",
2245                    field: Box::new(SettingField {
2246                        pick: |settings_content| {
2247                            if let Some(title_bar) = &settings_content.title_bar {
2248                                &title_bar.show_onboarding_banner
2249                            } else {
2250                                &None
2251                            }
2252                        },
2253                        pick_mut: |settings_content| {
2254                            &mut settings_content
2255                                .title_bar
2256                                .get_or_insert_default()
2257                                .show_onboarding_banner
2258                        },
2259                    }),
2260                    metadata: None,
2261                    files: USER,
2262                }),
2263                SettingsPageItem::SettingItem(SettingItem {
2264                    title: "Show User Picture",
2265                    description: "Show user picture in the titlebar",
2266                    field: Box::new(SettingField {
2267                        pick: |settings_content| {
2268                            if let Some(title_bar) = &settings_content.title_bar {
2269                                &title_bar.show_user_picture
2270                            } else {
2271                                &None
2272                            }
2273                        },
2274                        pick_mut: |settings_content| {
2275                            &mut settings_content
2276                                .title_bar
2277                                .get_or_insert_default()
2278                                .show_user_picture
2279                        },
2280                    }),
2281                    metadata: None,
2282                    files: USER,
2283                }),
2284                SettingsPageItem::SettingItem(SettingItem {
2285                    title: "Show Sign In",
2286                    description: "Show the sign in button in the titlebar",
2287                    field: Box::new(SettingField {
2288                        pick: |settings_content| {
2289                            if let Some(title_bar) = &settings_content.title_bar {
2290                                &title_bar.show_sign_in
2291                            } else {
2292                                &None
2293                            }
2294                        },
2295                        pick_mut: |settings_content| {
2296                            &mut settings_content
2297                                .title_bar
2298                                .get_or_insert_default()
2299                                .show_sign_in
2300                        },
2301                    }),
2302                    metadata: None,
2303                    files: USER,
2304                }),
2305                SettingsPageItem::SettingItem(SettingItem {
2306                    title: "Show Menus",
2307                    description: "Show the menus in the titlebar",
2308                    field: Box::new(SettingField {
2309                        pick: |settings_content| {
2310                            if let Some(title_bar) = &settings_content.title_bar {
2311                                &title_bar.show_menus
2312                            } else {
2313                                &None
2314                            }
2315                        },
2316                        pick_mut: |settings_content| {
2317                            &mut settings_content
2318                                .title_bar
2319                                .get_or_insert_default()
2320                                .show_menus
2321                        },
2322                    }),
2323                    metadata: None,
2324                    files: USER,
2325                }),
2326                SettingsPageItem::SectionHeader("Tab Bar"),
2327                SettingsPageItem::SettingItem(SettingItem {
2328                    title: "Show Tab Bar",
2329                    description: "Show the tab bar in the editor",
2330                    field: Box::new(SettingField {
2331                        pick: |settings_content| {
2332                            if let Some(tab_bar) = &settings_content.tab_bar {
2333                                &tab_bar.show
2334                            } else {
2335                                &None
2336                            }
2337                        },
2338                        pick_mut: |settings_content| {
2339                            &mut settings_content.tab_bar.get_or_insert_default().show
2340                        },
2341                    }),
2342                    metadata: None,
2343                    files: USER,
2344                }),
2345                SettingsPageItem::SettingItem(SettingItem {
2346                    title: "Show Git Status In Tabs",
2347                    description: "Show the Git file status on a tab item",
2348                    field: Box::new(SettingField {
2349                        pick: |settings_content| {
2350                            if let Some(tabs) = &settings_content.tabs {
2351                                &tabs.git_status
2352                            } else {
2353                                &None
2354                            }
2355                        },
2356                        pick_mut: |settings_content| {
2357                            &mut settings_content.tabs.get_or_insert_default().git_status
2358                        },
2359                    }),
2360                    metadata: None,
2361                    files: USER,
2362                }),
2363                SettingsPageItem::SettingItem(SettingItem {
2364                    title: "Show File Icons In Tabs",
2365                    description: "Show the file icon for a tab",
2366                    field: Box::new(SettingField {
2367                        pick: |settings_content| {
2368                            if let Some(tabs) = &settings_content.tabs {
2369                                &tabs.file_icons
2370                            } else {
2371                                &None
2372                            }
2373                        },
2374                        pick_mut: |settings_content| {
2375                            &mut settings_content.tabs.get_or_insert_default().file_icons
2376                        },
2377                    }),
2378                    metadata: None,
2379                    files: USER,
2380                }),
2381                SettingsPageItem::SettingItem(SettingItem {
2382                    title: "Tab Close Position",
2383                    description: "Position of the close button in a tab",
2384                    field: Box::new(SettingField {
2385                        pick: |settings_content| {
2386                            if let Some(tabs) = &settings_content.tabs {
2387                                &tabs.close_position
2388                            } else {
2389                                &None
2390                            }
2391                        },
2392                        pick_mut: |settings_content| {
2393                            &mut settings_content.tabs.get_or_insert_default().close_position
2394                        },
2395                    }),
2396                    metadata: None,
2397                    files: USER,
2398                }),
2399                SettingsPageItem::SettingItem(SettingItem {
2400                    files: USER,
2401                    title: "Maximum Tabs",
2402                    description: "Maximum open tabs in a pane. Will not close an unsaved tab",
2403                    // todo(settings_ui): The default for this value is null and it's use in code
2404                    // is complex, so I'm going to come back to this later
2405                    field: Box::new(
2406                        SettingField {
2407                            pick: |settings_content| &settings_content.workspace.max_tabs,
2408                            pick_mut: |settings_content| &mut settings_content.workspace.max_tabs,
2409                        }
2410                        .unimplemented(),
2411                    ),
2412                    metadata: None,
2413                }),
2414                SettingsPageItem::SettingItem(SettingItem {
2415                    title: "Show Navigation History Buttons",
2416                    description: "Show the navigation history buttons in the tab bar",
2417                    field: Box::new(SettingField {
2418                        pick: |settings_content| {
2419                            if let Some(tab_bar) = &settings_content.tab_bar {
2420                                &tab_bar.show_nav_history_buttons
2421                            } else {
2422                                &None
2423                            }
2424                        },
2425                        pick_mut: |settings_content| {
2426                            &mut settings_content
2427                                .tab_bar
2428                                .get_or_insert_default()
2429                                .show_nav_history_buttons
2430                        },
2431                    }),
2432                    metadata: None,
2433                    files: USER,
2434                }),
2435                SettingsPageItem::SectionHeader("Tab Settings"),
2436                SettingsPageItem::SettingItem(SettingItem {
2437                    title: "Activate On Close",
2438                    description: "What to do after closing the current tab",
2439                    field: Box::new(SettingField {
2440                        pick: |settings_content| {
2441                            if let Some(tabs) = &settings_content.tabs {
2442                                &tabs.activate_on_close
2443                            } else {
2444                                &None
2445                            }
2446                        },
2447                        pick_mut: |settings_content| {
2448                            &mut settings_content
2449                                .tabs
2450                                .get_or_insert_default()
2451                                .activate_on_close
2452                        },
2453                    }),
2454                    metadata: None,
2455                    files: USER,
2456                }),
2457                SettingsPageItem::SettingItem(SettingItem {
2458                    title: "Tab Show Diagnostics",
2459                    description: "Which files containing diagnostic errors/warnings to mark in the tabs",
2460                    field: Box::new(SettingField {
2461                        pick: |settings_content| {
2462                            if let Some(tabs) = &settings_content.tabs {
2463                                &tabs.show_diagnostics
2464                            } else {
2465                                &None
2466                            }
2467                        },
2468                        pick_mut: |settings_content| {
2469                            &mut settings_content
2470                                .tabs
2471                                .get_or_insert_default()
2472                                .show_diagnostics
2473                        },
2474                    }),
2475                    metadata: None,
2476                    files: USER,
2477                }),
2478                SettingsPageItem::SettingItem(SettingItem {
2479                    title: "Show Close Button",
2480                    description: "Controls the appearance behavior of the tab's close button",
2481                    field: Box::new(SettingField {
2482                        pick: |settings_content| {
2483                            if let Some(tabs) = &settings_content.tabs {
2484                                &tabs.show_close_button
2485                            } else {
2486                                &None
2487                            }
2488                        },
2489                        pick_mut: |settings_content| {
2490                            &mut settings_content
2491                                .tabs
2492                                .get_or_insert_default()
2493                                .show_close_button
2494                        },
2495                    }),
2496                    metadata: None,
2497                    files: USER,
2498                }),
2499                SettingsPageItem::SectionHeader("Preview Tabs"),
2500                SettingsPageItem::SettingItem(SettingItem {
2501                    title: "Preview Tabs Enabled",
2502                    description: "Show opened editors as preview tabs",
2503                    field: Box::new(SettingField {
2504                        pick: |settings_content| {
2505                            if let Some(preview_tabs) = &settings_content.preview_tabs {
2506                                &preview_tabs.enabled
2507                            } else {
2508                                &None
2509                            }
2510                        },
2511                        pick_mut: |settings_content| {
2512                            &mut settings_content
2513                                .preview_tabs
2514                                .get_or_insert_default()
2515                                .enabled
2516                        },
2517                    }),
2518                    metadata: None,
2519                    files: USER,
2520                }),
2521                SettingsPageItem::SettingItem(SettingItem {
2522                    title: "Enable Preview From File Finder",
2523                    description: "Whether to open tabs in preview mode when selected from the file finder",
2524                    field: Box::new(SettingField {
2525                        pick: |settings_content| {
2526                            if let Some(preview_tabs) = &settings_content.preview_tabs {
2527                                &preview_tabs.enable_preview_from_file_finder
2528                            } else {
2529                                &None
2530                            }
2531                        },
2532                        pick_mut: |settings_content| {
2533                            &mut settings_content
2534                                .preview_tabs
2535                                .get_or_insert_default()
2536                                .enable_preview_from_file_finder
2537                        },
2538                    }),
2539                    metadata: None,
2540                    files: USER,
2541                }),
2542                SettingsPageItem::SettingItem(SettingItem {
2543                    title: "Enable Preview From Code Navigation",
2544                    description: "Whether a preview tab gets replaced when code navigation is used to navigate away from the tab",
2545                    field: Box::new(SettingField {
2546                        pick: |settings_content| {
2547                            if let Some(preview_tabs) = &settings_content.preview_tabs {
2548                                &preview_tabs.enable_preview_from_code_navigation
2549                            } else {
2550                                &None
2551                            }
2552                        },
2553                        pick_mut: |settings_content| {
2554                            &mut settings_content
2555                                .preview_tabs
2556                                .get_or_insert_default()
2557                                .enable_preview_from_code_navigation
2558                        },
2559                    }),
2560                    metadata: None,
2561                    files: USER,
2562                }),
2563                SettingsPageItem::SectionHeader("Layout"),
2564                SettingsPageItem::SettingItem(SettingItem {
2565                    title: "Bottom Dock Layout",
2566                    description: "Layout mode for the bottom dock",
2567                    field: Box::new(SettingField {
2568                        pick: |settings_content| &settings_content.workspace.bottom_dock_layout,
2569                        pick_mut: |settings_content| {
2570                            &mut settings_content.workspace.bottom_dock_layout
2571                        },
2572                    }),
2573                    metadata: None,
2574                    files: USER,
2575                }),
2576                SettingsPageItem::SettingItem(SettingItem {
2577                    files: USER,
2578                    title: "Centered Layout Left Padding",
2579                    description: "Left padding for centered layout",
2580                    field: Box::new(SettingField {
2581                        pick: |settings_content| {
2582                            if let Some(centered_layout) =
2583                                &settings_content.workspace.centered_layout
2584                            {
2585                                ¢ered_layout.left_padding
2586                            } else {
2587                                &None
2588                            }
2589                        },
2590                        pick_mut: |settings_content| {
2591                            &mut settings_content
2592                                .workspace
2593                                .centered_layout
2594                                .get_or_insert_default()
2595                                .left_padding
2596                        },
2597                    }),
2598                    metadata: None,
2599                }),
2600                SettingsPageItem::SettingItem(SettingItem {
2601                    files: USER,
2602                    title: "Centered Layout Right Padding",
2603                    description: "Right padding for centered layout",
2604                    field: Box::new(SettingField {
2605                        pick: |settings_content| {
2606                            if let Some(centered_layout) =
2607                                &settings_content.workspace.centered_layout
2608                            {
2609                                ¢ered_layout.right_padding
2610                            } else {
2611                                &None
2612                            }
2613                        },
2614                        pick_mut: |settings_content| {
2615                            &mut settings_content
2616                                .workspace
2617                                .centered_layout
2618                                .get_or_insert_default()
2619                                .right_padding
2620                        },
2621                    }),
2622                    metadata: None,
2623                }),
2624                SettingsPageItem::SectionHeader("Window"),
2625                // todo(settings_ui): Should we filter by platform?
2626                SettingsPageItem::SettingItem(SettingItem {
2627                    title: "Use System Window Tabs",
2628                    description: "(macOS only) Whether to allow windows to tab together",
2629                    field: Box::new(SettingField {
2630                        pick: |settings_content| &settings_content.workspace.use_system_window_tabs,
2631                        pick_mut: |settings_content| {
2632                            &mut settings_content.workspace.use_system_window_tabs
2633                        },
2634                    }),
2635                    metadata: None,
2636                    files: USER,
2637                }),
2638                SettingsPageItem::SectionHeader("Pane Modifiers"),
2639                SettingsPageItem::SettingItem(SettingItem {
2640                    title: "Inactive Opacity",
2641                    description: "Opacity of inactive panels (0.0 - 1.0)",
2642                    field: Box::new(SettingField {
2643                        pick: |settings_content| match settings_content
2644                            .workspace
2645                            .active_pane_modifiers
2646                            .as_ref()
2647                        {
2648                            Some(modifiers) => &modifiers.inactive_opacity,
2649                            None => &None,
2650                        },
2651                        pick_mut: |settings_content| {
2652                            &mut settings_content
2653                                .workspace
2654                                .active_pane_modifiers
2655                                .get_or_insert_default()
2656                                .inactive_opacity
2657                        },
2658                    }),
2659                    metadata: None,
2660                    files: USER,
2661                }),
2662                SettingsPageItem::SettingItem(SettingItem {
2663                    title: "Border Size",
2664                    description: "Size of the border surrounding the active pane",
2665                    field: Box::new(SettingField {
2666                        pick: |settings_content| match settings_content
2667                            .workspace
2668                            .active_pane_modifiers
2669                            .as_ref()
2670                        {
2671                            Some(modifiers) => &modifiers.border_size,
2672                            None => &None,
2673                        },
2674                        pick_mut: |settings_content| {
2675                            &mut settings_content
2676                                .workspace
2677                                .active_pane_modifiers
2678                                .get_or_insert_default()
2679                                .border_size
2680                        },
2681                    }),
2682                    metadata: None,
2683                    files: USER,
2684                }),
2685                SettingsPageItem::SettingItem(SettingItem {
2686                    title: "Zoomed Padding",
2687                    description: "Show padding for zoomed panes",
2688                    field: Box::new(SettingField {
2689                        pick: |settings_content| &settings_content.workspace.zoomed_padding,
2690                        pick_mut: |settings_content| &mut settings_content.workspace.zoomed_padding,
2691                    }),
2692                    metadata: None,
2693                    files: USER,
2694                }),
2695                SettingsPageItem::SectionHeader("Pane Split Direction"),
2696                SettingsPageItem::SettingItem(SettingItem {
2697                    title: "Vertical Split Direction",
2698                    description: "Direction to split vertically",
2699                    field: Box::new(SettingField {
2700                        pick: |settings_content| {
2701                            &settings_content.workspace.pane_split_direction_vertical
2702                        },
2703                        pick_mut: |settings_content| {
2704                            &mut settings_content.workspace.pane_split_direction_vertical
2705                        },
2706                    }),
2707                    metadata: None,
2708                    files: USER,
2709                }),
2710                SettingsPageItem::SettingItem(SettingItem {
2711                    title: "Horizontal Split Direction",
2712                    description: "Direction to split horizontally",
2713                    field: Box::new(SettingField {
2714                        pick: |settings_content| {
2715                            &settings_content.workspace.pane_split_direction_horizontal
2716                        },
2717                        pick_mut: |settings_content| {
2718                            &mut settings_content.workspace.pane_split_direction_horizontal
2719                        },
2720                    }),
2721                    metadata: None,
2722                    files: USER,
2723                }),
2724            ],
2725        },
2726        SettingsPage {
2727            title: "Panels",
2728            items: vec![
2729                SettingsPageItem::SectionHeader("Project Panel"),
2730                SettingsPageItem::SettingItem(SettingItem {
2731                    title: "Project Panel Dock",
2732                    description: "Where to dock the project panel",
2733                    field: Box::new(SettingField {
2734                        pick: |settings_content| {
2735                            if let Some(project_panel) = &settings_content.project_panel {
2736                                &project_panel.dock
2737                            } else {
2738                                &None
2739                            }
2740                        },
2741                        pick_mut: |settings_content| {
2742                            &mut settings_content.project_panel.get_or_insert_default().dock
2743                        },
2744                    }),
2745                    metadata: None,
2746                    files: USER,
2747                }),
2748                SettingsPageItem::SettingItem(SettingItem {
2749                    title: "Project Panel Default Width",
2750                    description: "Default width of the project panel in pixels",
2751                    field: Box::new(SettingField {
2752                        pick: |settings_content| {
2753                            if let Some(project_panel) = &settings_content.project_panel {
2754                                &project_panel.default_width
2755                            } else {
2756                                &None
2757                            }
2758                        },
2759                        pick_mut: |settings_content| {
2760                            &mut settings_content
2761                                .project_panel
2762                                .get_or_insert_default()
2763                                .default_width
2764                        },
2765                    }),
2766                    metadata: None,
2767                    files: USER,
2768                }),
2769                SettingsPageItem::SettingItem(SettingItem {
2770                    title: "Hide .gitignore",
2771                    description: "Whether to hide the gitignore entries in the project panel",
2772                    field: Box::new(SettingField {
2773                        pick: |settings_content| {
2774                            if let Some(project_panel) = &settings_content.project_panel {
2775                                &project_panel.hide_gitignore
2776                            } else {
2777                                &None
2778                            }
2779                        },
2780                        pick_mut: |settings_content| {
2781                            &mut settings_content
2782                                .project_panel
2783                                .get_or_insert_default()
2784                                .hide_gitignore
2785                        },
2786                    }),
2787                    metadata: None,
2788                    files: USER,
2789                }),
2790                SettingsPageItem::SettingItem(SettingItem {
2791                    title: "Entry Spacing",
2792                    description: "Spacing between worktree entries in the project panel",
2793                    field: Box::new(SettingField {
2794                        pick: |settings_content| {
2795                            if let Some(project_panel) = &settings_content.project_panel {
2796                                &project_panel.entry_spacing
2797                            } else {
2798                                &None
2799                            }
2800                        },
2801                        pick_mut: |settings_content| {
2802                            &mut settings_content
2803                                .project_panel
2804                                .get_or_insert_default()
2805                                .entry_spacing
2806                        },
2807                    }),
2808                    metadata: None,
2809                    files: USER,
2810                }),
2811                SettingsPageItem::SettingItem(SettingItem {
2812                    title: "File Icons",
2813                    description: "Show file icons in the project panel",
2814                    field: Box::new(SettingField {
2815                        pick: |settings_content| {
2816                            if let Some(project_panel) = &settings_content.project_panel {
2817                                &project_panel.file_icons
2818                            } else {
2819                                &None
2820                            }
2821                        },
2822                        pick_mut: |settings_content| {
2823                            &mut settings_content
2824                                .project_panel
2825                                .get_or_insert_default()
2826                                .file_icons
2827                        },
2828                    }),
2829                    metadata: None,
2830                    files: USER,
2831                }),
2832                SettingsPageItem::SettingItem(SettingItem {
2833                    title: "Folder Icons",
2834                    description: "Whether to show folder icons or chevrons for directories in the project panel",
2835                    field: Box::new(SettingField {
2836                        pick: |settings_content| {
2837                            if let Some(project_panel) = &settings_content.project_panel {
2838                                &project_panel.folder_icons
2839                            } else {
2840                                &None
2841                            }
2842                        },
2843                        pick_mut: |settings_content| {
2844                            &mut settings_content
2845                                .project_panel
2846                                .get_or_insert_default()
2847                                .folder_icons
2848                        },
2849                    }),
2850                    metadata: None,
2851                    files: USER,
2852                }),
2853                SettingsPageItem::SettingItem(SettingItem {
2854                    title: "Git Status",
2855                    description: "Show the git status in the project panel",
2856                    field: Box::new(SettingField {
2857                        pick: |settings_content| {
2858                            if let Some(project_panel) = &settings_content.project_panel {
2859                                &project_panel.git_status
2860                            } else {
2861                                &None
2862                            }
2863                        },
2864                        pick_mut: |settings_content| {
2865                            &mut settings_content
2866                                .project_panel
2867                                .get_or_insert_default()
2868                                .git_status
2869                        },
2870                    }),
2871                    metadata: None,
2872                    files: USER,
2873                }),
2874                SettingsPageItem::SettingItem(SettingItem {
2875                    title: "Indent Size",
2876                    description: "Amount of indentation for nested items",
2877                    field: Box::new(SettingField {
2878                        pick: |settings_content| {
2879                            if let Some(project_panel) = &settings_content.project_panel {
2880                                &project_panel.indent_size
2881                            } else {
2882                                &None
2883                            }
2884                        },
2885                        pick_mut: |settings_content| {
2886                            &mut settings_content
2887                                .project_panel
2888                                .get_or_insert_default()
2889                                .indent_size
2890                        },
2891                    }),
2892                    metadata: None,
2893                    files: USER,
2894                }),
2895                SettingsPageItem::SettingItem(SettingItem {
2896                    title: "Auto Reveal Entries",
2897                    description: "Whether to reveal entries in the project panel automatically when a corresponding project entry becomes active",
2898                    field: Box::new(SettingField {
2899                        pick: |settings_content| {
2900                            if let Some(project_panel) = &settings_content.project_panel {
2901                                &project_panel.auto_reveal_entries
2902                            } else {
2903                                &None
2904                            }
2905                        },
2906                        pick_mut: |settings_content| {
2907                            &mut settings_content
2908                                .project_panel
2909                                .get_or_insert_default()
2910                                .auto_reveal_entries
2911                        },
2912                    }),
2913                    metadata: None,
2914                    files: USER,
2915                }),
2916                SettingsPageItem::SettingItem(SettingItem {
2917                    title: "Starts Open",
2918                    description: "Whether the project panel should open on startup",
2919                    field: Box::new(SettingField {
2920                        pick: |settings_content| {
2921                            if let Some(project_panel) = &settings_content.project_panel {
2922                                &project_panel.starts_open
2923                            } else {
2924                                &None
2925                            }
2926                        },
2927                        pick_mut: |settings_content| {
2928                            &mut settings_content
2929                                .project_panel
2930                                .get_or_insert_default()
2931                                .starts_open
2932                        },
2933                    }),
2934                    metadata: None,
2935                    files: USER,
2936                }),
2937                SettingsPageItem::SettingItem(SettingItem {
2938                    title: "Auto Fold Directories",
2939                    description: "Whether to fold directories automatically and show compact folders when a directory has only one subdirectory inside",
2940                    field: Box::new(SettingField {
2941                        pick: |settings_content| {
2942                            if let Some(project_panel) = &settings_content.project_panel {
2943                                &project_panel.auto_fold_dirs
2944                            } else {
2945                                &None
2946                            }
2947                        },
2948                        pick_mut: |settings_content| {
2949                            &mut settings_content
2950                                .project_panel
2951                                .get_or_insert_default()
2952                                .auto_fold_dirs
2953                        },
2954                    }),
2955                    metadata: None,
2956                    files: USER,
2957                }),
2958                SettingsPageItem::SettingItem(SettingItem {
2959                    title: "Scrollbar Show",
2960                    description: "Show the scrollbar in the project panel",
2961                    field: Box::new(SettingField {
2962                        pick: |settings_content| {
2963                            if let Some(project_panel) = &settings_content.project_panel
2964                                && let Some(scrollbar) = &project_panel.scrollbar
2965                                && scrollbar.show.is_some()
2966                            {
2967                                &scrollbar.show
2968                            } else if let Some(scrollbar) = &settings_content.editor.scrollbar {
2969                                &scrollbar.show
2970                            } else {
2971                                &None
2972                            }
2973                        },
2974                        pick_mut: |settings_content| {
2975                            &mut settings_content
2976                                .project_panel
2977                                .get_or_insert_default()
2978                                .scrollbar
2979                                .get_or_insert_default()
2980                                .show
2981                        },
2982                    }),
2983                    metadata: None,
2984                    files: USER,
2985                }),
2986                SettingsPageItem::SettingItem(SettingItem {
2987                    title: "Show Diagnostics",
2988                    description: "Which files containing diagnostic errors/warnings to mark in the project panel",
2989                    field: Box::new(SettingField {
2990                        pick: |settings_content| {
2991                            if let Some(project_panel) = &settings_content.project_panel {
2992                                &project_panel.show_diagnostics
2993                            } else {
2994                                &None
2995                            }
2996                        },
2997                        pick_mut: |settings_content| {
2998                            &mut settings_content
2999                                .project_panel
3000                                .get_or_insert_default()
3001                                .show_diagnostics
3002                        },
3003                    }),
3004                    metadata: None,
3005                    files: USER,
3006                }),
3007                SettingsPageItem::SettingItem(SettingItem {
3008                    title: "Sticky Scroll",
3009                    description: "Whether to stick parent directories at top of the project panel",
3010                    field: Box::new(SettingField {
3011                        pick: |settings_content| {
3012                            if let Some(project_panel) = &settings_content.project_panel {
3013                                &project_panel.sticky_scroll
3014                            } else {
3015                                &None
3016                            }
3017                        },
3018                        pick_mut: |settings_content| {
3019                            &mut settings_content
3020                                .project_panel
3021                                .get_or_insert_default()
3022                                .sticky_scroll
3023                        },
3024                    }),
3025                    metadata: None,
3026                    files: USER,
3027                }),
3028                SettingsPageItem::SettingItem(SettingItem {
3029                    files: USER,
3030                    title: "Indent Guides Show",
3031                    description: "Show indent guides in the project panel",
3032                    field: Box::new(
3033                        SettingField {
3034                            pick: |settings_content| {
3035                                if let Some(project_panel) = &settings_content.project_panel {
3036                                    if let Some(indent_guides) = &project_panel.indent_guides {
3037                                        &indent_guides.show
3038                                    } else {
3039                                        &None
3040                                    }
3041                                } else {
3042                                    &None
3043                                }
3044                            },
3045                            pick_mut: |settings_content| {
3046                                &mut settings_content
3047                                    .project_panel
3048                                    .get_or_insert_default()
3049                                    .indent_guides
3050                                    .get_or_insert_default()
3051                                    .show
3052                            },
3053                        }
3054                        .unimplemented(),
3055                    ),
3056                    metadata: None,
3057                }),
3058                SettingsPageItem::SettingItem(SettingItem {
3059                    title: "Drag and Drop",
3060                    description: "Whether to enable drag-and-drop operations in the project panel",
3061                    field: Box::new(SettingField {
3062                        pick: |settings_content| {
3063                            if let Some(project_panel) = &settings_content.project_panel {
3064                                &project_panel.drag_and_drop
3065                            } else {
3066                                &None
3067                            }
3068                        },
3069                        pick_mut: |settings_content| {
3070                            &mut settings_content
3071                                .project_panel
3072                                .get_or_insert_default()
3073                                .drag_and_drop
3074                        },
3075                    }),
3076                    metadata: None,
3077                    files: USER,
3078                }),
3079                SettingsPageItem::SettingItem(SettingItem {
3080                    title: "Hide Root",
3081                    description: "Whether to hide the root entry when only one folder is open in the window",
3082                    field: Box::new(SettingField {
3083                        pick: |settings_content| {
3084                            if let Some(project_panel) = &settings_content.project_panel {
3085                                &project_panel.hide_root
3086                            } else {
3087                                &None
3088                            }
3089                        },
3090                        pick_mut: |settings_content| {
3091                            &mut settings_content
3092                                .project_panel
3093                                .get_or_insert_default()
3094                                .hide_root
3095                        },
3096                    }),
3097                    metadata: None,
3098                    files: USER,
3099                }),
3100                SettingsPageItem::SettingItem(SettingItem {
3101                    title: "Hide Hidden",
3102                    description: "Whether to hide the hidden entries in the project panel",
3103                    field: Box::new(SettingField {
3104                        pick: |settings_content| {
3105                            if let Some(project_panel) = &settings_content.project_panel {
3106                                &project_panel.hide_hidden
3107                            } else {
3108                                &None
3109                            }
3110                        },
3111                        pick_mut: |settings_content| {
3112                            &mut settings_content
3113                                .project_panel
3114                                .get_or_insert_default()
3115                                .hide_hidden
3116                        },
3117                    }),
3118                    metadata: None,
3119                    files: USER,
3120                }),
3121                SettingsPageItem::SectionHeader("Terminal Panel"),
3122                SettingsPageItem::SettingItem(SettingItem {
3123                    title: "Terminal Dock",
3124                    description: "Where to dock the terminal panel",
3125                    field: Box::new(SettingField {
3126                        pick: |settings_content| {
3127                            if let Some(terminal) = &settings_content.terminal {
3128                                &terminal.dock
3129                            } else {
3130                                &None
3131                            }
3132                        },
3133                        pick_mut: |settings_content| {
3134                            &mut settings_content.terminal.get_or_insert_default().dock
3135                        },
3136                    }),
3137                    metadata: None,
3138                    files: USER,
3139                }),
3140                SettingsPageItem::SectionHeader("Outline Panel"),
3141                SettingsPageItem::SettingItem(SettingItem {
3142                    title: "Outline Panel Button",
3143                    description: "Show the outline panel button in the status bar",
3144                    field: Box::new(SettingField {
3145                        pick: |settings_content| {
3146                            if let Some(outline_panel) = &settings_content.outline_panel {
3147                                &outline_panel.button
3148                            } else {
3149                                &None
3150                            }
3151                        },
3152                        pick_mut: |settings_content| {
3153                            &mut settings_content
3154                                .outline_panel
3155                                .get_or_insert_default()
3156                                .button
3157                        },
3158                    }),
3159                    metadata: None,
3160                    files: USER,
3161                }),
3162                SettingsPageItem::SettingItem(SettingItem {
3163                    title: "Outline Panel Dock",
3164                    description: "Where to dock the outline panel",
3165                    field: Box::new(SettingField {
3166                        pick: |settings_content| {
3167                            if let Some(outline_panel) = &settings_content.outline_panel {
3168                                &outline_panel.dock
3169                            } else {
3170                                &None
3171                            }
3172                        },
3173                        pick_mut: |settings_content| {
3174                            &mut settings_content.outline_panel.get_or_insert_default().dock
3175                        },
3176                    }),
3177                    metadata: None,
3178                    files: USER,
3179                }),
3180                SettingsPageItem::SettingItem(SettingItem {
3181                    title: "Outline Panel Default Width",
3182                    description: "Default width of the outline panel in pixels",
3183                    field: Box::new(SettingField {
3184                        pick: |settings_content| {
3185                            if let Some(outline_panel) = &settings_content.outline_panel {
3186                                &outline_panel.default_width
3187                            } else {
3188                                &None
3189                            }
3190                        },
3191                        pick_mut: |settings_content| {
3192                            &mut settings_content
3193                                .outline_panel
3194                                .get_or_insert_default()
3195                                .default_width
3196                        },
3197                    }),
3198                    metadata: None,
3199                    files: USER,
3200                }),
3201                SettingsPageItem::SettingItem(SettingItem {
3202                    title: "File Icons",
3203                    description: "Show file icons in the outline panel",
3204                    field: Box::new(SettingField {
3205                        pick: |settings_content| {
3206                            if let Some(outline_panel) = &settings_content.outline_panel {
3207                                &outline_panel.file_icons
3208                            } else {
3209                                &None
3210                            }
3211                        },
3212                        pick_mut: |settings_content| {
3213                            &mut settings_content
3214                                .outline_panel
3215                                .get_or_insert_default()
3216                                .file_icons
3217                        },
3218                    }),
3219                    metadata: None,
3220                    files: USER,
3221                }),
3222                SettingsPageItem::SettingItem(SettingItem {
3223                    title: "Folder Icons",
3224                    description: "Whether to show folder icons or chevrons for directories in the outline panel",
3225                    field: Box::new(SettingField {
3226                        pick: |settings_content| {
3227                            if let Some(outline_panel) = &settings_content.outline_panel {
3228                                &outline_panel.folder_icons
3229                            } else {
3230                                &None
3231                            }
3232                        },
3233                        pick_mut: |settings_content| {
3234                            &mut settings_content
3235                                .outline_panel
3236                                .get_or_insert_default()
3237                                .folder_icons
3238                        },
3239                    }),
3240                    metadata: None,
3241                    files: USER,
3242                }),
3243                SettingsPageItem::SettingItem(SettingItem {
3244                    title: "Git Status",
3245                    description: "Show the git status in the outline panel",
3246                    field: Box::new(SettingField {
3247                        pick: |settings_content| {
3248                            if let Some(outline_panel) = &settings_content.outline_panel {
3249                                &outline_panel.git_status
3250                            } else {
3251                                &None
3252                            }
3253                        },
3254                        pick_mut: |settings_content| {
3255                            &mut settings_content
3256                                .outline_panel
3257                                .get_or_insert_default()
3258                                .git_status
3259                        },
3260                    }),
3261                    metadata: None,
3262                    files: USER,
3263                }),
3264                SettingsPageItem::SettingItem(SettingItem {
3265                    title: "Indent Size",
3266                    description: "Amount of indentation for nested items",
3267                    field: Box::new(SettingField {
3268                        pick: |settings_content| {
3269                            if let Some(outline_panel) = &settings_content.outline_panel {
3270                                &outline_panel.indent_size
3271                            } else {
3272                                &None
3273                            }
3274                        },
3275                        pick_mut: |settings_content| {
3276                            &mut settings_content
3277                                .outline_panel
3278                                .get_or_insert_default()
3279                                .indent_size
3280                        },
3281                    }),
3282                    metadata: None,
3283                    files: USER,
3284                }),
3285                SettingsPageItem::SettingItem(SettingItem {
3286                    title: "Auto Reveal Entries",
3287                    description: "Whether to reveal when a corresponding outline entry becomes active",
3288                    field: Box::new(SettingField {
3289                        pick: |settings_content| {
3290                            if let Some(outline_panel) = &settings_content.outline_panel {
3291                                &outline_panel.auto_reveal_entries
3292                            } else {
3293                                &None
3294                            }
3295                        },
3296                        pick_mut: |settings_content| {
3297                            &mut settings_content
3298                                .outline_panel
3299                                .get_or_insert_default()
3300                                .auto_reveal_entries
3301                        },
3302                    }),
3303                    metadata: None,
3304                    files: USER,
3305                }),
3306                SettingsPageItem::SettingItem(SettingItem {
3307                    title: "Auto Fold Directories",
3308                    description: "Whether to fold directories automatically when a directory contains only one subdirectory",
3309                    field: Box::new(SettingField {
3310                        pick: |settings_content| {
3311                            if let Some(outline_panel) = &settings_content.outline_panel {
3312                                &outline_panel.auto_fold_dirs
3313                            } else {
3314                                &None
3315                            }
3316                        },
3317                        pick_mut: |settings_content| {
3318                            &mut settings_content
3319                                .outline_panel
3320                                .get_or_insert_default()
3321                                .auto_fold_dirs
3322                        },
3323                    }),
3324                    metadata: None,
3325                    files: USER,
3326                }),
3327                SettingsPageItem::SettingItem(SettingItem {
3328                    files: USER,
3329                    title: "Indent Guides Show",
3330                    description: "When to show indent guides in the outline panel",
3331                    field: Box::new(
3332                        SettingField {
3333                            pick: |settings_content| {
3334                                if let Some(outline_panel) = &settings_content.outline_panel {
3335                                    if let Some(indent_guides) = &outline_panel.indent_guides {
3336                                        &indent_guides.show
3337                                    } else {
3338                                        &None
3339                                    }
3340                                } else {
3341                                    &None
3342                                }
3343                            },
3344                            pick_mut: |settings_content| {
3345                                &mut settings_content
3346                                    .outline_panel
3347                                    .get_or_insert_default()
3348                                    .indent_guides
3349                                    .get_or_insert_default()
3350                                    .show
3351                            },
3352                        }
3353                        .unimplemented(),
3354                    ),
3355                    metadata: None,
3356                }),
3357                SettingsPageItem::SectionHeader("Git Panel"),
3358                SettingsPageItem::SettingItem(SettingItem {
3359                    title: "Git Panel Button",
3360                    description: "Show the Git panel button in the status bar",
3361                    field: Box::new(SettingField {
3362                        pick: |settings_content| {
3363                            if let Some(git_panel) = &settings_content.git_panel {
3364                                &git_panel.button
3365                            } else {
3366                                &None
3367                            }
3368                        },
3369                        pick_mut: |settings_content| {
3370                            &mut settings_content.git_panel.get_or_insert_default().button
3371                        },
3372                    }),
3373                    metadata: None,
3374                    files: USER,
3375                }),
3376                SettingsPageItem::SettingItem(SettingItem {
3377                    title: "Git Panel Dock",
3378                    description: "Where to dock the Git panel",
3379                    field: Box::new(SettingField {
3380                        pick: |settings_content| {
3381                            if let Some(git_panel) = &settings_content.git_panel {
3382                                &git_panel.dock
3383                            } else {
3384                                &None
3385                            }
3386                        },
3387                        pick_mut: |settings_content| {
3388                            &mut settings_content.git_panel.get_or_insert_default().dock
3389                        },
3390                    }),
3391                    metadata: None,
3392                    files: USER,
3393                }),
3394                SettingsPageItem::SettingItem(SettingItem {
3395                    title: "Git Panel Default Width",
3396                    description: "Default width of the Git panel in pixels",
3397                    field: Box::new(SettingField {
3398                        pick: |settings_content| {
3399                            if let Some(git_panel) = &settings_content.git_panel {
3400                                &git_panel.default_width
3401                            } else {
3402                                &None
3403                            }
3404                        },
3405                        pick_mut: |settings_content| {
3406                            &mut settings_content
3407                                .git_panel
3408                                .get_or_insert_default()
3409                                .default_width
3410                        },
3411                    }),
3412                    metadata: None,
3413                    files: USER,
3414                }),
3415                SettingsPageItem::SettingItem(SettingItem {
3416                    title: "Git Panel Status Style",
3417                    description: "How entry statuses are displayed",
3418                    field: Box::new(SettingField {
3419                        pick: |settings_content| {
3420                            if let Some(git_panel) = &settings_content.git_panel {
3421                                &git_panel.status_style
3422                            } else {
3423                                &None
3424                            }
3425                        },
3426                        pick_mut: |settings_content| {
3427                            &mut settings_content
3428                                .git_panel
3429                                .get_or_insert_default()
3430                                .status_style
3431                        },
3432                    }),
3433                    metadata: None,
3434                    files: USER,
3435                }),
3436                SettingsPageItem::SettingItem(SettingItem {
3437                    title: "Fallback Branch Name",
3438                    description: "Default branch name will be when init.defaultBranch is not set in git",
3439                    field: Box::new(SettingField {
3440                        pick: |settings_content| {
3441                            if let Some(git_panel) = &settings_content.git_panel {
3442                                &git_panel.fallback_branch_name
3443                            } else {
3444                                &None
3445                            }
3446                        },
3447                        pick_mut: |settings_content| {
3448                            &mut settings_content
3449                                .git_panel
3450                                .get_or_insert_default()
3451                                .fallback_branch_name
3452                        },
3453                    }),
3454                    metadata: None,
3455                    files: USER,
3456                }),
3457                SettingsPageItem::SettingItem(SettingItem {
3458                    title: "Sort By Path",
3459                    description: "Enable to sort entries in the panel by path, disable to sort by status",
3460                    field: Box::new(SettingField {
3461                        pick: |settings_content| {
3462                            if let Some(git_panel) = &settings_content.git_panel {
3463                                &git_panel.sort_by_path
3464                            } else {
3465                                &None
3466                            }
3467                        },
3468                        pick_mut: |settings_content| {
3469                            &mut settings_content
3470                                .git_panel
3471                                .get_or_insert_default()
3472                                .sort_by_path
3473                        },
3474                    }),
3475                    metadata: None,
3476                    files: USER,
3477                }),
3478                SettingsPageItem::SettingItem(SettingItem {
3479                    title: "Collapse Untracked Diff",
3480                    description: "Whether to collapse untracked files in the diff panel",
3481                    field: Box::new(SettingField {
3482                        pick: |settings_content| {
3483                            if let Some(git_panel) = &settings_content.git_panel {
3484                                &git_panel.collapse_untracked_diff
3485                            } else {
3486                                &None
3487                            }
3488                        },
3489                        pick_mut: |settings_content| {
3490                            &mut settings_content
3491                                .git_panel
3492                                .get_or_insert_default()
3493                                .collapse_untracked_diff
3494                        },
3495                    }),
3496                    metadata: None,
3497                    files: USER,
3498                }),
3499                SettingsPageItem::SettingItem(SettingItem {
3500                    title: "Scroll Bar",
3501                    description: "How and when the scrollbar should be displayed",
3502                    field: Box::new(SettingField {
3503                        pick: |settings_content| match &settings_content.git_panel {
3504                            Some(settings::GitPanelSettingsContent {
3505                                scrollbar: Some(scrollbar),
3506                                ..
3507                            }) => &scrollbar.show,
3508                            _ => &None,
3509                        },
3510                        pick_mut: |settings_content| {
3511                            &mut settings_content
3512                                .git_panel
3513                                .get_or_insert_default()
3514                                .scrollbar
3515                                .get_or_insert_default()
3516                                .show
3517                        },
3518                    }),
3519                    metadata: None,
3520                    files: USER,
3521                }),
3522                SettingsPageItem::SectionHeader("Debugger Panel"),
3523                SettingsPageItem::SettingItem(SettingItem {
3524                    title: "Debugger Panel Dock",
3525                    description: "The dock position of the debug panel",
3526                    field: Box::new(SettingField {
3527                        pick: |settings_content| {
3528                            if let Some(debugger) = &settings_content.debugger {
3529                                &debugger.dock
3530                            } else {
3531                                &None
3532                            }
3533                        },
3534                        pick_mut: |settings_content| {
3535                            &mut settings_content.debugger.get_or_insert_default().dock
3536                        },
3537                    }),
3538                    metadata: None,
3539                    files: USER,
3540                }),
3541                SettingsPageItem::SectionHeader("Notification Panel"),
3542                SettingsPageItem::SettingItem(SettingItem {
3543                    title: "Notification Panel Button",
3544                    description: "Show the notification panel button in the status bar",
3545                    field: Box::new(SettingField {
3546                        pick: |settings_content| {
3547                            if let Some(notification_panel) = &settings_content.notification_panel {
3548                                ¬ification_panel.button
3549                            } else {
3550                                &None
3551                            }
3552                        },
3553                        pick_mut: |settings_content| {
3554                            &mut settings_content
3555                                .notification_panel
3556                                .get_or_insert_default()
3557                                .button
3558                        },
3559                    }),
3560                    metadata: None,
3561                    files: USER,
3562                }),
3563                SettingsPageItem::SettingItem(SettingItem {
3564                    title: "Notification Panel Dock",
3565                    description: "Where to dock the notification panel",
3566                    field: Box::new(SettingField {
3567                        pick: |settings_content| {
3568                            if let Some(notification_panel) = &settings_content.notification_panel {
3569                                ¬ification_panel.dock
3570                            } else {
3571                                &None
3572                            }
3573                        },
3574                        pick_mut: |settings_content| {
3575                            &mut settings_content
3576                                .notification_panel
3577                                .get_or_insert_default()
3578                                .dock
3579                        },
3580                    }),
3581                    metadata: None,
3582                    files: USER,
3583                }),
3584                SettingsPageItem::SettingItem(SettingItem {
3585                    title: "Notification Panel Default Width",
3586                    description: "Default width of the notification panel in pixels",
3587                    field: Box::new(SettingField {
3588                        pick: |settings_content| {
3589                            if let Some(notification_panel) = &settings_content.notification_panel {
3590                                ¬ification_panel.default_width
3591                            } else {
3592                                &None
3593                            }
3594                        },
3595                        pick_mut: |settings_content| {
3596                            &mut settings_content
3597                                .notification_panel
3598                                .get_or_insert_default()
3599                                .default_width
3600                        },
3601                    }),
3602                    metadata: None,
3603                    files: USER,
3604                }),
3605                SettingsPageItem::SectionHeader("Collaboration Panel"),
3606                SettingsPageItem::SettingItem(SettingItem {
3607                    title: "Collaboration Panel Button",
3608                    description: "Show the collaboration panel button in the status bar",
3609                    field: Box::new(SettingField {
3610                        pick: |settings_content| {
3611                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
3612                            {
3613                                &collaboration_panel.button
3614                            } else {
3615                                &None
3616                            }
3617                        },
3618                        pick_mut: |settings_content| {
3619                            &mut settings_content
3620                                .collaboration_panel
3621                                .get_or_insert_default()
3622                                .button
3623                        },
3624                    }),
3625                    metadata: None,
3626                    files: USER,
3627                }),
3628                SettingsPageItem::SettingItem(SettingItem {
3629                    title: "Collaboration Panel Dock",
3630                    description: "Where to dock the collaboration panel",
3631                    field: Box::new(SettingField {
3632                        pick: |settings_content| {
3633                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
3634                            {
3635                                &collaboration_panel.dock
3636                            } else {
3637                                &None
3638                            }
3639                        },
3640                        pick_mut: |settings_content| {
3641                            &mut settings_content
3642                                .collaboration_panel
3643                                .get_or_insert_default()
3644                                .dock
3645                        },
3646                    }),
3647                    metadata: None,
3648                    files: USER,
3649                }),
3650                SettingsPageItem::SettingItem(SettingItem {
3651                    title: "Collaboration Panel Default Width",
3652                    description: "Default width of the collaboration panel in pixels",
3653                    field: Box::new(SettingField {
3654                        pick: |settings_content| {
3655                            if let Some(collaboration_panel) = &settings_content.collaboration_panel
3656                            {
3657                                &collaboration_panel.default_width
3658                            } else {
3659                                &None
3660                            }
3661                        },
3662                        pick_mut: |settings_content| {
3663                            &mut settings_content
3664                                .collaboration_panel
3665                                .get_or_insert_default()
3666                                .default_width
3667                        },
3668                    }),
3669                    metadata: None,
3670                    files: USER,
3671                }),
3672                SettingsPageItem::SectionHeader("Agent Panel"),
3673                SettingsPageItem::SettingItem(SettingItem {
3674                    title: "Agent Panel Button",
3675                    description: "Whether to show the agent panel button in the status bar",
3676                    field: Box::new(SettingField {
3677                        pick: |settings_content| {
3678                            if let Some(agent) = &settings_content.agent {
3679                                &agent.button
3680                            } else {
3681                                &None
3682                            }
3683                        },
3684                        pick_mut: |settings_content| {
3685                            &mut settings_content.agent.get_or_insert_default().button
3686                        },
3687                    }),
3688                    metadata: None,
3689                    files: USER,
3690                }),
3691                SettingsPageItem::SettingItem(SettingItem {
3692                    title: "Agent Panel Dock",
3693                    description: "Where to dock the agent panel.",
3694                    field: Box::new(SettingField {
3695                        pick: |settings_content| {
3696                            if let Some(agent) = &settings_content.agent {
3697                                &agent.dock
3698                            } else {
3699                                &None
3700                            }
3701                        },
3702                        pick_mut: |settings_content| {
3703                            &mut settings_content.agent.get_or_insert_default().dock
3704                        },
3705                    }),
3706                    metadata: None,
3707                    files: USER,
3708                }),
3709                SettingsPageItem::SettingItem(SettingItem {
3710                    title: "Agent Panel Default Width",
3711                    description: "Default width when the agent panel is docked to the left or right",
3712                    field: Box::new(SettingField {
3713                        pick: |settings_content| {
3714                            if let Some(agent) = &settings_content.agent {
3715                                &agent.default_width
3716                            } else {
3717                                &None
3718                            }
3719                        },
3720                        pick_mut: |settings_content| {
3721                            &mut settings_content.agent.get_or_insert_default().default_width
3722                        },
3723                    }),
3724                    metadata: None,
3725                    files: USER,
3726                }),
3727                SettingsPageItem::SettingItem(SettingItem {
3728                    title: "Agent Panel Default Height",
3729                    description: "Default height when the agent panel is docked to the bottom",
3730                    field: Box::new(SettingField {
3731                        pick: |settings_content| {
3732                            if let Some(agent) = &settings_content.agent {
3733                                &agent.default_height
3734                            } else {
3735                                &None
3736                            }
3737                        },
3738                        pick_mut: |settings_content| {
3739                            &mut settings_content
3740                                .agent
3741                                .get_or_insert_default()
3742                                .default_height
3743                        },
3744                    }),
3745                    metadata: None,
3746                    files: USER,
3747                }),
3748            ],
3749        },
3750        SettingsPage {
3751            title: "Debugger",
3752            items: vec![
3753                SettingsPageItem::SectionHeader("General"),
3754                SettingsPageItem::SettingItem(SettingItem {
3755                    title: "Stepping Granularity",
3756                    description: "Determines the stepping granularity for debug operations",
3757                    field: Box::new(SettingField {
3758                        pick: |settings_content| {
3759                            if let Some(debugger) = &settings_content.debugger {
3760                                &debugger.stepping_granularity
3761                            } else {
3762                                &None
3763                            }
3764                        },
3765                        pick_mut: |settings_content| {
3766                            &mut settings_content
3767                                .debugger
3768                                .get_or_insert_default()
3769                                .stepping_granularity
3770                        },
3771                    }),
3772                    metadata: None,
3773                    files: USER,
3774                }),
3775                SettingsPageItem::SettingItem(SettingItem {
3776                    title: "Save Breakpoints",
3777                    description: "Whether breakpoints should be reused across Zed sessions",
3778                    field: Box::new(SettingField {
3779                        pick: |settings_content| {
3780                            if let Some(debugger) = &settings_content.debugger {
3781                                &debugger.save_breakpoints
3782                            } else {
3783                                &None
3784                            }
3785                        },
3786                        pick_mut: |settings_content| {
3787                            &mut settings_content
3788                                .debugger
3789                                .get_or_insert_default()
3790                                .save_breakpoints
3791                        },
3792                    }),
3793                    metadata: None,
3794                    files: USER,
3795                }),
3796                SettingsPageItem::SettingItem(SettingItem {
3797                    title: "Timeout",
3798                    description: "Time in milliseconds until timeout error when connecting to a TCP debug adapter",
3799                    field: Box::new(SettingField {
3800                        pick: |settings_content| {
3801                            if let Some(debugger) = &settings_content.debugger {
3802                                &debugger.timeout
3803                            } else {
3804                                &None
3805                            }
3806                        },
3807                        pick_mut: |settings_content| {
3808                            &mut settings_content.debugger.get_or_insert_default().timeout
3809                        },
3810                    }),
3811                    metadata: None,
3812                    files: USER,
3813                }),
3814                SettingsPageItem::SettingItem(SettingItem {
3815                    title: "Log DAP Communications",
3816                    description: "Whether to log messages between active debug adapters and Zed",
3817                    field: Box::new(SettingField {
3818                        pick: |settings_content| {
3819                            if let Some(debugger) = &settings_content.debugger {
3820                                &debugger.log_dap_communications
3821                            } else {
3822                                &None
3823                            }
3824                        },
3825                        pick_mut: |settings_content| {
3826                            &mut settings_content
3827                                .debugger
3828                                .get_or_insert_default()
3829                                .log_dap_communications
3830                        },
3831                    }),
3832                    metadata: None,
3833                    files: USER,
3834                }),
3835                SettingsPageItem::SettingItem(SettingItem {
3836                    title: "Format DAP Log Messages",
3837                    description: "Whether to format DAP messages when adding them to debug adapter logger",
3838                    field: Box::new(SettingField {
3839                        pick: |settings_content| {
3840                            if let Some(debugger) = &settings_content.debugger {
3841                                &debugger.format_dap_log_messages
3842                            } else {
3843                                &None
3844                            }
3845                        },
3846                        pick_mut: |settings_content| {
3847                            &mut settings_content
3848                                .debugger
3849                                .get_or_insert_default()
3850                                .format_dap_log_messages
3851                        },
3852                    }),
3853                    metadata: None,
3854                    files: USER,
3855                }),
3856            ],
3857        },
3858        SettingsPage {
3859            title: "Terminal",
3860            items: vec![
3861                SettingsPageItem::SectionHeader("Environment"),
3862                SettingsPageItem::SettingItem(SettingItem {
3863                    title: "Shell",
3864                    description: "What shell to use when opening a terminal",
3865                    field: Box::new(
3866                        SettingField {
3867                            pick: |settings_content| {
3868                                if let Some(terminal) = &settings_content.terminal {
3869                                    &terminal.project.shell
3870                                } else {
3871                                    &None
3872                                }
3873                            },
3874                            pick_mut: |settings_content| {
3875                                &mut settings_content
3876                                    .terminal
3877                                    .get_or_insert_default()
3878                                    .project
3879                                    .shell
3880                            },
3881                        }
3882                        .unimplemented(),
3883                    ),
3884                    metadata: None,
3885                    files: USER | LOCAL,
3886                }),
3887                SettingsPageItem::SettingItem(SettingItem {
3888                    title: "Working Directory",
3889                    description: "What working directory to use when launching the terminal",
3890                    field: Box::new(
3891                        SettingField {
3892                            pick: |settings_content| {
3893                                if let Some(terminal) = &settings_content.terminal {
3894                                    &terminal.project.working_directory
3895                                } else {
3896                                    &None
3897                                }
3898                            },
3899                            pick_mut: |settings_content| {
3900                                &mut settings_content
3901                                    .terminal
3902                                    .get_or_insert_default()
3903                                    .project
3904                                    .working_directory
3905                            },
3906                        }
3907                        .unimplemented(),
3908                    ),
3909                    metadata: None,
3910                    files: USER | LOCAL,
3911                }),
3912                SettingsPageItem::SettingItem(SettingItem {
3913                    title: "Environment Variables",
3914                    description: "Key-value pairs to add to the terminal's environment",
3915                    field: Box::new(
3916                        SettingField {
3917                            pick: |settings_content| {
3918                                if let Some(terminal) = &settings_content.terminal {
3919                                    &terminal.project.env
3920                                } else {
3921                                    &None
3922                                }
3923                            },
3924                            pick_mut: |settings_content| {
3925                                &mut settings_content
3926                                    .terminal
3927                                    .get_or_insert_default()
3928                                    .project
3929                                    .env
3930                            },
3931                        }
3932                        .unimplemented(),
3933                    ),
3934                    metadata: None,
3935                    files: USER | LOCAL,
3936                }),
3937                SettingsPageItem::SettingItem(SettingItem {
3938                    title: "Detect Virtual Environment",
3939                    description: "Activates the python virtual environment, if one is found, in the terminal's working directory",
3940                    field: Box::new(
3941                        SettingField {
3942                            pick: |settings_content| {
3943                                if let Some(terminal) = &settings_content.terminal {
3944                                    &terminal.project.detect_venv
3945                                } else {
3946                                    &None
3947                                }
3948                            },
3949                            pick_mut: |settings_content| {
3950                                &mut settings_content
3951                                    .terminal
3952                                    .get_or_insert_default()
3953                                    .project
3954                                    .detect_venv
3955                            },
3956                        }
3957                        .unimplemented(),
3958                    ),
3959                    metadata: None,
3960                    files: USER | LOCAL,
3961                }),
3962                SettingsPageItem::SectionHeader("Font"),
3963                SettingsPageItem::SettingItem(SettingItem {
3964                    title: "Font Size",
3965                    description: "Font size for terminal text. If not set, defaults to buffer font size",
3966                    field: Box::new(SettingField {
3967                        pick: |settings_content| {
3968                            if let Some(terminal) = &settings_content.terminal
3969                                && terminal.font_size.is_some()
3970                            {
3971                                &terminal.font_size
3972                            } else if settings_content.theme.buffer_font_size.is_some() {
3973                                &settings_content.theme.buffer_font_size
3974                            } else {
3975                                &None
3976                            }
3977                        },
3978                        pick_mut: |settings_content| {
3979                            &mut settings_content.terminal.get_or_insert_default().font_size
3980                        },
3981                    }),
3982                    metadata: None,
3983                    files: USER,
3984                }),
3985                SettingsPageItem::SettingItem(SettingItem {
3986                    title: "Font Family",
3987                    description: "Font family for terminal text. If not set, defaults to buffer font family",
3988                    field: Box::new(SettingField {
3989                        pick: |settings_content| {
3990                            if let Some(terminal) = &settings_content.terminal
3991                                && terminal.font_family.is_some()
3992                            {
3993                                &terminal.font_family
3994                            } else if settings_content.theme.buffer_font_family.is_some() {
3995                                &settings_content.theme.buffer_font_family
3996                            } else {
3997                                &None
3998                            }
3999                        },
4000                        pick_mut: |settings_content| {
4001                            &mut settings_content
4002                                .terminal
4003                                .get_or_insert_default()
4004                                .font_family
4005                        },
4006                    }),
4007                    metadata: None,
4008                    files: USER,
4009                }),
4010                SettingsPageItem::SettingItem(SettingItem {
4011                    title: "Font Fallbacks",
4012                    description: "Font fallbacks for terminal text. If not set, defaults to buffer font fallbacks",
4013                    field: Box::new(
4014                        SettingField {
4015                            pick: |settings_content| {
4016                                if let Some(terminal) = &settings_content.terminal {
4017                                    &terminal.font_fallbacks
4018                                } else {
4019                                    &None
4020                                }
4021                            },
4022                            pick_mut: |settings_content| {
4023                                &mut settings_content
4024                                    .terminal
4025                                    .get_or_insert_default()
4026                                    .font_fallbacks
4027                            },
4028                        }
4029                        .unimplemented(),
4030                    ),
4031                    metadata: None,
4032                    files: USER,
4033                }),
4034                SettingsPageItem::SettingItem(SettingItem {
4035                    title: "Font Weight",
4036                    description: "Font weight for terminal text in CSS weight units (100-900)",
4037                    field: Box::new(SettingField {
4038                        pick: |settings_content| {
4039                            if let Some(terminal) = &settings_content.terminal {
4040                                &terminal.font_weight
4041                            } else {
4042                                &None
4043                            }
4044                        },
4045                        pick_mut: |settings_content| {
4046                            &mut settings_content
4047                                .terminal
4048                                .get_or_insert_default()
4049                                .font_weight
4050                        },
4051                    }),
4052                    metadata: None,
4053                    files: USER,
4054                }),
4055                SettingsPageItem::SettingItem(SettingItem {
4056                    title: "Font Features",
4057                    description: "Font features for terminal text",
4058                    field: Box::new(
4059                        SettingField {
4060                            pick: |settings_content| {
4061                                if let Some(terminal) = &settings_content.terminal {
4062                                    &terminal.font_features
4063                                } else {
4064                                    &None
4065                                }
4066                            },
4067                            pick_mut: |settings_content| {
4068                                &mut settings_content
4069                                    .terminal
4070                                    .get_or_insert_default()
4071                                    .font_features
4072                            },
4073                        }
4074                        .unimplemented(),
4075                    ),
4076                    metadata: None,
4077                    files: USER,
4078                }),
4079                SettingsPageItem::SectionHeader("Display Settings"),
4080                SettingsPageItem::SettingItem(SettingItem {
4081                    title: "Line Height",
4082                    description: "Line height for terminal text",
4083                    field: Box::new(
4084                        SettingField {
4085                            pick: |settings_content| {
4086                                if let Some(terminal) = &settings_content.terminal {
4087                                    &terminal.line_height
4088                                } else {
4089                                    &None
4090                                }
4091                            },
4092                            pick_mut: |settings_content| {
4093                                &mut settings_content
4094                                    .terminal
4095                                    .get_or_insert_default()
4096                                    .line_height
4097                            },
4098                        }
4099                        .unimplemented(),
4100                    ),
4101                    metadata: None,
4102                    files: USER,
4103                }),
4104                SettingsPageItem::SettingItem(SettingItem {
4105                    title: "Cursor Shape",
4106                    description: "Default cursor shape for the terminal (bar, block, underline, or hollow)",
4107                    field: Box::new(SettingField {
4108                        pick: |settings_content| {
4109                            if let Some(terminal) = &settings_content.terminal {
4110                                &terminal.cursor_shape
4111                            } else {
4112                                &None
4113                            }
4114                        },
4115                        pick_mut: |settings_content| {
4116                            &mut settings_content
4117                                .terminal
4118                                .get_or_insert_default()
4119                                .cursor_shape
4120                        },
4121                    }),
4122                    metadata: None,
4123                    files: USER,
4124                }),
4125                SettingsPageItem::SettingItem(SettingItem {
4126                    title: "Cursor Blinking",
4127                    description: "Sets the cursor blinking behavior in the terminal",
4128                    field: Box::new(SettingField {
4129                        pick: |settings_content| {
4130                            if let Some(terminal) = &settings_content.terminal {
4131                                &terminal.blinking
4132                            } else {
4133                                &None
4134                            }
4135                        },
4136                        pick_mut: |settings_content| {
4137                            &mut settings_content.terminal.get_or_insert_default().blinking
4138                        },
4139                    }),
4140                    metadata: None,
4141                    files: USER,
4142                }),
4143                SettingsPageItem::SettingItem(SettingItem {
4144                    title: "Alternate Scroll",
4145                    description: "Whether Alternate Scroll mode is active by default (converts mouse scroll to arrow keys in apps like vim)",
4146                    field: Box::new(SettingField {
4147                        pick: |settings_content| {
4148                            if let Some(terminal) = &settings_content.terminal {
4149                                &terminal.alternate_scroll
4150                            } else {
4151                                &None
4152                            }
4153                        },
4154                        pick_mut: |settings_content| {
4155                            &mut settings_content
4156                                .terminal
4157                                .get_or_insert_default()
4158                                .alternate_scroll
4159                        },
4160                    }),
4161                    metadata: None,
4162                    files: USER,
4163                }),
4164                SettingsPageItem::SettingItem(SettingItem {
4165                    title: "Minimum Contrast",
4166                    description: "The minimum APCA perceptual contrast between foreground and background colors (0-106)",
4167                    field: Box::new(SettingField {
4168                        pick: |settings_content| {
4169                            if let Some(terminal) = &settings_content.terminal {
4170                                &terminal.minimum_contrast
4171                            } else {
4172                                &None
4173                            }
4174                        },
4175                        pick_mut: |settings_content| {
4176                            &mut settings_content
4177                                .terminal
4178                                .get_or_insert_default()
4179                                .minimum_contrast
4180                        },
4181                    }),
4182                    metadata: None,
4183                    files: USER,
4184                }),
4185                SettingsPageItem::SectionHeader("Behavior Settings"),
4186                SettingsPageItem::SettingItem(SettingItem {
4187                    title: "Option As Meta",
4188                    description: "Whether the option key behaves as the meta key",
4189                    field: Box::new(SettingField {
4190                        pick: |settings_content| {
4191                            if let Some(terminal) = &settings_content.terminal {
4192                                &terminal.option_as_meta
4193                            } else {
4194                                &None
4195                            }
4196                        },
4197                        pick_mut: |settings_content| {
4198                            &mut settings_content
4199                                .terminal
4200                                .get_or_insert_default()
4201                                .option_as_meta
4202                        },
4203                    }),
4204                    metadata: None,
4205                    files: USER,
4206                }),
4207                SettingsPageItem::SettingItem(SettingItem {
4208                    title: "Copy On Select",
4209                    description: "Whether selecting text in the terminal automatically copies to the system clipboard",
4210                    field: Box::new(SettingField {
4211                        pick: |settings_content| {
4212                            if let Some(terminal) = &settings_content.terminal {
4213                                &terminal.copy_on_select
4214                            } else {
4215                                &None
4216                            }
4217                        },
4218                        pick_mut: |settings_content| {
4219                            &mut settings_content
4220                                .terminal
4221                                .get_or_insert_default()
4222                                .copy_on_select
4223                        },
4224                    }),
4225                    metadata: None,
4226                    files: USER,
4227                }),
4228                SettingsPageItem::SettingItem(SettingItem {
4229                    title: "Keep Selection On Copy",
4230                    description: "Whether to keep the text selection after copying it to the clipboard",
4231                    field: Box::new(SettingField {
4232                        pick: |settings_content| {
4233                            if let Some(terminal) = &settings_content.terminal {
4234                                &terminal.keep_selection_on_copy
4235                            } else {
4236                                &None
4237                            }
4238                        },
4239                        pick_mut: |settings_content| {
4240                            &mut settings_content
4241                                .terminal
4242                                .get_or_insert_default()
4243                                .keep_selection_on_copy
4244                        },
4245                    }),
4246                    metadata: None,
4247                    files: USER,
4248                }),
4249                SettingsPageItem::SectionHeader("Layout Settings"),
4250                SettingsPageItem::SettingItem(SettingItem {
4251                    title: "Default Width",
4252                    description: "Default width when the terminal is docked to the left or right (in pixels)",
4253                    field: Box::new(SettingField {
4254                        pick: |settings_content| {
4255                            if let Some(terminal) = &settings_content.terminal {
4256                                &terminal.default_width
4257                            } else {
4258                                &None
4259                            }
4260                        },
4261                        pick_mut: |settings_content| {
4262                            &mut settings_content
4263                                .terminal
4264                                .get_or_insert_default()
4265                                .default_width
4266                        },
4267                    }),
4268                    metadata: None,
4269                    files: USER,
4270                }),
4271                SettingsPageItem::SettingItem(SettingItem {
4272                    title: "Default Height",
4273                    description: "Default height when the terminal is docked to the bottom (in pixels)",
4274                    field: Box::new(SettingField {
4275                        pick: |settings_content| {
4276                            if let Some(terminal) = &settings_content.terminal {
4277                                &terminal.default_height
4278                            } else {
4279                                &None
4280                            }
4281                        },
4282                        pick_mut: |settings_content| {
4283                            &mut settings_content
4284                                .terminal
4285                                .get_or_insert_default()
4286                                .default_height
4287                        },
4288                    }),
4289                    metadata: None,
4290                    files: USER,
4291                }),
4292                SettingsPageItem::SectionHeader("Advanced Settings"),
4293                SettingsPageItem::SettingItem(SettingItem {
4294                    title: "Max Scroll History Lines",
4295                    description: "Maximum number of lines to keep in scrollback history (max: 100,000; 0 disables scrolling)",
4296                    field: Box::new(SettingField {
4297                        pick: |settings_content| {
4298                            if let Some(terminal) = &settings_content.terminal {
4299                                &terminal.max_scroll_history_lines
4300                            } else {
4301                                &None
4302                            }
4303                        },
4304                        pick_mut: |settings_content| {
4305                            &mut settings_content
4306                                .terminal
4307                                .get_or_insert_default()
4308                                .max_scroll_history_lines
4309                        },
4310                    }),
4311                    metadata: None,
4312                    files: USER,
4313                }),
4314                SettingsPageItem::SectionHeader("Toolbar"),
4315                SettingsPageItem::SettingItem(SettingItem {
4316                    title: "Breadcrumbs",
4317                    description: "Display the terminal title in breadcrumbs inside the terminal pane",
4318                    field: Box::new(SettingField {
4319                        pick: |settings_content| {
4320                            if let Some(terminal) = &settings_content.terminal {
4321                                if let Some(toolbar) = &terminal.toolbar {
4322                                    &toolbar.breadcrumbs
4323                                } else {
4324                                    &None
4325                                }
4326                            } else {
4327                                &None
4328                            }
4329                        },
4330                        pick_mut: |settings_content| {
4331                            &mut settings_content
4332                                .terminal
4333                                .get_or_insert_default()
4334                                .toolbar
4335                                .get_or_insert_default()
4336                                .breadcrumbs
4337                        },
4338                    }),
4339                    metadata: None,
4340                    files: USER,
4341                }),
4342                SettingsPageItem::SectionHeader("Scrollbar"),
4343                SettingsPageItem::SettingItem(SettingItem {
4344                    title: "Show Scrollbar",
4345                    description: "When to show the scrollbar in the terminal",
4346                    field: Box::new(SettingField {
4347                        pick: |settings_content| {
4348                            if let Some(terminal) = &settings_content.terminal
4349                                && let Some(scrollbar) = &terminal.scrollbar
4350                                && scrollbar.show.is_some()
4351                            {
4352                                &scrollbar.show
4353                            } else if let Some(scrollbar) = &settings_content.editor.scrollbar {
4354                                &scrollbar.show
4355                            } else {
4356                                &None
4357                            }
4358                        },
4359                        pick_mut: |settings_content| {
4360                            &mut settings_content
4361                                .terminal
4362                                .get_or_insert_default()
4363                                .scrollbar
4364                                .get_or_insert_default()
4365                                .show
4366                        },
4367                    }),
4368                    metadata: None,
4369                    files: USER,
4370                }),
4371            ],
4372        },
4373        SettingsPage {
4374            title: "Version Control",
4375            items: vec![
4376                SettingsPageItem::SectionHeader("Git Gutter"),
4377                SettingsPageItem::SettingItem(SettingItem {
4378                    title: "Visibilility",
4379                    description: "Control whether git status is shown in the editor's gutter",
4380                    field: Box::new(SettingField {
4381                        pick: |settings_content| {
4382                            if let Some(git) = &settings_content.git {
4383                                &git.git_gutter
4384                            } else {
4385                                &None
4386                            }
4387                        },
4388                        pick_mut: |settings_content| {
4389                            &mut settings_content.git.get_or_insert_default().git_gutter
4390                        },
4391                    }),
4392                    metadata: None,
4393                    files: USER,
4394                }),
4395                // todo(settings_ui): Figure out the right default for this value in default.json
4396                SettingsPageItem::SettingItem(SettingItem {
4397                    title: "Debounce",
4398                    description: "Debounce threshold in milliseconds after which changes are reflected in the git gutter",
4399                    field: Box::new(SettingField {
4400                        pick: |settings_content| {
4401                            if let Some(git) = &settings_content.git {
4402                                &git.gutter_debounce
4403                            } else {
4404                                &None
4405                            }
4406                        },
4407                        pick_mut: |settings_content| {
4408                            &mut settings_content.git.get_or_insert_default().gutter_debounce
4409                        },
4410                    }),
4411                    metadata: None,
4412                    files: USER,
4413                }),
4414                SettingsPageItem::SectionHeader("Inline Git Blame"),
4415                SettingsPageItem::SettingItem(SettingItem {
4416                    title: "Enabled",
4417                    description: "Whether or not to show git blame data inline in the currently focused line",
4418                    field: Box::new(SettingField {
4419                        pick: |settings_content| {
4420                            if let Some(git) = &settings_content.git {
4421                                if let Some(inline_blame) = &git.inline_blame {
4422                                    &inline_blame.enabled
4423                                } else {
4424                                    &None
4425                                }
4426                            } else {
4427                                &None
4428                            }
4429                        },
4430                        pick_mut: |settings_content| {
4431                            &mut settings_content
4432                                .git
4433                                .get_or_insert_default()
4434                                .inline_blame
4435                                .get_or_insert_default()
4436                                .enabled
4437                        },
4438                    }),
4439                    metadata: None,
4440                    files: USER,
4441                }),
4442                SettingsPageItem::SettingItem(SettingItem {
4443                    title: "Delay",
4444                    description: "The delay after which the inline blame information is shown",
4445                    field: Box::new(SettingField {
4446                        pick: |settings_content| {
4447                            if let Some(git) = &settings_content.git {
4448                                if let Some(inline_blame) = &git.inline_blame {
4449                                    &inline_blame.delay_ms
4450                                } else {
4451                                    &None
4452                                }
4453                            } else {
4454                                &None
4455                            }
4456                        },
4457                        pick_mut: |settings_content| {
4458                            &mut settings_content
4459                                .git
4460                                .get_or_insert_default()
4461                                .inline_blame
4462                                .get_or_insert_default()
4463                                .delay_ms
4464                        },
4465                    }),
4466                    metadata: None,
4467                    files: USER,
4468                }),
4469                SettingsPageItem::SettingItem(SettingItem {
4470                    title: "Padding",
4471                    description: "Padding between the end of the source line and the start of the inline blame in columns",
4472                    field: Box::new(SettingField {
4473                        pick: |settings_content| {
4474                            if let Some(git) = &settings_content.git {
4475                                if let Some(inline_blame) = &git.inline_blame {
4476                                    &inline_blame.padding
4477                                } else {
4478                                    &None
4479                                }
4480                            } else {
4481                                &None
4482                            }
4483                        },
4484                        pick_mut: |settings_content| {
4485                            &mut settings_content
4486                                .git
4487                                .get_or_insert_default()
4488                                .inline_blame
4489                                .get_or_insert_default()
4490                                .padding
4491                        },
4492                    }),
4493                    metadata: None,
4494                    files: USER,
4495                }),
4496                SettingsPageItem::SettingItem(SettingItem {
4497                    title: "Minimum Column",
4498                    description: "The minimum column number at which to show the inline blame information",
4499                    field: Box::new(SettingField {
4500                        pick: |settings_content| match &settings_content.git {
4501                            Some(settings::GitSettings {
4502                                inline_blame: Some(inline_blame),
4503                                ..
4504                            }) => &inline_blame.min_column,
4505                            _ => &None,
4506                        },
4507                        pick_mut: |settings_content| {
4508                            &mut settings_content
4509                                .git
4510                                .get_or_insert_default()
4511                                .inline_blame
4512                                .get_or_insert_default()
4513                                .min_column
4514                        },
4515                    }),
4516                    metadata: None,
4517                    files: USER,
4518                }),
4519                SettingsPageItem::SettingItem(SettingItem {
4520                    title: "Show Commit Summary",
4521                    description: "Show commit summary as part of the inline blame",
4522                    field: Box::new(SettingField {
4523                        pick: |settings_content| {
4524                            if let Some(git) = &settings_content.git {
4525                                if let Some(inline_blame) = &git.inline_blame {
4526                                    &inline_blame.show_commit_summary
4527                                } else {
4528                                    &None
4529                                }
4530                            } else {
4531                                &None
4532                            }
4533                        },
4534                        pick_mut: |settings_content| {
4535                            &mut settings_content
4536                                .git
4537                                .get_or_insert_default()
4538                                .inline_blame
4539                                .get_or_insert_default()
4540                                .show_commit_summary
4541                        },
4542                    }),
4543                    metadata: None,
4544                    files: USER,
4545                }),
4546                SettingsPageItem::SectionHeader("Git Blame View"),
4547                SettingsPageItem::SettingItem(SettingItem {
4548                    title: "Show Avatar",
4549                    description: "Show the avatar of the author of the commit",
4550                    field: Box::new(SettingField {
4551                        pick: |settings_content| {
4552                            if let Some(git) = &settings_content.git {
4553                                if let Some(blame) = &git.blame {
4554                                    &blame.show_avatar
4555                                } else {
4556                                    &None
4557                                }
4558                            } else {
4559                                &None
4560                            }
4561                        },
4562                        pick_mut: |settings_content| {
4563                            &mut settings_content
4564                                .git
4565                                .get_or_insert_default()
4566                                .blame
4567                                .get_or_insert_default()
4568                                .show_avatar
4569                        },
4570                    }),
4571                    metadata: None,
4572                    files: USER,
4573                }),
4574                SettingsPageItem::SectionHeader("Branch Picker"),
4575                SettingsPageItem::SettingItem(SettingItem {
4576                    title: "Show Author Name",
4577                    description: "Show author name as part of the commit information in branch picker",
4578                    field: Box::new(SettingField {
4579                        pick: |settings_content| {
4580                            if let Some(git) = &settings_content.git {
4581                                if let Some(branch_picker) = &git.branch_picker {
4582                                    &branch_picker.show_author_name
4583                                } else {
4584                                    &None
4585                                }
4586                            } else {
4587                                &None
4588                            }
4589                        },
4590                        pick_mut: |settings_content| {
4591                            &mut settings_content
4592                                .git
4593                                .get_or_insert_default()
4594                                .branch_picker
4595                                .get_or_insert_default()
4596                                .show_author_name
4597                        },
4598                    }),
4599                    metadata: None,
4600                    files: USER,
4601                }),
4602                SettingsPageItem::SectionHeader("Git Hunks"),
4603                SettingsPageItem::SettingItem(SettingItem {
4604                    title: "Hunk Style",
4605                    description: "How git hunks are displayed visually in the editor",
4606                    field: Box::new(SettingField {
4607                        pick: |settings_content| {
4608                            if let Some(git) = &settings_content.git {
4609                                &git.hunk_style
4610                            } else {
4611                                &None
4612                            }
4613                        },
4614                        pick_mut: |settings_content| {
4615                            &mut settings_content.git.get_or_insert_default().hunk_style
4616                        },
4617                    }),
4618                    metadata: None,
4619                    files: USER,
4620                }),
4621            ],
4622        },
4623        SettingsPage {
4624            title: "Collaboration",
4625            items: vec![
4626                SettingsPageItem::SectionHeader("Calls"),
4627                SettingsPageItem::SettingItem(SettingItem {
4628                    title: "Mute On Join",
4629                    description: "Whether the microphone should be muted when joining a channel or a call",
4630                    field: Box::new(SettingField {
4631                        pick: |settings_content| {
4632                            if let Some(calls) = &settings_content.calls {
4633                                &calls.mute_on_join
4634                            } else {
4635                                &None
4636                            }
4637                        },
4638                        pick_mut: |settings_content| {
4639                            &mut settings_content.calls.get_or_insert_default().mute_on_join
4640                        },
4641                    }),
4642                    metadata: None,
4643                    files: USER,
4644                }),
4645                SettingsPageItem::SettingItem(SettingItem {
4646                    title: "Share On Join",
4647                    description: "Whether your current project should be shared when joining an empty channel",
4648                    field: Box::new(SettingField {
4649                        pick: |settings_content| {
4650                            if let Some(calls) = &settings_content.calls {
4651                                &calls.share_on_join
4652                            } else {
4653                                &None
4654                            }
4655                        },
4656                        pick_mut: |settings_content| {
4657                            &mut settings_content.calls.get_or_insert_default().share_on_join
4658                        },
4659                    }),
4660                    metadata: None,
4661                    files: USER,
4662                }),
4663                SettingsPageItem::SectionHeader("Experimental"),
4664                SettingsPageItem::SettingItem(SettingItem {
4665                    title: "Rodio Audio",
4666                    description: "Opt into the new audio system",
4667                    field: Box::new(SettingField {
4668                        pick: |settings_content| {
4669                            if let Some(audio) = &settings_content.audio {
4670                                &audio.rodio_audio
4671                            } else {
4672                                &None
4673                            }
4674                        },
4675                        pick_mut: |settings_content| {
4676                            &mut settings_content.audio.get_or_insert_default().rodio_audio
4677                        },
4678                    }),
4679                    metadata: None,
4680                    files: USER,
4681                }),
4682                SettingsPageItem::SettingItem(SettingItem {
4683                    title: "Auto Microphone Volume",
4684                    description: "Automatically adjust microphone volume (requires Rodio Audio)",
4685                    field: Box::new(SettingField {
4686                        pick: |settings_content| {
4687                            if let Some(audio) = &settings_content.audio {
4688                                &audio.auto_microphone_volume
4689                            } else {
4690                                &None
4691                            }
4692                        },
4693                        pick_mut: |settings_content| {
4694                            &mut settings_content
4695                                .audio
4696                                .get_or_insert_default()
4697                                .auto_microphone_volume
4698                        },
4699                    }),
4700                    metadata: None,
4701                    files: USER,
4702                }),
4703                SettingsPageItem::SettingItem(SettingItem {
4704                    title: "Auto Speaker Volume",
4705                    description: "Automatically adjust volume of other call members (requires Rodio Audio)",
4706                    field: Box::new(SettingField {
4707                        pick: |settings_content| {
4708                            if let Some(audio) = &settings_content.audio {
4709                                &audio.auto_speaker_volume
4710                            } else {
4711                                &None
4712                            }
4713                        },
4714                        pick_mut: |settings_content| {
4715                            &mut settings_content
4716                                .audio
4717                                .get_or_insert_default()
4718                                .auto_speaker_volume
4719                        },
4720                    }),
4721                    metadata: None,
4722                    files: USER,
4723                }),
4724                SettingsPageItem::SettingItem(SettingItem {
4725                    title: "Denoise",
4726                    description: "Remove background noises (requires Rodio Audio)",
4727                    field: Box::new(SettingField {
4728                        pick: |settings_content| {
4729                            if let Some(audio) = &settings_content.audio {
4730                                &audio.denoise
4731                            } else {
4732                                &None
4733                            }
4734                        },
4735                        pick_mut: |settings_content| {
4736                            &mut settings_content.audio.get_or_insert_default().denoise
4737                        },
4738                    }),
4739                    metadata: None,
4740                    files: USER,
4741                }),
4742                SettingsPageItem::SettingItem(SettingItem {
4743                    title: "Legacy Audio Compatible",
4744                    description: "Use audio parameters compatible with previous versions (requires Rodio Audio)",
4745                    field: Box::new(SettingField {
4746                        pick: |settings_content| {
4747                            if let Some(audio) = &settings_content.audio {
4748                                &audio.legacy_audio_compatible
4749                            } else {
4750                                &None
4751                            }
4752                        },
4753                        pick_mut: |settings_content| {
4754                            &mut settings_content
4755                                .audio
4756                                .get_or_insert_default()
4757                                .legacy_audio_compatible
4758                        },
4759                    }),
4760                    metadata: None,
4761                    files: USER,
4762                }),
4763            ],
4764        },
4765        SettingsPage {
4766            title: "AI",
4767            items: vec![
4768                SettingsPageItem::SectionHeader("General"),
4769                SettingsPageItem::SettingItem(SettingItem {
4770                    title: "Disable AI",
4771                    description: "Whether to disable all AI features in Zed",
4772                    field: Box::new(SettingField {
4773                        pick: |settings_content| &settings_content.disable_ai,
4774                        pick_mut: |settings_content| &mut settings_content.disable_ai,
4775                    }),
4776                    metadata: None,
4777                    files: USER,
4778                }),
4779                SettingsPageItem::SectionHeader("Agent Configuration"),
4780                SettingsPageItem::SettingItem(SettingItem {
4781                    title: "Always Allow Tool Actions",
4782                    description: "When enabled, the agent can run potentially destructive actions without asking for your confirmation. This setting has no effect on external agents.",
4783                    field: Box::new(SettingField {
4784                        pick: |settings_content| {
4785                            if let Some(agent) = &settings_content.agent {
4786                                &agent.always_allow_tool_actions
4787                            } else {
4788                                &None
4789                            }
4790                        },
4791                        pick_mut: |settings_content| {
4792                            &mut settings_content
4793                                .agent
4794                                .get_or_insert_default()
4795                                .always_allow_tool_actions
4796                        },
4797                    }),
4798                    metadata: None,
4799                    files: USER,
4800                }),
4801                SettingsPageItem::SettingItem(SettingItem {
4802                    title: "Single File Review",
4803                    description: "When enabled, agent edits will also be displayed in single-file buffers for review",
4804                    field: Box::new(SettingField {
4805                        pick: |settings_content| {
4806                            if let Some(agent) = &settings_content.agent {
4807                                &agent.single_file_review
4808                            } else {
4809                                &None
4810                            }
4811                        },
4812                        pick_mut: |settings_content| {
4813                            &mut settings_content
4814                                .agent
4815                                .get_or_insert_default()
4816                                .single_file_review
4817                        },
4818                    }),
4819                    metadata: None,
4820                    files: USER,
4821                }),
4822                SettingsPageItem::SettingItem(SettingItem {
4823                    title: "Enable Feedback",
4824                    description: "Show voting thumbs up/down icon buttons for feedback on agent edits",
4825                    field: Box::new(SettingField {
4826                        pick: |settings_content| {
4827                            if let Some(agent) = &settings_content.agent {
4828                                &agent.enable_feedback
4829                            } else {
4830                                &None
4831                            }
4832                        },
4833                        pick_mut: |settings_content| {
4834                            &mut settings_content
4835                                .agent
4836                                .get_or_insert_default()
4837                                .enable_feedback
4838                        },
4839                    }),
4840                    metadata: None,
4841                    files: USER,
4842                }),
4843                SettingsPageItem::SettingItem(SettingItem {
4844                    title: "Notify When Agent Waiting",
4845                    description: "Where to show notifications when the agent has completed its response or needs confirmation before running a tool action",
4846                    field: Box::new(SettingField {
4847                        pick: |settings_content| {
4848                            if let Some(agent) = &settings_content.agent {
4849                                &agent.notify_when_agent_waiting
4850                            } else {
4851                                &None
4852                            }
4853                        },
4854                        pick_mut: |settings_content| {
4855                            &mut settings_content
4856                                .agent
4857                                .get_or_insert_default()
4858                                .notify_when_agent_waiting
4859                        },
4860                    }),
4861                    metadata: None,
4862                    files: USER,
4863                }),
4864                SettingsPageItem::SettingItem(SettingItem {
4865                    title: "Play Sound When Agent Done",
4866                    description: "Whether to play a sound when the agent has either completed its response, or needs user input",
4867                    field: Box::new(SettingField {
4868                        pick: |settings_content| {
4869                            if let Some(agent) = &settings_content.agent {
4870                                &agent.play_sound_when_agent_done
4871                            } else {
4872                                &None
4873                            }
4874                        },
4875                        pick_mut: |settings_content| {
4876                            &mut settings_content
4877                                .agent
4878                                .get_or_insert_default()
4879                                .play_sound_when_agent_done
4880                        },
4881                    }),
4882                    metadata: None,
4883                    files: USER,
4884                }),
4885                SettingsPageItem::SettingItem(SettingItem {
4886                    title: "Expand Edit Card",
4887                    description: "Whether to have edit cards in the agent panel expanded, showing a preview of the diff",
4888                    field: Box::new(SettingField {
4889                        pick: |settings_content| {
4890                            if let Some(agent) = &settings_content.agent {
4891                                &agent.expand_edit_card
4892                            } else {
4893                                &None
4894                            }
4895                        },
4896                        pick_mut: |settings_content| {
4897                            &mut settings_content
4898                                .agent
4899                                .get_or_insert_default()
4900                                .expand_edit_card
4901                        },
4902                    }),
4903                    metadata: None,
4904                    files: USER,
4905                }),
4906                SettingsPageItem::SettingItem(SettingItem {
4907                    title: "Expand Terminal Card",
4908                    description: "Whether to have terminal cards in the agent panel expanded, showing the whole command output",
4909                    field: Box::new(SettingField {
4910                        pick: |settings_content| {
4911                            if let Some(agent) = &settings_content.agent {
4912                                &agent.expand_terminal_card
4913                            } else {
4914                                &None
4915                            }
4916                        },
4917                        pick_mut: |settings_content| {
4918                            &mut settings_content
4919                                .agent
4920                                .get_or_insert_default()
4921                                .expand_terminal_card
4922                        },
4923                    }),
4924                    metadata: None,
4925                    files: USER,
4926                }),
4927                SettingsPageItem::SettingItem(SettingItem {
4928                    title: "Use Modifier To Send",
4929                    description: "Whether to always use cmd-enter (or ctrl-enter on Linux or Windows) to send messages",
4930                    field: Box::new(SettingField {
4931                        pick: |settings_content| {
4932                            if let Some(agent) = &settings_content.agent {
4933                                &agent.use_modifier_to_send
4934                            } else {
4935                                &None
4936                            }
4937                        },
4938                        pick_mut: |settings_content| {
4939                            &mut settings_content
4940                                .agent
4941                                .get_or_insert_default()
4942                                .use_modifier_to_send
4943                        },
4944                    }),
4945                    metadata: None,
4946                    files: USER,
4947                }),
4948                SettingsPageItem::SettingItem(SettingItem {
4949                    title: "Message Editor Min Lines",
4950                    description: "Minimum number of lines to display in the agent message editor",
4951                    field: Box::new(SettingField {
4952                        pick: |settings_content| {
4953                            if let Some(agent) = &settings_content.agent {
4954                                &agent.message_editor_min_lines
4955                            } else {
4956                                &None
4957                            }
4958                        },
4959                        pick_mut: |settings_content| {
4960                            &mut settings_content
4961                                .agent
4962                                .get_or_insert_default()
4963                                .message_editor_min_lines
4964                        },
4965                    }),
4966                    metadata: None,
4967                    files: USER,
4968                }),
4969            ],
4970        },
4971        SettingsPage {
4972            title: "Network",
4973            items: vec![
4974                SettingsPageItem::SectionHeader("Network"),
4975                // todo(settings_ui): Proxy needs a default
4976                SettingsPageItem::SettingItem(SettingItem {
4977                    title: "Proxy",
4978                    description: "The proxy to use for network requests",
4979                    field: Box::new(
4980                        SettingField {
4981                            pick: |settings_content| &settings_content.proxy,
4982                            pick_mut: |settings_content| &mut settings_content.proxy,
4983                        }
4984                        .unimplemented(),
4985                    ),
4986                    metadata: Some(Box::new(SettingsFieldMetadata {
4987                        placeholder: Some("socks5h://localhost:10808"),
4988                        ..Default::default()
4989                    })),
4990                    files: USER,
4991                }),
4992                SettingsPageItem::SettingItem(SettingItem {
4993                    title: "Server URL",
4994                    description: "The URL of the Zed server to connect to",
4995                    field: Box::new(SettingField {
4996                        pick: |settings_content| &settings_content.server_url,
4997                        pick_mut: |settings_content| &mut settings_content.server_url,
4998                    }),
4999                    metadata: Some(Box::new(SettingsFieldMetadata {
5000                        placeholder: Some("https://zed.dev"),
5001                        ..Default::default()
5002                    })),
5003                    files: USER,
5004                }),
5005            ],
5006        },
5007    ]
5008}
5009
5010const LANGUAGES_SECTION_HEADER: &'static str = "Languages";
5011
5012fn current_language() -> Option<SharedString> {
5013    sub_page_stack().iter().find_map(|page| {
5014        (page.section_header == LANGUAGES_SECTION_HEADER).then(|| page.link.title.clone())
5015    })
5016}
5017
5018fn language_settings_field<T>(
5019    settings_content: &SettingsContent,
5020    get: fn(&LanguageSettingsContent) -> &Option<T>,
5021) -> &Option<T> {
5022    let all_languages = &settings_content.project.all_languages;
5023    if let Some(current_language_name) = current_language() {
5024        if let Some(current_language) = all_languages.languages.0.get(¤t_language_name) {
5025            let value = get(current_language);
5026            if value.is_some() {
5027                return value;
5028            }
5029        }
5030    }
5031    let default_value = get(&all_languages.defaults);
5032    return default_value;
5033}
5034
5035fn language_settings_field_mut<T>(
5036    settings_content: &mut SettingsContent,
5037    get: fn(&mut LanguageSettingsContent) -> &mut Option<T>,
5038) -> &mut Option<T> {
5039    let all_languages = &mut settings_content.project.all_languages;
5040    let language_content = if let Some(current_language) = current_language() {
5041        all_languages
5042            .languages
5043            .0
5044            .entry(current_language)
5045            .or_default()
5046    } else {
5047        &mut all_languages.defaults
5048    };
5049    return get(language_content);
5050}
5051
5052fn language_settings_data() -> Vec<SettingsPageItem> {
5053    let mut items = vec![
5054        SettingsPageItem::SectionHeader("Indentation"),
5055        SettingsPageItem::SettingItem(SettingItem {
5056            title: "Tab Size",
5057            description: "How many columns a tab should occupy",
5058            field: Box::new(SettingField {
5059                pick: |settings_content| {
5060                    language_settings_field(settings_content, |language| &language.tab_size)
5061                },
5062                pick_mut: |settings_content| {
5063                    language_settings_field_mut(settings_content, |language| &mut language.tab_size)
5064                },
5065            }),
5066            metadata: None,
5067            files: USER | LOCAL,
5068        }),
5069        SettingsPageItem::SettingItem(SettingItem {
5070            title: "Hard Tabs",
5071            description: "Whether to indent lines using tab characters, as opposed to multiple spaces",
5072            field: Box::new(SettingField {
5073                pick: |settings_content| {
5074                    language_settings_field(settings_content, |language| &language.hard_tabs)
5075                },
5076                pick_mut: |settings_content| {
5077                    language_settings_field_mut(settings_content, |language| {
5078                        &mut language.hard_tabs
5079                    })
5080                },
5081            }),
5082            metadata: None,
5083            files: USER | LOCAL,
5084        }),
5085        SettingsPageItem::SettingItem(SettingItem {
5086            title: "Auto Indent",
5087            description: "Whether indentation should be adjusted based on the context whilst typing",
5088            field: Box::new(SettingField {
5089                pick: |settings_content| {
5090                    language_settings_field(settings_content, |language| &language.auto_indent)
5091                },
5092                pick_mut: |settings_content| {
5093                    language_settings_field_mut(settings_content, |language| {
5094                        &mut language.auto_indent
5095                    })
5096                },
5097            }),
5098            metadata: None,
5099            files: USER | LOCAL,
5100        }),
5101        SettingsPageItem::SettingItem(SettingItem {
5102            title: "Auto Indent On Paste",
5103            description: "Whether indentation of pasted content should be adjusted based on the context",
5104            field: Box::new(SettingField {
5105                pick: |settings_content| {
5106                    language_settings_field(settings_content, |language| {
5107                        &language.auto_indent_on_paste
5108                    })
5109                },
5110                pick_mut: |settings_content| {
5111                    language_settings_field_mut(settings_content, |language| {
5112                        &mut language.auto_indent_on_paste
5113                    })
5114                },
5115            }),
5116            metadata: None,
5117            files: USER | LOCAL,
5118        }),
5119        SettingsPageItem::SectionHeader("Wrapping"),
5120        SettingsPageItem::SettingItem(SettingItem {
5121            title: "Soft Wrap",
5122            description: "How to soft-wrap long lines of text",
5123            field: Box::new(SettingField {
5124                pick: |settings_content| {
5125                    language_settings_field(settings_content, |language| &language.soft_wrap)
5126                },
5127                pick_mut: |settings_content| {
5128                    language_settings_field_mut(settings_content, |language| {
5129                        &mut language.soft_wrap
5130                    })
5131                },
5132            }),
5133            metadata: None,
5134            files: USER | LOCAL,
5135        }),
5136        SettingsPageItem::SettingItem(SettingItem {
5137            title: "Show Wrap Guides",
5138            description: "Show wrap guides in the editor",
5139            field: Box::new(SettingField {
5140                pick: |settings_content| {
5141                    language_settings_field(settings_content, |language| &language.show_wrap_guides)
5142                },
5143                pick_mut: |settings_content| {
5144                    language_settings_field_mut(settings_content, |language| {
5145                        &mut language.show_wrap_guides
5146                    })
5147                },
5148            }),
5149            metadata: None,
5150            files: USER | LOCAL,
5151        }),
5152        SettingsPageItem::SettingItem(SettingItem {
5153            title: "Preferred Line Length",
5154            description: "The column at which to soft-wrap lines, for buffers where soft-wrap is enabled",
5155            field: Box::new(SettingField {
5156                pick: |settings_content| {
5157                    language_settings_field(settings_content, |language| {
5158                        &language.preferred_line_length
5159                    })
5160                },
5161                pick_mut: |settings_content| {
5162                    language_settings_field_mut(settings_content, |language| {
5163                        &mut language.preferred_line_length
5164                    })
5165                },
5166            }),
5167            metadata: None,
5168            files: USER | LOCAL,
5169        }),
5170        SettingsPageItem::SettingItem(SettingItem {
5171            title: "Wrap Guides",
5172            description: "Character counts at which to show wrap guides in the editor",
5173            field: Box::new(
5174                SettingField {
5175                    pick: |settings_content| {
5176                        language_settings_field(settings_content, |language| &language.wrap_guides)
5177                    },
5178                    pick_mut: |settings_content| {
5179                        language_settings_field_mut(settings_content, |language| {
5180                            &mut language.wrap_guides
5181                        })
5182                    },
5183                }
5184                .unimplemented(),
5185            ),
5186            metadata: None,
5187            files: USER | LOCAL,
5188        }),
5189        SettingsPageItem::SettingItem(SettingItem {
5190            title: "Allow Rewrap",
5191            description: "Controls where the `editor::Rewrap` action is allowed for this language",
5192            field: Box::new(SettingField {
5193                pick: |settings_content| {
5194                    language_settings_field(settings_content, |language| &language.allow_rewrap)
5195                },
5196                pick_mut: |settings_content| {
5197                    language_settings_field_mut(settings_content, |language| {
5198                        &mut language.allow_rewrap
5199                    })
5200                },
5201            }),
5202            metadata: None,
5203            files: USER | LOCAL,
5204        }),
5205        SettingsPageItem::SectionHeader("Indent Guides"),
5206        SettingsPageItem::SettingItem(SettingItem {
5207            title: "Enabled",
5208            description: "Display indent guides in the editor",
5209            field: Box::new(SettingField {
5210                pick: |settings_content| {
5211                    language_settings_field(settings_content, |language| {
5212                        if let Some(indent_guides) = &language.indent_guides {
5213                            &indent_guides.enabled
5214                        } else {
5215                            &None
5216                        }
5217                    })
5218                },
5219                pick_mut: |settings_content| {
5220                    language_settings_field_mut(settings_content, |language| {
5221                        &mut language.indent_guides.get_or_insert_default().enabled
5222                    })
5223                },
5224            }),
5225            metadata: None,
5226            files: USER | LOCAL,
5227        }),
5228        SettingsPageItem::SettingItem(SettingItem {
5229            title: "Line Width",
5230            description: "The width of the indent guides in pixels, between 1 and 10",
5231            field: Box::new(SettingField {
5232                pick: |settings_content| {
5233                    language_settings_field(settings_content, |language| {
5234                        if let Some(indent_guides) = &language.indent_guides {
5235                            &indent_guides.line_width
5236                        } else {
5237                            &None
5238                        }
5239                    })
5240                },
5241                pick_mut: |settings_content| {
5242                    language_settings_field_mut(settings_content, |language| {
5243                        &mut language.indent_guides.get_or_insert_default().line_width
5244                    })
5245                },
5246            }),
5247            metadata: None,
5248            files: USER | LOCAL,
5249        }),
5250        SettingsPageItem::SettingItem(SettingItem {
5251            title: "Active Line Width",
5252            description: "The width of the active indent guide in pixels, between 1 and 10",
5253            field: Box::new(SettingField {
5254                pick: |settings_content| {
5255                    language_settings_field(settings_content, |language| {
5256                        if let Some(indent_guides) = &language.indent_guides {
5257                            &indent_guides.active_line_width
5258                        } else {
5259                            &None
5260                        }
5261                    })
5262                },
5263                pick_mut: |settings_content| {
5264                    language_settings_field_mut(settings_content, |language| {
5265                        &mut language
5266                            .indent_guides
5267                            .get_or_insert_default()
5268                            .active_line_width
5269                    })
5270                },
5271            }),
5272            metadata: None,
5273            files: USER | LOCAL,
5274        }),
5275        SettingsPageItem::SettingItem(SettingItem {
5276            title: "Coloring",
5277            description: "Determines how indent guides are colored",
5278            field: Box::new(SettingField {
5279                pick: |settings_content| {
5280                    language_settings_field(settings_content, |language| {
5281                        if let Some(indent_guides) = &language.indent_guides {
5282                            &indent_guides.coloring
5283                        } else {
5284                            &None
5285                        }
5286                    })
5287                },
5288                pick_mut: |settings_content| {
5289                    language_settings_field_mut(settings_content, |language| {
5290                        &mut language.indent_guides.get_or_insert_default().coloring
5291                    })
5292                },
5293            }),
5294            metadata: None,
5295            files: USER | LOCAL,
5296        }),
5297        SettingsPageItem::SettingItem(SettingItem {
5298            title: "Background Coloring",
5299            description: "Determines how indent guide backgrounds are colored",
5300            field: Box::new(SettingField {
5301                pick: |settings_content| {
5302                    language_settings_field(settings_content, |language| {
5303                        if let Some(indent_guides) = &language.indent_guides {
5304                            &indent_guides.background_coloring
5305                        } else {
5306                            &None
5307                        }
5308                    })
5309                },
5310                pick_mut: |settings_content| {
5311                    language_settings_field_mut(settings_content, |language| {
5312                        &mut language
5313                            .indent_guides
5314                            .get_or_insert_default()
5315                            .background_coloring
5316                    })
5317                },
5318            }),
5319            metadata: None,
5320            files: USER | LOCAL,
5321        }),
5322        SettingsPageItem::SectionHeader("Formatting"),
5323        SettingsPageItem::SettingItem(SettingItem {
5324            title: "Format On Save",
5325            description: "Whether or not to perform a buffer format before saving",
5326            field: Box::new(
5327                // TODO(settings_ui): this setting should just be a bool
5328                SettingField {
5329                    pick: |settings_content| {
5330                        language_settings_field(settings_content, |language| {
5331                            &language.format_on_save
5332                        })
5333                    },
5334                    pick_mut: |settings_content| {
5335                        language_settings_field_mut(settings_content, |language| {
5336                            &mut language.format_on_save
5337                        })
5338                    },
5339                },
5340            ),
5341            metadata: None,
5342            files: USER | LOCAL,
5343        }),
5344        SettingsPageItem::SettingItem(SettingItem {
5345            title: "Remove Trailing Whitespace On Save",
5346            description: "Whether or not to remove any trailing whitespace from lines of a buffer before saving it",
5347            field: Box::new(SettingField {
5348                pick: |settings_content| {
5349                    language_settings_field(settings_content, |language| {
5350                        &language.remove_trailing_whitespace_on_save
5351                    })
5352                },
5353                pick_mut: |settings_content| {
5354                    language_settings_field_mut(settings_content, |language| {
5355                        &mut language.remove_trailing_whitespace_on_save
5356                    })
5357                },
5358            }),
5359            metadata: None,
5360            files: USER | LOCAL,
5361        }),
5362        SettingsPageItem::SettingItem(SettingItem {
5363            title: "Ensure Final Newline On Save",
5364            description: "Whether or not to ensure there's a single newline at the end of a buffer when saving it",
5365            field: Box::new(SettingField {
5366                pick: |settings_content| {
5367                    language_settings_field(settings_content, |language| {
5368                        &language.ensure_final_newline_on_save
5369                    })
5370                },
5371                pick_mut: |settings_content| {
5372                    language_settings_field_mut(settings_content, |language| {
5373                        &mut language.ensure_final_newline_on_save
5374                    })
5375                },
5376            }),
5377            metadata: None,
5378            files: USER | LOCAL,
5379        }),
5380        SettingsPageItem::SettingItem(SettingItem {
5381            title: "Formatter",
5382            description: "How to perform a buffer format",
5383            field: Box::new(
5384                SettingField {
5385                    pick: |settings_content| {
5386                        language_settings_field(settings_content, |language| &language.formatter)
5387                    },
5388                    pick_mut: |settings_content| {
5389                        language_settings_field_mut(settings_content, |language| {
5390                            &mut language.formatter
5391                        })
5392                    },
5393                }
5394                .unimplemented(),
5395            ),
5396            metadata: None,
5397            files: USER | LOCAL,
5398        }),
5399        SettingsPageItem::SettingItem(SettingItem {
5400            title: "Use On Type Format",
5401            description: "Whether to use additional LSP queries to format (and amend) the code after every \"trigger\" symbol input, defined by LSP server capabilities",
5402            field: Box::new(SettingField {
5403                pick: |settings_content| {
5404                    language_settings_field(settings_content, |language| {
5405                        &language.use_on_type_format
5406                    })
5407                },
5408                pick_mut: |settings_content| {
5409                    language_settings_field_mut(settings_content, |language| {
5410                        &mut language.use_on_type_format
5411                    })
5412                },
5413            }),
5414            metadata: None,
5415            files: USER | LOCAL,
5416        }),
5417        SettingsPageItem::SectionHeader("Autoclose"),
5418        SettingsPageItem::SettingItem(SettingItem {
5419            title: "Use Autoclose",
5420            description: "Whether to automatically type closing characters for you. For example, when you type (, Zed will automatically add a closing ) at the correct position",
5421            field: Box::new(SettingField {
5422                pick: |settings_content| {
5423                    language_settings_field(settings_content, |language| &language.use_autoclose)
5424                },
5425                pick_mut: |settings_content| {
5426                    language_settings_field_mut(settings_content, |language| {
5427                        &mut language.use_autoclose
5428                    })
5429                },
5430            }),
5431            metadata: None,
5432            files: USER | LOCAL,
5433        }),
5434        SettingsPageItem::SettingItem(SettingItem {
5435            title: "Use Auto Surround",
5436            description: "Whether to automatically surround text with characters for you. For example, when you select text and type (, Zed will automatically surround text with ()",
5437            field: Box::new(SettingField {
5438                pick: |settings_content| {
5439                    language_settings_field(settings_content, |language| {
5440                        &language.use_auto_surround
5441                    })
5442                },
5443                pick_mut: |settings_content| {
5444                    language_settings_field_mut(settings_content, |language| {
5445                        &mut language.use_auto_surround
5446                    })
5447                },
5448            }),
5449            metadata: None,
5450            files: USER | LOCAL,
5451        }),
5452        SettingsPageItem::SettingItem(SettingItem {
5453            title: "Always Treat Brackets As Autoclosed",
5454            description: "Controls whether the closing characters are always skipped over and auto-removed no matter how they were inserted",
5455            field: Box::new(SettingField {
5456                pick: |settings_content| {
5457                    language_settings_field(settings_content, |language| {
5458                        &language.always_treat_brackets_as_autoclosed
5459                    })
5460                },
5461                pick_mut: |settings_content| {
5462                    language_settings_field_mut(settings_content, |language| {
5463                        &mut language.always_treat_brackets_as_autoclosed
5464                    })
5465                },
5466            }),
5467            metadata: None,
5468            files: USER | LOCAL,
5469        }),
5470        SettingsPageItem::SettingItem(SettingItem {
5471            title: "Jsx Tag Auto Close",
5472            description: "Whether to automatically close JSX tags",
5473            field: Box::new(SettingField {
5474                // TODO(settings_ui): this setting should just be a bool
5475                pick: |settings_content| {
5476                    language_settings_field(settings_content, |language| {
5477                        match language.jsx_tag_auto_close.as_ref() {
5478                            Some(s) => &s.enabled,
5479                            None => &None,
5480                        }
5481                    })
5482                },
5483                pick_mut: |settings_content| {
5484                    language_settings_field_mut(settings_content, |language| {
5485                        &mut language.jsx_tag_auto_close.get_or_insert_default().enabled
5486                    })
5487                },
5488            }),
5489            metadata: None,
5490            files: USER | LOCAL,
5491        }),
5492        SettingsPageItem::SectionHeader("Edit Predictions"),
5493        SettingsPageItem::SettingItem(SettingItem {
5494            title: "Show Edit Predictions",
5495            description: "Controls whether edit predictions are shown immediately (true) or manually by triggering `editor::ShowEditPrediction` (false)",
5496            field: Box::new(SettingField {
5497                pick: |settings_content| {
5498                    language_settings_field(settings_content, |language| {
5499                        &language.show_edit_predictions
5500                    })
5501                },
5502                pick_mut: |settings_content| {
5503                    language_settings_field_mut(settings_content, |language| {
5504                        &mut language.show_edit_predictions
5505                    })
5506                },
5507            }),
5508            metadata: None,
5509            files: USER | LOCAL,
5510        }),
5511        SettingsPageItem::SettingItem(SettingItem {
5512            title: "Edit Predictions Disabled In",
5513            description: "Controls whether edit predictions are shown in the given language scopes",
5514            field: Box::new(
5515                SettingField {
5516                    pick: |settings_content| {
5517                        language_settings_field(settings_content, |language| {
5518                            &language.edit_predictions_disabled_in
5519                        })
5520                    },
5521                    pick_mut: |settings_content| {
5522                        language_settings_field_mut(settings_content, |language| {
5523                            &mut language.edit_predictions_disabled_in
5524                        })
5525                    },
5526                }
5527                .unimplemented(),
5528            ),
5529            metadata: None,
5530            files: USER | LOCAL,
5531        }),
5532        SettingsPageItem::SectionHeader("Whitespace"),
5533        SettingsPageItem::SettingItem(SettingItem {
5534            title: "Show Whitespaces",
5535            description: "Whether to show tabs and spaces in the editor",
5536            field: Box::new(SettingField {
5537                pick: |settings_content| {
5538                    language_settings_field(settings_content, |language| &language.show_whitespaces)
5539                },
5540                pick_mut: |settings_content| {
5541                    language_settings_field_mut(settings_content, |language| {
5542                        &mut language.show_whitespaces
5543                    })
5544                },
5545            }),
5546            metadata: None,
5547            files: USER | LOCAL,
5548        }),
5549        SettingsPageItem::SettingItem(SettingItem {
5550            title: "Space Whitespace Indicator",
5551            description: "Visible character used to render space characters when show_whitespaces is enabled (default: \"•\")",
5552            field: Box::new(
5553                SettingField {
5554                    pick: |settings_content| {
5555                        language_settings_field(settings_content, |language| {
5556                            if let Some(whitespace_map) = &language.whitespace_map {
5557                                &whitespace_map.space
5558                            } else {
5559                                &None
5560                            }
5561                        })
5562                    },
5563                    pick_mut: |settings_content| {
5564                        language_settings_field_mut(settings_content, |language| {
5565                            &mut language.whitespace_map.get_or_insert_default().space
5566                        })
5567                    },
5568                }
5569                .unimplemented(),
5570            ),
5571            metadata: None,
5572            files: USER | LOCAL,
5573        }),
5574        SettingsPageItem::SettingItem(SettingItem {
5575            title: "Tab Whitespace Indicator",
5576            description: "Visible character used to render tab characters when show_whitespaces is enabled (default: \"→\")",
5577            field: Box::new(
5578                SettingField {
5579                    pick: |settings_content| {
5580                        language_settings_field(settings_content, |language| {
5581                            if let Some(whitespace_map) = &language.whitespace_map {
5582                                &whitespace_map.tab
5583                            } else {
5584                                &None
5585                            }
5586                        })
5587                    },
5588                    pick_mut: |settings_content| {
5589                        language_settings_field_mut(settings_content, |language| {
5590                            &mut language.whitespace_map.get_or_insert_default().tab
5591                        })
5592                    },
5593                }
5594                .unimplemented(),
5595            ),
5596            metadata: None,
5597            files: USER | LOCAL,
5598        }),
5599        SettingsPageItem::SectionHeader("Completions"),
5600        SettingsPageItem::SettingItem(SettingItem {
5601            title: "Show Completions On Input",
5602            description: "Whether to pop the completions menu while typing in an editor without explicitly requesting it",
5603            field: Box::new(SettingField {
5604                pick: |settings_content| {
5605                    language_settings_field(settings_content, |language| {
5606                        &language.show_completions_on_input
5607                    })
5608                },
5609                pick_mut: |settings_content| {
5610                    language_settings_field_mut(settings_content, |language| {
5611                        &mut language.show_completions_on_input
5612                    })
5613                },
5614            }),
5615            metadata: None,
5616            files: USER | LOCAL,
5617        }),
5618        SettingsPageItem::SettingItem(SettingItem {
5619            title: "Show Completion Documentation",
5620            description: "Whether to display inline and alongside documentation for items in the completions menu",
5621            field: Box::new(SettingField {
5622                pick: |settings_content| {
5623                    language_settings_field(settings_content, |language| {
5624                        &language.show_completion_documentation
5625                    })
5626                },
5627                pick_mut: |settings_content| {
5628                    language_settings_field_mut(settings_content, |language| {
5629                        &mut language.show_completion_documentation
5630                    })
5631                },
5632            }),
5633            metadata: None,
5634            files: USER | LOCAL,
5635        }),
5636        SettingsPageItem::SettingItem(SettingItem {
5637            title: "Words",
5638            description: "Controls how words are completed",
5639            field: Box::new(SettingField {
5640                pick: |settings_content| {
5641                    language_settings_field(settings_content, |language| {
5642                        if let Some(completions) = &language.completions {
5643                            &completions.words
5644                        } else {
5645                            &None
5646                        }
5647                    })
5648                },
5649                pick_mut: |settings_content| {
5650                    language_settings_field_mut(settings_content, |language| {
5651                        &mut language.completions.get_or_insert_default().words
5652                    })
5653                },
5654            }),
5655            metadata: None,
5656            files: USER | LOCAL,
5657        }),
5658        SettingsPageItem::SettingItem(SettingItem {
5659            title: "Words Min Length",
5660            description: "How many characters has to be in the completions query to automatically show the words-based completions",
5661            field: Box::new(SettingField {
5662                pick: |settings_content| {
5663                    language_settings_field(settings_content, |language| {
5664                        if let Some(completions) = &language.completions {
5665                            &completions.words_min_length
5666                        } else {
5667                            &None
5668                        }
5669                    })
5670                },
5671                pick_mut: |settings_content| {
5672                    language_settings_field_mut(settings_content, |language| {
5673                        &mut language
5674                            .completions
5675                            .get_or_insert_default()
5676                            .words_min_length
5677                    })
5678                },
5679            }),
5680            metadata: None,
5681            files: USER | LOCAL,
5682        }),
5683        SettingsPageItem::SectionHeader("Inlay Hints"),
5684        SettingsPageItem::SettingItem(SettingItem {
5685            title: "Enabled",
5686            description: "Global switch to toggle hints on and off",
5687            field: Box::new(SettingField {
5688                pick: |settings_content| {
5689                    language_settings_field(settings_content, |language| {
5690                        if let Some(inlay_hints) = &language.inlay_hints {
5691                            &inlay_hints.enabled
5692                        } else {
5693                            &None
5694                        }
5695                    })
5696                },
5697                pick_mut: |settings_content| {
5698                    language_settings_field_mut(settings_content, |language| {
5699                        &mut language.inlay_hints.get_or_insert_default().enabled
5700                    })
5701                },
5702            }),
5703            metadata: None,
5704            files: USER | LOCAL,
5705        }),
5706        SettingsPageItem::SettingItem(SettingItem {
5707            title: "Show Value Hints",
5708            description: "Global switch to toggle inline values on and off when debugging",
5709            field: Box::new(SettingField {
5710                pick: |settings_content| {
5711                    language_settings_field(settings_content, |language| {
5712                        if let Some(inlay_hints) = &language.inlay_hints {
5713                            &inlay_hints.show_value_hints
5714                        } else {
5715                            &None
5716                        }
5717                    })
5718                },
5719                pick_mut: |settings_content| {
5720                    language_settings_field_mut(settings_content, |language| {
5721                        &mut language
5722                            .inlay_hints
5723                            .get_or_insert_default()
5724                            .show_value_hints
5725                    })
5726                },
5727            }),
5728            metadata: None,
5729            files: USER | LOCAL,
5730        }),
5731        SettingsPageItem::SettingItem(SettingItem {
5732            title: "Show Type Hints",
5733            description: "Whether type hints should be shown",
5734            field: Box::new(SettingField {
5735                pick: |settings_content| {
5736                    language_settings_field(settings_content, |language| {
5737                        if let Some(inlay_hints) = &language.inlay_hints {
5738                            &inlay_hints.show_type_hints
5739                        } else {
5740                            &None
5741                        }
5742                    })
5743                },
5744                pick_mut: |settings_content| {
5745                    language_settings_field_mut(settings_content, |language| {
5746                        &mut language.inlay_hints.get_or_insert_default().show_type_hints
5747                    })
5748                },
5749            }),
5750            metadata: None,
5751            files: USER | LOCAL,
5752        }),
5753        SettingsPageItem::SettingItem(SettingItem {
5754            title: "Show Parameter Hints",
5755            description: "Whether parameter hints should be shown",
5756            field: Box::new(SettingField {
5757                pick: |settings_content| {
5758                    language_settings_field(settings_content, |language| {
5759                        if let Some(inlay_hints) = &language.inlay_hints {
5760                            &inlay_hints.show_parameter_hints
5761                        } else {
5762                            &None
5763                        }
5764                    })
5765                },
5766                pick_mut: |settings_content| {
5767                    language_settings_field_mut(settings_content, |language| {
5768                        &mut language
5769                            .inlay_hints
5770                            .get_or_insert_default()
5771                            .show_parameter_hints
5772                    })
5773                },
5774            }),
5775            metadata: None,
5776            files: USER | LOCAL,
5777        }),
5778        SettingsPageItem::SettingItem(SettingItem {
5779            title: "Show Other Hints",
5780            description: "Whether other hints should be shown",
5781            field: Box::new(SettingField {
5782                pick: |settings_content| {
5783                    language_settings_field(settings_content, |language| {
5784                        if let Some(inlay_hints) = &language.inlay_hints {
5785                            &inlay_hints.show_other_hints
5786                        } else {
5787                            &None
5788                        }
5789                    })
5790                },
5791                pick_mut: |settings_content| {
5792                    language_settings_field_mut(settings_content, |language| {
5793                        &mut language
5794                            .inlay_hints
5795                            .get_or_insert_default()
5796                            .show_other_hints
5797                    })
5798                },
5799            }),
5800            metadata: None,
5801            files: USER | LOCAL,
5802        }),
5803        SettingsPageItem::SettingItem(SettingItem {
5804            title: "Show Background",
5805            description: "Show a background for inlay hints",
5806            field: Box::new(SettingField {
5807                pick: |settings_content| {
5808                    language_settings_field(settings_content, |language| {
5809                        if let Some(inlay_hints) = &language.inlay_hints {
5810                            &inlay_hints.show_background
5811                        } else {
5812                            &None
5813                        }
5814                    })
5815                },
5816                pick_mut: |settings_content| {
5817                    language_settings_field_mut(settings_content, |language| {
5818                        &mut language.inlay_hints.get_or_insert_default().show_background
5819                    })
5820                },
5821            }),
5822            metadata: None,
5823            files: USER | LOCAL,
5824        }),
5825        SettingsPageItem::SettingItem(SettingItem {
5826            title: "Edit Debounce Ms",
5827            description: "Whether or not to debounce inlay hints updates after buffer edits (set to 0 to disable debouncing)",
5828            field: Box::new(SettingField {
5829                pick: |settings_content| {
5830                    language_settings_field(settings_content, |language| {
5831                        if let Some(inlay_hints) = &language.inlay_hints {
5832                            &inlay_hints.edit_debounce_ms
5833                        } else {
5834                            &None
5835                        }
5836                    })
5837                },
5838                pick_mut: |settings_content| {
5839                    language_settings_field_mut(settings_content, |language| {
5840                        &mut language
5841                            .inlay_hints
5842                            .get_or_insert_default()
5843                            .edit_debounce_ms
5844                    })
5845                },
5846            }),
5847            metadata: None,
5848            files: USER | LOCAL,
5849        }),
5850        SettingsPageItem::SettingItem(SettingItem {
5851            title: "Scroll Debounce Ms",
5852            description: "Whether or not to debounce inlay hints updates after buffer scrolls (set to 0 to disable debouncing)",
5853            field: Box::new(SettingField {
5854                pick: |settings_content| {
5855                    language_settings_field(settings_content, |language| {
5856                        if let Some(inlay_hints) = &language.inlay_hints {
5857                            &inlay_hints.scroll_debounce_ms
5858                        } else {
5859                            &None
5860                        }
5861                    })
5862                },
5863                pick_mut: |settings_content| {
5864                    language_settings_field_mut(settings_content, |language| {
5865                        &mut language
5866                            .inlay_hints
5867                            .get_or_insert_default()
5868                            .scroll_debounce_ms
5869                    })
5870                },
5871            }),
5872            metadata: None,
5873            files: USER | LOCAL,
5874        }),
5875        SettingsPageItem::SettingItem(SettingItem {
5876            title: "Toggle On Modifiers Press",
5877            description: "Toggles inlay hints (hides or shows) when the user presses the modifiers specified",
5878            field: Box::new(
5879                SettingField {
5880                    pick: |settings_content| {
5881                        language_settings_field(settings_content, |language| {
5882                            if let Some(inlay_hints) = &language.inlay_hints {
5883                                &inlay_hints.toggle_on_modifiers_press
5884                            } else {
5885                                &None
5886                            }
5887                        })
5888                    },
5889                    pick_mut: |settings_content| {
5890                        language_settings_field_mut(settings_content, |language| {
5891                            &mut language
5892                                .inlay_hints
5893                                .get_or_insert_default()
5894                                .toggle_on_modifiers_press
5895                        })
5896                    },
5897                }
5898                .unimplemented(),
5899            ),
5900            metadata: None,
5901            files: USER | LOCAL,
5902        }),
5903    ];
5904    if current_language().is_none() {
5905        items.push(SettingsPageItem::SettingItem(SettingItem {
5906            title: "LSP Document Colors",
5907            description: "How to render LSP color previews in the editor",
5908            field: Box::new(SettingField {
5909                pick: |settings_content| &settings_content.editor.lsp_document_colors,
5910                pick_mut: |settings_content| &mut settings_content.editor.lsp_document_colors,
5911            }),
5912            metadata: None,
5913            files: USER,
5914        }))
5915    }
5916    items.extend([
5917        SettingsPageItem::SectionHeader("Tasks"),
5918        SettingsPageItem::SettingItem(SettingItem {
5919            title: "Enabled",
5920            description: "Whether tasks are enabled for this language",
5921            field: Box::new(SettingField {
5922                pick: |settings_content| {
5923                    language_settings_field(settings_content, |language| {
5924                        if let Some(tasks) = &language.tasks {
5925                            &tasks.enabled
5926                        } else {
5927                            &None
5928                        }
5929                    })
5930                },
5931                pick_mut: |settings_content| {
5932                    language_settings_field_mut(settings_content, |language| {
5933                        &mut language.tasks.get_or_insert_default().enabled
5934                    })
5935                },
5936            }),
5937            metadata: None,
5938            files: USER | LOCAL,
5939        }),
5940        SettingsPageItem::SettingItem(SettingItem {
5941            title: "Variables",
5942            description: "Extra task variables to set for a particular language",
5943            field: Box::new(
5944                SettingField {
5945                    pick: |settings_content| {
5946                        language_settings_field(settings_content, |language| {
5947                            if let Some(tasks) = &language.tasks {
5948                                &tasks.variables
5949                            } else {
5950                                &None
5951                            }
5952                        })
5953                    },
5954                    pick_mut: |settings_content| {
5955                        language_settings_field_mut(settings_content, |language| {
5956                            &mut language.tasks.get_or_insert_default().variables
5957                        })
5958                    },
5959                }
5960                .unimplemented(),
5961            ),
5962            metadata: None,
5963            files: USER | LOCAL,
5964        }),
5965        SettingsPageItem::SettingItem(SettingItem {
5966            title: "Prefer LSP",
5967            description: "Use LSP tasks over Zed language extension tasks",
5968            field: Box::new(SettingField {
5969                pick: |settings_content| {
5970                    language_settings_field(settings_content, |language| {
5971                        if let Some(tasks) = &language.tasks {
5972                            &tasks.prefer_lsp
5973                        } else {
5974                            &None
5975                        }
5976                    })
5977                },
5978                pick_mut: |settings_content| {
5979                    language_settings_field_mut(settings_content, |language| {
5980                        &mut language.tasks.get_or_insert_default().prefer_lsp
5981                    })
5982                },
5983            }),
5984            metadata: None,
5985            files: USER | LOCAL,
5986        }),
5987        SettingsPageItem::SectionHeader("Miscellaneous"),
5988        SettingsPageItem::SettingItem(SettingItem {
5989            title: "Debuggers",
5990            description: "Preferred debuggers for this language",
5991            field: Box::new(
5992                SettingField {
5993                    pick: |settings_content| {
5994                        language_settings_field(settings_content, |language| &language.debuggers)
5995                    },
5996                    pick_mut: |settings_content| {
5997                        language_settings_field_mut(settings_content, |language| {
5998                            &mut language.debuggers
5999                        })
6000                    },
6001                }
6002                .unimplemented(),
6003            ),
6004            metadata: None,
6005            files: USER | LOCAL,
6006        }),
6007        SettingsPageItem::SettingItem(SettingItem {
6008            title: "Middle Click Paste",
6009            description: "Enable middle-click paste on Linux",
6010            field: Box::new(SettingField {
6011                pick: |settings_content| &settings_content.editor.middle_click_paste,
6012                pick_mut: |settings_content| &mut settings_content.editor.middle_click_paste,
6013            }),
6014            metadata: None,
6015            files: USER,
6016        }),
6017        SettingsPageItem::SettingItem(SettingItem {
6018            title: "Extend Comment On Newline",
6019            description: "Whether to start a new line with a comment when a previous line is a comment as well",
6020            field: Box::new(SettingField {
6021                pick: |settings_content| {
6022                    language_settings_field(settings_content, |language| {
6023                        &language.extend_comment_on_newline
6024                    })
6025                },
6026                pick_mut: |settings_content| {
6027                    language_settings_field_mut(settings_content, |language| {
6028                        &mut language.extend_comment_on_newline
6029                    })
6030                },
6031            }),
6032            metadata: None,
6033            files: USER | LOCAL,
6034        }),
6035    ]);
6036
6037    if current_language().is_none() {
6038        items.extend([
6039            SettingsPageItem::SettingItem(SettingItem {
6040                title: "Image Viewer",
6041                description: "The unit for image file sizes",
6042                field: Box::new(SettingField {
6043                    pick: |settings_content| {
6044                        if let Some(image_viewer) = settings_content.image_viewer.as_ref() {
6045                            &image_viewer.unit
6046                        } else {
6047                            &None
6048                        }
6049                    },
6050                    pick_mut: |settings_content| {
6051                        &mut settings_content.image_viewer.get_or_insert_default().unit
6052                    },
6053                }),
6054                metadata: None,
6055                files: USER,
6056            }),
6057            SettingsPageItem::SettingItem(SettingItem {
6058                title: "Auto Replace Emoji Shortcode",
6059                description: "Whether to automatically replace emoji shortcodes with emoji characters",
6060                field: Box::new(SettingField {
6061                    pick: |settings_content| {
6062                        if let Some(message_editor) = settings_content.message_editor.as_ref() {
6063                            &message_editor.auto_replace_emoji_shortcode
6064                        } else {
6065                            &None
6066                        }
6067                    },
6068                    pick_mut: |settings_content| {
6069                        &mut settings_content.message_editor.get_or_insert_default().auto_replace_emoji_shortcode
6070                    },
6071                }),
6072                metadata: None,
6073                files: USER,
6074            }),
6075            SettingsPageItem::SettingItem(SettingItem {
6076                title: "Drop Size Target",
6077                description: "Relative size of the drop target in the editor that will open dropped file as a split pane",
6078                field: Box::new(SettingField {
6079                    pick: |settings_content| {
6080                        &settings_content.workspace.drop_target_size
6081                    },
6082                    pick_mut: |settings_content| {
6083                        &mut settings_content.workspace.drop_target_size
6084                    },
6085                }),
6086                metadata: None,
6087                files: USER,
6088            }),
6089        ]);
6090    }
6091    items
6092}
6093
6094/// LanguageSettings items that should be included in the "Languages & Tools" page
6095/// not the "Editor" page
6096fn non_editor_language_settings_data() -> Vec<SettingsPageItem> {
6097    vec![
6098        SettingsPageItem::SectionHeader("LSP"),
6099        SettingsPageItem::SettingItem(SettingItem {
6100            title: "Enable Language Server",
6101            description: "Whether to use language servers to provide code intelligence",
6102            field: Box::new(SettingField {
6103                pick: |settings_content| {
6104                    language_settings_field(settings_content, |language| {
6105                        &language.enable_language_server
6106                    })
6107                },
6108                pick_mut: |settings_content| {
6109                    language_settings_field_mut(settings_content, |language| {
6110                        &mut language.enable_language_server
6111                    })
6112                },
6113            }),
6114            metadata: None,
6115            files: USER | LOCAL,
6116        }),
6117        SettingsPageItem::SettingItem(SettingItem {
6118            title: "Language Servers",
6119            description: "The list of language servers to use (or disable) for this language",
6120            field: Box::new(
6121                SettingField {
6122                    pick: |settings_content| {
6123                        language_settings_field(settings_content, |language| {
6124                            &language.language_servers
6125                        })
6126                    },
6127                    pick_mut: |settings_content| {
6128                        language_settings_field_mut(settings_content, |language| {
6129                            &mut language.language_servers
6130                        })
6131                    },
6132                }
6133                .unimplemented(),
6134            ),
6135            metadata: None,
6136            files: USER | LOCAL,
6137        }),
6138        SettingsPageItem::SettingItem(SettingItem {
6139            title: "Linked Edits",
6140            description: "Whether to perform linked edits of associated ranges, if the LS supports it. For example, when editing opening <html> tag, the contents of the closing </html> tag will be edited as well",
6141            field: Box::new(SettingField {
6142                pick: |settings_content| {
6143                    language_settings_field(settings_content, |language| &language.linked_edits)
6144                },
6145                pick_mut: |settings_content| {
6146                    language_settings_field_mut(settings_content, |language| {
6147                        &mut language.linked_edits
6148                    })
6149                },
6150            }),
6151            metadata: None,
6152            files: USER | LOCAL,
6153        }),
6154        SettingsPageItem::SettingItem(SettingItem {
6155            title: "Go To Definition Fallback",
6156            description: "Whether to follow-up empty go to definition responses from the language server",
6157            field: Box::new(SettingField {
6158                pick: |settings_content| &settings_content.editor.go_to_definition_fallback,
6159                pick_mut: |settings_content| &mut settings_content.editor.go_to_definition_fallback,
6160            }),
6161            metadata: None,
6162            files: USER,
6163        }),
6164        SettingsPageItem::SectionHeader("LSP Completions"),
6165        SettingsPageItem::SettingItem(SettingItem {
6166            title: "Enabled",
6167            description: "Whether to fetch LSP completions or not",
6168            field: Box::new(SettingField {
6169                pick: |settings_content| {
6170                    language_settings_field(settings_content, |language| {
6171                        if let Some(completions) = &language.completions {
6172                            &completions.lsp
6173                        } else {
6174                            &None
6175                        }
6176                    })
6177                },
6178                pick_mut: |settings_content| {
6179                    language_settings_field_mut(settings_content, |language| {
6180                        &mut language.completions.get_or_insert_default().lsp
6181                    })
6182                },
6183            }),
6184            metadata: None,
6185            files: USER | LOCAL,
6186        }),
6187        SettingsPageItem::SettingItem(SettingItem {
6188            title: "Fetch Timeout (milliseconds)",
6189            description: "When fetching LSP completions, determines how long to wait for a response of a particular server (set to 0 to wait indefinitely)",
6190            field: Box::new(SettingField {
6191                pick: |settings_content| {
6192                    language_settings_field(settings_content, |language| {
6193                        if let Some(completions) = &language.completions {
6194                            &completions.lsp_fetch_timeout_ms
6195                        } else {
6196                            &None
6197                        }
6198                    })
6199                },
6200                pick_mut: |settings_content| {
6201                    language_settings_field_mut(settings_content, |language| {
6202                        &mut language
6203                            .completions
6204                            .get_or_insert_default()
6205                            .lsp_fetch_timeout_ms
6206                    })
6207                },
6208            }),
6209            metadata: None,
6210            files: USER | LOCAL,
6211        }),
6212        SettingsPageItem::SettingItem(SettingItem {
6213            title: "Insert Mode",
6214            description: "Controls how LSP completions are inserted",
6215            field: Box::new(SettingField {
6216                pick: |settings_content| {
6217                    language_settings_field(settings_content, |language| {
6218                        if let Some(completions) = &language.completions {
6219                            &completions.lsp_insert_mode
6220                        } else {
6221                            &None
6222                        }
6223                    })
6224                },
6225                pick_mut: |settings_content| {
6226                    language_settings_field_mut(settings_content, |language| {
6227                        &mut language.completions.get_or_insert_default().lsp_insert_mode
6228                    })
6229                },
6230            }),
6231            metadata: None,
6232            files: USER | LOCAL,
6233        }),
6234        SettingsPageItem::SectionHeader("Debuggers"),
6235        SettingsPageItem::SettingItem(SettingItem {
6236            title: "Debuggers",
6237            description: "Preferred debuggers for this language",
6238            field: Box::new(
6239                SettingField {
6240                    pick: |settings_content| {
6241                        language_settings_field(settings_content, |language| &language.debuggers)
6242                    },
6243                    pick_mut: |settings_content| {
6244                        language_settings_field_mut(settings_content, |language| {
6245                            &mut language.debuggers
6246                        })
6247                    },
6248                }
6249                .unimplemented(),
6250            ),
6251            metadata: None,
6252            files: USER | LOCAL,
6253        }),
6254        SettingsPageItem::SectionHeader("Prettier"),
6255        SettingsPageItem::SettingItem(SettingItem {
6256            title: "Allowed",
6257            description: "Enables or disables formatting with Prettier for a given language",
6258            field: Box::new(SettingField {
6259                pick: |settings_content| {
6260                    language_settings_field(settings_content, |language| {
6261                        if let Some(prettier) = &language.prettier {
6262                            &prettier.allowed
6263                        } else {
6264                            &None
6265                        }
6266                    })
6267                },
6268                pick_mut: |settings_content| {
6269                    language_settings_field_mut(settings_content, |language| {
6270                        &mut language.prettier.get_or_insert_default().allowed
6271                    })
6272                },
6273            }),
6274            metadata: None,
6275            files: USER | LOCAL,
6276        }),
6277        SettingsPageItem::SettingItem(SettingItem {
6278            title: "Parser",
6279            description: "Forces Prettier integration to use a specific parser name when formatting files with the language",
6280            field: Box::new(SettingField {
6281                pick: |settings_content| {
6282                    language_settings_field(settings_content, |language| {
6283                        if let Some(prettier) = &language.prettier {
6284                            &prettier.parser
6285                        } else {
6286                            &None
6287                        }
6288                    })
6289                },
6290                pick_mut: |settings_content| {
6291                    language_settings_field_mut(settings_content, |language| {
6292                        &mut language.prettier.get_or_insert_default().parser
6293                    })
6294                },
6295            }),
6296            metadata: None,
6297            files: USER | LOCAL,
6298        }),
6299        SettingsPageItem::SettingItem(SettingItem {
6300            title: "Plugins",
6301            description: "Forces Prettier integration to use specific plugins when formatting files with the language",
6302            field: Box::new(
6303                SettingField {
6304                    pick: |settings_content| {
6305                        language_settings_field(settings_content, |language| {
6306                            if let Some(prettier) = &language.prettier {
6307                                &prettier.plugins
6308                            } else {
6309                                &None
6310                            }
6311                        })
6312                    },
6313                    pick_mut: |settings_content| {
6314                        language_settings_field_mut(settings_content, |language| {
6315                            &mut language.prettier.get_or_insert_default().plugins
6316                        })
6317                    },
6318                }
6319                .unimplemented(),
6320            ),
6321            metadata: None,
6322            files: USER | LOCAL,
6323        }),
6324        SettingsPageItem::SettingItem(SettingItem {
6325            title: "Options",
6326            description: "Default Prettier options, in the format as in package.json section for Prettier",
6327            field: Box::new(
6328                SettingField {
6329                    pick: |settings_content| {
6330                        language_settings_field(settings_content, |language| {
6331                            if let Some(prettier) = &language.prettier {
6332                                &prettier.options
6333                            } else {
6334                                &None
6335                            }
6336                        })
6337                    },
6338                    pick_mut: |settings_content| {
6339                        language_settings_field_mut(settings_content, |language| {
6340                            &mut language.prettier.get_or_insert_default().options
6341                        })
6342                    },
6343                }
6344                .unimplemented(),
6345            ),
6346            metadata: None,
6347            files: USER | LOCAL,
6348        }),
6349    ]
6350}